feat: support stage decorators and remove space plugin floder
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
		@@ -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.scan: "Scanning Plugins in {folder} ..."
 | 
				
			||||||
ms.plugin.manager.initialize.error: "§6Plugin §b{name} §6initialize error §4{ex}"
 | 
					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: "{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.load: "Loading"
 | 
				
			||||||
ms.plugin.manager.stage.enable: "Enabling"
 | 
					ms.plugin.manager.stage.enable: "Enabling"
 | 
				
			||||||
ms.plugin.manager.stage.disable: "Disabling"
 | 
					ms.plugin.manager.stage.disable: "Disabling"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,6 +33,7 @@ ms.plugin.event.map: "总计 {count} 个 {type} 事件 映射完成..."
 | 
				
			|||||||
ms.plugin.manager.scan: "扫描 {folder} 文件夹中插件..."
 | 
					ms.plugin.manager.scan: "扫描 {folder} 文件夹中插件..."
 | 
				
			||||||
ms.plugin.manager.initialize.error: "§6插件 §b{name} §6初始化错误 §4{ex}"
 | 
					ms.plugin.manager.initialize.error: "§6插件 §b{name} §6初始化错误 §4{ex}"
 | 
				
			||||||
ms.plugin.manager.stage: "{stage} {plugin} 版本 {version} 作者 {author}"
 | 
					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.load: "加载"
 | 
				
			||||||
ms.plugin.manager.stage.enable: "启用"
 | 
					ms.plugin.manager.stage.enable: "启用"
 | 
				
			||||||
