diff --git a/packages/api/src/command.ts b/packages/api/src/command.ts index 202f4376..fce59729 100644 --- a/packages/api/src/command.ts +++ b/packages/api/src/command.ts @@ -4,15 +4,15 @@ export namespace command { @injectable() export abstract class Command { on(plugin: any, name: string, exec: { cmd: Function, tab?: Function }) { - var cmd = this.create(plugin, { name: name }); + var cmd = this.create(plugin, name); console.debug(`插件 ${plugin.description.name} 创建命令 ${name}(${cmd})...`) if (exec.cmd && typeof exec.cmd === "function") { - this.onCommand(plugin, cmd, exec.cmd) + this.onCommand(plugin, cmd, exec.cmd); } else { throw Error("CommandExec Must be a function... Input: " + exec.cmd) } if (exec.tab && typeof exec.tab === "function") { - this.onTabComplete(plugin, cmd, exec.tab) + this.onTabComplete(plugin, cmd, exec.tab); } } off(plugin: any, name: string) { @@ -21,8 +21,46 @@ export namespace command { /** * Create Server Command Object */ - abstract create(name: string, opts: { name: string }); - abstract onCommand(plugin: object, command: any, opts: { name: string }); - abstract onTabComplete(plugin: object, command: any, opts: { name: string }); + abstract create(plugin: any, command: string); + abstract onCommand(plugin: any, command: any, executor: Function); + abstract onTabComplete(plugin: any, command: any, tabCompleter: Function); + + setExecutor(plugin: any, command: any, executor: Function) { + return (sender: any, _, command: string, args: string[]) => { + try { + return executor(sender, command, Java.from(args)); + } catch (ex) { + console.console(`§6玩家 §a${sender.name} §6执行 §b${plugin.description.name} §6插件 §d${command} ${Java.from(args).join(' ')} §6命令时发生异常 §4${ex}`); + console.ex(ex); + console.sender(sender, [`§6执行 §b${plugin.description.name} §6插件 §d${command} ${Java.from(args).join(' ')} §6命令时发生异常`, ...console.stack(ex)]) + return true; + } + } + } + + setTabCompleter(plugin: any, command: any, tabCompleter: Function) { + return (sender: any, _, command: string, args: string[]) => { + try { + var token = args[args.length - 1]; + var complete = tabCompleter(sender, command, Java.from(args)) || []; + return this.copyPartialMatches(complete, token); + } catch (ex) { + console.console(`§6玩家 §a${sender.name} §6执行 §b${plugin.description.name} §6插件 §d${command} ${Java.from(args).join(' ')} §6补全时发生异常 §4${ex}`); + console.ex(ex); + console.sender(sender, [`§6执行 §b${plugin.description.name} §6插件 §d${command} ${Java.from(args).join(' ')} §6补全时发生异常 §4${ex}`, ...console.stack(ex)]); + return []; + } + } + } + + protected copyPartialMatches(complete: string[], token: string, array: string[] = []): string[] { + if (!token) { return complete } + complete.forEach(function(e) { + if (typeof e === "string" && e.toLowerCase().startsWith(token.toLowerCase())) { + array.push(e) + } + }); + return array + } } } diff --git a/packages/api/src/console.ts b/packages/api/src/console.ts index 769b4005..a43b2a16 100644 --- a/packages/api/src/console.ts +++ b/packages/api/src/console.ts @@ -57,9 +57,10 @@ export class MiaoScriptConsole implements Console { ex(ex: Error) { this.stack(ex).forEach(line => this.console(line)) }; - stack(ex: Error | any): string[] { + stack(ex: Error): string[] { var stack = ex.getStackTrace(); var cache = ['§4' + ex]; + //@ts-ignore if (stack.class) { stack = Arrays.asList(stack) } @@ -70,8 +71,10 @@ export class MiaoScriptConsole implements Console { cache.push(` §e->§c ${fileName} => §4${trace.methodName}:${trace.lineNumber}`) } else { var className = trace.className; + var fileName = trace.fileName if (className.startsWith('jdk.nashorn.internal.scripts')) { className = className.substr(className.lastIndexOf('$') + 1) + if (fileName.startsWith(root)) { fileName = fileName.split(root)[1] } } else { for (var prefix in ignoreLogPrefix) { if (className.startsWith(ignoreLogPrefix[prefix])) { @@ -79,7 +82,7 @@ export class MiaoScriptConsole implements Console { } } } - cache.push(` §e->§c ${className}.${trace.methodName}(§4${trace.fileName}:${trace.lineNumber}§c)`); + cache.push(` §e->§c ${className}.${trace.methodName}(§4${fileName}:${trace.lineNumber}§c)`); } }); return cache; diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index 996b67d6..ab5b8e5f 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -1,5 +1,6 @@ import './typings/global' +export * from './task' export * from './event' export * from './console' export * from './command' diff --git a/packages/api/src/interfaces/task.ts b/packages/api/src/interfaces/task.ts deleted file mode 100644 index 812f727a..00000000 --- a/packages/api/src/interfaces/task.ts +++ /dev/null @@ -1,9 +0,0 @@ -export namespace task { - export const Task = Symbol('Task') - export interface Task { - run(func: Function): void; - async(func: Function): void; - later(tick: number): task.Task; - timer(tick: number): task.Task; - } -} diff --git a/packages/api/src/task.ts b/packages/api/src/task.ts new file mode 100644 index 00000000..71259ce0 --- /dev/null +++ b/packages/api/src/task.ts @@ -0,0 +1,55 @@ +import { injectable, DefaultContainer as container } from "@ms/container"; + +export namespace task { + export const TaskManager = Symbol('TaskManager') + export interface TaskManager { + create(func: Function): task.Task; + } + /** + * 任务抽象 + */ + export abstract class Task { + protected plugin: any; + protected func: Function; + protected isAsync: boolean = false; + protected laterTime: number = 0; + protected interval: number = 0; + + constructor(plugin: any, func: Function) { + this.plugin = plugin; + this.func = func; + } + + async(isAsync: boolean = true): task.Task { + this.isAsync = isAsync; + return this; + } + + later(tick: number): task.Task { + this.laterTime = tick; + return this; + } + + timer(tick: number): task.Task { + this.interval = tick; + return this; + } + + protected run(): void { + try { + this.func(); + } catch (ex) { + console.console('§4插件执行任务时发生错误', ex) + console.ex(ex); + } + } + + abstract submit(): Cancelable; + } + /** + * 返可取消的对象 + */ + export interface Cancelable { + cancel(): boolean; + } +}