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