diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index 2285b75..709f317 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -1,6 +1,11 @@
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 32e9583..84348df 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,6 +17,12 @@
opencollab
https://repo.opencollab.dev/maven-releases/
+
+
+ minecraft-libraries
+ Minecraft Libraries
+ https://libraries.minecraft.net
+
@@ -38,6 +44,12 @@
1.18.24
provided
+
+
+ com.mojang
+ brigadier
+ 1.0.18
+
@@ -71,5 +83,4 @@
-
diff --git a/src/main/java/land/chipmunk/chipmunkbot/Client.java b/src/main/java/land/chipmunk/chipmunkbot/Client.java
index 077bedb..74de893 100644
--- a/src/main/java/land/chipmunk/chipmunkbot/Client.java
+++ b/src/main/java/land/chipmunk/chipmunkbot/Client.java
@@ -26,16 +26,21 @@ public class Client {
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);
+ Plugin plugin = pluginClass.newInstance();
+ plugin.inject(this, null);
+ plugins.put(plugin.id(), plugin);
+ System.out.println("loaded " + plugin.id());
} catch (Exception ignored) {
}
}
// TODO: Maybe also add unloading?
- public void inject (Injector injector) {
- injector.inject(this);
+ public void inject (Class extends Injector> injectorClass) {
+ try {
+ Injector injector = injectorClass.newInstance();
+ injector.inject(this);
+ } catch (Exception ignored) {
+ }
}
}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/Main.java b/src/main/java/land/chipmunk/chipmunkbot/Main.java
index 12f1685..dd53277 100644
--- a/src/main/java/land/chipmunk/chipmunkbot/Main.java
+++ b/src/main/java/land/chipmunk/chipmunkbot/Main.java
@@ -20,6 +20,7 @@ import com.google.gson.Gson;
import land.chipmunk.chipmunkbot.plugins.ChatPlugin;
import land.chipmunk.chipmunkbot.plugins.PlayerListPlugin;
+import land.chipmunk.chipmunkbot.plugins.CommandManagerPlugin;
public class Main {
private static File CONFIG_FILE = new File("config.json");
@@ -54,6 +55,7 @@ public class Main {
Client client = new Client(options); // TODO: Maybe create a list of some sort
client.loadPlugin(ChatPlugin.class);
client.loadPlugin(PlayerListPlugin.class);
+ client.loadPlugin(CommandManagerPlugin.class);
}
}
}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/Plugin.java b/src/main/java/land/chipmunk/chipmunkbot/Plugin.java
index 5c6ec54..7de4f74 100644
--- a/src/main/java/land/chipmunk/chipmunkbot/Plugin.java
+++ b/src/main/java/land/chipmunk/chipmunkbot/Plugin.java
@@ -1,11 +1,8 @@
package land.chipmunk.chipmunkbot;
-public class Plugin {
- public String id;
- public Client client;
+import com.google.gson.JsonObject;
- public Plugin (Client client, String id) {
- this.client = client;
- this.id = id;
- }
+public interface Plugin {
+ String id ();
+ void inject (Client client, JsonObject options);
}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/command/CommandSource.java b/src/main/java/land/chipmunk/chipmunkbot/command/CommandSource.java
new file mode 100644
index 0000000..6f851f3
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/command/CommandSource.java
@@ -0,0 +1,12 @@
+package land.chipmunk.chipmunkbot.command;
+
+import com.mojang.brigadier.Message;
+import net.kyori.adventure.text.Component;
+
+public interface CommandSource {
+ // ? Should I support message objects?
+ void sendOutput (Component message, boolean broadcast);
+ void sendOutput (Component message);
+
+ Component displayName ();
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/command/CommandSyntaxErrorTypeMap.java b/src/main/java/land/chipmunk/chipmunkbot/command/CommandSyntaxErrorTypeMap.java
new file mode 100644
index 0000000..b42be54
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/command/CommandSyntaxErrorTypeMap.java
@@ -0,0 +1,66 @@
+package land.chipmunk.chipmunkbot.command;
+
+import com.mojang.brigadier.Message;
+import com.mojang.brigadier.exceptions.BuiltInExceptionProvider;
+import com.mojang.brigadier.exceptions.CommandSyntaxException;
+import com.mojang.brigadier.exceptions.CommandExceptionType;
+import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
+import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
+import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.ComponentLike;
+import net.kyori.adventure.text.TextComponent;
+
+import java.util.Map;
+import java.util.HashMap;
+
+public class CommandSyntaxErrorTypeMap {
+ private CommandSyntaxErrorTypeMap () {
+ }
+
+ // Just some methods for stuff repeated a lot
+ private static Message message (final String key, final ComponentLike... args) { return ComponentMessage.wrap(Component.translatable(key, args)); }
+ private static TextComponent text (final Object text) { return Component.text(String.valueOf(text)); }
+ private static TextComponent text (final int text) { return Component.text(text); }
+ private static TextComponent text (final char text) { return Component.text(String.valueOf(text)); }
+
+ public static Map map = new HashMap<>();
+
+ static {
+ final BuiltInExceptionProvider builtIn = CommandSyntaxException.BUILT_IN_EXCEPTIONS;
+
+ map.put(builtIn.doubleTooLow(), new Dynamic2CommandExceptionType((found, min) -> message("argument.double.low", text(min), text(found))));
+ map.put(builtIn.doubleTooHigh(), new Dynamic2CommandExceptionType((found, max) -> message("argument.double.big", text(max), text(found))));
+
+ map.put(builtIn.floatTooLow(), new Dynamic2CommandExceptionType((found, min) -> message("argument.float.low", text(min), text(found))));
+ map.put(builtIn.floatTooHigh(), new Dynamic2CommandExceptionType((found, max) -> message("argument.float.big", text(max), text(found))));
+
+ map.put(builtIn.integerTooLow(), new Dynamic2CommandExceptionType((found, min) -> message("argument.integer.low", text(min), text(found))));
+ map.put(builtIn.integerTooHigh(), new Dynamic2CommandExceptionType((found, max) -> message("argument.integer.big", text(max), text(found))));
+
+ map.put(builtIn.longTooLow(), new Dynamic2CommandExceptionType((found, min) -> message("argument.long.low", text(min), text(found))));
+ map.put(builtIn.longTooHigh(), new Dynamic2CommandExceptionType((found, max) -> message("argument.long.big", text(max), text(found))));
+
+ map.put(builtIn.literalIncorrect(), new DynamicCommandExceptionType(expected -> message("argument.literal.incorrect", text(expected))));
+
+ map.put(builtIn.readerExpectedStartOfQuote(), new SimpleCommandExceptionType(message("parsing.quote.expected.start")));
+ map.put(builtIn.readerExpectedEndOfQuote(), new SimpleCommandExceptionType(message("parsing.quote.expected.end")));
+ map.put(builtIn.readerInvalidEscape(), new DynamicCommandExceptionType(character -> message("parsing.quote.escape", text(character))));
+ map.put(builtIn.readerInvalidBool(), new DynamicCommandExceptionType(value -> message("parsing.bool.invalid", text(value))));
+ map.put(builtIn.readerInvalidInt(), new DynamicCommandExceptionType(value -> message("parsing.int.invalid", text(value))));
+ map.put(builtIn.readerExpectedInt(), new SimpleCommandExceptionType(message("parsing.int.expected")));
+ map.put(builtIn.readerInvalidLong(), new DynamicCommandExceptionType(value -> message("parsing.long.invalid", text(value))));
+ map.put(builtIn.readerExpectedLong(), new SimpleCommandExceptionType(message("parsing.long.expected")));
+ map.put(builtIn.readerInvalidDouble(), new DynamicCommandExceptionType(value -> message("parsing.double.invalid", text(value))));
+ map.put(builtIn.readerExpectedDouble(), new SimpleCommandExceptionType(message("parsing.double.expected")));
+ map.put(builtIn.readerInvalidFloat(), new DynamicCommandExceptionType(value -> message("parsing.float.invalid", text(value))));
+ map.put(builtIn.readerExpectedFloat(), new SimpleCommandExceptionType(message("parsing.float.expected")));
+ map.put(builtIn.readerExpectedBool(), new SimpleCommandExceptionType(message("parsing.bool.expected")));
+ map.put(builtIn.readerExpectedSymbol(), new DynamicCommandExceptionType(symbol -> message("parsing.expected", text(symbol))));
+
+ map.put(builtIn.dispatcherUnknownCommand(), new SimpleCommandExceptionType(message("command.unknown.command")));
+ map.put(builtIn.dispatcherUnknownArgument(), new SimpleCommandExceptionType(message("command.unknown.argument")));
+ map.put(builtIn.dispatcherExpectedArgumentSeparator(), new SimpleCommandExceptionType(message("command.expected.separator")));
+ map.put(builtIn.dispatcherParseException(), new SimpleCommandExceptionType(message("command.exception")));
+ }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/command/ComponentMessage.java b/src/main/java/land/chipmunk/chipmunkbot/command/ComponentMessage.java
new file mode 100644
index 0000000..25bd419
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/command/ComponentMessage.java
@@ -0,0 +1,25 @@
+package land.chipmunk.chipmunkbot.command;
+
+import net.kyori.adventure.text.Component;
+import com.mojang.brigadier.Message;
+import lombok.Getter;
+
+public class ComponentMessage implements Message {
+ @Getter private final Component component;
+
+ private ComponentMessage (Component component) {
+ this.component = component;
+ }
+
+ public static ComponentMessage wrap (Component component) {
+ return new ComponentMessage(component);
+ }
+
+ public String getString () {
+ return component.toString(); // ? Is this the best way to get the string?
+ }
+
+ public String toString () {
+ return component.toString();
+ }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/command/ConsoleCommandSource.java b/src/main/java/land/chipmunk/chipmunkbot/command/ConsoleCommandSource.java
new file mode 100644
index 0000000..1b19a37
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/command/ConsoleCommandSource.java
@@ -0,0 +1,22 @@
+package land.chipmunk.chipmunkbot.command;
+
+import com.mojang.brigadier.Message;
+import net.kyori.adventure.text.Component;
+
+public class ConsoleCommandSource implements CommandSource {
+ @Override
+ public void sendOutput (Component message, boolean broadcast) {
+ System.out.println(message);
+ // TODO: broadcast
+ }
+
+ @Override
+ public void sendOutput (Component message) {
+ sendOutput(message, true);
+ }
+
+ @Override
+ public Component displayName () {
+ return Component.text("Console");
+ }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/plugins/ChatPlugin.java b/src/main/java/land/chipmunk/chipmunkbot/plugins/ChatPlugin.java
index 8f655cc..7714a17 100644
--- a/src/main/java/land/chipmunk/chipmunkbot/plugins/ChatPlugin.java
+++ b/src/main/java/land/chipmunk/chipmunkbot/plugins/ChatPlugin.java
@@ -9,14 +9,19 @@ import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCh
import com.github.steveice10.packetlib.packet.Packet;
import com.github.steveice10.packetlib.Session;
import com.github.steveice10.packetlib.event.session.SessionAdapter;
+import com.google.gson.JsonObject;
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");
+public class ChatPlugin implements Plugin {
+ private Client client;
+
+ @Override public String id () { return "chat"; }
+
+ public void inject (Client client, JsonObject options) {
+ this.client = client;
}
public void message (String message) {
diff --git a/src/main/java/land/chipmunk/chipmunkbot/plugins/CommandManagerPlugin.java b/src/main/java/land/chipmunk/chipmunkbot/plugins/CommandManagerPlugin.java
new file mode 100644
index 0000000..209face
--- /dev/null
+++ b/src/main/java/land/chipmunk/chipmunkbot/plugins/CommandManagerPlugin.java
@@ -0,0 +1,21 @@
+package land.chipmunk.chipmunkbot.plugins;
+
+import com.mojang.brigadier.CommandDispatcher;
+import land.chipmunk.chipmunkbot.Client;
+import land.chipmunk.chipmunkbot.Plugin;
+import land.chipmunk.chipmunkbot.command.CommandSource;
+import com.google.gson.JsonObject;
+import lombok.Getter;
+import lombok.Setter;
+
+public class CommandManagerPlugin implements Plugin {
+ private Client client;
+ @Getter @Setter private CommandDispatcher dispatcher = new CommandDispatcher<>();
+
+ @Override public String id () { return "command_manager"; }
+
+ @Override
+ public void inject (Client client, JsonObject options) {
+ this.client = client;
+ }
+}
diff --git a/src/main/java/land/chipmunk/chipmunkbot/plugins/PlayerListPlugin.java b/src/main/java/land/chipmunk/chipmunkbot/plugins/PlayerListPlugin.java
index 8c1e7fa..c91ea9b 100644
--- a/src/main/java/land/chipmunk/chipmunkbot/plugins/PlayerListPlugin.java
+++ b/src/main/java/land/chipmunk/chipmunkbot/plugins/PlayerListPlugin.java
@@ -9,16 +9,21 @@ 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 com.google.gson.JsonObject;
import java.util.List;
import java.util.ArrayList;
import java.util.UUID;
-public class PlayerListPlugin extends Plugin {
+public class PlayerListPlugin implements Plugin {
+ private Client client;
public List list = new ArrayList();
- public PlayerListPlugin (Client client) {
- super(client, "player_list");
+ @Override public String id () { return "player_list"; }
+
+ @Override
+ public void inject (Client client, JsonObject options) {
+ this.client = client;
client.session().addListener(new SessionAdapter() {
@Override