diff --git a/src/main/resources/api/plugin.js b/src/main/resources/api/plugin.js index a423360..bcab1c4 100644 --- a/src/main/resources/api/plugin.js +++ b/src/main/resources/api/plugin.js @@ -67,16 +67,23 @@ function loadJsPlugins(files) { files.filter(function (file) { return file.name.endsWith(".js") }).forEach(function (file) { - try { - loadPlugin(file); - } catch (ex) { - console.console('§6插件 §b%s §6初始化时发生错误 §4%s'.format(fs.path(file), ex.message)); - console.ex(ex); - } + loadPlugin(file) }) } function loadPlugin(file) { + try { + var plugin = readPlugin(file); + initPlugin(plugin); + plugins[plugin.description.name] = plugin; + return plugin + } catch (ex) { + console.console('§6插件 §b%s §6初始化时发生错误 §4%s'.format(file.name, ex.message)); + console.ex(ex); + } +} + +function readPlugin(file) { var update = fs.file(fs.file(file.parentFile, 'update'), file.name); if (update.exists()) { console.info('自动升级插件 %s'.format(file.name)); @@ -89,13 +96,17 @@ function loadPlugin(file) { } }) console.debug("插件编译结果: %s".format(JSON.stringify(plugin))); + plugin.__FILE__ = file; + return plugin; +} + +function initPlugin(plugin) { var desc = plugin.description; if (!desc || !desc.name) { - console.warn("文件 %s 不存在 description 描述信息 无法加载插件!".format(file)); + throw new Error("文件 %s 不存在 description 描述信息 无法加载插件!".format(plugin.__FILE__)); } else { - initPlugin(file, plugin); + internalInitPlugin(plugin); afterLoadHook(plugin); - plugins[plugin.description.name] = plugin; console.info('载入插件 %s 版本 %s By %s'.format(desc.name, desc.version || '未知', desc.author || '未知')); } return plugin; @@ -106,9 +117,9 @@ function beforeLoadHook(origin) { // 处理 event 为了不影响 正常逻辑 event 还是手动require吧 // result = result + 'var event = {}; module.exports.event = event;'; // 注入 console 对象 // 给插件注入单独的 console - result = result + 'var console = new Console(); module.exports.console = console;'; + result = result + '\nvar console = new Console(); module.exports.console = console;'; // 插件注入 self 对象 - result = result + 'var self = {}; module.exports.self = self;'; + result = result + '\nvar self = {}; module.exports.self = self;'; return result; } @@ -123,11 +134,9 @@ function afterLoadHook(plugin) { /** * 初始化插件内容(提供config,__DATA__等参数) */ -function initPlugin(file, plugin) { - // 初始化 __FILE__ - plugin.__FILE__ = file; +function internalInitPlugin(plugin) { // 初始化 __DATA__ - plugin.__DATA__ = plugin.dataFolder = fs.file(file.parentFile, plugin.description.name); + plugin.__DATA__ = plugin.dataFolder = fs.file(plugin.__FILE__.parentFile, plugin.description.name); // 初始化 getDataFolder() plugin.getDataFolder = function getDataFolder() { return plugin.__DATA__; @@ -204,7 +213,7 @@ function checkAndGet(args) { } var name = args[0]; // 如果是插件 则直接返回 - if (name.description) { + if (name && name.description) { return [name]; } if (!exports.plugins[name]) { @@ -221,7 +230,7 @@ function checkAndRun(args, name, ext) { try { // 绑定方法的this到插件自身 if (typeof exec === "function") exec.call(jsp); - if (ext) ext.call(jsp); + if (typeof ext === "function") ext.call(jsp); } catch (ex) { console.console('§6插件 §b%s §6执行 §d%s §6方法时发生错误 §4%s'.format(jsp.description.name, name, ex.message)); console.ex(ex); @@ -270,5 +279,6 @@ exports = module.exports = { load: load, enable: enable, disable: disable, - reload: reload + reload: reload, + loadPlugin: loadPlugin } diff --git a/src/main/resources/core/ext/Array.js b/src/main/resources/core/ext/Array.js new file mode 100644 index 0000000..4e00aa5 --- /dev/null +++ b/src/main/resources/core/ext/Array.js @@ -0,0 +1,18 @@ +/** + * 补丁和方法扩展 + */ +(function () { + if (!Array.prototype.copyPartialMatches) { + Object.defineProperty(Array.prototype, "copyPartialMatches", { + enumerable: false, + value: function (token, array) { + this.forEach(function (e) { + if (e.startsWith(token)) { + array.push(e) + } + }) + return array + } + }); + } +})(); \ No newline at end of file diff --git a/src/main/resources/core/fs.js b/src/main/resources/core/fs.js index 1c4bab2..ae23099 100644 --- a/src/main/resources/core/fs.js +++ b/src/main/resources/core/fs.js @@ -98,11 +98,9 @@ function read(f) { * @param override 是否覆盖 */ function save(path, content, override) { - var file = new File(path); - file.getParentFile().mkdirs(); - Files.write(file.toPath(), - content.getBytes("UTF-8"), - override ? StandardCopyOption['REPLACE_EXISTING'] : StandardCopyOption['ATOMIC_MOVE']); + var f = file(path); + f.getParentFile().mkdirs(); + Files.write(f.toPath(), new java.lang.String(content).getBytes("UTF-8")); }; /** * 列出目录文件 diff --git a/src/main/resources/internal/bukkit/command.js b/src/main/resources/internal/bukkit/command.js index 54b4312..b7f4f8d 100644 --- a/src/main/resources/internal/bukkit/command.js +++ b/src/main/resources/internal/bukkit/command.js @@ -78,10 +78,9 @@ function on(jsp, name, exec) { c.setTabCompleter(new org.bukkit.command.TabCompleter({ onTabComplete: function (sender, cmd, command, args) { try { - var completions = new ArrayList(); var token = args[args.length - 1]; - StringUtil.copyPartialMatches(token, Arrays.asList(exec.tab(sender, command, args)), completions); - return completions; + var complate = exec.tab(sender, command, args) || [] + return Arrays.asList(complate.copyPartialMatches(token, [])); } catch (ex) { console.console('§6玩家 §a%s §6执行 §b%s §6插件 §d%s %s §6补全时发生异常 §4%s'.format(sender.name, jsp.description.name, command, Java.from(args).join(' '), ex)); console.ex(ex); diff --git a/src/main/resources/internal/sponge/command.js b/src/main/resources/internal/sponge/command.js index 2497c60..9fc766f 100644 --- a/src/main/resources/internal/sponge/command.js +++ b/src/main/resources/internal/sponge/command.js @@ -23,19 +23,19 @@ var Arrays = Java.type('java.util.Arrays'); var commandMap=[]; -var SimpleCommandCallable = function (name) { +var SimpleCommandCallable = function (command) { var that = this; - this.name = name; + this.name = command.name; this.cmd = noop; this.tab = function() { return new ArrayList(); }; this.callable = new CommandCallable({ //CommandResult process(CommandSource source, String arguments) throws CommandException; process: function (src, args) { - return that.cmd(src, name, args.split(" ")) ? CommandResult.success() : CommandResult.empty(); + return that.cmd(src, that.name, args.split(" ")) ? CommandResult.success() : CommandResult.empty(); }, //List getSuggestions(CommandSource source, String arguments, @Nullable Location targetPosition) throws CommandException; getSuggestions: function (src, args, target) { - return that.tab(src, name, args.split(" ")); + return that.tab(src, that.name, args.split(" ")); }, //boolean testPermission(CommandSource source); testPermission: function () { @@ -43,7 +43,7 @@ var SimpleCommandCallable = function (name) { }, //Optional getShortDescription(CommandSource source); getShortDescription: function () { - return Optional.of(Text.of("")); + return Optional.of(Text.of(command.description || '暂无描述!')); }, //Optional getHelp(CommandSource source); getHelp: function () { @@ -70,7 +70,8 @@ function enable(jsp) { for (var name in commands) { var command = commands[name]; if (typeof command !== 'object') continue; - create(jsp, name) + command.name = name + create(jsp, command) console.debug('插件 %s 注册命令 %s ...'.format(jsp.description.name, name)); } } @@ -79,18 +80,17 @@ function enable(jsp) { function get(name) { } -function create(jsp, name) { - var commandKey = jsp.description.name.toLowerCase() + ":" + name; +function create(jsp, command) { + var commandKey = jsp.description.name.toLowerCase() + ":" + command.name; if(!commandMap[commandKey]){ - commandMap[commandKey] = new SimpleCommandCallable(); - commandMap[commandKey].name = name; - Sponge.getCommandManager().register(plugin, commandMap[commandKey].callable, name, commandKey); + commandMap[commandKey] = new SimpleCommandCallable(command); + Sponge.getCommandManager().register(plugin, commandMap[commandKey].callable, command.name, commandKey); } return commandMap[commandKey]; } function on(jsp, name, exec) { - var c = create(jsp, name); + var c = create(jsp, {name: name}); console.debug('插件 %s 设置命令 %s 执行器 ...'.format(jsp.description.name, name)); if (exec.cmd) { c.setExecutor(function (sender, command, args) { @@ -107,7 +107,8 @@ function on(jsp, name, exec) { c.setTabCompleter(function (sender, command, args) { try { var token = args[args.length - 1]; - return Arrays.asList(exec.tab(sender, command, args)); + var complate = exec.tab(sender, command, args) || [] + return Arrays.asList(complate.copyPartialMatches(token, [])); } catch (ex) { console.console('§6玩家 §a%s §6执行 §b%s §6插件 §d%s %s §6补全时发生异常 §4%s'.format(sender.name, jsp.description.name, command, args, ex)); console.ex(ex);