From 48ffc7c01c405cdf8df51c824fac7523d89ea7a0 Mon Sep 17 00:00:00 2001 From: ChomeNS <95471003+ChomeNS@users.noreply.github.com> Date: Tue, 27 May 2025 17:48:17 +0700 Subject: [PATCH] refactor: make eval use only 1 connection to hopefully reduce threads amount + some misc refactors fix: in GetBotInfoFunction, i misspelled `username` as `usernane`, it has been fixed refactor: remove GetLatestChatMessageFunction, since the functions are now global and not bot-specific (yes, i know i can still implement it somewhere like in EvalPlugin or even call a function in GetLatestChatMessageFunction itself passing the bot, but no one really use this function anyway except the last time when ploat made some telnet ahh eval thing which used this function) --- build-number.txt | 2 +- .../java/me/chayapak1/chomens_bot/Main.java | 6 +- .../chomens_bot/commands/EvalCommand.java | 18 ++- .../chomens_bot/data/eval/EvalFunction.java | 10 +- .../evalFunctions/ChatFunction.java | 6 +- .../evalFunctions/CoreFunction.java | 6 +- .../evalFunctions/CorePlaceBlockFunction.java | 6 +- .../evalFunctions/GetBotInfoFunction.java | 8 +- .../GetLatestChatMessageFunction.java | 29 ---- .../evalFunctions/GetPlayerListFunction.java | 6 +- .../chomens_bot/plugins/EvalPlugin.java | 144 ++++++++++-------- 11 files changed, 110 insertions(+), 131 deletions(-) delete mode 100644 src/main/java/me/chayapak1/chomens_bot/evalFunctions/GetLatestChatMessageFunction.java diff --git a/build-number.txt b/build-number.txt index 59dc2236..8a6d441a 100644 --- a/build-number.txt +++ b/build-number.txt @@ -1 +1 @@ -3342 \ No newline at end of file +3354 \ No newline at end of file diff --git a/src/main/java/me/chayapak1/chomens_bot/Main.java b/src/main/java/me/chayapak1/chomens_bot/Main.java index 83e7ef8f..afe0fc46 100644 --- a/src/main/java/me/chayapak1/chomens_bot/Main.java +++ b/src/main/java/me/chayapak1/chomens_bot/Main.java @@ -2,10 +2,7 @@ package me.chayapak1.chomens_bot; import com.google.common.util.concurrent.ThreadFactoryBuilder; import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import me.chayapak1.chomens_bot.plugins.ConsolePlugin; -import me.chayapak1.chomens_bot.plugins.DatabasePlugin; -import me.chayapak1.chomens_bot.plugins.DiscordPlugin; -import me.chayapak1.chomens_bot.plugins.IRCPlugin; +import me.chayapak1.chomens_bot.plugins.*; import me.chayapak1.chomens_bot.util.*; import net.dv8tion.jda.api.requests.restaction.MessageCreateAction; import org.yaml.snakeyaml.LoaderOptions; @@ -146,6 +143,7 @@ public class Main { console = new ConsolePlugin(config); if (config.discord.enabled) discord = new DiscordPlugin(config); if (config.irc.enabled) irc = new IRCPlugin(config); + EvalPlugin.connect(config.eval.address); LoggerUtilities.log(I18nUtilities.get("initialized")); diff --git a/src/main/java/me/chayapak1/chomens_bot/commands/EvalCommand.java b/src/main/java/me/chayapak1/chomens_bot/commands/EvalCommand.java index 8bb53cc2..adfbf40a 100644 --- a/src/main/java/me/chayapak1/chomens_bot/commands/EvalCommand.java +++ b/src/main/java/me/chayapak1/chomens_bot/commands/EvalCommand.java @@ -7,6 +7,7 @@ import me.chayapak1.chomens_bot.command.CommandException; import me.chayapak1.chomens_bot.command.TrustLevel; import me.chayapak1.chomens_bot.data.chat.ChatPacketType; import me.chayapak1.chomens_bot.data.eval.EvalOutput; +import me.chayapak1.chomens_bot.plugins.EvalPlugin; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -28,7 +29,7 @@ public class EvalCommand extends Command { public Component execute (final CommandContext context) throws CommandException { final Bot bot = context.bot; - if (!bot.eval.connected) throw new CommandException(Component.translatable("commands.eval.error.offline")); + if (!EvalPlugin.connected) throw new CommandException(Component.translatable("commands.eval.error.offline")); final String action = context.getAction(); @@ -38,16 +39,19 @@ public class EvalCommand extends Command { final CompletableFuture future = bot.eval.run(command); - future.thenApply(output -> { - if (output.isError()) context.sendOutput(Component.text(output.output()).color(NamedTextColor.RED)); - else context.sendOutput(Component.text(output.output())); + // it returns null when the eval server isn't online, even though we have already checked, + // i'm just fixing the warning here + if (future == null) return null; - return output; + future.thenApply(result -> { + if (result.isError()) context.sendOutput(Component.text(result.output(), NamedTextColor.RED)); + else context.sendOutput(Component.text(result.output())); + + return result; }); } case "reset" -> { - bot.eval.reset(); - + EvalPlugin.reset(); return Component.translatable("commands.eval.reset", bot.colorPalette.defaultColor); } default -> throw new CommandException(Component.translatable("commands.generic.error.invalid_action")); diff --git a/src/main/java/me/chayapak1/chomens_bot/data/eval/EvalFunction.java b/src/main/java/me/chayapak1/chomens_bot/data/eval/EvalFunction.java index 3e3d7dd8..938cdc2e 100644 --- a/src/main/java/me/chayapak1/chomens_bot/data/eval/EvalFunction.java +++ b/src/main/java/me/chayapak1/chomens_bot/data/eval/EvalFunction.java @@ -5,17 +5,11 @@ import me.chayapak1.chomens_bot.Bot; public class EvalFunction { public final String name; - protected final Bot bot; - - public EvalFunction ( - final String name, - final Bot bot - ) { + public EvalFunction (final String name) { this.name = name; - this.bot = bot; } - public Output execute (final Object... args) throws Exception { return null; } + public Output execute (final Bot bot, final Object... args) throws Exception { return null; } public record Output(String message, boolean parseJSON) { } diff --git a/src/main/java/me/chayapak1/chomens_bot/evalFunctions/ChatFunction.java b/src/main/java/me/chayapak1/chomens_bot/evalFunctions/ChatFunction.java index 603c1655..3a35c597 100644 --- a/src/main/java/me/chayapak1/chomens_bot/evalFunctions/ChatFunction.java +++ b/src/main/java/me/chayapak1/chomens_bot/evalFunctions/ChatFunction.java @@ -4,12 +4,12 @@ import me.chayapak1.chomens_bot.Bot; import me.chayapak1.chomens_bot.data.eval.EvalFunction; public class ChatFunction extends EvalFunction { - public ChatFunction (final Bot bot) { - super("chat", bot); + public ChatFunction () { + super("chat"); } @Override - public Output execute (final Object... args) { + public Output execute (final Bot bot, final Object... args) { if (args.length == 0) return null; final String message = (String) args[0]; diff --git a/src/main/java/me/chayapak1/chomens_bot/evalFunctions/CoreFunction.java b/src/main/java/me/chayapak1/chomens_bot/evalFunctions/CoreFunction.java index 998c93db..54b445d0 100644 --- a/src/main/java/me/chayapak1/chomens_bot/evalFunctions/CoreFunction.java +++ b/src/main/java/me/chayapak1/chomens_bot/evalFunctions/CoreFunction.java @@ -11,12 +11,12 @@ import java.util.concurrent.TimeUnit; public class CoreFunction extends EvalFunction { private long lastExecutionTime = System.currentTimeMillis(); - public CoreFunction (final Bot bot) { - super("core", bot); + public CoreFunction () { + super("core"); } @Override - public Output execute (final Object... args) throws Exception { + public Output execute (final Bot bot, final Object... args) throws Exception { if (args.length == 0) return null; // prevent 69 DDOS exploit !!! diff --git a/src/main/java/me/chayapak1/chomens_bot/evalFunctions/CorePlaceBlockFunction.java b/src/main/java/me/chayapak1/chomens_bot/evalFunctions/CorePlaceBlockFunction.java index 04421e4c..fa13d686 100644 --- a/src/main/java/me/chayapak1/chomens_bot/evalFunctions/CorePlaceBlockFunction.java +++ b/src/main/java/me/chayapak1/chomens_bot/evalFunctions/CorePlaceBlockFunction.java @@ -4,12 +4,12 @@ import me.chayapak1.chomens_bot.Bot; import me.chayapak1.chomens_bot.data.eval.EvalFunction; public class CorePlaceBlockFunction extends EvalFunction { - public CorePlaceBlockFunction (final Bot bot) { - super("corePlaceBlock", bot); + public CorePlaceBlockFunction () { + super("corePlaceBlock"); } @Override - public Output execute (final Object... args) { + public Output execute (final Bot bot, final Object... args) { if (args.length == 0) return null; final String command = (String) args[0]; diff --git a/src/main/java/me/chayapak1/chomens_bot/evalFunctions/GetBotInfoFunction.java b/src/main/java/me/chayapak1/chomens_bot/evalFunctions/GetBotInfoFunction.java index f4d5b06c..353e2a03 100644 --- a/src/main/java/me/chayapak1/chomens_bot/evalFunctions/GetBotInfoFunction.java +++ b/src/main/java/me/chayapak1/chomens_bot/evalFunctions/GetBotInfoFunction.java @@ -5,15 +5,15 @@ import me.chayapak1.chomens_bot.Bot; import me.chayapak1.chomens_bot.data.eval.EvalFunction; public class GetBotInfoFunction extends EvalFunction { - public GetBotInfoFunction (final Bot bot) { - super("getBotInfo", bot); + public GetBotInfoFunction () { + super("getBotInfo"); } @Override - public Output execute (final Object... args) { + public Output execute (final Bot bot, final Object... args) { final JsonObject object = new JsonObject(); - object.addProperty("usernane", bot.username); + object.addProperty("username", bot.username); object.addProperty("host", bot.host); object.addProperty("port", bot.port); object.addProperty("loggedIn", bot.loggedIn); diff --git a/src/main/java/me/chayapak1/chomens_bot/evalFunctions/GetLatestChatMessageFunction.java b/src/main/java/me/chayapak1/chomens_bot/evalFunctions/GetLatestChatMessageFunction.java deleted file mode 100644 index bf6c5172..00000000 --- a/src/main/java/me/chayapak1/chomens_bot/evalFunctions/GetLatestChatMessageFunction.java +++ /dev/null @@ -1,29 +0,0 @@ -package me.chayapak1.chomens_bot.evalFunctions; - -import me.chayapak1.chomens_bot.Bot; -import me.chayapak1.chomens_bot.data.eval.EvalFunction; -import me.chayapak1.chomens_bot.data.listener.Listener; -import me.chayapak1.chomens_bot.util.SNBTUtilities; -import net.kyori.adventure.text.Component; - -public class GetLatestChatMessageFunction extends EvalFunction implements Listener { - private String latestMessage = ""; - - public GetLatestChatMessageFunction (final Bot bot) { - super("getLatestChatMessage", bot); - - bot.listener.addListener(this); - } - - @Override - public boolean onSystemMessageReceived (final Component component, final String string, final String ansi) { - latestMessage = SNBTUtilities.fromComponent(false, component); - - return true; - } - - @Override - public Output execute (final Object... args) { - return new Output(latestMessage, true); - } -} diff --git a/src/main/java/me/chayapak1/chomens_bot/evalFunctions/GetPlayerListFunction.java b/src/main/java/me/chayapak1/chomens_bot/evalFunctions/GetPlayerListFunction.java index ce677c47..7d87cc0c 100644 --- a/src/main/java/me/chayapak1/chomens_bot/evalFunctions/GetPlayerListFunction.java +++ b/src/main/java/me/chayapak1/chomens_bot/evalFunctions/GetPlayerListFunction.java @@ -10,12 +10,12 @@ import me.chayapak1.chomens_bot.util.SNBTUtilities; import java.util.List; public class GetPlayerListFunction extends EvalFunction { - public GetPlayerListFunction (final Bot bot) { - super("getPlayerList", bot); + public GetPlayerListFunction () { + super("getPlayerList"); } @Override - public Output execute (final Object... args) { + public Output execute (final Bot bot, final Object... args) { final List list = bot.players.list; final JsonArray array = new JsonArray(); diff --git a/src/main/java/me/chayapak1/chomens_bot/plugins/EvalPlugin.java b/src/main/java/me/chayapak1/chomens_bot/plugins/EvalPlugin.java index 23567da4..df92ef2c 100644 --- a/src/main/java/me/chayapak1/chomens_bot/plugins/EvalPlugin.java +++ b/src/main/java/me/chayapak1/chomens_bot/plugins/EvalPlugin.java @@ -2,115 +2,127 @@ package me.chayapak1.chomens_bot.plugins; import com.google.gson.Gson; import com.google.gson.JsonArray; +import com.google.gson.JsonObject; import io.socket.client.IO; import io.socket.client.Socket; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectList; import me.chayapak1.chomens_bot.Bot; +import me.chayapak1.chomens_bot.Main; import me.chayapak1.chomens_bot.data.eval.EvalFunction; import me.chayapak1.chomens_bot.data.eval.EvalOutput; import me.chayapak1.chomens_bot.evalFunctions.*; +import me.chayapak1.chomens_bot.util.LoggerUtilities; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicInteger; public class EvalPlugin { - public static final String BRIDGE_PREFIX = "function:"; + private static final String BRIDGE_PREFIX = "function:"; + public static final List FUNCTIONS = ObjectList.of( + new CoreFunction(), + new CorePlaceBlockFunction(), + new ChatFunction(), + new GetPlayerListFunction(), + new GetBotInfoFunction() + ); + private static final Gson GSON = new Gson(); - public boolean connected = false; + private static Socket socket = null; + public static boolean connected = false; - private Socket socket = null; - - private int transactionId = 0; - - private final Map> futures = new Object2ObjectOpenHashMap<>(); - - public final List functions = new ArrayList<>(); - - private final Gson gson = new Gson(); - - public EvalPlugin (final Bot bot) { - functions.add(new CoreFunction(bot)); - functions.add(new CorePlaceBlockFunction(bot)); - functions.add(new ChatFunction(bot)); - functions.add(new GetPlayerListFunction(bot)); - functions.add(new GetBotInfoFunction(bot)); - functions.add(new GetLatestChatMessageFunction(bot)); + private static final AtomicInteger transactionId = new AtomicInteger(); + private static final Map> futures = new Object2ObjectOpenHashMap<>(); + public static void connect (final String address) { try { - socket = IO.socket(bot.config.eval.address); + socket = IO.socket(address); } catch (final Exception e) { - bot.logger.error(e); + LoggerUtilities.error(e); + return; } - socket.on(Socket.EVENT_CONNECT, (args) -> { + socket.on(Socket.EVENT_CONNECT, args -> { connected = true; - final JsonArray array = new JsonArray(); + final JsonArray functionsArray = new JsonArray(); - for (final EvalFunction function : functions) array.add(function.name); + for (final Bot bot : Main.bots) { + final String server = bot.getServerString(true); + + for (final EvalFunction function : FUNCTIONS) { + final JsonObject object = new JsonObject(); + + object.addProperty("name", function.name); + object.addProperty("server", server); + + functionsArray.add(object); + } + + for (final EvalFunction function : FUNCTIONS) { + socket.on( + BRIDGE_PREFIX + function.name + ":" + bot.getServerString(true), + functionArgs -> + Main.EXECUTOR_SERVICE.submit(() -> { + try { + final EvalFunction.Output output = function.execute(bot, functionArgs); + if (output == null) return; + socket.emit("functionOutput:" + function.name, output.message(), output.parseJSON()); + } catch (final Exception ignored) { } + }) + ); + } + + socket.on("codeOutput", outputArgs -> { + if (outputArgs.length < 3) return; + + try { + final int id = (int) outputArgs[0]; + final boolean isError = (boolean) outputArgs[1]; + final String output = (String) outputArgs[2]; + + if (!futures.containsKey(id)) return; + + final CompletableFuture future = futures.remove(id); + + future.complete(new EvalOutput(isError, output)); + } catch (final ClassCastException | NumberFormatException ignored) { } + }); + } socket.emit( "setFunctions", - gson.toJson(array) + GSON.toJson(functionsArray) ); }); - socket.on(Socket.EVENT_DISCONNECT, (args) -> connected = false); - socket.on(Socket.EVENT_CONNECT_ERROR, (args) -> connected = false); - - for (final EvalFunction function : functions) { - socket.on( - BRIDGE_PREFIX + function.name, - args -> - bot.executorService.submit(() -> { - try { - final EvalFunction.Output output = function.execute(args); - - if (output == null) return; - - socket.emit("functionOutput:" + function.name, output.message(), output.parseJSON()); - } catch (final Exception ignored) { } - }) - ); - } - - socket.on("codeOutput", (args) -> { - if (args.length < 3) return; - - try { - final int id = (int) args[0]; - final boolean isError = (boolean) args[1]; - final String output = (String) args[2]; - - if (!futures.containsKey(id)) return; - - final CompletableFuture future = futures.remove(id); - - future.complete(new EvalOutput(isError, output)); - } catch (final NumberFormatException ignored) { } - }); + socket.on(Socket.EVENT_DISCONNECT, args -> connected = false); + socket.on(Socket.EVENT_CONNECT_ERROR, args -> connected = false); socket.connect(); } + private final Bot bot; + + public EvalPlugin (final Bot bot) { + this.bot = bot; + } + public CompletableFuture run (final String code) { final CompletableFuture future = new CompletableFuture<>(); if (!connected) return null; - socket.emit("runCode", transactionId, code); + socket.emit("runCode", bot.getServerString(true), transactionId.get(), code); - futures.put(transactionId, future); - - transactionId++; + futures.put(transactionId.getAndIncrement(), future); return future; } - public void reset () { + public static void reset () { if (!connected) return; - socket.emit("reset"); } }