From b1255510f9449ff52dc785639c27d2f1f3efde08 Mon Sep 17 00:00:00 2001
From: Chip <65827213+ChipmunkMC@users.noreply.github.com>
Date: Fri, 16 Dec 2022 18:56:20 -0500
Subject: [PATCH] among
---
.idea/.gitignore | 3 +
.idea/codeStyles/codeStyleConfig.xml | 5 +
.idea/compiler.xml | 13 ++
.idea/jarRepositories.xml | 25 ++++
.idea/misc.xml | 12 ++
.idea/uiDesigner.xml | 124 ++++++++++++++++++
pom.xml | 68 ++++++++++
.../land/chipmunk/chipmunkbot/Client.java | 44 +++++++
.../chipmunk/chipmunkbot/ClientOptions.java | 70 ++++++++++
.../land/chipmunk/chipmunkbot/Injector.java | 5 +
.../java/land/chipmunk/chipmunkbot/Main.java | 58 ++++++++
.../land/chipmunk/chipmunkbot/Plugin.java | 11 ++
.../chipmunkbot/chat/ChatMessage.java | 37 ++++++
.../chipmunk/chipmunkbot/chat/ChatParser.java | 7 +
.../chipmunkbot/chat/MessageType.java | 8 ++
.../chipmunkbot/chat/MinecraftChatParser.java | 37 ++++++
.../chipmunkbot/chat/PlayerMessage.java | 47 +++++++
.../data/MutablePlayerListEntry.java | 60 +++++++++
.../chipmunkbot/plugins/ChatPlugin.java | 38 ++++++
.../chipmunkbot/plugins/PlayerListPlugin.java | 102 ++++++++++++++
20 files changed, 774 insertions(+)
create mode 100644 .idea/.gitignore
create mode 100644 .idea/codeStyles/codeStyleConfig.xml
create mode 100644 .idea/compiler.xml
create mode 100644 .idea/jarRepositories.xml
create mode 100644 .idea/misc.xml
create mode 100644 .idea/uiDesigner.xml
create mode 100644 pom.xml
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/Client.java
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/ClientOptions.java
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/Injector.java
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/Main.java
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/Plugin.java
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/chat/ChatMessage.java
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/chat/ChatParser.java
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/chat/MessageType.java
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/chat/MinecraftChatParser.java
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/chat/PlayerMessage.java
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/data/MutablePlayerListEntry.java
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/plugins/ChatPlugin.java
create mode 100644 src/main/java/land/chipmunk/chipmunkbot/plugins/PlayerListPlugin.java
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..a55e7a1
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..e65b78d
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..2285b75
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..ad2ba02
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..fd62198
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,68 @@
+
+ 4.0.0
+ land.chipmunk
+ chipmunkbot
+ jar
+ 1.0-SNAPSHOT
+ chipmunkbot
+
+
+ 1.8
+ 1.8
+
+
+
+
+ opencollab
+ https://repo.opencollab.dev/maven-releases/
+
+
+
+
+
+ com.github.steveice10
+ mcprotocollib
+ 1.19.2-1
+
+
+
+ com.google.code.gson
+ gson
+ 2.9.0
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.2.0
+
+
+
+ land.chipmunk.chipmunkbot.Main
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.4.1
+
+
+ package
+
+ shade
+
+
+
+
+
+
+
+
diff --git a/src/main/java/land/chipmunk/chipmunkbot/Client.java b/src/main/java/land/chipmunk/chipmunkbot/Client.java
new file mode 100644
index 0000000..d777b90
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/Client.java
@@ -0,0 +1,44 @@
+package land.chipmunk.chipmunkbot;
+
+import com.github.steveice10.mc.auth.service.AuthenticationService;
+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;
+import java.util.Map;
+import java.util.HashMap;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+public class Client {
+ private Session session;
+ private Map plugins = new HashMap();
+
+ public Client (ClientOptions options) {
+ Session session = new TcpClientSession(options.host(), options.port(), options.protocol(), options.proxy());
+ this.session = session;
+
+ session.connect();
+ }
+
+ public Session session () {
+ return session;
+ }
+
+ public Plugin getPlugin (String id) { return plugins.get(id); }
+
+ public void loadPlugin (Class extends Plugin> pluginClass) {
+ try {
+ Constructor extends Plugin> constructor = pluginClass.getConstructor(Client.class);
+ Plugin plugin = constructor.newInstance(this);
+ plugins.put(plugin.id, plugin);
+ } catch (Exception ignored) {
+ }
+ }
+
+ // TODO: Maybe also add unloading?
+
+ public void inject (Injector injector) {
+ injector.inject(this);
+ }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/ClientOptions.java b/src/main/java/land/chipmunk/chipmunkbot/ClientOptions.java
new file mode 100644
index 0000000..8aed0b5
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/ClientOptions.java
@@ -0,0 +1,70 @@
+package land.chipmunk.chipmunkbot;
+
+import com.github.steveice10.mc.auth.service.AuthenticationService;
+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;
+
+public class ClientOptions {
+ private String host;
+ private int port;
+ private MinecraftProtocol protocol;
+ private ProxyInfo proxy;
+
+ public ClientOptions (String host, int port, MinecraftProtocol protocol, ProxyInfo proxy) {
+ this.host = host;
+ this.port = port;
+ this.protocol = protocol;
+ this.proxy = proxy;
+ }
+
+ public ClientOptions () { // So it can easily be used as a builder
+ }
+
+ public String host () {
+ return host;
+ }
+
+ public ClientOptions host (String value) {
+ host = value;
+ return this;
+ }
+
+ public int port () {
+ return port;
+ }
+
+ public ClientOptions port (int value) {
+ port = value;
+ return this;
+ }
+
+ public MinecraftProtocol protocol () {
+ return protocol;
+ }
+
+ public ClientOptions protocol (MinecraftProtocol value) {
+ protocol = value;
+ return this;
+ }
+
+ /* public ClientOptions profile (GameProfile profile) {
+ protocol(new MinecraftProtocol(profile));
+ return this;
+ } */
+
+ public ClientOptions username (String username) {
+ protocol(new MinecraftProtocol(username));
+ return this;
+ }
+
+ public ProxyInfo proxy () {
+ return proxy;
+ }
+
+ public ClientOptions proxy (ProxyInfo value) {
+ proxy = value;
+ return this;
+ }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/Injector.java b/src/main/java/land/chipmunk/chipmunkbot/Injector.java
new file mode 100644
index 0000000..4745e8c
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/Injector.java
@@ -0,0 +1,5 @@
+package land.chipmunk.chipmunkbot;
+
+public interface Injector {
+ public void inject (Client client);
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/Main.java b/src/main/java/land/chipmunk/chipmunkbot/Main.java
new file mode 100644
index 0000000..82e2a90
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/Main.java
@@ -0,0 +1,58 @@
+package land.chipmunk.chipmunkbot;
+
+import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundLoginPacket;
+import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket;
+import com.github.steveice10.packetlib.Session;
+import com.github.steveice10.packetlib.event.session.SessionAdapter;
+import com.github.steveice10.packetlib.packet.Packet;
+
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
+import java.io.File;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+
+import land.chipmunk.chipmunkbot.plugins.ChatPlugin;
+
+import com.google.gson.Gson;
+import land.chipmunk.chipmunkbot.plugins.PlayerListPlugin;
+
+public class Main {
+ private static File CONFIG_FILE = new File("config.json");
+
+ private static JsonObject getConfig () throws Exception {
+ InputStream opt = new FileInputStream(CONFIG_FILE);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(opt));
+
+ return JsonParser.parseReader(reader).getAsJsonObject();
+ }
+
+ public static ClientOptions parseClientOptions (JsonObject options) {
+ return new ClientOptions()
+ .host(options.has("host") ? options.get("host").getAsString() : "0.0.0.0")
+ .port(options.has("port") ? options.get("port").getAsInt() : 25565)
+ .username(options.has("username") ? options.get("username").getAsString() : "username");
+ }
+
+ public static void main (String[] arguments) {
+ System.out.println("ChipmunkBot is starting...");
+
+ JsonObject config = null;
+ try {
+ config = getConfig();
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ System.exit(1);
+ }
+
+ for (JsonElement element : config.get("bots").getAsJsonArray()) {
+ ClientOptions options = parseClientOptions(element.getAsJsonObject());
+ Client client = new Client(options); // TODO: Maybe create a list of some sort
+ client.loadPlugin(PlayerListPlugin.class);
+ }
+ }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/Plugin.java b/src/main/java/land/chipmunk/chipmunkbot/Plugin.java
new file mode 100644
index 0000000..5c6ec54
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/Plugin.java
@@ -0,0 +1,11 @@
+package land.chipmunk.chipmunkbot;
+
+public class Plugin {
+ public String id;
+ public Client client;
+
+ public Plugin (Client client, String id) {
+ this.client = client;
+ this.id = id;
+ }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/chat/ChatMessage.java b/src/main/java/land/chipmunk/chipmunkbot/chat/ChatMessage.java
new file mode 100644
index 0000000..b1b16fd
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/chat/ChatMessage.java
@@ -0,0 +1,37 @@
+package land.chipmunk.chipmunkbot.chat;
+
+import net.kyori.adventure.text.Component;
+import java.util.UUID;
+
+public class ChatMessage {
+ // * I do not really care about signatures, they were likely made for the sus chat reporting system anyway, but I still include the sender as it really helps with stuff such as commands.
+ private Component component;
+ private UUID sender;
+
+ public ChatMessage (Component component, UUID sender) {
+ this.component = component;
+ this.sender = sender;
+ }
+
+ public ChatMessage (Component component) {
+ this(component, new UUID(0, 0));
+ }
+
+ public Component component () {
+ return component;
+ }
+
+ public ChatMessage component (Component value) {
+ component = value;
+ return this;
+ }
+
+ public UUID sender () {
+ return sender;
+ }
+
+ public ChatMessage sender (UUID value) {
+ sender = value;
+ return this;
+ }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/chat/ChatParser.java b/src/main/java/land/chipmunk/chipmunkbot/chat/ChatParser.java
new file mode 100644
index 0000000..e6c4a8d
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/chat/ChatParser.java
@@ -0,0 +1,7 @@
+package land.chipmunk.chipmunkbot.chat;
+
+import net.kyori.adventure.text.Component;
+
+public interface ChatParser {
+ public PlayerMessage parseMessage(ChatMessage message);
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/chat/MessageType.java b/src/main/java/land/chipmunk/chipmunkbot/chat/MessageType.java
new file mode 100644
index 0000000..7addf21
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/chat/MessageType.java
@@ -0,0 +1,8 @@
+package land.chipmunk.chipmunkbot.chat;
+
+public enum MessageType {
+ TEXT,
+ ANNOUNCEMENT,
+ EMOTE,
+ WHISPER
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/chat/MinecraftChatParser.java b/src/main/java/land/chipmunk/chipmunkbot/chat/MinecraftChatParser.java
new file mode 100644
index 0000000..77b196f
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/chat/MinecraftChatParser.java
@@ -0,0 +1,37 @@
+package land.chipmunk.chipmunkbot.chat;
+
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.TranslatableComponent;
+import java.util.UUID;
+import java.util.List;
+
+public class MinecraftChatParser implements ChatParser {
+ private MessageType getMessageType (TranslatableComponent component) {
+ String key = component.key();
+ if (key.equals("chat.type.text")) return MessageType.TEXT;
+ if (key.equals("chat.type.announcement")) return MessageType.ANNOUNCEMENT;
+ if (key.equals("chat.type.emote")) return MessageType.EMOTE;
+ if (key.equals("chat.type.command")) return MessageType.WHISPER;
+ return null;
+ }
+
+ public PlayerMessage parseMessage (ChatMessage message) {
+ Component component = message.component();
+ if (component instanceof TranslatableComponent) return parseTranslatable((TranslatableComponent) component, message.sender());
+ return null;
+ }
+
+ public PlayerMessage parseTranslatable (TranslatableComponent component, UUID providedSender) {
+ TranslatableComponent translate = (TranslatableComponent) component;
+ MessageType type = getMessageType(translate);
+ if (type == null) return null;
+
+ List args = component.args();
+
+ // Component displayName = args.get(0);
+ Component contents = args.get(1);
+
+ return new PlayerMessage(null, contents, type); // TODO: Use player list
+ }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/chat/PlayerMessage.java b/src/main/java/land/chipmunk/chipmunkbot/chat/PlayerMessage.java
new file mode 100644
index 0000000..b19892a
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/chat/PlayerMessage.java
@@ -0,0 +1,47 @@
+package land.chipmunk.chipmunkbot.chat;
+
+import net.kyori.adventure.text.Component;
+import com.github.steveice10.mc.protocol.data.game.PlayerListEntry;
+
+public class PlayerMessage {
+ private PlayerListEntry sender;
+ private Component contents;
+ private MessageType type;
+
+ PlayerMessage (PlayerListEntry sender, Component contents, MessageType type) {
+ this.sender = sender;
+ this.contents = contents;
+ this.type = type;
+ }
+
+ PlayerMessage (PlayerListEntry sender, Component contents) {
+ this(sender, contents, MessageType.TEXT);
+ }
+
+ public PlayerListEntry sender () {
+ return sender;
+ }
+
+ public PlayerMessage sender (PlayerListEntry value) {
+ sender = value;
+ return this;
+ }
+
+ public Component contents () {
+ return contents;
+ }
+
+ public PlayerMessage contents (Component value) {
+ contents = value;
+ return this;
+ }
+
+ public MessageType type () {
+ return type;
+ }
+
+ public PlayerMessage type (MessageType value) {
+ type = value;
+ return this;
+ }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/data/MutablePlayerListEntry.java b/src/main/java/land/chipmunk/chipmunkbot/data/MutablePlayerListEntry.java
new file mode 100644
index 0000000..4a577da
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/data/MutablePlayerListEntry.java
@@ -0,0 +1,60 @@
+package land.chipmunk.chipmunkbot.data;
+
+import com.github.steveice10.mc.auth.data.GameProfile;
+import com.github.steveice10.mc.protocol.data.game.PlayerListEntry;
+import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
+import net.kyori.adventure.text.Component;
+
+import java.security.PublicKey;
+
+public class MutablePlayerListEntry {
+ private GameProfile profile;
+ private GameMode gamemode;
+ private int latency;
+ private Component displayName;
+ private long expiresAt;
+ private PublicKey publicKey;
+ private byte[] keySignature;
+
+ public MutablePlayerListEntry (GameProfile profile, GameMode gamemode, int latency, Component displayName, long expiresAt, PublicKey publicKey, byte[] keySignature) {
+ this.profile = profile;
+ this.gamemode = gamemode;
+ this.latency = latency;
+ this.displayName = displayName;
+ this.expiresAt = expiresAt;
+ this.publicKey = publicKey;
+ this.keySignature = keySignature;
+ }
+
+ public MutablePlayerListEntry (PlayerListEntry entry) {
+ this(entry.getProfile(), entry.getGameMode(), entry.getPing(), entry.getDisplayName(), entry.getExpiresAt(), entry.getPublicKey(), entry.getKeySignature());
+ }
+
+ public GameProfile profile () { return this.profile; }
+
+ public void profile (GameProfile profile) { this.profile = profile; }
+
+ public GameMode gamemode () { return this.gamemode; }
+
+ public void gamemode (GameMode gamemode) { this.gamemode = gamemode; }
+
+ public int latency () { return this.latency; }
+
+ public void latency (int latency) { this.latency = latency; }
+
+ public Component displayName () { return this.displayName; }
+
+ public void displayName (Component displayName) { this.displayName = displayName; }
+
+ public long expiresAt () { return this.expiresAt; }
+
+ public void expiresAt (long expiresAt) { this.expiresAt = expiresAt; }
+
+ public PublicKey publicKey () { return this.publicKey; }
+
+ public void publicKey (PublicKey publicKey) { this.publicKey = publicKey; }
+
+ public byte[] keySignature () { return this.keySignature; }
+
+ public void keySignature (byte[] keySignature) { this.keySignature = keySignature; }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/plugins/ChatPlugin.java b/src/main/java/land/chipmunk/chipmunkbot/plugins/ChatPlugin.java
new file mode 100644
index 0000000..7d2d8a8
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/plugins/ChatPlugin.java
@@ -0,0 +1,38 @@
+package land.chipmunk.chipmunkbot.plugins;
+
+import land.chipmunk.chipmunkbot.Plugin;
+import land.chipmunk.chipmunkbot.Client;
+import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerChatPacket;
+import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundSystemChatPacket;
+import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket;
+import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandPacket;
+import com.github.steveice10.packetlib.packet.Packet;
+import com.github.steveice10.packetlib.Session;
+import com.github.steveice10.packetlib.event.session.SessionAdapter;
+import java.util.BitSet;
+import java.util.ArrayList;
+import java.util.List;
+import java.time.Instant;
+
+public class ChatPlugin extends Plugin {
+ public ChatPlugin (Client client) {
+ super(client, "chat");
+
+ /* client.session().addListener(new SessionAdapter () {
+ @Override
+ packetReceived (Session session, Packet packet) {
+ if (packet instanceof Server)
+ }
+ }); */
+ }
+
+ public void message (String message) {
+ final ServerboundChatPacket packet = new ServerboundChatPacket(message, Instant.now().toEpochMilli(), 0, new byte[0], false, new ArrayList<>(), null);
+ client.session().send(packet);
+ }
+
+ public void command (String command) {
+ final ServerboundChatCommandPacket packet = new ServerboundChatCommandPacket(command, Instant.now().toEpochMilli(), 0, new ArrayList<>(), false, new ArrayList<>(), null);
+ client.session().send(packet);
+ }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/plugins/PlayerListPlugin.java b/src/main/java/land/chipmunk/chipmunkbot/plugins/PlayerListPlugin.java
new file mode 100644
index 0000000..9a67f14
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/plugins/PlayerListPlugin.java
@@ -0,0 +1,102 @@
+package land.chipmunk.chipmunkbot.plugins;
+
+import land.chipmunk.chipmunkbot.Plugin;
+import land.chipmunk.chipmunkbot.Client;
+import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerInfoPacket;
+import com.github.steveice10.packetlib.packet.Packet;
+import com.github.steveice10.packetlib.Session;
+import com.github.steveice10.packetlib.event.session.SessionAdapter;
+import com.github.steveice10.mc.protocol.data.game.PlayerListEntry;
+import com.github.steveice10.mc.protocol.data.game.PlayerListEntryAction;
+import land.chipmunk.chipmunkbot.data.MutablePlayerListEntry;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.UUID;
+
+public class PlayerListPlugin extends Plugin {
+ public List list = new ArrayList();
+
+ public PlayerListPlugin (Client client) {
+ super(client, "player_list");
+
+ client.session().addListener(new SessionAdapter() {
+ @Override
+ public void packetReceived (Session session, Packet packet) {
+ if (packet instanceof ClientboundPlayerInfoPacket) {
+ ClientboundPlayerInfoPacket _packet = (ClientboundPlayerInfoPacket) packet;
+
+ PlayerListEntryAction action = _packet.getAction();
+
+ for (PlayerListEntry entry : _packet.getEntries()) {
+ if (action == PlayerListEntryAction.ADD_PLAYER) addPlayer(entry);
+ else if (action == PlayerListEntryAction.UPDATE_GAMEMODE) updateGamemode(entry);
+ else if (action == PlayerListEntryAction.UPDATE_LATENCY) updateLatency(entry);
+ else if (action == PlayerListEntryAction.UPDATE_DISPLAY_NAME) updateDisplayName(entry);
+ else if (action == PlayerListEntryAction.REMOVE_PLAYER) removePlayer(entry);
+ }
+ }
+ }
+ });
+ }
+
+ public final MutablePlayerListEntry getEntry (UUID uuid) {
+ for (MutablePlayerListEntry candidate : list) {
+ if (candidate.profile().getId().equals(uuid)) {
+ return candidate;
+ }
+ }
+
+ return null;
+ }
+
+ public final MutablePlayerListEntry getEntry (String username) {
+ for (MutablePlayerListEntry candidate : list) {
+ if (candidate.profile().getName().equals(username)) {
+ return candidate;
+ }
+ }
+
+ return null;
+ }
+
+ private final MutablePlayerListEntry getEntry (PlayerListEntry other) {
+ return getEntry(other.getProfile().getId());
+ }
+
+ private void addPlayer (PlayerListEntry newEntry) {
+ final MutablePlayerListEntry duplicate = getEntry(newEntry);
+ if (duplicate != null) list.remove(duplicate);
+
+ list.add(new MutablePlayerListEntry(newEntry));
+ System.out.println("Added " + newEntry.getProfile().getName() + " to the player list.");
+ }
+
+ private void updateGamemode (PlayerListEntry newEntry) {
+ final MutablePlayerListEntry target = getEntry(newEntry);
+ if (target == null) return;
+
+ target.gamemode(newEntry.getGameMode());
+ }
+
+ private void updateLatency (PlayerListEntry newEntry) {
+ final MutablePlayerListEntry target = getEntry(newEntry);
+ if (target == null) return;
+
+ target.latency(newEntry.getPing());
+ }
+
+ private void updateDisplayName (PlayerListEntry newEntry) {
+ final MutablePlayerListEntry target = getEntry(newEntry);
+ if (target == null) return;
+
+ target.displayName(newEntry.getDisplayName());
+ }
+
+ private void removePlayer (PlayerListEntry newEntry) {
+ final MutablePlayerListEntry target = getEntry(newEntry);
+ if (target == null) return;
+
+ list.remove(target);
+ }
+}