ms.plugin.manager.stage.disable: "关闭"
 | 
					ms.plugin.manager.stage.disable: "关闭"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,4 +4,9 @@ export const METADATA_KEY = {
 | 
				
			|||||||
    tab: "@ms/plugin:tab",
 | 
					    tab: "@ms/plugin:tab",
 | 
				
			||||||
    listener: "@ms/plugin:listener",
 | 
					    listener: "@ms/plugin:listener",
 | 
				
			||||||
    config: "@ms/plugin:config",
 | 
					    config: "@ms/plugin:config",
 | 
				
			||||||
 | 
					    stage: {
 | 
				
			||||||
 | 
					        load: "@ms/plugin:stage:load",
 | 
				
			||||||
 | 
					        enable: "@ms/plugin:stage:enable",
 | 
				
			||||||
 | 
					        disable: "@ms/plugin:stage:disable"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,14 +1,14 @@
 | 
				
			|||||||
import { injectable, decorate } from "@ms/container";
 | 
					import { injectable, decorate } from "@ms/container";
 | 
				
			||||||
import { interfaces } from './interfaces'
 | 
					import { interfaces } from './interfaces'
 | 
				
			||||||
import { METADATA_KEY } from './constants'
 | 
					import { METADATA_KEY } from './constants'
 | 
				
			||||||
import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPluginTabCompleterMetadata, getPluginConfigMetadata } from './utils'
 | 
					import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata, getPluginTabCompleterMetadata, getPluginConfigMetadata, getPluginStageMetadata } from './utils'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * MiaoScript plugin
 | 
					 * MiaoScript plugin
 | 
				
			||||||
 * @param metadata PluginMetadata
 | 
					 * @param metadata PluginMetadata
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export function plugin(metadata: interfaces.PluginMetadata) {
 | 
					export function plugin(metadata: interfaces.PluginMetadata) {
 | 
				
			||||||
    return function(target: any) {
 | 
					    return function (target: any) {
 | 
				
			||||||
        metadata.target = target;
 | 
					        metadata.target = target;
 | 
				
			||||||
        decorate(injectable(), target);
 | 
					        decorate(injectable(), target);
 | 
				
			||||||
        Reflect.defineMetadata(METADATA_KEY.plugin, metadata, target);
 | 
					        Reflect.defineMetadata(METADATA_KEY.plugin, metadata, target);
 | 
				
			||||||
@@ -23,7 +23,7 @@ export function plugin(metadata: interfaces.PluginMetadata) {
 | 
				
			|||||||
 * @param metadata CommandMetadata
 | 
					 * @param metadata CommandMetadata
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export function cmd(metadata: interfaces.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.name = metadata.name || key;
 | 
				
			||||||
        metadata.executor = key;
 | 
					        metadata.executor = key;
 | 
				
			||||||
        metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key)
 | 
					        metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key)
 | 
				
			||||||
@@ -38,7 +38,7 @@ export function cmd(metadata: interfaces.CommandMetadata = {}) {
 | 
				
			|||||||
 * @param metadata TabCompleterMetadata
 | 
					 * @param metadata TabCompleterMetadata
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export function tab(metadata: interfaces.CommandMetadata = {}) {
 | 
					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);
 | 
					        metadata.name = metadata.name || (key.startsWith('tab') ? key.split('tab', 2)[1] : key);
 | 
				
			||||||
        if (!metadata.name) { return; }
 | 
					        if (!metadata.name) { return; }
 | 
				
			||||||
        metadata.executor = key;
 | 
					        metadata.executor = key;
 | 
				
			||||||
@@ -54,7 +54,7 @@ export function tab(metadata: interfaces.CommandMetadata = {}) {
 | 
				
			|||||||
 * @param metadata ListenerMetadata
 | 
					 * @param metadata ListenerMetadata
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export function listener(metadata: interfaces.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.name = metadata.name || key;
 | 
				
			||||||
        metadata.executor = key;
 | 
					        metadata.executor = key;
 | 
				
			||||||
        const previousMetadata: interfaces.ListenerMetadata[] = getPluginListenerMetadata(target)
 | 
					        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' }) {
 | 
					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.name = metadata.name || key;
 | 
				
			||||||
        metadata.variable = key;
 | 
					        metadata.variable = key;
 | 
				
			||||||
        const previousMetadata: Map<string, interfaces.ConfigMetadata> = getPluginConfigMetadata(target)
 | 
					        const previousMetadata: Map<string, interfaces.ConfigMetadata> = getPluginConfigMetadata(target)
 | 
				
			||||||
@@ -71,3 +71,24 @@ export function config(metadata: interfaces.ConfigMetadata = { version: 1, forma
 | 
				
			|||||||
        Reflect.defineMetadata(METADATA_KEY.config, previousMetadata, target.constructor);
 | 
					        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')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import { server, MiaoScriptConsole } from "@ms/api";
 | 
					import { server, MiaoScriptConsole, event } from "@ms/api";
 | 
				
			||||||
import { METADATA_KEY } from './constants'
 | 
					import { METADATA_KEY } from './constants'
 | 
				
			||||||
import { injectable, inject, postConstruct } from "@ms/container";
 | 
					import { injectable, inject, postConstruct } from "@ms/container";
 | 
				
			||||||
import { getPluginMetadata } from "./utils";
 | 
					import { getPluginMetadata } from "./utils";
 | 
				
			||||||
@@ -55,7 +55,7 @@ export namespace interfaces {
 | 
				
			|||||||
         */
 | 
					         */
 | 
				
			||||||
        target?: any;
 | 
					        target?: any;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    interface ExecMetadata extends BaseMetadata {
 | 
					    export interface ExecMetadata extends BaseMetadata {
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * 执行器
 | 
					         * 执行器
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
@@ -68,6 +68,15 @@ export namespace interfaces {
 | 
				
			|||||||
        paramtypes?: string[];
 | 
					        paramtypes?: string[];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    export interface ListenerMetadata extends ExecMetadata {
 | 
					    export interface ListenerMetadata extends ExecMetadata {
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 监听优先级
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        priority?: event.EventPriority;
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * 是否忽略已取消的事件
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        ignoreCancel?: boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    export interface ConfigMetadata extends BaseMetadata {
 | 
					    export interface ConfigMetadata extends BaseMetadata {
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,14 @@
 | 
				
			|||||||
import i18n from '@ms/i18n'
 | 
					import i18n from '@ms/i18n'
 | 
				
			||||||
import { plugin, server, command, event } from '@ms/api'
 | 
					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 * 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 { interfaces } from './interfaces'
 | 
				
			||||||
import { getConfigLoader } from './config'
 | 
					import { getConfigLoader } from './config'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Thread = Java.type('java.lang.Thread')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@provideSingleton(plugin.PluginManager)
 | 
					@provideSingleton(plugin.PluginManager)
 | 
				
			||||||
export class PluginManagerImpl implements plugin.PluginManager {
 | 
					export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			||||||
    @inject(ContainerInstance)
 | 
					    @inject(ContainerInstance)
 | 
				
			||||||
@@ -22,25 +24,23 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
    @inject(event.Event)
 | 
					    @inject(event.Event)
 | 
				
			||||||
    private EventManager: event.Event
 | 
					    private EventManager: event.Event
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private initialized: boolean = false
 | 
				
			||||||
    private pluginMap: Map<string, interfaces.Plugin>
 | 
					    private pluginMap: Map<string, interfaces.Plugin>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @postConstruct()
 | 
					 | 
				
			||||||
    initialize() {
 | 
					    initialize() {
 | 
				
			||||||
        if (this.pluginInstance !== null) {
 | 
					        if (this.pluginInstance !== null && this.initialized !== true) {
 | 
				
			||||||
            // 如果plugin不等于null 则代表是正式环境
 | 
					            // 如果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()
 | 
					            this.pluginMap = new Map()
 | 
				
			||||||
            console.i18n('ms.plugin.event.map', { count: this.EventManager.mapEventName().toFixed(0), type: this.serverType });
 | 
					            console.i18n('ms.plugin.event.map', { count: this.EventManager.mapEventName().toFixed(0), type: this.serverType });
 | 
				
			||||||
 | 
					            this.initialized = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    scan(folder: string): void {
 | 
					    scan(folder: string): void {
 | 
				
			||||||
 | 
					        this.initialize()
 | 
				
			||||||
        var plugin = fs.file(root, folder)
 | 
					        var plugin = fs.file(root, folder)
 | 
				
			||||||
        var files = []
 | 
					        var files = this.scanFolder(plugin)
 | 
				
			||||||
            // load common plugin
 | 
					 | 
				
			||||||
            .concat(this.scanFolder(plugin))
 | 
					 | 
				
			||||||
            // load space plugin
 | 
					 | 
				
			||||||
            .concat(this.scanFolder(fs.file(plugin, this.serverType)))
 | 
					 | 
				
			||||||
        this.loadPlugins(files)
 | 
					        this.loadPlugins(files)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -58,6 +58,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
            this.loadConfig(plugin)
 | 
					            this.loadConfig(plugin)
 | 
				
			||||||
            this.runCatch(plugin, 'load')
 | 
					            this.runCatch(plugin, 'load')
 | 
				
			||||||
            this.runCatch(plugin, `${this.serverType}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.registryListener(plugin)
 | 
				
			||||||
            this.runCatch(plugin, 'enable')
 | 
					            this.runCatch(plugin, 'enable')
 | 
				
			||||||
            this.runCatch(plugin, `${this.serverType}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.unregistryListener(plugin)
 | 
				
			||||||
            this.runCatch(plugin, 'disable')
 | 
					            this.runCatch(plugin, 'disable')
 | 
				
			||||||
            this.runCatch(plugin, `${this.serverType}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[]) {
 | 
					    private allowProcess(servers: string[]) {
 | 
				
			||||||
        // Not set servers allow
 | 
					        // Not set servers allow
 | 
				
			||||||
        if (!servers) return true
 | 
					        if (!servers || !servers.length) return true
 | 
				
			||||||
        // include !type deny
 | 
					        // include !type deny
 | 
				
			||||||
        let denyServers = servers.filter(svr => svr.startsWith("!"))
 | 
					        let denyServers = servers.filter(svr => svr.startsWith("!"))
 | 
				
			||||||
        if (denyServers.length !== 0) {
 | 
					        if (denyServers.length !== 0) {
 | 
				
			||||||
@@ -260,4 +263,13 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
    private unregistryListener(pluginInstance: interfaces.Plugin) {
 | 
					    private unregistryListener(pluginInstance: interfaces.Plugin) {
 | 
				
			||||||
        this.EventManager.disable(pluginInstance)
 | 
					        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)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,6 +57,14 @@ function getPluginConfigMetadata(target: any) {
 | 
				
			|||||||
    return configMetadata;
 | 
					    return configMetadata;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getPluginStageMetadata(target: any, stage: string) {
 | 
				
			||||||
 | 
					    let stageMetadata: interfaces.ExecMetadata[] = Reflect.getMetadata(
 | 
				
			||||||
 | 
					        METADATA_KEY.stage[stage],
 | 
				
			||||||
 | 
					        target.constructor
 | 
				
			||||||
 | 
					    ) || [];
 | 
				
			||||||
 | 
					    return stageMetadata;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export {
 | 
					export {
 | 
				
			||||||
    getPlugin,
 | 
					    getPlugin,
 | 
				
			||||||
    getPlugins,
 | 
					    getPlugins,
 | 
				
			||||||
@@ -65,5 +73,6 @@ export {
 | 
				
			|||||||
    getPluginCommandMetadata,
 | 
					    getPluginCommandMetadata,
 | 
				
			||||||
    getPluginTabCompleterMetadata,
 | 
					    getPluginTabCompleterMetadata,
 | 
				
			||||||
    getPluginListenerMetadata,
 | 
					    getPluginListenerMetadata,
 | 
				
			||||||
    getPluginConfigMetadata
 | 
					    getPluginConfigMetadata,
 | 
				
			||||||
 | 
					    getPluginStageMetadata
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user