diff --git a/build.gradle b/build.gradle index ca45e03..03007b7 100644 --- a/build.gradle +++ b/build.gradle @@ -44,6 +44,7 @@ dependencies { implementation 'joda-time:joda-time:2.12.4' implementation 'net.kyori:adventure-text-serializer-legacy:4.13.1' implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.20.0' + implementation 'io.socket:socket.io-client:2.1.0' } jar { diff --git a/src/main/java/land/chipmunk/chayapak/chomens_bot/Bot.java b/src/main/java/land/chipmunk/chayapak/chomens_bot/Bot.java index e298a6f..9dd34d1 100644 --- a/src/main/java/land/chipmunk/chayapak/chomens_bot/Bot.java +++ b/src/main/java/land/chipmunk/chayapak/chomens_bot/Bot.java @@ -61,7 +61,7 @@ public class Bot { @Getter private BossbarManagerPlugin bossbar; @Getter private MusicPlayerPlugin music; @Getter private TPSPlugin tps; - @Getter private EvalRunnerPlugin eval; + @Getter private EvalPlugin eval; @Getter private TrustedPlugin trusted; @Getter private BruhifyPlugin bruhify; @Getter private GrepLogPlugin grepLog; @@ -107,7 +107,7 @@ public class Bot { this.bossbar = new BossbarManagerPlugin(this); this.music = new MusicPlayerPlugin(this); this.tps = new TPSPlugin(this); - this.eval = new EvalRunnerPlugin(this); + this.eval = new EvalPlugin(this); this.trusted = new TrustedPlugin(this); this.bruhify = new BruhifyPlugin(this); this.grepLog = new GrepLogPlugin(this); diff --git a/src/main/java/land/chipmunk/chayapak/chomens_bot/commands/EvalCommand.java b/src/main/java/land/chipmunk/chayapak/chomens_bot/commands/EvalCommand.java new file mode 100644 index 0000000..5a1829a --- /dev/null +++ b/src/main/java/land/chipmunk/chayapak/chomens_bot/commands/EvalCommand.java @@ -0,0 +1,57 @@ +package land.chipmunk.chayapak.chomens_bot.commands; + +import land.chipmunk.chayapak.chomens_bot.Bot; +import land.chipmunk.chayapak.chomens_bot.command.Command; +import land.chipmunk.chayapak.chomens_bot.command.CommandContext; +import land.chipmunk.chayapak.chomens_bot.command.TrustLevel; +import land.chipmunk.chayapak.chomens_bot.data.EvalOutput; +import land.chipmunk.chayapak.chomens_bot.util.ColorUtilities; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; + +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; + +public class EvalCommand extends Command { + public EvalCommand () { + super( + "eval", + "Evaluate JavaScript codes", + new String[] { "run <{code}>", "reset" }, + new String[] {}, + TrustLevel.PUBLIC + ); + } + + @Override + public Component execute(CommandContext context, String[] args, String[] fullArgs) { + final Bot bot = context.bot(); + + if (!bot.eval().connected()) return Component.text("Eval server is not online").color(NamedTextColor.RED); + + switch (args[0]) { + case "run" -> { + final String command = String.join(" ", Arrays.copyOfRange(args, 1, args.length)); + + 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())); + + return output; + }); + } + case "reset" -> { + bot.eval().reset(); + + return Component.text("Reset the eval context").color(ColorUtilities.getColorByString(bot.config().colorPalette().defaultColor())); + } + default -> { + return Component.text("Invalid argument").color(NamedTextColor.RED); + } + } + + return null; + } +} diff --git a/src/main/java/land/chipmunk/chayapak/chomens_bot/commands/ServerEvalCommand.java b/src/main/java/land/chipmunk/chayapak/chomens_bot/commands/ServerEvalCommand.java index cbd75a3..de26fae 100644 --- a/src/main/java/land/chipmunk/chayapak/chomens_bot/commands/ServerEvalCommand.java +++ b/src/main/java/land/chipmunk/chayapak/chomens_bot/commands/ServerEvalCommand.java @@ -6,8 +6,10 @@ import land.chipmunk.chayapak.chomens_bot.command.CommandContext; import land.chipmunk.chayapak.chomens_bot.command.TrustLevel; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; +import org.luaj.vm2.Globals; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.jse.CoerceJavaToLua; +import org.luaj.vm2.lib.jse.JsePlatform; public class ServerEvalCommand extends Command { public ServerEvalCommand () { @@ -25,9 +27,15 @@ public class ServerEvalCommand extends Command { try { final Bot bot = context.bot(); - bot.eval().globals().set("context", CoerceJavaToLua.coerce(context)); + final Globals globals = JsePlatform.standardGlobals(); - final LuaValue output = context.bot().eval().run(String.join(" ", args)); + globals.set("bot", CoerceJavaToLua.coerce(bot)); + globals.set("class", CoerceJavaToLua.coerce(Class.class)); + globals.set("context", CoerceJavaToLua.coerce(context)); + + LuaValue chunk = globals.load(String.join(" ", args)); + + final LuaValue output = chunk.call(); return Component.text(output.toString()).color(NamedTextColor.GREEN); } catch (Exception e) { diff --git a/src/main/java/land/chipmunk/chayapak/chomens_bot/data/EvalOutput.java b/src/main/java/land/chipmunk/chayapak/chomens_bot/data/EvalOutput.java new file mode 100644 index 0000000..11996a1 --- /dev/null +++ b/src/main/java/land/chipmunk/chayapak/chomens_bot/data/EvalOutput.java @@ -0,0 +1,10 @@ +package land.chipmunk.chayapak.chomens_bot.data; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public class EvalOutput { + @Getter private final boolean isError; + @Getter private final String output; +} diff --git a/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/CommandHandlerPlugin.java b/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/CommandHandlerPlugin.java index aba4bcd..2b644cc 100644 --- a/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/CommandHandlerPlugin.java +++ b/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/CommandHandlerPlugin.java @@ -67,6 +67,7 @@ public class CommandHandlerPlugin { registerCommand(new UptimeCommand()); registerCommand(new MailCommand()); registerCommand(new SeenCommand()); + registerCommand(new EvalCommand()); } public void registerCommand (Command command) { diff --git a/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/EvalPlugin.java b/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/EvalPlugin.java new file mode 100644 index 0000000..46068d8 --- /dev/null +++ b/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/EvalPlugin.java @@ -0,0 +1,79 @@ +package land.chipmunk.chayapak.chomens_bot.plugins; + +import io.socket.client.IO; +import io.socket.client.Socket; +import land.chipmunk.chayapak.chomens_bot.Bot; +import land.chipmunk.chayapak.chomens_bot.data.EvalOutput; +import lombok.Getter; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +public class EvalPlugin { + public static final String BRIDGE_PREFIX = "function:"; + + @Getter private boolean connected = false; + + private Socket socket = null; + + private int transactionId = 0; + + private final Map> futures = new HashMap<>(); + + public EvalPlugin (Bot bot) { + try { + socket = IO.socket("ws://localhost:3069"); + } catch (Exception e) { + e.printStackTrace(); + } + + socket.on(Socket.EVENT_CONNECT, (args) -> connected = true); + socket.on(Socket.EVENT_DISCONNECT, (args) -> connected = false); + socket.on(Socket.EVENT_CONNECT_ERROR, (args) -> connected = false); + + socket.on("codeOutput", (args) -> { + final int id = (int) args[0]; + final boolean isError = (boolean) args[1]; + final String output = (String) args[2]; + + final CompletableFuture future = futures.get(id); + + future.complete(new EvalOutput(isError, output)); + }); + + socket.on(BRIDGE_PREFIX + "chat", (args) -> { + final String message = (String) args[0]; + + bot.chat().send(message); + }); + + socket.on(BRIDGE_PREFIX + "core", (args) -> { + final String command = (String) args[0]; + + bot.core().run(command); + }); + + socket.connect(); + } + + public CompletableFuture run (String code) { + final CompletableFuture future = new CompletableFuture<>(); + + if (!connected) return null; + + socket.emit("runCode", transactionId, code); + + futures.put(transactionId, future); + + transactionId++; + + return future; + } + + public void reset () { + if (!connected) return; + + socket.emit("reset"); + } +} diff --git a/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/EvalRunnerPlugin.java b/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/EvalRunnerPlugin.java deleted file mode 100644 index deaba3a..0000000 --- a/src/main/java/land/chipmunk/chayapak/chomens_bot/plugins/EvalRunnerPlugin.java +++ /dev/null @@ -1,23 +0,0 @@ -package land.chipmunk.chayapak.chomens_bot.plugins; - -import lombok.Getter; -import land.chipmunk.chayapak.chomens_bot.Bot; -import org.luaj.vm2.Globals; -import org.luaj.vm2.LuaValue; -import org.luaj.vm2.lib.jse.CoerceJavaToLua; -import org.luaj.vm2.lib.jse.JsePlatform; - -public class EvalRunnerPlugin { - @Getter private final Globals globals = JsePlatform.standardGlobals(); - - public EvalRunnerPlugin (Bot bot) { - globals.set("bot", CoerceJavaToLua.coerce(bot)); - globals.set("class", CoerceJavaToLua.coerce(Class.class)); - } - - public LuaValue run (String code) { - LuaValue chunk = globals.load(code); - - return chunk.call(); - } -}