diff --git a/src/main/java/cn/wode490390/nukkit/radio/IRadio.java b/src/main/java/cn/wode490390/nukkit/radio/IRadio.java index cae40ff..20ea9c7 100644 --- a/src/main/java/cn/wode490390/nukkit/radio/IRadio.java +++ b/src/main/java/cn/wode490390/nukkit/radio/IRadio.java @@ -1,6 +1,8 @@ package cn.wode490390.nukkit.radio; import cn.nukkit.Player; +import cn.nukkit.level.Level; + import java.util.List; public interface IRadio { @@ -16,9 +18,9 @@ public interface IRadio { void addMusic(IMusic music); - void next(); + void next(Player player, Level level); - void addListener(Player player); + void addListener(Player player, Level level); void removeListener(Player player); } diff --git a/src/main/java/cn/wode490390/nukkit/radio/Radio.java b/src/main/java/cn/wode490390/nukkit/radio/Radio.java index 9184219..47a00e6 100644 --- a/src/main/java/cn/wode490390/nukkit/radio/Radio.java +++ b/src/main/java/cn/wode490390/nukkit/radio/Radio.java @@ -2,27 +2,22 @@ import cn.nukkit.Player; import cn.nukkit.Server; +import cn.nukkit.level.Level; import cn.nukkit.network.protocol.PlaySoundPacket; import cn.nukkit.network.protocol.StopSoundPacket; import cn.nukkit.utils.TextFormat; import com.google.common.base.Preconditions; -import com.google.common.collect.Sets; import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import java.util.List; -import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; + +import java.util.*; public class Radio implements IRadio { private byte mode = MODE_ORDER; private final List playlist = new ObjectArrayList<>(); - private final Set listeners = Sets.newHashSet(); - private IMusic playing; - private int index = 0; - private static final Timer timer = new Timer("Radio Timer", true); - private TimerTask updater; + private final HashMap playings = new HashMap<>(); + private final HashMap timers = new HashMap<>(); @Override public byte getMode() { @@ -44,60 +39,64 @@ public void addMusic(IMusic music) { this.playlist.add(music); } - @Override - public void next() { - this.next(false); + public synchronized void next(Player player) { + this.next(player, null); } - public synchronized void next(boolean force) { - if (this.listeners.isEmpty() && !force) { - this.playing = null; - return; + @Override + public synchronized void next(Player player, Level level) { + if (level == null) { + level = player.getLevel(); } - Player[] players = this.listeners.toArray(new Player[0]); - - switch (this.mode) { - case MODE_RANDOM: - this.index = RadioPlugin.getRNG().nextInt(this.playlist.size()); - break; - case MODE_ORDER: - default: - if (++this.index >= this.playlist.size()) { - this.index = 0; - } - break; + IMusic newIMusic = null; + if (this.playings.containsKey(player)) { + stop(null, player); + newIMusic = getIMusic(this.playings.get(player), level); } - this.playing = this.playlist.get(this.index); - - stop(null, players); - play(this.playing, players); - - this.updater = new TimerTask() { + if (newIMusic == null) { + newIMusic = getIMusic(null, level); + } + if (newIMusic == null) { + newIMusic = this.playlist.get(RadioPlugin.getRNG().nextInt(this.playlist.size())); + } + if (newIMusic == null) return; + this.playings.put(player, newIMusic); + play(newIMusic, player); + TimerTask updater = new TimerTask() { @Override public void run() { - Radio.this.next(); + Radio.this.next(player); } }; - timer.schedule(this.updater, this.playing.getDuration()); + if (this.timers.containsKey(player)) { + this.timers.get(player).cancel(); + } + this.timers.put(player, new Timer("Radio " + player.getName(), true)); + this.timers.get(player).schedule(updater, newIMusic.getDuration()); } - @Override - public void addListener(Player player) { - if (this.listeners.add(player)) { - if (this.playing == null) { - this.next(); - } else { - stop(null, player); - play(this.playing, player); + private IMusic getIMusic(IMusic iMusic, Level level) { + for (IMusic newIMusic : this.playlist) { + if (iMusic != null && iMusic.getMD5().equals(newIMusic.getMD5())) { + continue; + } + String[] s = newIMusic.getName().split("]"); + if (s.length > 0 && + s[0].replace("[", "").trim().equals(level.getName())) { + return newIMusic; } } + return null; + } + + @Override + public void addListener(Player player, Level level) { + this.next(player, level); } @Override public void removeListener(Player player) { - if (this.listeners.remove(player)) { - stop(null, player); - } + stop(null, player); } @Override @@ -144,4 +143,5 @@ public static void stop(String identifier, Player... players) { Server.broadcastPacket(players, pk); } } + } diff --git a/src/main/java/cn/wode490390/nukkit/radio/RadioPlugin.java b/src/main/java/cn/wode490390/nukkit/radio/RadioPlugin.java index 504a9cd..1393d31 100644 --- a/src/main/java/cn/wode490390/nukkit/radio/RadioPlugin.java +++ b/src/main/java/cn/wode490390/nukkit/radio/RadioPlugin.java @@ -3,11 +3,13 @@ import cn.nukkit.event.EventHandler; import cn.nukkit.event.Listener; import cn.nukkit.event.player.PlayerQuitEvent; +import cn.nukkit.event.player.PlayerTeleportEvent; import cn.nukkit.event.server.DataPacketReceiveEvent; import cn.nukkit.network.protocol.SetLocalPlayerAsInitializedPacket; import cn.nukkit.plugin.PluginBase; import cn.nukkit.resourcepacks.ResourcePack; import cn.nukkit.resourcepacks.ResourcePackManager; +import cn.nukkit.scheduler.Task; import cn.nukkit.utils.Config; import cn.wode490390.nukkit.radio.command.RadioAdminCommand; import cn.wode490390.nukkit.radio.command.RadioCommand; @@ -24,12 +26,9 @@ import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.StandardOpenOption; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.StringJoiner; -import java.util.UUID; +import java.util.*; import java.util.concurrent.ThreadLocalRandom; + import org.jaudiotagger.audio.ogg.util.OggInfoReader; public class RadioPlugin extends PluginBase implements Listener { @@ -131,7 +130,14 @@ public void onEnable() { @EventHandler public void onDataPacketReceive(DataPacketReceiveEvent event) { if (event.getPacket() instanceof SetLocalPlayerAsInitializedPacket && this.autoplay) { - this.global.addListener(event.getPlayer()); + this.global.addListener(event.getPlayer(), null); + } + } + + @EventHandler + public void onPlayerTeleport(PlayerTeleportEvent event) { + if (!event.getFrom().getLevel().getName().equals(event.getTo().getLevel().getName())) { + this.global.addListener(event.getPlayer(), event.getTo().getLevel()); } } diff --git a/src/main/java/cn/wode490390/nukkit/radio/command/RadioCommand.java b/src/main/java/cn/wode490390/nukkit/radio/command/RadioCommand.java index 46d6600..19fcca5 100644 --- a/src/main/java/cn/wode490390/nukkit/radio/command/RadioCommand.java +++ b/src/main/java/cn/wode490390/nukkit/radio/command/RadioCommand.java @@ -51,7 +51,7 @@ public boolean execute(CommandSender sender, String label, String[] args) { Player player = (Player) sender; switch (args[0].toLowerCase()) { case "play": - global.addListener(player); + global.addListener(player, null); break; case "stop": global.removeListener(player);