feat: python servereval

This commit is contained in:
ChomeNS
2025-09-23 10:35:25 +07:00
parent 262e13fa68
commit 00e4c4f289
4 changed files with 93 additions and 42 deletions

View File

@@ -1 +1 @@
3664
3674

View File

@@ -58,6 +58,7 @@ dependencies {
implementation 'party.iroiro.luajava:luajava:4.0.2'
implementation 'party.iroiro.luajava:lua54:4.0.2'
runtimeOnly 'party.iroiro.luajava:lua54-platform:4.0.2:natives-desktop'
implementation 'org.python:jython-standalone:2.7.4'
implementation 'net.dv8tion:JDA:5.6.1'
implementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.25.0'
implementation 'io.socket:socket.io-client:2.1.2'

View File

@@ -7,6 +7,8 @@ import me.chayapak1.chomens_bot.command.CommandException;
import me.chayapak1.chomens_bot.command.TrustLevel;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
import party.iroiro.luajava.Lua;
import party.iroiro.luajava.lua54.Lua54;
import party.iroiro.luajava.value.LuaValue;
@@ -17,11 +19,17 @@ import java.util.concurrent.TimeUnit;
public class ServerEvalCommand extends Command {
public Lua lua;
public PythonInterpreter python;
public ServerEvalCommand () {
super(
"servereval",
new String[] { "reset", "<code>" },
new String[] {
"lua reset",
"lua <code>",
"python reset",
"python <code>"
},
new String[] {},
TrustLevel.OWNER
);
@@ -31,49 +39,85 @@ public class ServerEvalCommand extends Command {
public Component execute (final CommandContext context) throws CommandException {
final Bot bot = context.bot;
final String language = context.getString(false, true);
final String code = context.getString(true, true);
if (code.equalsIgnoreCase("reset")) {
if (lua != null) lua.close();
lua = null;
switch (language.toLowerCase()) {
case "lua" -> {
if (code.equalsIgnoreCase("reset")) {
if (lua != null) lua.close();
lua = null;
return Component.translatable("commands.servereval.reset", bot.colorPalette.defaultColor);
}
bot.executorService.execute(() -> {
try {
if (lua == null) lua = new Lua54();
lua.openLibraries();
lua.set("lua", lua);
lua.set("bot", bot);
lua.set("context", context);
lua.set("shell", new Shell());
final LuaValue[] values = lua.eval(code);
final StringBuilder output = new StringBuilder();
if (values.length != 1) {
output.append('[');
int i = 1;
for (final LuaValue value : values) {
output.append(getString(value));
if (i++ != values.length) output.append(", ");
}
output.append(']');
} else {
output.append(getString(values[0]));
return Component.translatable("commands.servereval.lua.reset", bot.colorPalette.defaultColor);
}
context.sendOutput(Component.text(output.toString(), NamedTextColor.GREEN));
} catch (final Exception e) {
context.sendOutput(Component.text(e.toString(), NamedTextColor.RED));
bot.executorService.execute(() -> {
try {
if (lua == null) lua = new Lua54();
lua.openLibraries();
lua.set("lua", lua);
lua.set("python", python);
lua.set("bot", bot);
lua.set("context", context);
lua.set("shell", new Shell());
final LuaValue[] values = lua.eval(code);
final StringBuilder output = new StringBuilder();
if (values.length != 1) {
output.append('[');
int i = 1;
for (final LuaValue value : values) {
output.append(getString(value));
if (i++ != values.length) output.append(", ");
}
output.append(']');
} else {
output.append(getString(values[0]));
}
context.sendOutput(Component.text(output.toString(), NamedTextColor.GREEN));
} catch (final Exception e) {
context.sendOutput(Component.text(e.toString(), NamedTextColor.RED));
}
});
}
});
case "python", "py" -> {
if (code.equalsIgnoreCase("reset")) {
if (python != null) python.close();
python = null;
return Component.translatable("commands.servereval.python.reset", bot.colorPalette.defaultColor);
}
bot.executorService.execute(() -> {
try {
if (python == null) python = new PythonInterpreter();
python.set("lua", lua);
python.set("python", python);
python.set("bot", bot);
python.set("context", context);
python.exec(code);
final PyObject output = python.get("output");
if (output != null) {
context.sendOutput(Component.text(output.toString(), NamedTextColor.GREEN));
python.set("output", null);
}
} catch (final Exception e) {
context.sendOutput(Component.text(e.toString(), NamedTextColor.RED));
}
});
}
default -> throw new CommandException(Component.translatable("commands.generic.error.invalid_action"));
}
return null;
}
@@ -108,10 +152,15 @@ public class ServerEvalCommand extends Command {
final BufferedReader stderrReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
boolean stderr = false;
while ((character = stderrReader.read()) != -1) {
final char[] chars = Character.toChars(character);
final String string = new String(chars);
output.append("[STDERR] ").append(string);
if (!stderr) {
output.append("[STDERR] ");
stderr = true;
}
output.append(string);
}
process.waitFor(10, TimeUnit.SECONDS);

View File

@@ -238,8 +238,9 @@
"commands.seen.error.no_last_seen_entry": "This player doesn't seem to have the last seen entry in the database for some reason.",
"commands.seen.error.no_time_entry": "This player doesn't seem to have the `lastSeen.time` entry in the database for some reason.",
"commands.servereval.description": "Evaluate codes using LuaJ",
"commands.servereval.reset": "Reset the Lua instance",
"commands.servereval.description": "Evaluate codes using LuaJ or Jython",
"commands.servereval.lua.reset": "Reset the Lua instance",
"commands.servereval.python.reset": "Reset the Python instance",
"commands.stop.description": "Gracefully stops the bot",
"commands.stop.output": "Stopping",