From afdc39b1de0a724430133130c4e8da814a6183d7 Mon Sep 17 00:00:00 2001 From: 502647092 Date: Wed, 11 Oct 2017 14:20:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E9=83=A8=E5=88=86=20=E6=B7=BB=E5=8A=A0=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=B3=A8=E9=94=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 502647092 --- src/main/resources/kit/reflect.js | 23 +++++++------ src/main/resources/modules/command.js | 22 ++++++------ src/main/resources/modules/event.js | 27 +++++++++++++-- src/main/resources/modules/plugin.js | 49 +++++++++++---------------- src/main/resources/plugins/hello.js | 11 +++--- 5 files changed, 73 insertions(+), 59 deletions(-) diff --git a/src/main/resources/kit/reflect.js b/src/main/resources/kit/reflect.js index e3d10ad..e693fd3 100644 --- a/src/main/resources/kit/reflect.js +++ b/src/main/resources/kit/reflect.js @@ -10,8 +10,13 @@ var NoSuchFieldException = Java.type('java.lang.NoSuchFieldException'); var methodCache = []; function Reflect(obj) { - this.obj = obj; - this.class = obj instanceof Class ? obj : obj.class; + if (obj instanceof Class) { + this.obj = null; + this.class = obj; + } else { + this.obj = obj; + this.class = obj.class; + } this.field = function (name) { try { // Try getting a public field @@ -27,9 +32,8 @@ function Reflect(obj) { } }; - this.method = function () { - var name = arguments[0]; - var clazzs = Array.prototype.slice.call(arguments, 1); + this.method = function (name, param) { + var clazzs = types(param); try { return this.class.getMethod(name, clazzs); } catch (ex) { @@ -37,11 +41,10 @@ function Reflect(obj) { } }; - this.cacheMethod = function () { - var name = arguments[0]; + this.cacheMethod = function (name, param) { var mkey = this.class.name + '.' + name; if (!methodCache[mkey]) { - methodCache[mkey] = this.method(name, arguments.slice(1)); + methodCache[mkey] = this.method(name, param); } return methodCache[mkey]; }; @@ -91,10 +94,10 @@ function declaredConstructor(clazz, param) { var constructor; try { constructor = clazz.getDeclaredConstructor(types(param)); - }catch(ex) { + } catch (ex) { try { constructor = clazz.getDeclaredConstructor(types(param, true)); - }catch(ex) { + } catch (ex) { constructor = clazz.getDeclaredConstructors()[0]; } } diff --git a/src/main/resources/modules/command.js b/src/main/resources/modules/command.js index 56d23b6..435ed6a 100644 --- a/src/main/resources/modules/command.js +++ b/src/main/resources/modules/command.js @@ -41,21 +41,21 @@ function register(jsp, name, cmd) { // // } // }; -/ + exports.on = function (jsp, name, exec) { var c = create(jsp, name); if (exec.cmd) { - c.setExecutor( - function (sender, cmd, command, args) { - return exec.cmd(sender, command, args); - } - ); + c.setExecutor(function (sender, cmd, command, args) { + return exec.cmd(sender, command, args); + }); } if (exec.tab) { - c.setTabCompleter( - function (sender, cmd, command, args) { - return Arrays.asList(exec.tab(sender, command, args)); - } - ); + c.setTabCompleter(function (sender, cmd, command, args) { + return Arrays.asList(exec.tab(sender, command, args)); + }); } +}; + +exports.off = function () { + }; \ No newline at end of file diff --git a/src/main/resources/modules/event.js b/src/main/resources/modules/event.js index 3fd8fc8..607d014 100644 --- a/src/main/resources/modules/event.js +++ b/src/main/resources/modules/event.js @@ -8,12 +8,17 @@ var Bukkit = Java.type("org.bukkit.Bukkit"); var Listener = Java.type("org.bukkit.event.Listener"); var Modifier = Java.type("java.lang.reflect.Modifier"); var BukkitEvent = Java.type("org.bukkit.event.Event"); +var HandlerList = Java.type('org.bukkit.event.HandlerList'); var EventPriority = Java.type("org.bukkit.event.EventPriority"); var EventExecutor = Java.type("org.bukkit.plugin.EventExecutor"); var IllegalStateException = Java.type("java.lang.IllegalStateException"); var plugin = base.plugin; +var ref = require('kit/reflect'); + +var jspListener = []; + /** * 扫描包 org.bukkit.event 下的所有事件 * 映射简写名称 org.bukkit.event.player.PlayerLoginEvent => playerloginevent @@ -69,12 +74,17 @@ function isVaildEvent(clz) { /** * 添加事件监听 + * @param jsp * @param event * @param exec {function} * @param priority * @param ignoreCancel */ -function listen(event, exec, priority, ignoreCancel) { +function listen(jsp, event, exec, priority, ignoreCancel) { + var pname = jsp.description.name; + if (ext.isNull(pname)) { + throw new TypeError('插件名称为空 请检查传入参数!'); + } var eventCls = mapEvent[event]; if (!eventCls) { try { @@ -90,6 +100,9 @@ function listen(event, exec, priority, ignoreCancel) { if (ignoreCancel === undefined) { ignoreCancel = false; } + if (!jspListener[jsp.description.name]) { + jspListener[jsp.description.name] = []; + } var listener = new Listener({}); // noinspection JSUnusedGlobalSymbols /** @@ -111,6 +124,9 @@ function listen(event, exec, priority, ignoreCancel) { }), plugin, ignoreCancel); + // 添加到缓存 用于关闭插件的时候关闭事件 + var listeners = jspListener[jsp.description.name]; + listeners.push(listener); // noinspection JSUnresolvedVariable log.d('注册事件 %s 方法 %s', eventCls.simpleName, exec.name === '' ? '匿名方法' : exec.name); return { @@ -127,7 +143,7 @@ function unlisten(listener) { if (!listener.event || !listener.listener) { throw new IllegalStateException("非法的监听器对象 无法取消事件!"); } - listener.event.getMethod("getHandlerList").invoke(null).unregister(listener.listener); + ref.on(listener.event).call('getHandlerList').get().unregister(listener.listener); // noinspection JSUnresolvedVariable log.d('注销事件 %s', listener.event.simpleName); } @@ -139,5 +155,10 @@ mapEventName(); module.exports = { on: listen, - off: unlisten + off: unlisten, + disable: function (jsp) { + jspListener[jsp.description.name].forEach(function (t) { + ref.on(HandlerList).call('unregisterAll', t); + }) + } }; \ No newline at end of file diff --git a/src/main/resources/modules/plugin.js b/src/main/resources/modules/plugin.js index 84448e5..47f4a74 100644 --- a/src/main/resources/modules/plugin.js +++ b/src/main/resources/modules/plugin.js @@ -5,6 +5,7 @@ /*global Java, base, module, exports, require, __FILE__*/ // var zip = require("core/zip"); var fs = require('core/fs'); +var event = require('modules/event'); /** * 载入插件 @@ -36,7 +37,8 @@ function updatePlugins(path) { update.mkdirs(); } else { fs.list(update).forEach(function (file) { - fs.move(fs.file(update, file.name), fs.file(path, file.name), true); + log.i('自动升级插件 %s', file); + fs.move(file, fs.file(path, file.name), true); }) } } @@ -75,22 +77,30 @@ function loadJsPlugin(files) { }) } -function runAndCatch(name, exec) { +function runAndCatch(jsp, exec, ext) { if (exec) { try { - exec(); + // 绑定方法的this到插件自身 + exec.bind(jsp)(); + if (ext) { + ext(); + } } catch (ex) { - log.w('插件 %s 执行 %s 发生错误: %s', name, exec.name, ex.message); + log.w('插件 %s 执行 %s 发生错误: %s', jsp.description.name, exec.name, ex.message); ex.printStackTrace(); } } } -function checkAndGet(name) { +function checkAndGet(args) { + if (args.length === 0) { + return plugins; + } + var name = args[0]; if (!exports.plugins[name]) { throw new Error("插件 " + name + "不存在!"); } - return exports.plugins[name]; + return [exports.plugins[name]]; } var plugins = []; @@ -106,32 +116,11 @@ exports.init = function (plugin, path) { loadPlugins(path); }; exports.load = function () { - if (arguments.length === 0) { - plugins.forEach(function (p) { - runAndCatch(p.description.name, p.load); - }) - } else { - var p = checkAndGet(arguments[0]); - runAndCatch(p.description.name, p.load); - } + checkAndGet(arguments).forEach(function (p) runAndCatch(p, p.load)); }; exports.enable = function () { - if (arguments.length === 0) { - plugins.forEach(function (p) { - runAndCatch(p.description.name, p.enable); - }) - } else { - var p = checkAndGet(arguments[0]); - runAndCatch(p.description.name, p.enable); - } + checkAndGet(arguments).forEach(function (p) runAndCatch(p, p.enable)); }; exports.disable = function () { - if (arguments.length === 0) { - plugins.forEach(function (p) { - runAndCatch(p.description.name, p.disable); - }) - } else { - var p = checkAndGet(arguments[0]); - runAndCatch(p.description.name, p.disable); - } + checkAndGet(arguments).forEach(function (p) runAndCatch(p, p.disable, function () event.disable(p))); }; \ No newline at end of file diff --git a/src/main/resources/plugins/hello.js b/src/main/resources/plugins/hello.js index 22b585f..87ee6e1 100644 --- a/src/main/resources/plugins/hello.js +++ b/src/main/resources/plugins/hello.js @@ -19,7 +19,7 @@ function load() { function enable() { console.log('启用 Hello Wrold 测试插件!'); - join = event.on('playerloginevent', function join(event) { + join = event.on(this, 'playerloginevent', function join(event) { // noinspection JSUnresolvedVariable log.d('玩家 %s 触发事件 %s', event.player.name, event.name); setTimeout(function () { @@ -27,9 +27,9 @@ function enable() { event.player.sendMessage(require("plugins/ext/papi").$(event.player, "§a欢迎来到 §bMiaoScript §a的世界! 当前在线: %server_online%")); }, 10); }); - cmd.on(module.exports, 'hello', { + cmd.on(this, 'hello', { cmd: function (sender, command, args) { - console.log(command, args); + console.log(command, args.join(' ')); return true; }, tab: function (sender, command, args) { @@ -39,8 +39,9 @@ function enable() { } function disable() { - log.i('卸载 Hello Wrold 测试插件!'); - event.off(join); + console.log('卸载 Hello Wrold 测试插件!'); + // 可以不用关闭事件 程序将自动处理 + // event.off(join); } module.exports = {