From 05e9feee9b20bd76fab8e638163263098e1144d9 Mon Sep 17 00:00:00 2001 From: MiaoWoo Date: Tue, 22 Sep 2020 17:33:59 +0800 Subject: [PATCH] feat: update Autowired & support command alias Signed-off-by: MiaoWoo --- packages/api/src/event.ts | 2 + packages/api/src/interfaces/plugin.ts | 27 +++---- packages/api/src/interfaces/server/index.ts | 88 +++++++++------------ packages/container/src/index.ts | 30 ++++++- packages/core/src/index.ts | 6 +- packages/i18n/languages/zh_cn.yml | 5 +- packages/nashorn/src/index.ts | 3 +- packages/plugin/src/decorators.ts | 2 + packages/plugin/src/interfaces.ts | 4 + 9 files changed, 96 insertions(+), 71 deletions(-) diff --git a/packages/api/src/event.ts b/packages/api/src/event.ts index 7bd8bd57..bd85ef7d 100644 --- a/packages/api/src/event.ts +++ b/packages/api/src/event.ts @@ -138,6 +138,8 @@ export namespace event { // add to cache Be used for close plugin to close event if (!listenerMap[name]) listenerMap[name] = [] var off = () => { + if (off['offed']) return + off['offed'] = true this.unregister(eventCls, listener) console.debug(i18n.translate("ms.api.event.unregister", { name, event: this.class2Name(eventCls), exec: executor })) } diff --git a/packages/api/src/interfaces/plugin.ts b/packages/api/src/interfaces/plugin.ts index e6cc74f2..fcce919c 100644 --- a/packages/api/src/interfaces/plugin.ts +++ b/packages/api/src/interfaces/plugin.ts @@ -1,3 +1,5 @@ +import { injectable } from '@ccms/container' + export namespace plugin { /** * MiaoScript Plugin @@ -11,23 +13,20 @@ export namespace plugin { * Runtime Plugin Instance */ export const PluginInstance = Symbol("PluginInstance") - /** - * MiaoScript Plugin Manager Symbol - */ - export const PluginManager = Symbol("PluginManager") /** * MiaoScript Plugin Manager Interface */ - export interface PluginManager { - scan(folder: string): void - build(): void - loadFromFile(file: string, scanner?: plugin.PluginScanner): Plugin - load(...args: any[]): void - enable(...args: any[]): void - disable(...args: any[]): void - reload(...args: any[]): void - getPlugin(name: string): plugin.Plugin - getPlugins(): Map + @injectable() + export abstract class PluginManager { + abstract scan(folder: string): void + abstract build(): void + abstract loadFromFile(file: string, scanner?: plugin.PluginScanner): Plugin + abstract load(...args: any[]): void + abstract enable(...args: any[]): void + abstract disable(...args: any[]): void + abstract reload(...args: any[]): void + abstract getPlugin(name: string): plugin.Plugin + abstract getPlugins(): Map } export const PluginScanner = Symbol("PluginScanner") /** diff --git a/packages/api/src/interfaces/server/index.ts b/packages/api/src/interfaces/server/index.ts index d0a816ce..df972ca1 100644 --- a/packages/api/src/interfaces/server/index.ts +++ b/packages/api/src/interfaces/server/index.ts @@ -22,19 +22,44 @@ export namespace server { /** * MiaoScript Server */ + @injectable() export abstract class Server { - abstract getVersion(): string - abstract getPlayer(name: string): any - abstract getOnlinePlayers(): any[] - abstract getConsoleSender(): any - abstract getService(service: string): any - abstract dispatchCommand(sender: string | any, command: string): boolean - abstract dispatchConsoleCommand(command: string): boolean - abstract getPluginsFolder(): string - abstract getNativePluginManager(): NativePluginManager - abstract getDedicatedServer?(): any - abstract getNettyPipeline(): any - abstract getRootLogger(): any + getVersion(): string { + throw new Error("Method not implemented.") + } + getPlayer(name: string): any { + throw new Error("Method not implemented.") + } + getOnlinePlayers(): any[] { + throw new Error("Method not implemented.") + } + getConsoleSender(): any { + throw new Error("Method not implemented.") + } + getService(service: string): any { + throw new Error("Method not implemented.") + } + dispatchCommand(sender: string | any, command: string): boolean { + throw new Error("Method not implemented.") + } + dispatchConsoleCommand(command: string): boolean { + throw new Error("Method not implemented.") + } + getPluginsFolder(): string { + throw new Error("Method not implemented.") + } + getNativePluginManager(): NativePluginManager { + throw new Error("Method not implemented.") + } + getDedicatedServer?(): any { + throw new Error("Method not implemented.") + } + getNettyPipeline(): any { + throw new Error("Method not implemented.") + } + getRootLogger(): any { + throw new Error("Method not implemented.") + } } @injectable() export class ServerChecker { @@ -54,50 +79,15 @@ export namespace server { } } @injectable() - export abstract class ReflectServer implements server.Server { + export abstract class ReflectServer extends server.Server { protected pipeline: any protected rootLogger: any constructor() { + super() this.reflect() } - getVersion(): string { - throw new Error("Method not implemented.") - } - getPlayer(name: string) { - throw new Error("Method not implemented.") - } - getOnlinePlayers(): any[] { - throw new Error("Method not implemented.") - } - getConsoleSender() { - throw new Error("Method not implemented.") - } - getService(service: string) { - throw new Error("Method not implemented.") - } - dispatchCommand(sender: any, command: string): boolean { - throw new Error("Method not implemented.") - } - dispatchConsoleCommand(command: string): boolean { - throw new Error("Method not implemented.") - } - getPluginsFolder(): string { - throw new Error("Method not implemented.") - } - getNativePluginManager(): NativePluginManager { - throw new Error("Method not implemented.") - } - getDedicatedServer() { - throw new Error("Method not implemented.") - } - getNettyPipeline() { - throw new Error("Method not implemented.") - } - getRootLogger() { - throw new Error("Method not implemented.") - } protected reflect() { try { let consoleServer = this.getDedicatedServer() diff --git a/packages/container/src/index.ts b/packages/container/src/index.ts index 75e89453..2d71c26a 100644 --- a/packages/container/src/index.ts +++ b/packages/container/src/index.ts @@ -60,8 +60,22 @@ export const JSClass = (className: string) => { * @param className 类名 */ export const Autowired = (className?: string | any) => { - return function (target: any, propertyKey: string) { - target[propertyKey] = getContainer().getNamed(ioc.Autowired, className || propertyKey) + return function (target: any, propertyKey: string, index?: number) { + let container = getContainer() + let type = Reflect.getMetadata('design:type', target, propertyKey) + if (type && type !== Object) { + try { + return target[propertyKey] = container.getNamed(type, className || propertyKey) + } catch (error) { + try { + return target[propertyKey] = container.get(type) + } catch (error) { + } + } + } + if (container.isBound(ioc.Autowired)) { + target[propertyKey] = container.getNamed(ioc.Autowired, className || propertyKey) + } } } @@ -70,7 +84,7 @@ export const Autowired = (className?: string | any) => { * @param className 类名 */ export const Resource = (resourceName?: string | any) => { - return function (target: any, propertyKey: string) { + return function (target: any, propertyKey: string, index?: number) { target[propertyKey] = getContainer().getNamed(ioc.Resource, resourceName || propertyKey) } } @@ -82,8 +96,18 @@ export const reduceMetadata = (ctx: interfaces.Context): any => { }, {}) } +function initAutowired(container: Container) { + container.bind(ioc.Autowired).toDynamicValue((ctx) => { + var metadata: any = reduceMetadata(ctx) + let key = Object.toString.call(metadata.named) + if (key === "[object Function]" || key === "[object Symbol]") { return container.get(metadata.named) } + return undefined + }) +} + export const DefaultContainer = new Container() initContainer(DefaultContainer) +initAutowired(DefaultContainer) export * from 'inversify' export * from './constants' diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index a8650c81..e0ba363a 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -49,10 +49,12 @@ class MiaoScriptCore { } disable() { + let disableStartTime = Date.now() console.i18n("ms.core.engine.disable") this.pluginManager.disable(this.pluginManager.getPlugins()) this.taskManager.disable() process.exit(0) + console.i18n("ms.core.engine.disable.finish", { version: 'v' + global.ScriptEngineVersion, time: (new Date().getTime() - disableStartTime) / 1000 }) } } @@ -86,7 +88,7 @@ function detectServer(): constants.ServerType { } function initialize() { - // @ts-ignore + global.ScriptEngineVersion = require('../package.json').version try { engineLoad({ script: http.get("http://ms.yumc.pw/api/plugin/download/name/initialize"), name: 'core/initialize.js' }) } catch (error) { console.debug(error) } try { let corePackageStartTime = new Date().getTime() @@ -103,7 +105,7 @@ function initialize() { container.load(buildProviderModule()) console.i18n("ms.core.package.completed", { scope: global.scope, type, time: (Date.now() - corePackageStartTime) / 1000 }) let disable = container.get(MiaoScriptCore).enable() - console.i18n("ms.core.engine.completed", { time: (Date.now() - global.NashornEngineStartTime) / 1000 }) + console.i18n("ms.core.engine.completed", { version: 'v' + global.ScriptEngineVersion, time: (Date.now() - global.ScriptEngineStartTime) / 1000 }) return disable } catch (error) { console.i18n("ms.core.initialize.error", { error }) diff --git a/packages/i18n/languages/zh_cn.yml b/packages/i18n/languages/zh_cn.yml index 8ff4a0c3..b7f15f91 100644 --- a/packages/i18n/languages/zh_cn.yml +++ b/packages/i18n/languages/zh_cn.yml @@ -10,8 +10,9 @@ ms.core.package.initialize: "初始化 MiaoScript 扩展 {scope}/core {scope}/{t ms.core.package.completed: "MiaoScript 扩展 {scope}/core {scope}/{type} {scope}/plugin 加载完成 耗时({time}s)" ms.core.plugin.initialize: "MiaoScript 开始引导插件系统. 请稍候..." ms.core.plugin.completed: "MiaoScript 插件加载完毕 耗时({time}s)!" -ms.core.engine.completed: "MiaoScript 脚本引擎 加载完毕... 耗时({time}s)!" -ms.core.engine.disable: "关闭 MiaoScript 引擎..." +ms.core.engine.completed: "MiaoScript 脚本引擎 {version} 加载完毕... 耗时({time}s)!" +ms.core.engine.disable: "MiaoScript 关闭脚本引擎 请稍候..." +ms.core.engine.disable.finish: "MiaoScript 脚本引擎 {version} 关闭完成... 耗时({time}s)!" ms.core.engine.disable.abnormal: "引擎异常启动或初始化未完成 跳过关闭流程..." ms.api.event.resource.not.found: "无法映射事件 未找到资源文件 {resource}!" diff --git a/packages/nashorn/src/index.ts b/packages/nashorn/src/index.ts index 40f4ae71..0a550f53 100644 --- a/packages/nashorn/src/index.ts +++ b/packages/nashorn/src/index.ts @@ -48,7 +48,8 @@ declare global { logger: any debug: boolean level: string - NashornEngineStartTime: number + ScriptEngineVersion: string + ScriptEngineStartTime: number setGlobal: (key: string, value: any, config?: PropertyDescriptor & ThisType) => void noop: () => void console: Console diff --git a/packages/plugin/src/decorators.ts b/packages/plugin/src/decorators.ts index 014964fd..2b2c8e43 100644 --- a/packages/plugin/src/decorators.ts +++ b/packages/plugin/src/decorators.ts @@ -35,6 +35,7 @@ export function cmd(metadata: interfaces.CommandMetadata = {}) { metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key) const previousMetadata: Map = getPluginCommandMetadata(target) previousMetadata.set(metadata.name, metadata) + metadata.alias?.forEach((name) => previousMetadata.set(name, metadata)) Reflect.defineMetadata(METADATA_KEY.cmd, previousMetadata, target.constructor) } } @@ -52,6 +53,7 @@ export function tab(metadata: interfaces.CommandMetadata = {}) { metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key) const previousMetadata: Map = getPluginTabCompleterMetadata(target) previousMetadata.set(metadata.name, metadata) + metadata.alias?.forEach((name) => previousMetadata.set(name, metadata)) Reflect.defineMetadata(METADATA_KEY.tab, previousMetadata, target.constructor) } } diff --git a/packages/plugin/src/interfaces.ts b/packages/plugin/src/interfaces.ts index 4283e33a..0a8d9a19 100644 --- a/packages/plugin/src/interfaces.ts +++ b/packages/plugin/src/interfaces.ts @@ -35,6 +35,10 @@ export namespace interfaces { executor?: string } export interface CommandMetadata extends ExecMetadata { + /** + * 命令别名 + */ + alias?: string[] /** * 命令描述 */