diff --git a/packages/i18n/languages/en.yml b/packages/i18n/languages/en.yml index 0ae1366b..bd10124c 100644 --- a/packages/i18n/languages/en.yml +++ b/packages/i18n/languages/en.yml @@ -33,6 +33,7 @@ ms.plugin.event.map: "Total {count} {type} Event Mapping Complate..." ms.plugin.manager.scan: "Scanning Plugins in {folder} ..." ms.plugin.manager.initialize.error: "§6Plugin §b{name} §6initialize error §4{ex}" ms.plugin.manager.stage: "{stage} {plugin} version {version} by {author}" +ms.plugin.manager.stage.exec: "[{plugin}] Exec {name} Stage {stage} When servers is {servers}..." ms.plugin.manager.stage.load: "Loading" ms.plugin.manager.stage.enable: "Enabling" ms.plugin.manager.stage.disable: "Disabling" diff --git a/packages/i18n/languages/zh_cn.yml b/packages/i18n/languages/zh_cn.yml index 95b2299d..e68bafcc 100644 --- a/packages/i18n/languages/zh_cn.yml +++ b/packages/i18n/languages/zh_cn.yml @@ -33,6 +33,7 @@ ms.plugin.event.map: "总计 {count} 个 {type} 事件 映射完成..." ms.plugin.manager.scan: "扫描 {folder} 文件夹中插件..." ms.plugin.manager.initialize.error: "§6插件 §b{name} §6初始化错误 §4{ex}" ms.plugin.manager.stage: "{stage} {plugin} 版本 {version} 作者 {author}" +ms.plugin.manager.stage.exec: "[{plugin}] 执行 {stage} 阶段函数 {name} 匹配类型 {servers}..." ms.plugin.manager.stage.load: "加载" ms.plugin.manager.stage.enable: "启用" ms.plugin.manager.stage.disable: "关闭" diff --git a/packages/plugin/src/constants.ts b/packages/plugin/src/constants.ts index d68b2fbe..0ee77e1f 100644 --- a/packages/plugin/src/constants.ts +++ b/packages/plugin/src/constants.ts @@ -4,4 +4,9 @@ export const METADATA_KEY = { tab: "@ms/plugin:tab", listener: "@ms/plugin:listener", config: "@ms/plugin:config", + stage: { + load: "@ms/plugin:stage:load", + enable: "@ms/plugin:stage:enable", + disable: "@ms/plugin:stage:disable" + } }; diff --git a/packages/plugin/src/decorators.ts b/packages/plugin/src/decorators.ts index 76e2acd1..5043ccdd 100644 --- a/packages/plugin/src/decorators.ts +++ b/packages/plugin/src/decorators.ts @@ -1,14 +1,14 @@ import { injectable, decorate } from "@ms/container"; import { interfaces } from './interfaces' import { METADATA_KEY } from './constants' -import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPluginTabCompleterMetadata, getPluginConfigMetadata } from './utils' +import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata } from './utils' /** * MiaoScript plugin * @param metadata PluginMetadata */ export function plugin(metadata: interfaces.PluginMetadata) { - return function(target: any) { + return function (target: any) { metadata.target = target; decorate(injectable(), target); Reflect.defineMetadata(METADATA_KEY.plugin, metadata, target); @@ -23,7 +23,7 @@ export function plugin(metadata: interfaces.PluginMetadata) { * @param metadata CommandMetadata */ export function cmd(metadata: interfaces.CommandMetadata = {}) { - return function(target: any, key: string, value: any) { + return function (target: any, key: string, value: any) { metadata.name = metadata.name || key; metadata.executor = key; metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key) @@ -38,7 +38,7 @@ export function cmd(metadata: interfaces.CommandMetadata = {}) { * @param metadata TabCompleterMetadata */ export function tab(metadata: interfaces.CommandMetadata = {}) { - return function(target: any, key: string, value: any) { + return function (target: any, key: string, value: any) { metadata.name = metadata.name || (key.startsWith('tab') ? key.split('tab', 2)[1] : key); if (!metadata.name) { return; } metadata.executor = key; @@ -54,7 +54,7 @@ export function tab(metadata: interfaces.CommandMetadata = {}) { * @param metadata ListenerMetadata */ export function listener(metadata: interfaces.ListenerMetadata = {}) { - return function(target: any, key: string, value: any) { + return function (target: any, key: string, value: any) { metadata.name = metadata.name || key; metadata.executor = key; const previousMetadata: interfaces.ListenerMetadata[] = getPluginListenerMetadata(target) @@ -63,7 +63,7 @@ export function listener(metadata: interfaces.ListenerMetadata = {}) { } export function config(metadata: interfaces.ConfigMetadata = { version: 1, format: 'yml' }) { - return function(target: any, key: string) { + return function (target: any, key: string) { metadata.name = metadata.name || key; metadata.variable = key; const previousMetadata: Map = getPluginConfigMetadata(target) @@ -71,3 +71,24 @@ export function config(metadata: interfaces.ConfigMetadata = { version: 1, forma Reflect.defineMetadata(METADATA_KEY.config, previousMetadata, target.constructor); } } + +function stage(metadata: interfaces.ExecMetadata = {}, stage: string) { + return function (target: any, key: string, value: any) { + metadata.name = metadata.name || key; + metadata.executor = key; + const previousMetadata: interfaces.ExecMetadata[] = getPluginStageMetadata(target, stage) + Reflect.defineMetadata(METADATA_KEY.stage[stage], [metadata, ...previousMetadata], target.constructor); + }; +} + +export function load(metadata: interfaces.ExecMetadata = {}) { + return stage(metadata, 'load') +} + +export function enable(metadata: interfaces.ExecMetadata = {}) { + return stage(metadata, 'enable') +} + +export function disable(metadata: interfaces.ExecMetadata = {}) { + return stage(metadata, 'disable') +} diff --git a/packages/plugin/src/interfaces.ts b/packages/plugin/src/interfaces.ts index 7eb6ba17..81d20c0b 100644 --- a/packages/plugin/src/interfaces.ts +++ b/packages/plugin/src/interfaces.ts @@ -1,4 +1,4 @@ -import { server, MiaoScriptConsole } from "@ms/api"; +import { server, MiaoScriptConsole, event } from "@ms/api"; import { METADATA_KEY } from './constants' import { injectable, inject, postConstruct } from "@ms/container"; import { getPluginMetadata } from "./utils"; @@ -55,7 +55,7 @@ export namespace interfaces { */ target?: any; } - interface ExecMetadata extends BaseMetadata { + export interface ExecMetadata extends BaseMetadata { /** * 执行器 */ @@ -68,6 +68,15 @@ export namespace interfaces { paramtypes?: string[]; } export interface ListenerMetadata extends ExecMetadata { + /** + * 监听优先级 + */ + priority?: event.EventPriority; + /** + * 是否忽略已取消的事件 + */ + ignoreCancel?: boolean; + } export interface ConfigMetadata extends BaseMetadata { /** diff --git a/packages/plugin/src/manager.ts b/packages/plugin/src/manager.ts index c0de47f2..264c9978 100644 --- a/packages/plugin/src/manager.ts +++ b/packages/plugin/src/manager.ts @@ -1,12 +1,14 @@ import i18n from '@ms/i18n' import { plugin, server, command, event } from '@ms/api' -import { inject, provideSingleton, postConstruct, Container, ContainerInstance } from '@ms/container' +import { inject, provideSingleton, Container, ContainerInstance } from '@ms/container' import * as fs from '@ms/common/dist/fs' -import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPlugin, getPluginTabCompleterMetadata, getPluginConfigMetadata } from './utils' +import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPlugin, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata } from './utils' import { interfaces } from './interfaces' import { getConfigLoader } from './config' +const Thread = Java.type('java.lang.Thread') + @provideSingleton(plugin.PluginManager) export class PluginManagerImpl implements plugin.PluginManager { @inject(ContainerInstance) @@ -22,25 +24,23 @@ export class PluginManagerImpl implements plugin.PluginManager { @inject(event.Event) private EventManager: event.Event + private initialized: boolean = false private pluginMap: Map - @postConstruct() initialize() { - if (this.pluginInstance !== null) { + if (this.pluginInstance !== null && this.initialized !== true) { // 如果plugin不等于null 则代表是正式环境 - console.i18n('ms.plugin.initialize', { plugin: this.pluginInstance }) + console.i18n('ms.plugin.initialize', { plugin: this.pluginInstance, loader: Thread.currentThread().contextClassLoader }) this.pluginMap = new Map() console.i18n('ms.plugin.event.map', { count: this.EventManager.mapEventName().toFixed(0), type: this.serverType }); + this.initialized = true; } } scan(folder: string): void { + this.initialize() var plugin = fs.file(root, folder) - var files = [] - // load common plugin - .concat(this.scanFolder(plugin)) - // load space plugin - .concat(this.scanFolder(fs.file(plugin, this.serverType))) + var files = this.scanFolder(plugin) this.loadPlugins(files) } @@ -58,6 +58,7 @@ export class PluginManagerImpl implements plugin.PluginManager { this.loadConfig(plugin) this.runCatch(plugin, 'load') this.runCatch(plugin, `${this.serverType}load`) + this.execPluginStage(plugin, 'load') }) } @@ -68,6 +69,7 @@ export class PluginManagerImpl implements plugin.PluginManager { this.registryListener(plugin) this.runCatch(plugin, 'enable') this.runCatch(plugin, `${this.serverType}enable`) + this.execPluginStage(plugin, 'enable') }) } @@ -78,6 +80,7 @@ export class PluginManagerImpl implements plugin.PluginManager { this.unregistryListener(plugin) this.runCatch(plugin, 'disable') this.runCatch(plugin, `${this.serverType}disable`) + this.execPluginStage(plugin, 'disable') }) } @@ -162,7 +165,7 @@ export class PluginManagerImpl implements plugin.PluginManager { private allowProcess(servers: string[]) { // Not set servers allow - if (!servers) return true + if (!servers || !servers.length) return true // include !type deny let denyServers = servers.filter(svr => svr.startsWith("!")) if (denyServers.length !== 0) { @@ -260,4 +263,13 @@ export class PluginManagerImpl implements plugin.PluginManager { private unregistryListener(pluginInstance: interfaces.Plugin) { this.EventManager.disable(pluginInstance) } + + private execPluginStage(pluginInstance: interfaces.Plugin, stageName: string) { + let stages = getPluginStageMetadata(pluginInstance, stageName); + for (const stage of stages) { + if (!this.allowProcess(stage.servers)) { continue } + console.i18n("ms.plugin.manager.stage.exec", { plugin: pluginInstance.description.name, name: stage.executor, stage: stageName, servers: stage.servers }) + pluginInstance[stage.executor].apply(pluginInstance) + } + } } diff --git a/packages/plugin/src/utils.ts b/packages/plugin/src/utils.ts index c8daf459..bec360fb 100644 --- a/packages/plugin/src/utils.ts +++ b/packages/plugin/src/utils.ts @@ -57,6 +57,14 @@ function getPluginConfigMetadata(target: any) { return configMetadata; } +function getPluginStageMetadata(target: any, stage: string) { + let stageMetadata: interfaces.ExecMetadata[] = Reflect.getMetadata( + METADATA_KEY.stage[stage], + target.constructor + ) || []; + return stageMetadata; +} + export { getPlugin, getPlugins, @@ -65,5 +73,6 @@ export { getPluginCommandMetadata, getPluginTabCompleterMetadata, getPluginListenerMetadata, - getPluginConfigMetadata + getPluginConfigMetadata, + getPluginStageMetadata }