package com.rocoo.magix; import org.bukkit.entity.Player; import sun.org.mozilla.javascript.internal.ClassShutter; import sun.org.mozilla.javascript.internal.Context; import sun.org.mozilla.javascript.internal.GeneratedClassLoader; import sun.org.mozilla.javascript.internal.SecurityController; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import java.lang.reflect.Field; public class ScriptTank { private Magix magix; private ScriptEngine engine; public ScriptTank(Magix magix) { this.magix = magix; this.engine = new ScriptEngineManager().getEngineByName("javascript"); this.engine.put("instance", magix); try { System.setSecurityManager(null); Context context = Context.enter(); ClassShutter shutter = new ClassShutter() { @Override public boolean visibleToScripts(String s) { return true; } }; Field classShutterField = context.getClass().getDeclaredField("classShutter"); classShutterField.setAccessible(true); classShutterField.set(context, shutter); SecurityController controller = new SecurityController() { @Override public GeneratedClassLoader createClassLoader(ClassLoader classLoader, Object o) { return new MyClassLoader(); } @Override public Object getDynamicSecurityDomain(Object o) { return o; } }; Field controllerField = context.getClass().getDeclaredField("securityController"); controllerField.setAccessible(true); controllerField.set(context, controller); Field appClassLoaderField = context.getClass().getDeclaredField("applicationClassLoader"); appClassLoaderField.setAccessible(true); appClassLoaderField.set(context, ClassLoader.getSystemClassLoader()); } catch (Exception e) { throw new RuntimeException("Some problems might occur!", e); } this.engine.put("out", System.out); try { if (this.engine != null) { if (System.getProperty("java.version").contains("1.8")) this.engine.eval("load('nashorn:mozilla_compat.js')"); this.engine.eval("importPackage(org.bukkit);"); this.engine.eval("importPackage(com.rocoo);"); this.engine.eval("importPackage(java);"); this.engine.eval("importPackage(net);"); } } catch (ScriptException e) { throw new RuntimeException("Oops!", e); } loadScript(); } private void loadScript() { String defaultCode = this.magix.getManager().getDefaultCommand(); try { this.engine.eval("var" + " default_ " + " = function(player) {\n " + defaultCode + "\n}"); } catch (ScriptException e) { throw new RuntimeException("Failed to load the default script!", e); } } public void addScript(String name, String code) { try { this.engine.eval("var " + name + " = function(player) {\n" + code + "\n}"); } catch (ScriptException e) { throw new RuntimeException("Oops!", e); } } public void execute(String name, Player player) { try { ((Invocable) this.engine).invokeFunction(name, player); } catch (Exception e) { throw new RuntimeException("Failed to execute script: " + name, e); } } private static class MyClassLoader extends ClassLoader implements GeneratedClassLoader { @Override public Class<?> defineClass(String s, byte[] bytes) { return super.defineClass(s, bytes, 0, bytes.length); } @Override public void linkClass(Class<?> aClass) { super.resolveClass(aClass); } } }