centralize tick loop + other refactors
This commit is contained in:
parent
97b7a225fb
commit
cee88ffa3d
6 changed files with 109 additions and 64 deletions
|
@ -8,26 +8,27 @@ import com.github.steveice10.packetlib.event.session.SessionListener;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import land.chipmunk.chipmunkbot.plugins.*;
|
import land.chipmunk.chipmunkbot.plugins.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ChipmunkBot extends Client {
|
public class ChipmunkBot extends Client {
|
||||||
@Getter public final ChatPlugin chat;
|
@Getter private final TickLoop tickLoop;
|
||||||
@Getter public final TabCompletePlugin tabComplete;
|
@Getter private final ChatPlugin chat;
|
||||||
@Getter public final QueryPlugin query;
|
@Getter private final TabCompletePlugin tabComplete;
|
||||||
@Getter public final PlayerListPlugin playerList;
|
@Getter private final QueryPlugin query;
|
||||||
@Getter public final CommandManager commandManager;
|
@Getter private final PlayerListPlugin playerList;
|
||||||
@Getter public final ChatCommandHandler chatCommandHandler;
|
@Getter private final CommandManager commandManager;
|
||||||
@Getter public final PositionManager position;
|
@Getter private final ChatCommandHandler chatCommandHandler;
|
||||||
@Getter public final CommandCore core;
|
@Getter private final PositionManager position;
|
||||||
@Getter public final SelfCarePlugin selfCare;
|
@Getter private final CommandCore core;
|
||||||
@Getter public final SongPlayer songPlayer;
|
@Getter private final SelfCarePlugin selfCare;
|
||||||
|
@Getter private final SongPlayer songPlayer;
|
||||||
|
|
||||||
public ChipmunkBot (Options options, List<Client> allClients) {
|
public ChipmunkBot (Options options, List<Client> allClients) {
|
||||||
super(options.host, options.port, new MinecraftProtocol(options.username), null, options.reconnectDelay, 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.chat = new ChatPlugin(this);
|
||||||
this.tabComplete = new TabCompletePlugin(this);
|
this.tabComplete = new TabCompletePlugin(this);
|
||||||
this.query = new QueryPlugin(this);
|
this.query = new QueryPlugin(this);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package land.chipmunk.chipmunkbot;
|
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.ProxyInfo;
|
||||||
import com.github.steveice10.packetlib.Session;
|
import com.github.steveice10.packetlib.Session;
|
||||||
import com.github.steveice10.packetlib.tcp.TcpClientSession;
|
import com.github.steveice10.packetlib.tcp.TcpClientSession;
|
||||||
|
@ -22,13 +22,13 @@ public class Client {
|
||||||
|
|
||||||
private String host;
|
private String host;
|
||||||
private int port;
|
private int port;
|
||||||
private PacketProtocol protocol;
|
private MinecraftProtocol protocol;
|
||||||
private ProxyInfo proxy;
|
private ProxyInfo proxy;
|
||||||
|
|
||||||
@Getter @Setter private long reconnectDelay;
|
@Getter @Setter private long reconnectDelay;
|
||||||
@Getter @Setter private List<Client> allClients;
|
@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.host = host;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.protocol = protocol;
|
this.protocol = protocol;
|
||||||
|
|
|
@ -10,7 +10,6 @@ import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import com.github.steveice10.packetlib.Session;
|
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.MinecraftProtocol;
|
||||||
import com.github.steveice10.mc.protocol.data.ProtocolState;
|
import com.github.steveice10.mc.protocol.data.ProtocolState;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
@ -45,8 +44,8 @@ public class NetMsgCommand {
|
||||||
if (!(remote instanceof ChipmunkBot)) continue; // ? Is this optimal?
|
if (!(remote instanceof ChipmunkBot)) continue; // ? Is this optimal?
|
||||||
|
|
||||||
final Session session = remote.session();
|
final Session session = remote.session();
|
||||||
final PacketProtocol protocol = session.getPacketProtocol();
|
final MinecraftProtocol protocol = (MinecraftProtocol) session.getPacketProtocol();
|
||||||
if (!session.isConnected() || (protocol instanceof MinecraftProtocol && ((MinecraftProtocol) protocol).getState() != ProtocolState.GAME)) continue;
|
if (!session.isConnected() || protocol.getState() != ProtocolState.GAME) continue;
|
||||||
|
|
||||||
((ChipmunkBot) remote).chat().tellraw(message);
|
((ChipmunkBot) remote).chat().tellraw(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,4 +155,5 @@ public class ChatPlugin extends SessionAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addListener (Listener listener) { listeners.add(listener); }
|
public void addListener (Listener listener) { listeners.add(listener); }
|
||||||
|
public void removeListener (Listener listener) { listeners.remove(listener); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,6 @@ import lombok.Setter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
public class SongPlayer extends SessionAdapter {
|
public class SongPlayer extends SessionAdapter {
|
||||||
|
@ -32,7 +30,6 @@ public class SongPlayer extends SessionAdapter {
|
||||||
|
|
||||||
@Getter @Setter private Song currentSong;
|
@Getter @Setter private Song currentSong;
|
||||||
@Getter @Setter private LinkedList<Song> songQueue = new LinkedList<>();
|
@Getter @Setter private LinkedList<Song> songQueue = new LinkedList<>();
|
||||||
@Getter @Setter private Timer playTimer;
|
|
||||||
@Getter @Setter private SongLoaderThread loaderThread;
|
@Getter @Setter private SongLoaderThread loaderThread;
|
||||||
private int ticksUntilPausedActionbar = 20;
|
private int ticksUntilPausedActionbar = 20;
|
||||||
|
|
||||||
|
@ -42,6 +39,9 @@ public class SongPlayer extends SessionAdapter {
|
||||||
client.core().addListener(new CommandCore.Listener() {
|
client.core().addListener(new CommandCore.Listener() {
|
||||||
public void ready () { coreReady(); } // TODO: Handle listeners in a better way than this
|
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
|
// TODO: Less duplicate code
|
||||||
|
@ -81,50 +81,45 @@ public class SongPlayer extends SessionAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void coreReady () {
|
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();
|
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 () {
|
public Component generateActionbar () {
|
||||||
Component component = Component.empty()
|
Component component = Component.empty()
|
||||||
.append(Component.translatable("Now playing %s", Component.empty().append(currentSong.name).color(NamedTextColor.DARK_GREEN)).color(NamedTextColor.GREEN))
|
.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
|
@Override
|
||||||
public void disconnected (DisconnectedEvent event) {
|
public void disconnected (DisconnectedEvent event) {
|
||||||
playTimer.cancel();
|
|
||||||
playTimer.purge();
|
|
||||||
|
|
||||||
if (currentSong != null) currentSong.pause();
|
if (currentSong != null) currentSong.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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); }
|
||||||
|
}
|
Loading…
Reference in a new issue