Add nashorn sandbox
This commit is contained in:
parent
4039d11513
commit
5545dc1ab8
4 changed files with 60 additions and 47 deletions
|
@ -20,6 +20,7 @@ group = mod_group_id
|
|||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven { url 'https://repo.nea.moe/releases/' }
|
||||
}
|
||||
|
||||
base {
|
||||
|
@ -52,7 +53,10 @@ dependencies {
|
|||
// And its provides the option to then use net.minecraft as the group, and one of; client, server or joined as the module name, plus the game version as version.
|
||||
// For all intends and purposes: You can treat this dependency as if it is a normal library you would use.
|
||||
implementation "net.neoforged:neoforge:${neo_version}"
|
||||
libraries 'org.mozilla:rhino-engine:1.7.15'
|
||||
libraries('org.javadelight:delight-nashorn-sandbox:0.4.2-jpms') {
|
||||
exclude(group: "org.ow2.asm")
|
||||
exclude(group: "org.slf4j")
|
||||
}
|
||||
// Example optional mod dependency with JEI
|
||||
// The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
|
||||
// compileOnly "mezz.jei:jei-${mc_version}-common-api:${jei_version}"
|
||||
|
|
|
@ -35,7 +35,7 @@ public class ComputerBlockEntity extends BlockEntity {
|
|||
private static final MapCodec<ComputerTerminal> screenCodec = ComputerTerminal.CODEC
|
||||
.fieldOf("screen")
|
||||
.setPartial(() -> ComputerTerminal.ofSize(20, 30));
|
||||
JsVm jsVm = new JsVm();
|
||||
JsVm jsVm = new JsVm(this);
|
||||
private List<String> lines = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
|
@ -77,20 +77,17 @@ public class ComputerBlockEntity extends BlockEntity {
|
|||
|
||||
public void executeCommand(String line) {
|
||||
lines.add("$ " + line);
|
||||
lines.add(jsVm.evalJs(line));
|
||||
// if (line.equals("small")) {
|
||||
// screen = ComputerTerminal.ofSize(10, 20);
|
||||
// lines.add("Made small!");
|
||||
// } else if (line.equals("big")) {
|
||||
// screen = ComputerTerminal.ofSize(20, 30);
|
||||
// lines.add("Made big!");
|
||||
// } else if (line.startsWith("add")) {
|
||||
// var newline = line.replaceFirst("add ", "").split(" ");
|
||||
// lines.add(JsVm.EvalJs("mathj.add("+newline[0]+","+newline[1]+")"));
|
||||
// }
|
||||
// else {
|
||||
// lines.add("Made unknown!");
|
||||
// }
|
||||
if (line.equals("small")) {
|
||||
screen = ComputerTerminal.ofSize(10, 20);
|
||||
lines.add("Made small!");
|
||||
} else if (line.equals("big")) {
|
||||
screen = ComputerTerminal.ofSize(20, 30);
|
||||
lines.add("Made big!");
|
||||
} else if (line.startsWith("add")) {
|
||||
lines.add(jsVm.add(69, 42) + "");
|
||||
} else {
|
||||
lines.add("Made unknown!");
|
||||
}
|
||||
}
|
||||
|
||||
public ComputerScreenUpdate getSyncPacket(int windowId) {
|
||||
|
|
|
@ -1,44 +1,53 @@
|
|||
package dev.exhq.ajarc.vm;
|
||||
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
import org.mozilla.javascript.ScriptableObject;
|
||||
import org.mozilla.javascript.JavaScriptException;
|
||||
import delight.nashornsandbox.NashornSandbox;
|
||||
import delight.nashornsandbox.NashornSandboxes;
|
||||
import delight.nashornsandbox.internal.JsSanitizer;
|
||||
import dev.exhq.ajarc.Ajar;
|
||||
import dev.exhq.ajarc.computer.ComputerBlockEntity;
|
||||
import dev.exhq.ajarc.computer.ComputerTerminal;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
public class JsVm {
|
||||
private Context cx;
|
||||
private Scriptable scope;
|
||||
private final NashornSandbox sandbox;
|
||||
|
||||
public JsVm() {
|
||||
cx = Context.enter();
|
||||
try {
|
||||
scope = cx.initStandardObjects();
|
||||
MathJ mathJ = new MathJ();
|
||||
Object wrappedJsVm = Context.javaToJS(mathJ, scope);
|
||||
ScriptableObject.putProperty(scope, "mathj", wrappedJsVm);
|
||||
} finally {
|
||||
Context.exit();
|
||||
public JsVm(ComputerBlockEntity entity) {
|
||||
sandbox = NashornSandboxes.create();
|
||||
sandbox.inject("screen", new ScreenHelper(entity));
|
||||
}
|
||||
|
||||
public record ScreenHelper(ComputerBlockEntity entity) {
|
||||
public void setScreenSize(int rows, int cols) {
|
||||
entity.setTerminal(ComputerTerminal.ofSize(rows, cols));
|
||||
}
|
||||
}
|
||||
|
||||
public String evalJs(String command) {
|
||||
Context.enter();
|
||||
public int add(int left, int right) {
|
||||
String text;
|
||||
try {
|
||||
Object result = cx.evaluateString(scope, command, "<cmd>", 1, null);
|
||||
return Context.toString(result);
|
||||
} catch (JavaScriptException e) {
|
||||
return e.getMessage();
|
||||
} catch (Exception e) {
|
||||
return e.getMessage();
|
||||
} finally {
|
||||
Context.exit();
|
||||
var stream = Minecraft.getInstance()
|
||||
.getResourceManager()
|
||||
.getResourceOrThrow(Ajar.identifier("script.js"))
|
||||
.open();
|
||||
text = IOUtils.toString(stream, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
var bindings = sandbox.createBindings();
|
||||
bindings.put("left", left);
|
||||
bindings.put("right", right);
|
||||
try {
|
||||
sandbox.eval(text, bindings);
|
||||
} catch (ScriptException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
if (cx != null) {
|
||||
cx.exit();
|
||||
cx = null;
|
||||
}
|
||||
return (int) (double) bindings.get("result");
|
||||
}
|
||||
}
|
||||
|
|
3
src/main/resources/assets/ajarc/script.js
Normal file
3
src/main/resources/assets/ajarc/script.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
screen.setScreenSize(5, 30)
|
||||
result = left + right
|
Loading…
Reference in a new issue