asd
This commit is contained in:
parent
ff747c9013
commit
29ed0b6a13
10 changed files with 203 additions and 153 deletions
|
@ -14,6 +14,10 @@ public class NotEncoder implements OpusEncoder {
|
|||
this.size = opusFrames.length;
|
||||
}
|
||||
|
||||
public void seek(int frame) {
|
||||
i = Math.clamp(frame, 0, size);
|
||||
}
|
||||
|
||||
public boolean hasRemaining() {
|
||||
return i < size;
|
||||
}
|
||||
|
|
|
@ -40,77 +40,53 @@ public class ItemEvents implements Listener {
|
|||
}
|
||||
} else {
|
||||
if (right) {
|
||||
System.out.println("shirt + rmb open inventory");
|
||||
// TODO open inventory
|
||||
} else {
|
||||
System.out.println("shift + lmb bind spekar");
|
||||
System.out.println("shift + rmb bind spekar");
|
||||
|
||||
var block = event.getClickedBlock();
|
||||
if (block != null) {
|
||||
if (block.getType() == Material.NOTE_BLOCK) {
|
||||
var speaker = BlockSpeaker.create(block.getLocation());
|
||||
if (speaker != null) {
|
||||
player.setSpeaker(speaker);
|
||||
block.getWorld().spawnParticle(Particle.HAPPY_VILLAGER, block.getLocation(), 10);
|
||||
event.setCancelled(true); // prevent break
|
||||
} else {
|
||||
event.getPlayer().sendMessage("This speaker is occupied");
|
||||
}
|
||||
var location = block.getLocation().add(0.5, 0.5, 0.5);
|
||||
var speaker = BlockSpeaker.create(location);
|
||||
|
||||
player.setSpeaker(speaker);
|
||||
block.getWorld().spawnParticle(Particle.HAPPY_VILLAGER, block.getLocation(), 10);
|
||||
|
||||
event.setCancelled(true); // prevent break
|
||||
}
|
||||
}
|
||||
}
|
||||
// originally inventory was supposed to be here
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(EntityDeathEvent event) {
|
||||
if (event.getEntity() instanceof Item item) {
|
||||
var id = PortableMediaPlayer.idFromItemStack(item.getItemStack());
|
||||
if (id == -1) return;
|
||||
|
||||
System.out.println("A player ded");
|
||||
|
||||
Speakers.destroy(id);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDespawn(ItemDespawnEvent event) {
|
||||
var id = PortableMediaPlayer.idFromItemStack(event.getEntity().getItemStack());
|
||||
if (id == -1) return;
|
||||
|
||||
System.out.println("A player despeawnd");
|
||||
|
||||
Speakers.destroy(id);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDrop(PlayerDropItemEvent event) {
|
||||
var id = PortableMediaPlayer.idFromItemStack(event.getItemDrop().getItemStack());
|
||||
if (id == -1) return;
|
||||
var item = PortableMediaPlayer.fromItemStack(event.getItemDrop().getItemStack());
|
||||
if (item == null) return;
|
||||
|
||||
System.out.println("A playe rdropped");
|
||||
|
||||
Speakers.attachTo(id, event.getItemDrop());
|
||||
item.stop();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPickup(EntityPickupItemEvent event) {
|
||||
var id = PortableMediaPlayer.idFromItemStack(event.getItem().getItemStack());
|
||||
if (id == -1) return;
|
||||
var item = PortableMediaPlayer.fromItemStack(event.getItem().getItemStack());
|
||||
if (item == null) return;
|
||||
|
||||
System.out.println("A player puckuperd");
|
||||
|
||||
Speakers.attachTo(id, event.getEntity());
|
||||
// TODO do somehting?
|
||||
}
|
||||
|
||||
public void onMove(InventoryMoveItemEvent event) {
|
||||
if (event.getDestination().getType() == InventoryType.PLAYER) {
|
||||
var id = PortableMediaPlayer.idFromItemStack(event.getItem());
|
||||
if (id == -1) return;
|
||||
var item = PortableMediaPlayer.fromItemStack(event.getItem());
|
||||
if (item == null) return;
|
||||
|
||||
System.out.println("A player storaged :((");
|
||||
|
||||
Speakers.destroy(id);
|
||||
item.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package eu.m724.musicPlugin.item;
|
|||
|
||||
import eu.m724.musicPlugin.item.speaker.Speaker;
|
||||
import eu.m724.musicPlugin.player.MovingMusicPlayer;
|
||||
import eu.m724.musicPlugin.player.MusicPlayer;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
|
@ -17,8 +16,8 @@ import java.util.List;
|
|||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class PortableMediaPlayer {
|
||||
private static NamespacedKey idKey = new NamespacedKey("tweaks724", "player_id");
|
||||
private static NamespacedKey dataKey = new NamespacedKey("tweaks724", "player_data");
|
||||
static NamespacedKey idKey = new NamespacedKey("tweaks724", "player_id");
|
||||
static NamespacedKey dataKey = new NamespacedKey("tweaks724", "player_data");
|
||||
|
||||
public final int id;
|
||||
|
||||
|
@ -29,10 +28,7 @@ public class PortableMediaPlayer {
|
|||
public final boolean premium;
|
||||
public final String engraving;
|
||||
|
||||
private final MovingMusicPlayer musicPlayer = new MovingMusicPlayer();
|
||||
private Speaker linkedSpeaker;
|
||||
|
||||
public PortableMediaPlayer(int id, int storageSeconds, int audioBitrate, boolean premium, String engraving) {
|
||||
PortableMediaPlayer(int id, int storageSeconds, int audioBitrate, boolean premium, String engraving) {
|
||||
this.id = id;
|
||||
this.storageSeconds = storageSeconds;
|
||||
this.audioBitrate = audioBitrate;
|
||||
|
@ -44,22 +40,33 @@ public class PortableMediaPlayer {
|
|||
return new PortableMediaPlayer(ThreadLocalRandom.current().nextInt(), 600, 32000, premium, engraving);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
Speakers.speakers.remove(id).destroy();
|
||||
getMusicPlayer().stop();
|
||||
Speakers.players.remove(id);
|
||||
}
|
||||
|
||||
public void setSpeaker(Speaker speaker) {
|
||||
Speakers.speakers.put(id, )
|
||||
if (speaker.equals(linkedSpeaker))
|
||||
var linked = Speakers.speakers.get(id);
|
||||
if (speaker.equals(linked))
|
||||
return;
|
||||
|
||||
if (linkedSpeaker != null)
|
||||
linkedSpeaker.destroy();
|
||||
if (linked != null)
|
||||
linked.destroy();
|
||||
|
||||
linkedSpeaker = speaker;
|
||||
speaker.setMusicPlayer(musicPlayer);
|
||||
var paused = getMusicPlayer().isPlaying();
|
||||
speaker.setMusicPlayer(getMusicPlayer());
|
||||
speaker.setDestroyCallback(c -> this.onSpeakerDestroyed());
|
||||
if (paused) getMusicPlayer().unpause();
|
||||
Speakers.speakers.put(id, speaker);
|
||||
}
|
||||
|
||||
public MusicPlayer getMusicPlayer() {
|
||||
return musicPlayer;
|
||||
public MovingMusicPlayer getMusicPlayer() {
|
||||
return Speakers.players.computeIfAbsent(id, m -> new MovingMusicPlayer());
|
||||
}
|
||||
|
||||
/* Item functions */
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
var is = new ItemStack(Material.IRON_INGOT);
|
||||
var meta = is.getItemMeta();
|
||||
|
@ -77,29 +84,6 @@ public class PortableMediaPlayer {
|
|||
return is;
|
||||
}
|
||||
|
||||
public static int idFromItemStack(ItemStack itemStack) {
|
||||
var meta = itemStack.getItemMeta();
|
||||
if (meta == null) return -1;
|
||||
|
||||
var id = meta.getPersistentDataContainer().get(idKey, PersistentDataType.INTEGER);
|
||||
if (id == null) return -1;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public static PortableMediaPlayer fromItemStack(ItemStack itemStack) {
|
||||
var meta = itemStack.getItemMeta();
|
||||
if (meta == null) return null;
|
||||
|
||||
var id = meta.getPersistentDataContainer().get(idKey, PersistentDataType.INTEGER);
|
||||
if (id == null) return null;
|
||||
|
||||
var data = meta.getPersistentDataContainer().get(dataKey, PersistentDataType.BYTE_ARRAY);
|
||||
if (data == null) return null;
|
||||
|
||||
return fromData(id, data);
|
||||
}
|
||||
|
||||
private byte[] getData() {
|
||||
var buffer = ByteBuffer.allocate(11 + engraving.length());
|
||||
buffer.put((byte) 0); // version
|
||||
|
@ -113,23 +97,4 @@ public class PortableMediaPlayer {
|
|||
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
private static PortableMediaPlayer fromData(int id, byte[] data) {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
|
||||
if (buffer.get() != 0) { // TODO version mismatch
|
||||
|
||||
}
|
||||
|
||||
var premium = buffer.get() == 1;
|
||||
|
||||
var storageSeconds = buffer.getShort() & 0xFFFF;
|
||||
var audioBitrate = (buffer.get() & 0xFF) * 1000;
|
||||
|
||||
var eb = new byte[buffer.get() & 0xFF];
|
||||
buffer.get(eb);
|
||||
var engraving = new String(eb, StandardCharsets.UTF_8);
|
||||
|
||||
return new PortableMediaPlayer(id, storageSeconds, audioBitrate, premium, engraving);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package eu.m724.musicPlugin.item;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
// This class stores PortableMediaPlayer instances so that there's no hassle of working with a new one every time
|
||||
public class PortableMediaPlayers {
|
||||
private static Map<Integer, PortableMediaPlayer> players = new HashMap<>();
|
||||
|
||||
public static PortableMediaPlayer get(Integer id) {
|
||||
return players.get(id);
|
||||
}
|
||||
|
||||
public static PortableMediaPlayer get(ItemStack itemStack) {
|
||||
var meta = itemStack.getItemMeta();
|
||||
if (meta == null) return null;
|
||||
|
||||
var id = meta.getPersistentDataContainer().get(PortableMediaPlayer.idKey, PersistentDataType.INTEGER);
|
||||
if (id == null) return null;
|
||||
|
||||
// check cache
|
||||
|
||||
var player = players.get(id);
|
||||
if (player != null) return player;
|
||||
|
||||
// if not cached
|
||||
|
||||
var data = meta.getPersistentDataContainer().get(PortableMediaPlayer.dataKey, PersistentDataType.BYTE_ARRAY);
|
||||
if (data == null) return null;
|
||||
|
||||
player = fromData(id, data);
|
||||
players.put(id, player);
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
private static PortableMediaPlayer fromData(int id, byte[] data) {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(data);
|
||||
|
||||
if (buffer.get() != 0) { // TODO version mismatch
|
||||
|
||||
}
|
||||
|
||||
var premium = buffer.get() == 1;
|
||||
|
||||
var storageSeconds = buffer.getShort() & 0xFFFF;
|
||||
var audioBitrate = (buffer.get() & 0xFF) * 1000;
|
||||
|
||||
var eb = new byte[buffer.get() & 0xFF];
|
||||
buffer.get(eb);
|
||||
var engraving = new String(eb, StandardCharsets.UTF_8);
|
||||
|
||||
return new PortableMediaPlayer(id, storageSeconds, audioBitrate, premium, engraving);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,7 @@
|
|||
package eu.m724.musicPlugin.item;
|
||||
|
||||
import eu.m724.musicPlugin.item.speaker.BlockSpeaker;
|
||||
import eu.m724.musicPlugin.item.speaker.Speaker;
|
||||
import eu.m724.musicPlugin.player.MovingMusicPlayer;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -13,21 +9,4 @@ import java.util.Map;
|
|||
public class Speakers {
|
||||
static Map<Integer, Speaker> speakers = new HashMap<>();
|
||||
static Map<Integer, MovingMusicPlayer> players = new HashMap<>();
|
||||
|
||||
static Speaker get(int id) {
|
||||
return speakers.get(id);
|
||||
}
|
||||
|
||||
static void destroy(int id) {
|
||||
var s = speakers.remove(id);
|
||||
if (s != null) s.destroy();
|
||||
}
|
||||
|
||||
static void moveTo(int id, Location location) {
|
||||
//speakers.computeIfAbsent(id, i -> new Speaker()).moveTo(location);
|
||||
}
|
||||
|
||||
static void attachTo(int id, Entity entity) {
|
||||
//speakers.computeIfAbsent(id, i -> new Speaker()).attachTo(entity);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package eu.m724.musicPlugin.item.speaker;
|
||||
|
||||
import eu.m724.musicPlugin.player.MovingMusicPlayer;
|
||||
import eu.m724.musicPlugin.player.MusicPlayer;
|
||||
import eu.m724.musicPlugin.player.StaticMusicPlayer;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
|
@ -2,24 +2,37 @@ package eu.m724.musicPlugin.item.speaker;
|
|||
|
||||
import eu.m724.musicPlugin.player.MovingMusicPlayer;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class Speaker {
|
||||
private MovingMusicPlayer musicPlayer;
|
||||
private Consumer<Void> destroyCallback;
|
||||
|
||||
public MovingMusicPlayer getMusicPlayer() {
|
||||
return musicPlayer;
|
||||
}
|
||||
|
||||
public void setMusicPlayer(MovingMusicPlayer musicPlayer) {
|
||||
if (musicPlayer != null) {
|
||||
if (musicPlayer.equals(this.musicPlayer)) return;
|
||||
|
||||
if (this.musicPlayer != null) {
|
||||
musicPlayer.pause();
|
||||
}
|
||||
|
||||
this.musicPlayer = musicPlayer;
|
||||
onSetMusicPlayer(musicPlayer);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
this.musicPlayer.stop();
|
||||
this.musicPlayer.pause();
|
||||
this.musicPlayer = null;
|
||||
|
||||
onDestroy();
|
||||
destroyCallback.accept(null);
|
||||
}
|
||||
|
||||
public void setDestroyCallback(Consumer<Void> consumer) {
|
||||
this.destroyCallback = consumer;
|
||||
}
|
||||
|
||||
abstract void onSetMusicPlayer(MovingMusicPlayer musicPlayer);
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package eu.m724.musicPlugin.player;
|
||||
|
||||
import de.maxhenkel.voicechat.api.ServerLevel;
|
||||
import de.maxhenkel.voicechat.api.VoicechatConnection;
|
||||
import de.maxhenkel.voicechat.api.audiochannel.AudioChannel;
|
||||
import eu.m724.musicPlugin.Statics;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class LocalMusicPlayer extends MusicPlayer {
|
||||
private final ServerLevel level;
|
||||
private final VoicechatConnection connection;
|
||||
|
||||
public LocalMusicPlayer(Player player) throws NotConnectedException {
|
||||
this.level = Statics.api.fromServerLevel(player.getWorld());
|
||||
this.connection = Statics.api.getConnectionOf(player.getUniqueId());
|
||||
|
||||
if (connection == null) {
|
||||
throw new NotConnectedException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
AudioChannel createChannel() {
|
||||
var channel = api.createStaticAudioChannel(
|
||||
UUID.randomUUID(),
|
||||
level,
|
||||
connection
|
||||
);
|
||||
|
||||
channel.setCategory("musicc");
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
public static class NotConnectedException extends Exception {}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package eu.m724.musicPlugin.player;
|
||||
|
||||
import de.maxhenkel.voicechat.api.audiochannel.AudioChannel;
|
||||
import de.maxhenkel.voicechat.api.audiochannel.LocationalAudioChannel;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
|
@ -12,18 +11,14 @@ public class MovingMusicPlayer extends MusicPlayer {
|
|||
private Location location;
|
||||
|
||||
public void moveTo(Location location) {
|
||||
if (channel == null || !location.getWorld().equals(this.location.getWorld())) {
|
||||
this.location = location;
|
||||
this.channel = createChannel();
|
||||
System.out.println("Mvoed to a");
|
||||
|
||||
if (isPlaying()) {
|
||||
this.pause();
|
||||
this.unpause();
|
||||
}
|
||||
} else {
|
||||
((LocationalAudioChannel)channel).updateLocation(
|
||||
api.createPosition(location.getX(), location.getY(), location.getZ())
|
||||
);
|
||||
this.location = location;
|
||||
this.channel = createChannel();
|
||||
|
||||
if (isReady() && !isPlaying()) {
|
||||
this.pause();
|
||||
this.unpause();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package eu.m724.musicPlugin.player;
|
|||
import de.maxhenkel.voicechat.api.VoicechatServerApi;
|
||||
import de.maxhenkel.voicechat.api.audiochannel.AudioChannel;
|
||||
import de.maxhenkel.voicechat.api.audiochannel.AudioPlayer;
|
||||
import de.maxhenkel.voicechat.api.audiochannel.LocationalAudioChannel;
|
||||
import eu.m724.musicPlugin.Statics;
|
||||
import eu.m724.musicPlugin.file.AudioFile;
|
||||
|
||||
|
@ -15,7 +16,7 @@ public abstract class MusicPlayer {
|
|||
|
||||
AudioChannel channel;
|
||||
|
||||
private boolean playing = false, paused = false;
|
||||
private boolean ready = false, playing = false;
|
||||
private AudioPlayer player;
|
||||
private AudioFile audioFile;
|
||||
|
||||
|
@ -54,7 +55,7 @@ public abstract class MusicPlayer {
|
|||
if (audioFile != null)
|
||||
this.audioFile = audioFile;
|
||||
|
||||
if (playing)
|
||||
if (ready)
|
||||
stop();
|
||||
|
||||
if (!audioFile.isLoaded()) {
|
||||
|
@ -65,11 +66,15 @@ public abstract class MusicPlayer {
|
|||
}
|
||||
}
|
||||
|
||||
ready = true;
|
||||
playing = true;
|
||||
|
||||
unpause();
|
||||
}
|
||||
|
||||
public void unpause() {
|
||||
if (playing) return;
|
||||
if (!ready || !playing) return;
|
||||
System.out.println("Unapised");
|
||||
|
||||
var sa = new short[960];
|
||||
var enc = audioFile.getEncoder();
|
||||
|
@ -79,18 +84,18 @@ public abstract class MusicPlayer {
|
|||
player.startPlaying();
|
||||
|
||||
// TODO this may take a long time and it might glitch if it does
|
||||
onAction.accept(playing ? TrackAction.UNPAUSE : TrackAction.START);
|
||||
onAction.accept(ready ? TrackAction.UNPAUSE : TrackAction.START);
|
||||
|
||||
playing = true;
|
||||
paused = false;
|
||||
playing = false;
|
||||
|
||||
System.out.println("unpaused");
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops playback and rewinds
|
||||
*/
|
||||
public void stop() {
|
||||
if (!playing) return;
|
||||
if (!ready) return;
|
||||
|
||||
stopPlayback(false);
|
||||
audioFile.getEncoder().resetState();
|
||||
|
@ -100,18 +105,27 @@ public abstract class MusicPlayer {
|
|||
* Pauses playback
|
||||
*/
|
||||
public void pause() {
|
||||
if (!ready || playing) return;
|
||||
stopPlayback(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek to some point in current track
|
||||
*
|
||||
* @param target the target time in milliseconds
|
||||
*/
|
||||
public void seek(int target) {
|
||||
audioFile.getEncoder().seek(target / 20); // a frame is 20 ms usually
|
||||
}
|
||||
|
||||
|
||||
/* Internal methods */
|
||||
|
||||
|
||||
private void stopPlayback(boolean pause) {
|
||||
if (!playing) return;
|
||||
|
||||
paused = pause;
|
||||
playing = false;
|
||||
System.out.println("psued");
|
||||
playing = pause;
|
||||
ready = pause;
|
||||
|
||||
player.stopPlaying();
|
||||
player = null;
|
||||
|
@ -120,13 +134,17 @@ public abstract class MusicPlayer {
|
|||
}
|
||||
|
||||
private void onStop() {
|
||||
if (paused) // paused
|
||||
if (playing) { // paused
|
||||
System.out.println("I detected pause");
|
||||
onAction.accept(TrackAction.PAUSE);
|
||||
else if (playing) { // not paused and still playing
|
||||
} else if (ready) { // not paused and still playing
|
||||
System.out.println("I detected end");
|
||||
onAction.accept(TrackAction.DURATION);
|
||||
playing = false;
|
||||
} else // not playing
|
||||
ready = false;
|
||||
} else { // not playing
|
||||
System.out.println("I detected stop");
|
||||
onAction.accept(TrackAction.STOP);
|
||||
}
|
||||
}
|
||||
|
||||
public enum TrackAction {
|
||||
|
@ -152,7 +170,11 @@ public abstract class MusicPlayer {
|
|||
UNPAUSE
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return ready;
|
||||
}
|
||||
|
||||
public boolean isPlaying() {
|
||||
return playing;
|
||||
return ready && playing;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue