From 29ed0b6a137e5e8c84bf4ef375ae49b73dee730a Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Wed, 18 Dec 2024 19:59:07 +0100 Subject: [PATCH] asd --- .../eu/m724/musicPlugin/file/NotEncoder.java | 4 + .../eu/m724/musicPlugin/item/ItemEvents.java | 62 +++++---------- .../musicPlugin/item/PortableMediaPlayer.java | 79 ++++++------------- .../item/PortableMediaPlayers.java | 60 ++++++++++++++ .../eu/m724/musicPlugin/item/Speakers.java | 21 ----- .../item/speaker/BlockSpeaker.java | 2 - .../musicPlugin/item/speaker/Speaker.java | 17 +++- .../musicPlugin/player/LocalMusicPlayer.java | 38 +++++++++ .../musicPlugin/player/MovingMusicPlayer.java | 19 ++--- .../m724/musicPlugin/player/MusicPlayer.java | 54 +++++++++---- 10 files changed, 203 insertions(+), 153 deletions(-) create mode 100644 src/main/java/eu/m724/musicPlugin/item/PortableMediaPlayers.java create mode 100644 src/main/java/eu/m724/musicPlugin/player/LocalMusicPlayer.java diff --git a/src/main/java/eu/m724/musicPlugin/file/NotEncoder.java b/src/main/java/eu/m724/musicPlugin/file/NotEncoder.java index 346f9f5..79a3527 100644 --- a/src/main/java/eu/m724/musicPlugin/file/NotEncoder.java +++ b/src/main/java/eu/m724/musicPlugin/file/NotEncoder.java @@ -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; } diff --git a/src/main/java/eu/m724/musicPlugin/item/ItemEvents.java b/src/main/java/eu/m724/musicPlugin/item/ItemEvents.java index bb1141f..b436101 100644 --- a/src/main/java/eu/m724/musicPlugin/item/ItemEvents.java +++ b/src/main/java/eu/m724/musicPlugin/item/ItemEvents.java @@ -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(); } } } diff --git a/src/main/java/eu/m724/musicPlugin/item/PortableMediaPlayer.java b/src/main/java/eu/m724/musicPlugin/item/PortableMediaPlayer.java index cb52743..e40e523 100644 --- a/src/main/java/eu/m724/musicPlugin/item/PortableMediaPlayer.java +++ b/src/main/java/eu/m724/musicPlugin/item/PortableMediaPlayer.java @@ -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); - } } diff --git a/src/main/java/eu/m724/musicPlugin/item/PortableMediaPlayers.java b/src/main/java/eu/m724/musicPlugin/item/PortableMediaPlayers.java new file mode 100644 index 0000000..ebf7571 --- /dev/null +++ b/src/main/java/eu/m724/musicPlugin/item/PortableMediaPlayers.java @@ -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 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); + } +} diff --git a/src/main/java/eu/m724/musicPlugin/item/Speakers.java b/src/main/java/eu/m724/musicPlugin/item/Speakers.java index 53d231b..e28e87d 100644 --- a/src/main/java/eu/m724/musicPlugin/item/Speakers.java +++ b/src/main/java/eu/m724/musicPlugin/item/Speakers.java @@ -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 speakers = new HashMap<>(); static Map 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); - } } diff --git a/src/main/java/eu/m724/musicPlugin/item/speaker/BlockSpeaker.java b/src/main/java/eu/m724/musicPlugin/item/speaker/BlockSpeaker.java index 77cc9e7..02a929f 100644 --- a/src/main/java/eu/m724/musicPlugin/item/speaker/BlockSpeaker.java +++ b/src/main/java/eu/m724/musicPlugin/item/speaker/BlockSpeaker.java @@ -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; diff --git a/src/main/java/eu/m724/musicPlugin/item/speaker/Speaker.java b/src/main/java/eu/m724/musicPlugin/item/speaker/Speaker.java index 5404dd6..3ea4c3e 100644 --- a/src/main/java/eu/m724/musicPlugin/item/speaker/Speaker.java +++ b/src/main/java/eu/m724/musicPlugin/item/speaker/Speaker.java @@ -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 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 consumer) { + this.destroyCallback = consumer; } abstract void onSetMusicPlayer(MovingMusicPlayer musicPlayer); diff --git a/src/main/java/eu/m724/musicPlugin/player/LocalMusicPlayer.java b/src/main/java/eu/m724/musicPlugin/player/LocalMusicPlayer.java new file mode 100644 index 0000000..659a930 --- /dev/null +++ b/src/main/java/eu/m724/musicPlugin/player/LocalMusicPlayer.java @@ -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 {} +} diff --git a/src/main/java/eu/m724/musicPlugin/player/MovingMusicPlayer.java b/src/main/java/eu/m724/musicPlugin/player/MovingMusicPlayer.java index d16f53c..aca953f 100644 --- a/src/main/java/eu/m724/musicPlugin/player/MovingMusicPlayer.java +++ b/src/main/java/eu/m724/musicPlugin/player/MovingMusicPlayer.java @@ -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(); } } diff --git a/src/main/java/eu/m724/musicPlugin/player/MusicPlayer.java b/src/main/java/eu/m724/musicPlugin/player/MusicPlayer.java index 55e2f02..31173e7 100644 --- a/src/main/java/eu/m724/musicPlugin/player/MusicPlayer.java +++ b/src/main/java/eu/m724/musicPlugin/player/MusicPlayer.java @@ -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; } }