diff --git a/.gitignore b/.gitignore index 8fc2d24..ee88a6d 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,6 @@ vendor/ # Minecraft Data /world **/node_modules/ + +# Gradle +.gradle diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml index b0685fa..6c25be5 100644 --- a/pom.xml +++ b/pom.xml @@ -2,13 +2,13 @@ 4.0.0 pw.yumc MiaoScript - 0.23.1 + 0.28.0 502647092 MiaoWoo admin@yumc.pw - http://www.yumc.pw + https://www.yumc.pw @@ -19,29 +19,6 @@ true - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.1 - - false - - - org.kamranzafar:jtar - - - - - - package - - shade - - - - - Jenkins @@ -50,6 +27,16 @@ DEV + §623-07-30 §afeat: 优化 require 性能; +       §cfix: 修复 require 加载特殊文件异常; + §623-07-22 §afeat: 网络加载 jtar 优化包大小; +       §afeat: 移除 Spring 相关支持; +       §aremove: 移除 Spring 相关支持; +       §adeps: 更新 Nashorn 和 GraalvmJS 引擎版本 + + + §622-11-22 §afeat: 兼容 1.7.10-1.19.2 版本; +       §afeat: 新增 MiaoScriptAPI 相关方法; §622-06-21 §afeat: 兼容 1.7.10-1.19 版本;       §afeat: 兼容 JDK17 BungeeCord; §622-05-25 §afeat: 兼容 1.7.10-1.18.2 版本; @@ -61,7 +48,7 @@       §afeat: 新增 自定义类型加载逻辑; §622-02-16 §afeat: 新增 MiaoScriptAPI;       §afeat: 新增 ScriptEvent; -       §afeat: 新增 .mjs.json 类型加载; +       §afeat: 新增 .mjs .json 类型加载; §622-02-16 §afeat: 优化 初始化逻辑 加快引擎加载速度;       §afeat: 新增 root 目录变更检测 变更后重新生成缓存;       §afeat: 添加常用库的软依赖; @@ -71,9 +58,7 @@ §621-06-25 §afeat: 调整启动逻辑 兼容 Arclight; §621-06-22 §afeat: 新增本地版本锁定功能; §621-06-19 §afeat: 兼容JDK16 反射异常; - §621-05-15 §afeat: 兼容JDK15+ 自动下载Nashorn类库 - - + §621-05-15 §afeat: 兼容JDK15+ 自动下载Nashorn类库; §621-03-25 §afeat: 异步加载 polyfill 并且同步加载 @ccms/core; §621-03-25 §cfix: 修改 ployfill 为 polyfill; §620-12-22 §cfix: 增加 require 效验; @@ -202,11 +187,6 @@ 1.18.24 compile - - org.kamranzafar - jtar - 2.3 - org.spigotmc spigot-api @@ -231,17 +211,5 @@ 1.0-SNAPSHOT compile - - org.springframework - spring-websocket - 5.3.19 - compile - - - org.apache.tomcat - tomcat-websocket - 9.0.35 - compile - \ No newline at end of file diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java index 7808d2a..1d5e897 100644 --- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java +++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java @@ -21,7 +21,7 @@ import java.io.File; * @author 喵♂呜 * Created on 2017/10/25 20:35. */ -@Plugin(id = "miaoscript", name = "MiaoScript", version = MiaoScriptAPI.VERSION, authors = "MiaoWoo") +@Plugin(id = "miaoscript", name = "MiaoScript", description = "MiaoScript runtime in Sponge", version = MiaoScriptAPI.VERSION, authors = "MiaoWoo") public class MiaoScriptSponge { private ScriptEngine engine; @Inject diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java deleted file mode 100644 index 64eb4ed..0000000 --- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSpring.java +++ /dev/null @@ -1,27 +0,0 @@ -package pw.yumc.MiaoScript; - -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.stereotype.Component; -import org.springframework.web.socket.server.standard.ServerEndpointExporter; -import pw.yumc.MiaoScript.api.MiaoScriptAPI; -import pw.yumc.MiaoScript.api.ScriptEngine; - -import java.io.File; - -@Slf4j -@Component -public class MiaoScriptSpring { - @Bean - @SneakyThrows - public ScriptEngine buildScriptEngine(ApplicationContext applicationContext) { - return MiaoScriptAPI.createEngine(new File("MiaoScript").getCanonicalPath(), log, applicationContext); - } - - @Bean - public ServerEndpointExporter serverEndpointExporter() { - return new ServerEndpointExporter(); - } -} diff --git a/src/main/java/pw/yumc/MiaoScript/api/Base.java b/src/main/java/pw/yumc/MiaoScript/api/Base.java index 23c5f29..ec9679c 100644 --- a/src/main/java/pw/yumc/MiaoScript/api/Base.java +++ b/src/main/java/pw/yumc/MiaoScript/api/Base.java @@ -1,5 +1,7 @@ package pw.yumc.MiaoScript.api; +import lombok.Getter; + import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -13,6 +15,7 @@ import java.nio.file.Paths; * @author 喵♂呜 * Created on 2017/10/9 12:40. */ +@Getter public class Base { private final Object instance; @@ -36,10 +39,6 @@ public class Base { } } - public Object getInstance() { - return this.instance; - } - public Class getProxyClass() { return ProxyClass.class; } diff --git a/src/main/java/pw/yumc/MiaoScript/api/JavaScriptTask.java b/src/main/java/pw/yumc/MiaoScript/api/JavaScriptTask.java index e128d7a..d947717 100644 --- a/src/main/java/pw/yumc/MiaoScript/api/JavaScriptTask.java +++ b/src/main/java/pw/yumc/MiaoScript/api/JavaScriptTask.java @@ -1,8 +1,11 @@ package pw.yumc.MiaoScript.api; +import lombok.Getter; + import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; +@Getter public class JavaScriptTask implements Delayed { private final long id; private final Object task; @@ -35,20 +38,4 @@ public class JavaScriptTask implements Delayed { return (int) (this.id - task.getId()); } } - - public long getId() { - return this.id; - } - - public Object getTask() { - return this.task; - } - - public long getStartTime() { - return this.startTime; - } - - public long getExecuteTime() { - return this.executeTime; - } } diff --git a/src/main/java/pw/yumc/MiaoScript/api/MiaoScriptAPI.java b/src/main/java/pw/yumc/MiaoScript/api/MiaoScriptAPI.java index bb729b6..a729296 100644 --- a/src/main/java/pw/yumc/MiaoScript/api/MiaoScriptAPI.java +++ b/src/main/java/pw/yumc/MiaoScript/api/MiaoScriptAPI.java @@ -1,5 +1,6 @@ package pw.yumc.MiaoScript.api; +import lombok.Getter; import pw.yumc.MiaoScript.api.loader.MavenDependLoader; import pw.yumc.MiaoScript.api.plugin.PluginManager; import pw.yumc.MiaoScript.engine.MiaoScriptEngine; @@ -8,10 +9,12 @@ import java.io.File; import java.nio.file.Paths; public class MiaoScriptAPI { - public static final String VERSION = "0.23.1"; + public static final String VERSION = "0.28.0"; + @Getter private static String root; private static String libPath; private static ScriptEngine scriptEngine; + @Getter private static PluginManager pluginManager; public static ScriptEngine createEngine(String root, Object logger, Object instance) { @@ -19,11 +22,7 @@ public class MiaoScriptAPI { return MiaoScriptAPI.scriptEngine; } - public static String getRoot() { - return root; - } - - public static void setRoot(String root) { + static void setRoot(String root) { MiaoScriptAPI.root = root; MiaoScriptAPI.libPath = Paths.get(root, "libs").toString(); } @@ -32,14 +31,10 @@ public class MiaoScriptAPI { return MiaoScriptAPI.scriptEngine.getEngine(); } - public static void setEngine(ScriptEngine scriptEngine) { + static void setEngine(ScriptEngine scriptEngine) { MiaoScriptAPI.scriptEngine = scriptEngine; } - public static PluginManager getPluginManager() { - return pluginManager; - } - public static void setPluginManager(Object pluginManager) { MiaoScriptAPI.pluginManager = getEngine().getInterface(pluginManager, PluginManager.class); } diff --git a/src/main/java/pw/yumc/MiaoScript/api/bukkit/EngineEvent.java b/src/main/java/pw/yumc/MiaoScript/api/bukkit/EngineEvent.java new file mode 100644 index 0000000..96126f8 --- /dev/null +++ b/src/main/java/pw/yumc/MiaoScript/api/bukkit/EngineEvent.java @@ -0,0 +1,39 @@ +package pw.yumc.MiaoScript.api.bukkit; + +import lombok.Getter; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import javax.script.Bindings; + +@Getter +public class EngineEvent extends Event implements Cancellable { + private final String event; + private final Bindings data; + + private boolean cancelled = false; + + public EngineEvent(String event, Bindings data) { + this.event = event; + this.data = data; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean b) { + this.cancelled = b; + } + + @Getter + private static final HandlerList handlerList = new HandlerList(); + + @Override + public HandlerList getHandlers() { + return handlerList; + } +} diff --git a/src/main/java/pw/yumc/MiaoScript/api/bukkit/ScriptEvent.java b/src/main/java/pw/yumc/MiaoScript/api/bukkit/ScriptEvent.java index 3503da0..9051681 100644 --- a/src/main/java/pw/yumc/MiaoScript/api/bukkit/ScriptEvent.java +++ b/src/main/java/pw/yumc/MiaoScript/api/bukkit/ScriptEvent.java @@ -1,15 +1,18 @@ package pw.yumc.MiaoScript.api.bukkit; +import lombok.Getter; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import javax.script.Bindings; +@Getter public class ScriptEvent extends Event implements Cancellable { private final Bindings plugin; private final String event; private final Bindings data; + private boolean cancelled = false; public ScriptEvent(Bindings plugin, String event, Bindings data) { @@ -18,33 +21,6 @@ public class ScriptEvent extends Event implements Cancellable { this.data = data; } - /** - * Which Plugin Call Event - * - * @return PluginName - */ - public Bindings getPlugin() { - return plugin; - } - - /** - * Plugin Event Name - * - * @return EventName - */ - public String getEvent() { - return event; - } - - /** - * Plugin Event Data - * - * @return EventData - */ - public Bindings getData() { - return data; - } - @Override public boolean isCancelled() { return this.cancelled; @@ -55,12 +31,9 @@ public class ScriptEvent extends Event implements Cancellable { this.cancelled = b; } + @Getter private static final HandlerList handlerList = new HandlerList(); - public static HandlerList getHandlerList() { - return handlerList; - } - @Override public HandlerList getHandlers() { return handlerList; diff --git a/src/main/java/pw/yumc/MiaoScript/api/loader/MavenDependLoader.java b/src/main/java/pw/yumc/MiaoScript/api/loader/MavenDependLoader.java index 5215564..78e3f18 100644 --- a/src/main/java/pw/yumc/MiaoScript/api/loader/MavenDependLoader.java +++ b/src/main/java/pw/yumc/MiaoScript/api/loader/MavenDependLoader.java @@ -4,6 +4,7 @@ import lombok.SneakyThrows; import java.io.File; import java.io.FileInputStream; +import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.nio.MappedByteBuffer; @@ -12,6 +13,8 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.security.MessageDigest; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; public class MavenDependLoader { public static final String MavenRepo = "https://maven.aliyun.com/repository/public"; @@ -48,6 +51,7 @@ public class MavenDependLoader { downloadFile(file, groupId, artifactId, version, ext); } if (!new String(Files.readAllBytes(sha1.toPath())).equals(getSha1(file))) { + sha1.delete(); file.delete(); throw new IllegalStateException("file " + file.getName() + " sha1 not match."); } @@ -71,17 +75,19 @@ public class MavenDependLoader { connection.setConnectTimeout(5000); connection.setReadTimeout(120000); connection.setUseCaches(true); - Files.copy(connection.getInputStream(), target.toPath(), StandardCopyOption.REPLACE_EXISTING); + try (InputStream inputStream = connection.getInputStream()) { + Files.copy(inputStream, target.toPath(), StandardCopyOption.REPLACE_EXISTING); + } } @SneakyThrows private static String getSha1(File file) { MessageDigest digest = MessageDigest.getInstance("SHA-1"); - FileInputStream in = new FileInputStream(file); - FileChannel ch = in.getChannel(); - MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); - digest.update(byteBuffer); - return getHash(digest.digest()); + try (FileInputStream in = new FileInputStream(file)) { + MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length()); + digest.update(byteBuffer); + return getHash(digest.digest()); + } } private static String getHash(byte[] bytes) { diff --git a/src/main/java/pw/yumc/MiaoScript/api/plugin/PluginManager.java b/src/main/java/pw/yumc/MiaoScript/api/plugin/PluginManager.java index a51682a..c079852 100644 --- a/src/main/java/pw/yumc/MiaoScript/api/plugin/PluginManager.java +++ b/src/main/java/pw/yumc/MiaoScript/api/plugin/PluginManager.java @@ -7,4 +7,16 @@ public interface PluginManager { Map getPlugins(); Bindings getPlugin(String name); + + boolean has(String name); + + Bindings get(String name); + + boolean enable(String name); + + boolean disable(String name); + + boolean install(String name); + + boolean uninstall(String name); } diff --git a/src/main/java/pw/yumc/MiaoScript/engine/MiaoScriptEngine.java b/src/main/java/pw/yumc/MiaoScript/engine/MiaoScriptEngine.java index ca13a5c..5965f11 100644 --- a/src/main/java/pw/yumc/MiaoScript/engine/MiaoScriptEngine.java +++ b/src/main/java/pw/yumc/MiaoScript/engine/MiaoScriptEngine.java @@ -1,5 +1,6 @@ package pw.yumc.MiaoScript.engine; +import lombok.Getter; import lombok.SneakyThrows; import lombok.val; import pw.yumc.MiaoScript.api.loader.JarLoader; @@ -19,33 +20,41 @@ import java.util.List; * @since 2016年8月29日 上午7:51:43 */ public class MiaoScriptEngine implements ScriptEngine, Invocable { + private final String libsRoot; + + @Getter private ScriptEngine engine; + @SneakyThrows public MiaoScriptEngine(String engineRoot) { + File libRootFile = new File(engineRoot, "libs"); + libRootFile.mkdirs(); + this.libsRoot = libRootFile.getCanonicalPath(); if (new File(engineRoot, "debug").exists()) { System.setProperty("nashorn.debug", "true"); } + MavenDependLoader.load(this.libsRoot, "org.kamranzafar", "jtar", "2.3"); if (getJavaVersion() > 15) { - this.loadGraalJS(engineRoot); + this.loadGraalJS(); } else { - this.loadNashorn(engineRoot); + this.loadNashorn(); } if (engine == null) throw new UnsupportedOperationException("当前环境不支持 Nashorn 或 GraalJS 脚本引擎."); } - private void loadGraalJS(String engineRoot) { + private void loadGraalJS() { try { - this.engine = this.parentLoadNetworkNashorn(engineRoot); + this.engine = this.parentLoadNetworkNashorn(); } catch (Throwable ex) { - this.engine = this.loadNetworkNashorn(engineRoot); + this.engine = this.loadNetworkNashorn(); } if (this.engine == null) { - this.engine = this.loadNetworkGraalJS(engineRoot); + this.engine = this.loadNetworkGraalJS(); } } - private void loadNashorn(String engineRoot) { + private void loadNashorn() { try { this.createEngineByName(); } catch (final Throwable ex) { @@ -61,7 +70,7 @@ public class MiaoScriptEngine implements ScriptEngine, Invocable { } try { if (this.engine == null) { - this.engine = this.loadNetworkNashorn(engineRoot); + this.engine = this.loadNetworkNashorn(); } } catch (final Throwable ex) { ex.printStackTrace(); @@ -95,43 +104,52 @@ public class MiaoScriptEngine implements ScriptEngine, Invocable { return null; } - @SneakyThrows - private ScriptEngine loadNetworkNashorn(String engineRoot) { - File libRootFile = new File(engineRoot, "libs"); - libRootFile.mkdirs(); - String libRoot = libRootFile.getCanonicalPath(); - MavenDependLoader.load(libRoot, "org.openjdk.nashorn", "nashorn-core", "15.4"); - MavenDependLoader.load(libRoot, "org.ow2.asm", "asm", "9.3"); - MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-commons", "9.3"); - MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-tree", "9.3"); - MavenDependLoader.load(libRoot, "org.ow2.asm", "asm-util", "9.3"); + private ScriptEngine loadNetworkNashorn() { + MavenDependLoader.load(this.libsRoot, "org.openjdk.nashorn", "nashorn-core", "15.4"); + MavenDependLoader.load(this.libsRoot, "org.ow2.asm", "asm", "9.5"); + MavenDependLoader.load(this.libsRoot, "org.ow2.asm", "asm-commons", "9.5"); + MavenDependLoader.load(this.libsRoot, "org.ow2.asm", "asm-tree", "9.5"); + MavenDependLoader.load(this.libsRoot, "org.ow2.asm", "asm-util", "9.5"); + return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false); + } + + private ScriptEngine parentLoadNetworkNashorn() { + MavenDependLoader.parentLoad(this.libsRoot, "org.openjdk.nashorn", "nashorn-core", "15.4"); + MavenDependLoader.parentLoad(this.libsRoot, "org.ow2.asm", "asm", "9.5"); + MavenDependLoader.parentLoad(this.libsRoot, "org.ow2.asm", "asm-commons", "9.5"); + MavenDependLoader.parentLoad(this.libsRoot, "org.ow2.asm", "asm-tree", "9.5"); + MavenDependLoader.parentLoad(this.libsRoot, "org.ow2.asm", "asm-util", "9.5"); return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false); } @SneakyThrows - private ScriptEngine parentLoadNetworkNashorn(String engineRoot) { - File libRootFile = new File(engineRoot, "libs"); - libRootFile.mkdirs(); - String libRoot = libRootFile.getCanonicalPath(); - MavenDependLoader.parentLoad(libRoot, "org.openjdk.nashorn", "nashorn-core", "15.4"); - MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm", "9.3"); - MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm-commons", "9.3"); - MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm-tree", "9.3"); - MavenDependLoader.parentLoad(libRoot, "org.ow2.asm", "asm-util", "9.3"); - return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false); - } - - @SneakyThrows - private ScriptEngine loadNetworkGraalJS(String engineRoot) { - File libRootFile = new File(engineRoot, "libs"); - libRootFile.mkdirs(); - String libRoot = libRootFile.getCanonicalPath(); - MavenDependLoader.load(libRoot, "org.graalvm.js", "js", "22.1.0.1"); - MavenDependLoader.load(libRoot, "org.graalvm.js", "js-scriptengine", "22.1.0.1"); - MavenDependLoader.load(libRoot, "org.graalvm.regex", "regex", "22.1.0.1"); - MavenDependLoader.load(libRoot, "org.graalvm.sdk", "graal-sdk", "22.1.0.1"); - MavenDependLoader.load(libRoot, "org.graalvm.truffle", "truffle-api", "22.1.0.1"); - return createEngineByFactoryClassName("org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory", false); + private ScriptEngine loadNetworkGraalJS() { + MavenDependLoader.load(this.libsRoot, "org.graalvm.js", "js", "23.0.1"); + MavenDependLoader.load(this.libsRoot, "org.graalvm.js", "js-scriptengine", "23.0.1"); + MavenDependLoader.load(this.libsRoot, "org.graalvm.regex", "regex", "23.0.1"); + MavenDependLoader.load(this.libsRoot, "org.graalvm.sdk", "graal-sdk", "23.0.1"); + MavenDependLoader.load(this.libsRoot, "org.graalvm.truffle", "truffle-api", "23.0.1"); + System.setProperty("polyglot.js.nashorn-compat", "true"); + System.setProperty("polyglot.js.scripting", "true"); + System.setProperty("polyglot.js.ecmascript-version", "5"); + System.setProperty("polyglot.js.allowAllAccess", "true"); + Class NashornScriptEngineFactory = Class.forName("com.oracle.truffle.js.scriptengine.GraalJSEngineFactory"); + Method getScriptEngine = NashornScriptEngineFactory.getMethod("getScriptEngine"); + Object factory = NashornScriptEngineFactory.newInstance(); + return (ScriptEngine) getScriptEngine.invoke(factory); +// Class GraalJSScriptEngine = Class.forName("com.oracle.truffle.js.scriptengine.GraalJSScriptEngine"); +// Method createScriptEngine = GraalJSScriptEngine.getMethod("create", Class.forName("org.graalvm.polyglot.Engine"), Class.forName("org.graalvm.polyglot.Context")); +// Class Context = Class.forName("org.graalvm.polyglot.Context"); +// Method newBuilder = Context.getMethod("newBuilder", String[].class); +// Class Builder = Class.forName("org.graalvm.polyglot.Context.Builder"); +// Method allowExperimentalOptions = Builder.getMethod("allowExperimentalOptions", boolean.class); +// Method allowAllAccess = Builder.getMethod("allowAllAccess", boolean.class); +// Method option = Builder.getMethod("option", String.class, String.class); +// Object context = newBuilder.invoke(null, (Object) new String[]{"js"}); +// allowExperimentalOptions.invoke(context, true); +// allowAllAccess.invoke(context, true); +// option.invoke(context, "js.nashorn-compat", "true"); +// return (ScriptEngine) createScriptEngine.invoke(null, null, context); } @SneakyThrows @@ -153,10 +171,6 @@ public class MiaoScriptEngine implements ScriptEngine, Invocable { return (ScriptEngine) getScriptEngine.invoke(factory, (Object) engineArgs.toArray(new String[]{})); } - public ScriptEngine getEngine() { - return this.engine; - } - @Override public Bindings createBindings() { return engine.createBindings(); diff --git a/src/main/java/pw/yumc/MiaoScript/web/WebFilterProxy.java b/src/main/java/pw/yumc/MiaoScript/web/WebFilterProxy.java deleted file mode 100644 index 05b57aa..0000000 --- a/src/main/java/pw/yumc/MiaoScript/web/WebFilterProxy.java +++ /dev/null @@ -1,6 +0,0 @@ -package pw.yumc.MiaoScript.web; - -import javax.servlet.Filter; - -public interface WebFilterProxy extends Filter { -} diff --git a/src/main/java/pw/yumc/MiaoScript/web/WebServerProxy.java b/src/main/java/pw/yumc/MiaoScript/web/WebServerProxy.java deleted file mode 100644 index 9f8fa71..0000000 --- a/src/main/java/pw/yumc/MiaoScript/web/WebServerProxy.java +++ /dev/null @@ -1,8 +0,0 @@ -package pw.yumc.MiaoScript.web; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public interface WebServerProxy { - Object process(HttpServletRequest req, HttpServletResponse resp); -} diff --git a/src/main/java/pw/yumc/MiaoScript/websocket/WebSocketProxy.java b/src/main/java/pw/yumc/MiaoScript/websocket/WebSocketProxy.java deleted file mode 100644 index 677de7f..0000000 --- a/src/main/java/pw/yumc/MiaoScript/websocket/WebSocketProxy.java +++ /dev/null @@ -1,15 +0,0 @@ -package pw.yumc.MiaoScript.websocket; - -import javax.websocket.CloseReason; -import javax.websocket.EndpointConfig; -import javax.websocket.Session; - -public interface WebSocketProxy { - void onOpen(Session session, EndpointConfig config); - - void onMessage(Session session, String message); - - void onClose(Session session, CloseReason reason); - - void onError(Session session, Throwable error); -} diff --git a/src/main/java/pw/yumc/MiaoScript/websocket/WebSocketServer.java b/src/main/java/pw/yumc/MiaoScript/websocket/WebSocketServer.java deleted file mode 100644 index 0b42207..0000000 --- a/src/main/java/pw/yumc/MiaoScript/websocket/WebSocketServer.java +++ /dev/null @@ -1,70 +0,0 @@ -package pw.yumc.MiaoScript.websocket; - -import lombok.SneakyThrows; - -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.stereotype.Component; - -import javax.websocket.*; -import javax.websocket.server.ServerEndpoint; - -@Component -@ServerEndpoint("/ws/") -public class WebSocketServer implements ApplicationContextAware { - private static ApplicationContext context; - private WebSocketProxy proxy; - - private boolean checkProxy(Session session) { - try { - if (this.proxy == null) { - this.proxy = context.getBean(WebSocketProxy.class); - } - return true; - } catch (Exception ex) { - try { - session.close(); - } catch (Exception ignore) { - } - return false; - } - } - - @OnOpen - @SneakyThrows - public void onOpen(Session session, EndpointConfig config) { - if (this.checkProxy(session)) { - this.proxy.onOpen(session, config); - } - } - - @OnMessage - @SneakyThrows - public void onMessage(Session session, String message) { - if (this.checkProxy(session)) { - this.proxy.onMessage(session, message); - } - } - - @OnClose - @SneakyThrows - public void onClose(Session session, CloseReason reason) { - if (this.checkProxy(session)) { - this.proxy.onClose(session, reason); - } - } - - @OnError - @SneakyThrows - public void onError(Session session, Throwable error) { - if (this.checkProxy(session)) { - this.proxy.onError(session, error); - } - } - - @Override - public void setApplicationContext(ApplicationContext ctx) throws BeansException { - context = ctx; - } -} diff --git a/src/main/resources/core/require.js b/src/main/resources/core/require.js index 08004c6..e5d4460 100644 --- a/src/main/resources/core/require.js +++ b/src/main/resources/core/require.js @@ -55,6 +55,7 @@ var MS_NODE_PATH = System.getenv("MS_NODE_PATH") || root + separatorChar + 'node_modules' var MS_NODE_REGISTRY = System.getenv("MS_NODE_REGISTRY") || 'https://registry.npmmirror.com' var MS_FALLBACK_NODE_REGISTRY = System.getenv("MS_FALLBACK_NODE_REGISTRY") || 'https://repo.yumc.pw/repository/npm' + var MS_SCRIPT_PACKAGE_CENTER = System.getenv("MS_SCRIPT_PACKAGE_CENTER") || 'https://mscript.yumc.pw/api/plugin/download' var MS_NETWORK_CONNECT_TIMEOUT = System.getenv("MS_NETWORK_CONNECT_TIMEOUT") || 5000 var MS_NETWORK_READ_TIMEOUT = System.getenv("MS_NETWORK_TIMEOUT") || 45000 var MS_NETWORK_DOWNLOAD_TIMEOUT = System.getenv("MS_NETWORK_DOWNLOAD_TIMEOUT") || 60000 @@ -114,9 +115,11 @@ return file.absolutePath } - function __error(message) { + function __error(message, name) { + var error = new Error(message) + if (name) { error.name = name } console.error(message) - return new Error(message) + return error } /** @@ -153,7 +156,8 @@ function resolveAsFile(file, dir) { file = dir !== undefined ? new File(dir, file) : new File(file) // 直接文件 - if (file.isFile()) { + // 只解析带后缀的文件 其他文件视为非法文件 + if (file.isFile() && file.name.lastIndexOf('.') != -1) { return file } // JS文件 @@ -364,6 +368,8 @@ /** * 尝试从网络下载依赖包 * @param {string} name 包名称 + * @param {string} optional 附加选项 + * @param {number} retry 重试次数 */ function download(name, optional, retry) { var name_arr = splitVersionFromName(name) @@ -376,15 +382,19 @@ var info = fetchPackageInfo(module_name) if (!module_version) { // if not special version get from lock or tag - module_version = ModulesVersionLock[module_name] || info['dist-tags']['latest'] + module_version = ModulesVersionLock[module_name] } else if (!/\d+\.\d+\.\w+/.test(module_version)) { - // maybe module_version = latest + // maybe module_version = latest if special version not exist then fallback latest + console.log('try get node_module ' + module_name + ' version from ' + module_version + ' tag waiting...') module_version = info['dist-tags'][module_version] } - var _version = info.versions[module_version] - if (!_version) { - throw __error('fetch node_module ' + module_name + ' version ' + module_version + ' failed. can\t found tarball from versions.') + if (!module_version) { + console.log('try get node_module ' + module_name + ' version from latest tag waiting...') + module_version = info['dist-tags']['latest'] } + if (!module_version) { throw __error('fetch node_module ' + module_name + " failed. can't found version from " + name + ".", 'ModuleNotFoundError') } + var _version = info.versions[module_version] + if (!_version) { throw __error('fetch node_module ' + module_name + ' version ' + module_version + " failed. can't found tarball from versions.", 'ModuleNotFoundError') } var url = _version.dist.tarball console.log('fetch node_module ' + module_name + ' version ' + module_version + ' waiting...') return executor.submit(new Callable(function () { @@ -400,18 +410,17 @@ Files.copy(tis, targetPath, StandardCopyOption.REPLACE_EXISTING) } return name - })).get(MS_NETWORK_DOWNLOAD_TIMEOUT, TimeUnit.SECONDS) + })).get(MS_NETWORK_DOWNLOAD_TIMEOUT, TimeUnit.MILLISECONDS) } catch (error) { - retry = retry || 1 - if (retry > 3) { - throw __error('fetch node_module ' + module_name + ' version ' + module_version + ' failed. greater than 3 times stop retry.') - } + if (error.name == 'ModuleNotFoundError') { throw error } + if (retry > 3) { throw __error('fetch node_module ' + module_name + ' version ' + module_version + ' failed. greater than 3 times stop retry.') } console.log('fetch node_module ' + module_name + ' version ' + module_version + ' failed retrying...') return download(name, optional, ++retry) } } /** + * 获取包信息 * @param {string} module_name */ function fetchPackageInfo(module_name) { @@ -419,7 +428,7 @@ try { content = fetchContent(MS_NODE_REGISTRY + '/' + module_name) } catch (ex) { - console.warn('can\'t fetch package ' + module_name + ' from ' + MS_NODE_REGISTRY + ' registry. try fetch from ' + MS_FALLBACK_NODE_REGISTRY + ' registry...') + console.warn("can't fetch package " + module_name + ' from ' + MS_NODE_REGISTRY + ' registry. try fetch from ' + MS_FALLBACK_NODE_REGISTRY + ' registry...') content = fetchContent(MS_FALLBACK_NODE_REGISTRY + '/' + module_name) } return JSON.parse(content) @@ -428,6 +437,7 @@ /** * 获取网络内容 * @param {string} url 网址 + * @param {number} [timeout] 超时时间 */ function fetchContent(url, timeout) { return executor.submit(new Callable(function fetchContent() { @@ -444,7 +454,7 @@ input.close() output.close() } - })).get(timeout || MS_NETWORK_READ_TIMEOUT, TimeUnit.SECONDS) + })).get(timeout || MS_NETWORK_READ_TIMEOUT, TimeUnit.MILLISECONDS) } var lastModule = '' @@ -466,7 +476,7 @@ if (resolve(newName, path, optional) !== undefined) { return newName } - throw __error("Can't load nodejs core module " + name + " . maybe later will auto replace to " + global.scope + "/nodejs/" + name + ' to compatible...') + throw __error("can't load nodejs core module " + name + " . maybe later will auto replace to " + global.scope + "/nodejs/" + name + ' to compatible...') } return name } @@ -488,7 +498,7 @@ function _require(name, path, optional) { // require direct file var file = _isFile(name) ? name : new File(name) - if (_isFile(file)) { + if (_isFile(file) && file.name.lastIndexOf('.') != -1) { return _requireFile(file, optional) } // require cache module @@ -499,14 +509,16 @@ } // check core module name = checkCoreModule(name, path, optional) + var file = resolve(name, path, optional) // search module - if ((file = resolve(name, path, optional)) === undefined) { + if (file === undefined) { // excloud local dir, prevent too many recursive call and cache not found module if (optional.local || optional.recursive || notFoundModules[name]) { - throw __error("Can't found module " + name + '(' + JSON.stringify(optional) + ') at local ' + path + ' or network!') + delete optional.parent + throw __error("can't found module " + name + '(' + JSON.stringify(optional) + ') at local ' + path + ' or network!') } optional.recursive = true - return _require(download(name, optional), path, optional) + return _require(download(name, optional, 1), path, optional) } setCacheModule(file, optional) return _requireFile(file, optional) @@ -545,7 +557,7 @@ */ return function __DynamicRequire__(path, optional) { if (!path) { - throw __error('require path can\'t be undefined or empty!') + throw __error("require path can't be undefined or empty!") } var optional = __assign({ cache: true, @@ -574,7 +586,7 @@ function __DynamicClear__(name) { for (var cacheModule in cacheModules) { if (cacheModule.indexOf(name) !== -1) { - console.trace('Clear module ' + cacheModule + ' ...') + console.trace('clear module ' + cacheModule + ' ...') delete cacheModules[cacheModule] } } @@ -585,12 +597,12 @@ for (var cacheModule in cacheModules) { delete cacheModules[cacheModule] } - cacheModules = undefined + cacheModules = {} for (var cacheModuleId in cacheModuleIds) { delete cacheModuleIds[cacheModuleId] } - cacheModuleIds = undefined - notFoundModules = undefined + cacheModuleIds = {} + notFoundModules = {} } function __setUpgradeMode__(status) { @@ -605,6 +617,7 @@ * @type {any} require */ var require = exports(parent) + require.cache = cacheModules require.resolve = __DynamicResolve__ require.clear = __DynamicClear__ require.disable = __DynamicDisable__ @@ -621,6 +634,7 @@ notFoundModules: notFoundModules, requireLoaders: requireLoaders } + require.loadCoreScript = loadCoreScript return require } @@ -629,8 +643,12 @@ * @param {any} loader */ function registerLoader(ext, loader) { + if (requireLoaders[ext]) { + return console.error('require loader ' + ext + ' already register ignore. if you want override loader please unregister before register.') + } + requireExts.push(ext) requireLoaders[ext] = loader - console.info('Register Require Loader ' + ext + ' => ' + (loader.name || '') + '.') + console.info('register require loader ' + ext + ' => ' + (loader.name || '') + '.') } /** * @param {*} ext @@ -642,15 +660,17 @@ * @param {*} ext */ function unregisterLoader(ext) { + requireExts.splice(requireExts.indexOf(ext), 1); delete requireLoaders[ext] - console.info('unregister Require Loader ' + ext + '.') + console.info('unregister require loader ' + ext + '.') } function printRequireInfo() { console.info('Initialization require module.') console.info('ParentDir:', root) console.info('Require module env list:') - console.info('- JAVA_VERSION: ', System.getProperty("java.version")) + console.info('- JAVA_VERSION:', System.getProperty("java.version")) + console.info('- PLUGIN_VERSION:', base.version) console.info('- MS_NODE_PATH:', MS_NODE_PATH.startsWith(root) ? MS_NODE_PATH.split(root)[1] : MS_NODE_PATH) console.info('- MS_NODE_REGISTRY:', MS_NODE_REGISTRY) console.info('- MS_FALLBACK_NODE_REGISTRY:', MS_FALLBACK_NODE_REGISTRY) @@ -672,7 +692,7 @@ function initVersionLock() { try { - var version_lock_url = 'https://ms.yumc.pw/api/plugin/download/name/version_lock' + (global.debug ? '-debug' : '') + var version_lock_url = MS_SCRIPT_PACKAGE_CENTER + '?name=version_lock' + (global.debug ? '-debug' : '') ModulesVersionLock = JSON.parse(fetchContent(version_lock_url, 5000)) try { ModulesVersionLock = __assign(ModulesVersionLock, JSON.parse(base.read(localVersionLockFile))) @@ -698,10 +718,7 @@ registerLoader('js', compileJsFile) registerLoader('json', compileJson) try { - engineLoad({ - script: fetchContent('https://ms.yumc.pw/api/plugin/download/name/require_loader', 5000), - name: 'core/require_loader.js' - })(require) + loadCoreScript('require_loader')(require) } catch (error) { console.warn("无法获取到最新的加载器信息 使用默认配置.") console.warn("InitRequireLoader Error:", error) @@ -711,25 +728,41 @@ return require } + function loadCoreScript(name) { + return engineLoad({ + script: fetchContent(MS_SCRIPT_PACKAGE_CENTER + '?name=' + name, 5000), + name: 'core/' + name + '.js' + }) + } + if (typeof parent === 'string') { parent = new File(parent) } /** + * require 支持的后缀 + * @type {string[]} requireExts + */ + var requireExts = [] + /** + * require加载器 * @type {{[key:string]:(module:any, file:string, optional?:any)=>any}} requireLoader */ var requireLoaders = {} /** - * @type {{[key:string]:any}} cacheModules + * 已缓存的模块 + * @type {{[key:string]:any}} [cacheModules] */ var cacheModules = {} var cacheModuleIdsFile = _canonical(new File(MS_NODE_PATH, 'cacheModuleIds.json')) var localVersionLockFile = _canonical(new File(MS_NODE_PATH, 'moduleVersionLock.json')) /** - * @type {{[key:string]:{[key:string]:string}|string}} cacheModuleIds + * 已缓存的模块ID + * @type {{[key:string]:{[key:string]:string}|string}} [cacheModuleIds] */ var cacheModuleIds = {} /** - * @type {{[key:string]:boolean}} notFoundModules + * 未找到的模块 + * @type {{[key:string]:boolean}} */ var notFoundModules = {} var upgradeMode = false