diff --git a/src/main/java/land/chipmunk/chipmunkbot/ChipmunkBot.java b/src/main/java/land/chipmunk/chipmunkbot/ChipmunkBot.java index 7193963..33d4f15 100644 --- a/src/main/java/land/chipmunk/chipmunkbot/ChipmunkBot.java +++ b/src/main/java/land/chipmunk/chipmunkbot/ChipmunkBot.java @@ -8,26 +8,27 @@ import com.github.steveice10.packetlib.event.session.SessionListener; import java.util.Map; import java.util.HashMap; import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import lombok.Getter; import land.chipmunk.chipmunkbot.plugins.*; import java.util.List; public class ChipmunkBot extends Client { - @Getter public final ChatPlugin chat; - @Getter public final TabCompletePlugin tabComplete; - @Getter public final QueryPlugin query; - @Getter public final PlayerListPlugin playerList; - @Getter public final CommandManager commandManager; - @Getter public final ChatCommandHandler chatCommandHandler; - @Getter public final PositionManager position; - @Getter public final CommandCore core; - @Getter public final SelfCarePlugin selfCare; - @Getter public final SongPlayer songPlayer; + @Getter private final TickLoop tickLoop; + @Getter private final ChatPlugin chat; + @Getter private final TabCompletePlugin tabComplete; + @Getter private final QueryPlugin query; + @Getter private final PlayerListPlugin playerList; + @Getter private final CommandManager commandManager; + @Getter private final ChatCommandHandler chatCommandHandler; + @Getter private final PositionManager position; + @Getter private final CommandCore core; + @Getter private final SelfCarePlugin selfCare; + @Getter private final SongPlayer songPlayer; public ChipmunkBot (Options options, List allClients) { super(options.host, options.port, new MinecraftProtocol(options.username), null, options.reconnectDelay, allClients); + this.tickLoop = new TickLoop(this); this.chat = new ChatPlugin(this); this.tabComplete = new TabCompletePlugin(this); this.query = new QueryPlugin(this); diff --git a/src/main/java/land/chipmunk/chipmunkbot/Client.java b/src/main/java/land/chipmunk/chipmunkbot/Client.java index 1173bbc..ed871bc 100644 --- a/src/main/java/land/chipmunk/chipmunkbot/Client.java +++ b/src/main/java/land/chipmunk/chipmunkbot/Client.java @@ -1,6 +1,6 @@ package land.chipmunk.chipmunkbot; -import com.github.steveice10.packetlib.packet.PacketProtocol; +import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.packetlib.ProxyInfo; import com.github.steveice10.packetlib.Session; import com.github.steveice10.packetlib.tcp.TcpClientSession; @@ -22,13 +22,13 @@ public class Client { private String host; private int port; - private PacketProtocol protocol; + private MinecraftProtocol protocol; private ProxyInfo proxy; @Getter @Setter private long reconnectDelay; @Getter @Setter private List allClients; - public Client (String host, int port, PacketProtocol protocol, ProxyInfo proxy, long reconnectDelay, List allClients) { + public Client (String host, int port, MinecraftProtocol protocol, ProxyInfo proxy, long reconnectDelay, List allClients) { this.host = host; this.port = port; this.protocol = protocol; diff --git a/src/main/java/land/chipmunk/chipmunkbot/commands/NetMsgCommand.java b/src/main/java/land/chipmunk/chipmunkbot/commands/NetMsgCommand.java index b5db754..19914b7 100644 --- a/src/main/java/land/chipmunk/chipmunkbot/commands/NetMsgCommand.java +++ b/src/main/java/land/chipmunk/chipmunkbot/commands/NetMsgCommand.java @@ -10,7 +10,6 @@ import static com.mojang.brigadier.arguments.StringArgumentType.getString; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.context.CommandContext; import com.github.steveice10.packetlib.Session; -import com.github.steveice10.packetlib.packet.PacketProtocol; import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.data.ProtocolState; import net.kyori.adventure.text.Component; @@ -45,8 +44,8 @@ public class NetMsgCommand { if (!(remote instanceof ChipmunkBot)) continue; // ? Is this optimal? final Session session = remote.session(); - final PacketProtocol protocol = session.getPacketProtocol(); - if (!session.isConnected() || (protocol instanceof MinecraftProtocol && ((MinecraftProtocol) protocol).getState() != ProtocolState.GAME)) continue; + final MinecraftProtocol protocol = (MinecraftProtocol) session.getPacketProtocol(); + if (!session.isConnected() || protocol.getState() != ProtocolState.GAME) continue; ((ChipmunkBot) remote).chat().tellraw(message); } diff --git a/src/main/java/land/chipmunk/chipmunkbot/plugins/ChatPlugin.java b/src/main/java/land/chipmunk/chipmunkbot/plugins/ChatPlugin.java index 194e6aa..a0d3991 100644 --- a/src/main/java/land/chipmunk/chipmunkbot/plugins/ChatPlugin.java +++ b/src/main/java/land/chipmunk/chipmunkbot/plugins/ChatPlugin.java @@ -155,4 +155,5 @@ public class ChatPlugin extends SessionAdapter { } public void addListener (Listener listener) { listeners.add(listener); } + public void removeListener (Listener listener) { listeners.remove(listener); } } diff --git a/src/main/java/land/chipmunk/chipmunkbot/plugins/SongPlayer.java b/src/main/java/land/chipmunk/chipmunkbot/plugins/SongPlayer.java index 7412778..3d0dcaf 100644 --- a/src/main/java/land/chipmunk/chipmunkbot/plugins/SongPlayer.java +++ b/src/main/java/land/chipmunk/chipmunkbot/plugins/SongPlayer.java @@ -15,8 +15,6 @@ import lombok.Setter; import java.io.File; import java.nio.file.Path; import java.net.URL; -import java.util.Timer; -import java.util.TimerTask; import java.util.LinkedList; public class SongPlayer extends SessionAdapter { @@ -32,7 +30,6 @@ public class SongPlayer extends SessionAdapter { @Getter @Setter private Song currentSong; @Getter @Setter private LinkedList songQueue = new LinkedList<>(); - @Getter @Setter private Timer playTimer; @Getter @Setter private SongLoaderThread loaderThread; private int ticksUntilPausedActionbar = 20; @@ -42,6 +39,9 @@ public class SongPlayer extends SessionAdapter { client.core().addListener(new CommandCore.Listener() { public void ready () { coreReady(); } // TODO: Handle listeners in a better way than this }); + client.tickLoop().addListener(new TickLoop.Listener() { + public void onTick (long t) { tick(); } // TODO: Handle listeners in a better way than this + }); } // TODO: Less duplicate code @@ -81,50 +81,45 @@ public class SongPlayer extends SessionAdapter { } public void coreReady () { - playTimer = new Timer(); - - final TimerTask playTask = new TimerTask() { - @Override - public void run () { - if (loaderThread != null && !loaderThread.isAlive()) { - if (loaderThread.exception != null) { - client.chat().tellraw(Component.translatable("Failed to load song: %s", loaderThread.exception.message()).color(NamedTextColor.RED)); - } else { - songQueue.add(loaderThread.song); - client.chat().tellraw(Component.translatable("Added %s to the song queue", Component.empty().append(loaderThread.song.name).color(NamedTextColor.DARK_GREEN)).color(NamedTextColor.GREEN)); - } - loaderThread = null; - } - - if (currentSong == null) { - if (songQueue.size() == 0) return; - - currentSong = songQueue.poll(); - client.chat().tellraw(Component.translatable("Now playing %s", Component.empty().append(currentSong.name).color(NamedTextColor.DARK_GREEN)).color(NamedTextColor.GREEN)); - currentSong.play(); - } - - if (currentSong.paused && ticksUntilPausedActionbar-- < 0) return; - else ticksUntilPausedActionbar = 20; - - client.core().run("title " + SELECTOR + " actionbar " + GsonComponentSerializer.gson().serialize(generateActionbar())); - - if (currentSong.paused) return; - - handlePlaying(); - - if (currentSong.finished()) { - client.chat().tellraw(Component.translatable("Finished playing %s", Component.empty().append(currentSong.name).color(NamedTextColor.DARK_GREEN)).color(NamedTextColor.GREEN)); - currentSong = null; - } - } - }; - - playTimer.schedule(playTask, 50, 50); - if (currentSong != null) currentSong.play(); } + public void tick () { + if (!client.core().ready()) return; + + if (loaderThread != null && !loaderThread.isAlive()) { + if (loaderThread.exception != null) { + client.chat().tellraw(Component.translatable("Failed to load song: %s", loaderThread.exception.message()).color(NamedTextColor.RED)); + } else { + songQueue.add(loaderThread.song); + client.chat().tellraw(Component.translatable("Added %s to the song queue", Component.empty().append(loaderThread.song.name).color(NamedTextColor.DARK_GREEN)).color(NamedTextColor.GREEN)); + } + loaderThread = null; + } + + if (currentSong == null) { + if (songQueue.size() == 0) return; + + currentSong = songQueue.poll(); + client.chat().tellraw(Component.translatable("Now playing %s", Component.empty().append(currentSong.name).color(NamedTextColor.DARK_GREEN)).color(NamedTextColor.GREEN)); + currentSong.play(); + } + + if (currentSong.paused && ticksUntilPausedActionbar-- < 0) return; + else ticksUntilPausedActionbar = 20; + + client.core().run("title " + SELECTOR + " actionbar " + GsonComponentSerializer.gson().serialize(generateActionbar())); + + if (currentSong.paused) return; + + handlePlaying(); + + if (currentSong.finished()) { + client.chat().tellraw(Component.translatable("Finished playing %s", Component.empty().append(currentSong.name).color(NamedTextColor.DARK_GREEN)).color(NamedTextColor.GREEN)); + currentSong = null; + } + } + public Component generateActionbar () { Component component = Component.empty() .append(Component.translatable("Now playing %s", Component.empty().append(currentSong.name).color(NamedTextColor.DARK_GREEN)).color(NamedTextColor.GREEN)) @@ -173,9 +168,6 @@ public class SongPlayer extends SessionAdapter { @Override public void disconnected (DisconnectedEvent event) { - playTimer.cancel(); - playTimer.purge(); - if (currentSong != null) currentSong.pause(); } diff --git a/src/main/java/land/chipmunk/chipmunkbot/plugins/TickLoop.java b/src/main/java/land/chipmunk/chipmunkbot/plugins/TickLoop.java new file mode 100644 index 0000000..b1647fe --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkbot/plugins/TickLoop.java @@ -0,0 +1,52 @@ +package land.chipmunk.chipmunkbot.plugins; + +import land.chipmunk.chipmunkbot.Client; +import com.github.steveice10.packetlib.event.session.SessionListener; +import com.github.steveice10.packetlib.event.session.SessionAdapter; +import com.github.steveice10.packetlib.event.session.DisconnectedEvent; +import com.github.steveice10.mc.protocol.MinecraftProtocol; +import com.github.steveice10.mc.protocol.data.ProtocolState; +import lombok.Getter; +import java.util.ArrayList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; + +public class TickLoop extends SessionAdapter { + private Client client; + private Timer timer; + @Getter private List listeners = new ArrayList<>(); + @Getter private long tick = 0; + + public TickLoop (Client client) { + this.client = client; + client.session().addListener((SessionListener) this); + + final TimerTask task = new TimerTask() { + public void run () { + for (Listener listener : listeners) { + listener.onTick(tick); + if (((MinecraftProtocol) client.session().getPacketProtocol()).getState() == ProtocolState.GAME) listener.onGameTick(tick); + } + } + }; + + timer = new Timer(); + timer.schedule(task, 50L, 50L); + } + + public void disconnected (DisconnectedEvent event) { + if (client.reconnectDelay() < 0 && timer != null) { + timer.cancel(); + timer.purge(); + } + } + + public static class Listener { + public void onTick (long tick) {} + public void onGameTick (long tick) {} + } + + public void addListener (Listener listener) { listeners.add(listener); } + public void removeListener (Listener listener) { listeners.remove(listener); } +}