centralize tick loop + other refactors

This commit is contained in:
Chipmunk 2023-04-30 22:29:39 -04:00
parent 97b7a225fb
commit cee88ffa3d
6 changed files with 109 additions and 64 deletions

View file

@ -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<Client> 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);

View file

@ -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<Client> allClients;
public Client (String host, int port, PacketProtocol protocol, ProxyInfo proxy, long reconnectDelay, List<Client> allClients) {
public Client (String host, int port, MinecraftProtocol protocol, ProxyInfo proxy, long reconnectDelay, List<Client> allClients) {
this.host = host;
this.port = port;
this.protocol = protocol;

View file

@ -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);
}

View file

@ -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); }
}

View file

@ -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<Song> 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();
}

View file

@ -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<Listener> 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); }
}