diff --git a/pom.xml b/pom.xml index 1ee00f8..aff84f1 100644 --- a/pom.xml +++ b/pom.xml @@ -1,9 +1,8 @@ - + 4.0.0 pw.yumc MiaoScript - 0.10.1 + 0.11.0 502647092 @@ -54,20 +53,25 @@ DEV - §620-12-17 §afeat: JavaScriptTask 新增任务ID 并通过ID比较优先级; - §620-12-16 §afeat: 优化 require 路径寻找速度; + §621-03-25 §afeat: 异步加载 polyfill 并且同步加载 @ccms/core; + §621-03-25 §cfix: 修改 ployfill 为 polyfill; + §620-12-22 §cfix: 增加 require 效验; + §620-12-17 §afeat: JavaScriptTask 新增任务ID 并通过 ID 比较优先级; + §620-12-16 §afeat: 新增 require 缓存 优化路径寻找速度; §620-12-15 §cfix: 修复 非主线程重载时发生的异常; - §620-12-07 §cfix: 修复 Windows 环境 重载异常; + §620-12-07 §cfix: 修复 Windows 环境 重载异常 + + §620-11-19 §afeat: 新增 JavaScriptTask 类; §620-11-11 §afeat: 新增 package 版本锁定逻辑; §620-09-21 §afeat: 完善 upgrade 逻辑; - §620-08-27 §afeat: 新增ProtocolLib依赖; + §620-08-27 §afeat: 新增 ProtocolLib 依赖; §620-07-28 §afeat: 新增框架升级功能; §620-06-23 §afeat: 支持自定义参数; §620-06-22 §afeat: 优化 require 加载逻辑; §620-05-28 §afeat: 新增 Spring 的支持; §620-05-02 §afeat: 调整 scope 为 @ccms; - §620-04-10 §afeat: 默认从 classpath 加载内建的js模块; + §620-04-10 §afeat: 默认从 classpath 加载内建的 js 模块; §620-04-07 §afeat: 默认初始化 内建 nodejs 模块; §620-04-03 §afeat: 优化 框架卸载逻辑; §620-03-31 §afeat: require 新增 内建 nodejs 模块; @@ -77,9 +81,7 @@ §620-02-16 §afeat: 新增 Source Map 支持; §620-02-02 §afeat: 迁移 ployfill 到 @ms/ployfill; §620-01-14 §afeat: 新增 Bungee 支持; -       §afeat: 新增 instance 实例获取 - - +        §afeat: 新增 instance 实例获取; §619-09-24 §cremove: 移除 okhttp3 类库;       §afeat: 新增require自动下载模块功能; §619-09-21 §afeat: 新增 okhttp3 类库; diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScript.java b/src/main/java/pw/yumc/MiaoScript/MiaoScript.java index 5582ea0..8deac2f 100644 --- a/src/main/java/pw/yumc/MiaoScript/MiaoScript.java +++ b/src/main/java/pw/yumc/MiaoScript/MiaoScript.java @@ -15,9 +15,14 @@ public class MiaoScript extends JavaPlugin { @Override @SneakyThrows - public void onEnable() { + public void onLoad() { Thread.currentThread().setContextClassLoader(getClassLoader()); engine = new ScriptEngine(getDataFolder().getCanonicalPath(), getLogger(), this); + engine.loadEngine(); + } + + @Override + public void onEnable() { engine.enableEngine(); } diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java index d991e53..d565a64 100644 --- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java +++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptBungee.java @@ -14,9 +14,14 @@ public class MiaoScriptBungee extends Plugin { @Override @SneakyThrows - public void onEnable() { + public void onLoad() { Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); engine = new ScriptEngine(getDataFolder().getCanonicalPath(), getLogger(), this); + engine.loadEngine(); + } + + @Override + public void onEnable() { engine.enableEngine(); } diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java index 5be8e1d..2b52666 100644 --- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java +++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptNukkit.java @@ -11,12 +11,17 @@ public class MiaoScriptNukkit extends PluginBase { @Override @SneakyThrows - public void onEnable() { + public void onLoad() { Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); engine = new ScriptEngine(getDataFolder().getCanonicalPath(), getLogger(), this); engine.enableEngine(); } + @Override + public void onEnable() { + engine.enableEngine(); + } + @Override public void onDisable() { engine.disableEngine(); diff --git a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java index 392719a..51710a0 100644 --- a/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java +++ b/src/main/java/pw/yumc/MiaoScript/MiaoScriptSponge.java @@ -7,6 +7,7 @@ import org.spongepowered.api.config.ConfigDir; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.game.GameReloadEvent; import org.spongepowered.api.event.game.state.GameStartedServerEvent; +import org.spongepowered.api.event.game.state.GameStartingServerEvent; import org.spongepowered.api.event.game.state.GameStoppingServerEvent; import org.spongepowered.api.plugin.Plugin; @@ -31,8 +32,14 @@ public class MiaoScriptSponge { @Listener @SneakyThrows - public void onStart(GameStartedServerEvent event) { + public void onStarting(GameStartingServerEvent event) { engine = new ScriptEngine(pluginConfigDir.getCanonicalPath(), logger, this); + engine.loadEngine(); + } + + @Listener + @SneakyThrows + public void onStart(GameStartedServerEvent event) { engine.enableEngine(); } diff --git a/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java b/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java index 62bc5d7..90d2e6d 100644 --- a/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java +++ b/src/main/java/pw/yumc/MiaoScript/ScriptEngine.java @@ -6,6 +6,10 @@ import javax.script.ScriptEngineManager; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; /** * Created with IntelliJ IDEA @@ -18,6 +22,7 @@ public class ScriptEngine { private final String root; private final Base base; private MiaoScriptEngine engine; + private Object future; public ScriptEngine(String root, Object logger, Object instance) { this.loader = Thread.currentThread().getContextClassLoader(); @@ -38,7 +43,7 @@ public class ScriptEngine { } @SneakyThrows - public void enableEngine() { + public void loadEngine() { ClassLoader originLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(this.loader); createEngine(); @@ -49,10 +54,15 @@ public class ScriptEngine { } else { this.engine.eval("load('classpath:bios.js')"); } - engine.invokeFunction("boot", root, logger); + future = engine.invokeFunction("boot", root, logger); Thread.currentThread().setContextClassLoader(originLoader); } + @SneakyThrows + public void enableEngine() { + engine.invokeFunction("start", future); + } + @SneakyThrows public void disableEngine() { synchronized (logger) { diff --git a/src/main/resources/bios.js b/src/main/resources/bios.js index c63db67..62b39e8 100644 --- a/src/main/resources/bios.js +++ b/src/main/resources/bios.js @@ -1,41 +1,40 @@ -'use strict'; +'use strict' var global = this; /** * Init MiaoScriptEngine Runtime */ (function () { - var loader; global.engineDisable = function () { global.engineDisableImpl && global.engineDisableImpl() if (java.nio.file.Files.exists(java.nio.file.Paths.get(root, "old_node_modules"))) { - logger.info('Found old_node_modules folder delete...'); + logger.info('Found old_node_modules folder delete...') base.delete(java.nio.file.Paths.get(root, "old_node_modules")) } if (java.nio.file.Files.exists(java.nio.file.Paths.get(root, "upgrade"))) { - logger.info('Found upgrade file delete node_modules...'); + logger.info('Found upgrade file delete node_modules...') base.delete(java.nio.file.Paths.get(root, "node_modules")) base.delete(java.nio.file.Paths.get(root, "upgrade")) } - }; + } global.boot = function (root, logger) { - global.scope = java.lang.System.getenv("MS_NODE_CORE_SCOPE") || "@ccms"; - global.log = logger; + global.scope = java.lang.System.getenv("MS_NODE_CORE_SCOPE") || "@ccms" + global.log = logger // Development Env Detect - global.root = root || "src/main/resources"; + global.root = root || "src/main/resources" if (__FILE__.indexOf('!') === -1) { - logger.info('Loading custom BIOS file ' + __FILE__); - global.debug = true; + logger.info('Loading custom BIOS file ' + __FILE__) + global.debug = true } if (java.nio.file.Files.exists(java.nio.file.Paths.get(root, "debug"))) { - logger.info('Running in debug mode...'); - global.debug = true; + logger.info('Running in debug mode...') + global.debug = true } if (java.nio.file.Files.exists(java.nio.file.Paths.get(root, "level"))) { global.level = base.read(java.nio.file.Paths.get(root, "level")) - logger.info('Set system level to [' + global.level + ']...'); + logger.info('Set system level to [' + global.level + ']...') } if (java.nio.file.Files.exists(java.nio.file.Paths.get(root, "upgrade"))) { - logger.info('Found upgrade file starting upgrade...'); + logger.info('Found upgrade file starting upgrade...') base.move(java.nio.file.Paths.get(root, "node_modules"), java.nio.file.Paths.get(root, "old_node_modules")) base.delete(java.nio.file.Paths.get(root, "upgrade")) } @@ -46,27 +45,37 @@ var global = this; } }, "MiaoScript node_modules clean thread").start() // Check Class Loader, Sometimes Server will can't found plugin.yml file - loader = checkClassLoader(); + var loader = checkClassLoader() + var future = new java.util.concurrent.FutureTask(function () { + java.lang.Thread.currentThread().contextClassLoader = loader + load(java.lang.System.getenv("MS_NODE_CORE_POLYFILL") || 'classpath:core/polyfill.js')(root, logger) + }) // Async Loading MiaoScript Engine - new java.lang.Thread(function () { - java.lang.Thread.currentThread().contextClassLoader = loader; - load(java.lang.System.getenv("MS_NODE_CORE_PLOYFILL") || 'classpath:core/ployfill.js')(root, logger); - global.engineDisableImpl = require(java.lang.System.getenv("MS_NODE_CORE_MODULE") || global.scope + '/core').default || function () { - logger.info('Error: abnormal Initialization MiaoScript Engine. Skip disable step...') - }; - }, "MiaoScript thread").start() - }; + new java.lang.Thread(future, "MiaoScript thread").start() + return future + } + + global.start = function (future) { + if (!future.isDone()) { + logger.info("Waiting MiaoScript booted...") + future.get() + } + logger.info("MiaoScript booted starting...") + global.engineDisableImpl = require(java.lang.System.getenv("MS_NODE_CORE_MODULE") || (global.scope + '/core')).default || function () { + logger.info('Error: abnormal Initialization MiaoScript Engine. Skip disable step...') + } + } function checkClassLoader() { - var classLoader = java.lang.Thread.currentThread().contextClassLoader; + var classLoader = java.lang.Thread.currentThread().contextClassLoader if (classLoader.getResource("bios.js") === null) { - throw Error("Error class loader: " + classLoader.class.name + " Please contact the author MiaoWoo!"); + throw Error("Error class loader: " + classLoader.class.name + " Please contact the author MiaoWoo!") } else { - log.info("Class loader compatible: " + classLoader.class.name); + log.info("Class loader compatible: " + classLoader.class.name) if (classLoader.parent) { - log.info("Parent class loader: " + classLoader.parent.class.name); + log.info("Parent class loader: " + classLoader.parent.class.name) } } - return classLoader; + return classLoader } -})(); +})() diff --git a/src/main/resources/core/ployfill.js b/src/main/resources/core/polyfill.js similarity index 96% rename from src/main/resources/core/ployfill.js rename to src/main/resources/core/polyfill.js index 19a25b4..d3426c3 100644 --- a/src/main/resources/core/ployfill.js +++ b/src/main/resources/core/polyfill.js @@ -23,6 +23,6 @@ global.console = engineLoad(java.lang.System.getenv("MS_NODE_CORE_CONSOLE") || 'classpath:core/console.js')(logger); console.log("Loading Engine at Thread", java.lang.Thread.currentThread().name) global.require = engineLoad(java.lang.System.getenv("MS_NODE_CORE_REQUIRE") || 'classpath:core/require.js')(root); - require(global.scope + '/ployfill') + require(global.scope + '/polyfill') } ) diff --git a/src/main/resources/core/require.js b/src/main/resources/core/require.js index f6c1d76..8a6b0a1 100644 --- a/src/main/resources/core/require.js +++ b/src/main/resources/core/require.js @@ -384,7 +384,6 @@ if ((file = resolve(name, path, optional)) === undefined) { // excloud local dir, prevent too many recursive call and cache not found module if (optional.local || optional.recursive || notFoundModules[name]) { - console.log(name, path, optional, notFoundModules[name]) throw new Error("Can't found module " + name + '(' + JSON.stringify(optional) + ') at local ' + path + ' or network!') } try { @@ -430,16 +429,17 @@ * @param {any} optional */ return function __DynamicRequire__(path, optional) { + if (!path) { throw new Error('require path can\'t be undefined or empty!') } return _require(path, parent, __assign({ cache: true, parentId: parentId, parent: parent, path: path, local: path.startsWith('.') || path.startsWith('/') }, optional)).exports } } /** - * @param {string} name + * @param {string} path * @param {any} optional 附加选项 */ - function __DynamicResolve__(name, optional) { - return _canonical(new File(resolve(name, parent, __assign({ cache: true, parent: parent, local: name.startsWith('.') || name.startsWith('/') }, optional)))) + function __DynamicResolve__(path, optional) { + return _canonical(new File(resolve(path, parent, __assign({ cache: true, parent: parent, local: path.startsWith('.') || path.startsWith('/') }, optional)))) } /**