diff --git a/packages/api/src/command.ts b/packages/api/src/command.ts index fce59729..6f75bd73 100644 --- a/packages/api/src/command.ts +++ b/packages/api/src/command.ts @@ -16,16 +16,18 @@ export namespace command { } } off(plugin: any, name: string) { - + console.debug(`插件 ${plugin.description.name} 注销命令 ${name}...`) + this.remove(plugin, name); } /** * Create Server Command Object */ - abstract create(plugin: any, command: string); - abstract onCommand(plugin: any, command: any, executor: Function); - abstract onTabComplete(plugin: any, command: any, tabCompleter: Function); + protected abstract create(plugin: any, command: string); + protected abstract remove(plugin: any, command: string); + protected abstract onCommand(plugin: any, command: any, executor: Function); + protected abstract onTabComplete(plugin: any, command: any, tabCompleter: Function); - setExecutor(plugin: any, command: any, executor: Function) { + protected setExecutor(plugin: any, command: any, executor: Function) { return (sender: any, _, command: string, args: string[]) => { try { return executor(sender, command, Java.from(args)); @@ -38,7 +40,7 @@ export namespace command { } } - setTabCompleter(plugin: any, command: any, tabCompleter: Function) { + protected setTabCompleter(plugin: any, command: any, tabCompleter: Function) { return (sender: any, _, command: string, args: string[]) => { try { var token = args[args.length - 1]; diff --git a/packages/api/src/interfaces/plugin.ts b/packages/api/src/interfaces/plugin.ts index ee6e7f04..90f8b757 100644 --- a/packages/api/src/interfaces/plugin.ts +++ b/packages/api/src/interfaces/plugin.ts @@ -23,5 +23,6 @@ export namespace plugin { enable(...args: any[]): void; disable(...args: any[]): void; reload(...args: any[]): void; + getPlugins(): Map; } } diff --git a/packages/bukkit/src/command.ts b/packages/bukkit/src/command.ts index 1a704ad9..95f6abbe 100644 --- a/packages/bukkit/src/command.ts +++ b/packages/bukkit/src/command.ts @@ -27,6 +27,12 @@ export class BukkitCommand extends command.Command { this.commandMap.register(plugin.description.name, cmd); return cmd; } + remove(plugin: any, command: string) { + var cmd = this.commandMap.getCommand(command) + if (cmd && cmd instanceof PluginCommand) { + cmd.unregister(this.commandMap); + } + } onCommand(plugin: any, command: any, executor: Function) { // 必须指定需要实现的接口类型 否则MOD服会报错 command.setExecutor(new CommandExecutor({ diff --git a/packages/plugin/src/manager.ts b/packages/plugin/src/manager.ts index 1b96535a..da155ff1 100644 --- a/packages/plugin/src/manager.ts +++ b/packages/plugin/src/manager.ts @@ -52,9 +52,11 @@ export class PluginManagerImpl implements plugin.PluginManager { } enable(...args: any[]): void { - this.checkAndGet(args[0]).forEach(pl => { - this.runCatch(pl, 'enable') - this.runCatch(pl, `${this.serverType}enable`); + this.checkAndGet(args[0]).forEach(plugin => { + this.runCatch(plugin, 'enable') + this.runCatch(plugin, `${this.serverType}enable`); + this.registryCommand(plugin); + this.registryListener(plugin); }); } @@ -62,7 +64,8 @@ export class PluginManagerImpl implements plugin.PluginManager { this.checkAndGet(args[0]).forEach(pl => { this.runCatch(pl, 'disable'); this.runCatch(pl, `${this.serverType}disable`); - this.EventManager.disable(pl); + this.unregistryCommand(pl); + this.unregistryListener(pl); }); } @@ -76,6 +79,10 @@ export class PluginManagerImpl implements plugin.PluginManager { }) } + getPlugins() { + return this.pluginMap; + } + private runCatch(pl: any, func: string) { try { if (pl[func]) pl[func].call(pl); @@ -172,9 +179,7 @@ export class PluginManagerImpl implements plugin.PluginManager { this.pluginMap.set(metadata.name, pluginInstance); pluginInstance.description = metadata; // @ts-ignore - pluginInstance.logger = new this.Console(metadata.name); - this.registryCommand(pluginInstance); - this.registryListener(pluginInstance); + pluginInstance.logger = new this.Console(metadata.prefix || metadata.name); return pluginInstance; } @@ -199,4 +204,15 @@ export class PluginManagerImpl implements plugin.PluginManager { this.EventManager.listen(pluginInstance, event.name, pluginInstance[event.executor].bind(pluginInstance)); } } + + private unregistryCommand(pluginInstance: interfaces.Plugin) { + let cmds = getPluginCommandMetadata(pluginInstance); + cmds.forEach(cmd => { + this.CommandManager.off(pluginInstance, cmd.name); + }) + } + + private unregistryListener(pluginInstance: interfaces.Plugin) { + this.EventManager.disable(pluginInstance); + } } diff --git a/packages/sponge/src/command.ts b/packages/sponge/src/command.ts index 9fd056e3..ff04efb2 100644 --- a/packages/sponge/src/command.ts +++ b/packages/sponge/src/command.ts @@ -47,6 +47,7 @@ class SimpleCommandCallable { setExecutor = (executor: Function) => this.executor = executor; setTabCompleter = (tabCompleter: Function) => this.tabCompleter = tabCompleter; + toString = () => `Sponge SimpleCommandCallable` } @injectable() @@ -54,19 +55,30 @@ export class SpongeCommand extends command.Command { @inject(plugin.PluginInstance) private pluginInstance: any private commandMap: any[] = []; + private commandMapping: any[] = []; create(plugin: any, command: string) { - var commandKey = plugin.description.name.toLowerCase() + ":" + command; + var commandKey = this.getCommandKey(plugin, command); if (!this.commandMap[commandKey]) { this.commandMap[commandKey] = new SimpleCommandCallable(command); - Sponge.getCommandManager().register(this.pluginInstance, this.commandMap[commandKey].callable, command, commandKey); + this.commandMapping[commandKey] = Sponge.getCommandManager().register(this.pluginInstance, this.commandMap[commandKey].callable, command, commandKey).orElse(null); } return this.commandMap[commandKey]; } + remove(plugin: any, command: string) { + var commandKey = this.getCommandKey(plugin, command); + if (this.commandMapping[commandKey]) { + Sponge.getCommandManager().removeMapping(this.commandMapping[commandKey]); + } + } onCommand(plugin: any, command: any, executor: Function) { command.setExecutor(super.setExecutor(plugin, command, executor)); } onTabComplete(plugin: any, command: any, tabCompleter: Function) { command.setTabCompleter(super.setTabCompleter(plugin, command, tabCompleter)); } -} \ No newline at end of file + + private getCommandKey(plugin: any, command: string) { + return plugin.description.name.toLowerCase() + ":" + command; + } +}