feat: split plugin ext stage exec
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
		@@ -152,21 +152,21 @@ export namespace plugin {
 | 
			
		||||
    }
 | 
			
		||||
    export interface PluginMetadata extends BaseMetadata {
 | 
			
		||||
        /**
 | 
			
		||||
         * 插件名称
 | 
			
		||||
         * 插件名称 不填默认为类名
 | 
			
		||||
         */
 | 
			
		||||
        name: string
 | 
			
		||||
        name?: string
 | 
			
		||||
        /**
 | 
			
		||||
         * 前缀
 | 
			
		||||
         */
 | 
			
		||||
        prefix?: string
 | 
			
		||||
        /**
 | 
			
		||||
         * 插件版本
 | 
			
		||||
         * 插件版本 不填默认为 1.0.0
 | 
			
		||||
         */
 | 
			
		||||
        version: string
 | 
			
		||||
        version?: string
 | 
			
		||||
        /**
 | 
			
		||||
         * 插件版本
 | 
			
		||||
         * 插件作者 不填默认为 Unknow
 | 
			
		||||
         */
 | 
			
		||||
        author: string | string[]
 | 
			
		||||
        author?: string | string[]
 | 
			
		||||
        /**
 | 
			
		||||
         * 插件源文件 必须指定为 __filename
 | 
			
		||||
         */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								packages/plugin/src/command.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								packages/plugin/src/command.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
import { command, plugin, server } from '@ccms/api'
 | 
			
		||||
import { provideSingleton, postConstruct, inject } from '@ccms/container'
 | 
			
		||||
import { getPluginCommandMetadata, getPluginTabCompleterMetadata } from './utils'
 | 
			
		||||
 | 
			
		||||
@provideSingleton(PluginCommandManager)
 | 
			
		||||
export class PluginCommandManager {
 | 
			
		||||
    @inject(server.ServerChecker)
 | 
			
		||||
    private ServerChecker: server.ServerChecker
 | 
			
		||||
    @inject(command.Command)
 | 
			
		||||
    private CommandManager: command.Command
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        process.on('plugin.before.enable', (plugin: plugin.Plugin) => this.registryCommand(plugin))
 | 
			
		||||
        process.on('plugin.after.disable', (plugin: plugin.Plugin) => this.unregistryCommand(plugin))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private registryCommand(pluginInstance: plugin.Plugin) {
 | 
			
		||||
        let cmds = getPluginCommandMetadata(pluginInstance)
 | 
			
		||||
        let tabs = getPluginTabCompleterMetadata(pluginInstance)
 | 
			
		||||
        for (const [_, cmd] of cmds) {
 | 
			
		||||
            let tab = tabs.get(cmd.name)
 | 
			
		||||
            if (!this.ServerChecker.check(cmd.servers)) { continue }
 | 
			
		||||
            this.CommandManager.on(pluginInstance, cmd.name, {
 | 
			
		||||
                cmd: pluginInstance[cmd.executor].bind(pluginInstance),
 | 
			
		||||
                tab: tab ? pluginInstance[tab.executor].bind(pluginInstance) : undefined
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private unregistryCommand(pluginInstance: plugin.Plugin) {
 | 
			
		||||
        let cmds = getPluginCommandMetadata(pluginInstance)
 | 
			
		||||
        cmds.forEach(cmd => {
 | 
			
		||||
            this.CommandManager.off(pluginInstance, cmd.name)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,33 +1,75 @@
 | 
			
		||||
import * as yaml from 'js-yaml'
 | 
			
		||||
import * as fs from '@ccms/common/dist/fs'
 | 
			
		||||
import { plugin } from '@ccms/api'
 | 
			
		||||
import { getPluginConfigMetadata } from './utils'
 | 
			
		||||
 | 
			
		||||
export interface PluginConfigLoader {
 | 
			
		||||
    load(content: string): any;
 | 
			
		||||
    dump(variable: any): string;
 | 
			
		||||
    load(content: string): any
 | 
			
		||||
    dump(variable: any): string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class YamlPluginConfig implements PluginConfigLoader {
 | 
			
		||||
    load(content: string) {
 | 
			
		||||
        return yaml.safeLoad(content);
 | 
			
		||||
        return yaml.safeLoad(content)
 | 
			
		||||
    }
 | 
			
		||||
    dump(variable: any): string {
 | 
			
		||||
        return yaml.safeDump(variable, { skipInvalid: true });
 | 
			
		||||
        return yaml.safeDump(variable, { skipInvalid: true })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class JsonPluginConfig implements PluginConfigLoader {
 | 
			
		||||
    load(content: string) {
 | 
			
		||||
        return JSON.parse(content);
 | 
			
		||||
        return JSON.parse(content)
 | 
			
		||||
    }
 | 
			
		||||
    dump(variable: any): string {
 | 
			
		||||
        return JSON.stringify(variable);
 | 
			
		||||
        return JSON.stringify(variable)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const configLoaderMap = new Map<string, PluginConfigLoader>();
 | 
			
		||||
const configLoaderMap = new Map<string, PluginConfigLoader>()
 | 
			
		||||
 | 
			
		||||
export function getConfigLoader(format: string) {
 | 
			
		||||
    if (!configLoaderMap.has(format)) { throw new Error(`Unsupport config format ${format} !`) }
 | 
			
		||||
    return configLoaderMap.get(format);
 | 
			
		||||
    return configLoaderMap.get(format)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function loadConfig(plugin: plugin.Plugin) {
 | 
			
		||||
    let configs = getPluginConfigMetadata(plugin)
 | 
			
		||||
    for (let [_, config] of configs) {
 | 
			
		||||
        try {
 | 
			
		||||
            let configFile = fs.concat(fs.file(plugin.description.loadMetadata.file).parent, plugin.description.name, config.name + '.' + config.format)
 | 
			
		||||
            let configFactory = getConfigLoader(config.format)
 | 
			
		||||
            if (!fs.exists(configFile)) {
 | 
			
		||||
                base.save(configFile, configFactory.dump(plugin[config.variable]))
 | 
			
		||||
                console.i18n("ms.plugin.manager.config.save.default", { plugin: plugin.description.name, name: config.name, format: config.format })
 | 
			
		||||
            } else {
 | 
			
		||||
                plugin[config.variable] = configFactory.load(base.read(configFile))
 | 
			
		||||
                plugin[config.variable].save = () => {
 | 
			
		||||
                    let result = configFactory.dump(plugin[config.variable])
 | 
			
		||||
                    base.save(configFile, result)
 | 
			
		||||
                    console.debug(`[${plugin.description.name}] Save Config ${config.variable} to file ${configFile} result ${result}`)
 | 
			
		||||
                }
 | 
			
		||||
                console.debug(`[${plugin.description.name}] Load Config ${config.variable} from file ${configFile} result ${JSON.stringify(plugin[config.variable])}`)
 | 
			
		||||
            }
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            console.i18n("ms.plugin.manager.config.load.error", { plugin: plugin.description.name, name: config.name, format: config.format, error })
 | 
			
		||||
            console.ex(error)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function saveConfig(plugin: plugin.Plugin) {
 | 
			
		||||
    let configs = getPluginConfigMetadata(plugin)
 | 
			
		||||
    for (let [_, config] of configs) {
 | 
			
		||||
        try {
 | 
			
		||||
            let configFile = fs.concat(fs.file(plugin.description.loadMetadata.file).parent, plugin.description.name, config.name + '.' + config.format)
 | 
			
		||||
            let configFactory = getConfigLoader(config.format)
 | 
			
		||||
            if (!config.readonly) { base.save(configFile, configFactory.dump(plugin[config.variable])) }
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            console.i18n("ms.plugin.manager.config.save.error", { plugin: plugin.description.name, name: config.name, format: config.format, error })
 | 
			
		||||
            console.ex(error)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function init() {
 | 
			
		||||
@@ -35,6 +77,8 @@ function init() {
 | 
			
		||||
    let yaml = new YamlPluginConfig()
 | 
			
		||||
    configLoaderMap.set("yml", yaml)
 | 
			
		||||
    configLoaderMap.set("yaml", yaml)
 | 
			
		||||
    process.on('plugin.before.load', loadConfig)
 | 
			
		||||
    process.on('plugin.after.load', saveConfig)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
init()
 | 
			
		||||
 
 | 
			
		||||
@@ -8,10 +8,10 @@ import { getPluginMetadatas, getPluginCommandMetadata, getPluginListenerMetadata
 | 
			
		||||
 * MiaoScript plugin
 | 
			
		||||
 * @param metadata PluginMetadata
 | 
			
		||||
 */
 | 
			
		||||
export function plugin(metadata: pluginApi.PluginMetadata) {
 | 
			
		||||
export function plugin(metadata: pluginApi.PluginMetadata | any) {
 | 
			
		||||
    return function (target: any) {
 | 
			
		||||
        metadata.target = target
 | 
			
		||||
        metadata.type = "ioc"
 | 
			
		||||
        if (!metadata.source) metadata = { souece: metadata }
 | 
			
		||||
        metadata = { name: target.name, version: '1.0.0', author: 'Unknow', target, type: 'ioc', ...metadata }
 | 
			
		||||
        decorate(injectable(), target)
 | 
			
		||||
        Reflect.defineMetadata(METADATA_KEY.plugin, metadata, target)
 | 
			
		||||
        const previousMetadata: Map<string, pluginApi.PluginMetadata> = getPluginMetadatas()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								packages/plugin/src/event.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								packages/plugin/src/event.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
import { event, plugin, server } from '@ccms/api'
 | 
			
		||||
import { provideSingleton, postConstruct, inject } from '@ccms/container'
 | 
			
		||||
import { getPluginListenerMetadata } from './utils'
 | 
			
		||||
 | 
			
		||||
@provideSingleton(PluginEventManager)
 | 
			
		||||
export class PluginEventManager {
 | 
			
		||||
    @inject(server.ServerChecker)
 | 
			
		||||
    private ServerChecker: server.ServerChecker
 | 
			
		||||
    @inject(event.Event)
 | 
			
		||||
    private EventManager: event.Event
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        process.on('plugin.before.enable', (plugin: plugin.Plugin) => this.registryListener(plugin))
 | 
			
		||||
        process.on('plugin.after.disable', (plugin: plugin.Plugin) => this.unregistryListener(plugin))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private registryListener(pluginInstance: plugin.Plugin) {
 | 
			
		||||
        let events = getPluginListenerMetadata(pluginInstance)
 | 
			
		||||
        for (const event of events) {
 | 
			
		||||
            // ignore space listener
 | 
			
		||||
            if (!this.ServerChecker.check(event.servers)) { continue }
 | 
			
		||||
            // here must bind this to pluginInstance
 | 
			
		||||
            this.EventManager.listen(pluginInstance, event.name, pluginInstance[event.executor].bind(pluginInstance))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private unregistryListener(pluginInstance: plugin.Plugin) {
 | 
			
		||||
        this.EventManager.disable(pluginInstance)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
import i18n from '@ccms/i18n'
 | 
			
		||||
import { plugin, server, command, event } from '@ccms/api'
 | 
			
		||||
import { plugin, server, event } from '@ccms/api'
 | 
			
		||||
import { inject, provideSingleton, Container, ContainerInstance } from '@ccms/container'
 | 
			
		||||
import * as fs from '@ccms/common/dist/fs'
 | 
			
		||||
 | 
			
		||||
import './config'
 | 
			
		||||
import { interfaces } from './interfaces'
 | 
			
		||||
import { getConfigLoader } from './config'
 | 
			
		||||
import { getPluginCommandMetadata, getPluginListenerMetadata, getPluginTabCompleterMetadata, getPluginConfigMetadata } from './utils'
 | 
			
		||||
import { PluginCommandManager } from './command'
 | 
			
		||||
import { PluginEventManager } from './event'
 | 
			
		||||
 | 
			
		||||
const Thread = Java.type('java.lang.Thread')
 | 
			
		||||
 | 
			
		||||
@@ -15,15 +15,16 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
    private container: Container
 | 
			
		||||
    @inject(plugin.PluginInstance)
 | 
			
		||||
    private pluginInstance: any
 | 
			
		||||
    @inject(plugin.PluginFolder)
 | 
			
		||||
    private pluginFolder: string
 | 
			
		||||
    @inject(server.ServerType)
 | 
			
		||||
    private serverType: string
 | 
			
		||||
    @inject(command.Command)
 | 
			
		||||
    private CommandManager: command.Command
 | 
			
		||||
    @inject(event.Event)
 | 
			
		||||
    private EventManager: event.Event
 | 
			
		||||
 | 
			
		||||
    @inject(PluginCommandManager)
 | 
			
		||||
    private commandManager: PluginCommandManager
 | 
			
		||||
    @inject(PluginEventManager)
 | 
			
		||||
    private eventManager: PluginEventManager
 | 
			
		||||
 | 
			
		||||
    private initialized: boolean = false
 | 
			
		||||
 | 
			
		||||
    private sacnnerMap: Map<string, plugin.PluginScanner>
 | 
			
		||||
@@ -38,6 +39,10 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
 | 
			
		||||
        this.instanceMap = new Map()
 | 
			
		||||
        this.metadataMap = new Map()
 | 
			
		||||
 | 
			
		||||
        // ignore unused
 | 
			
		||||
        this.commandManager
 | 
			
		||||
        this.eventManager
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    initialize() {
 | 
			
		||||
@@ -90,14 +95,15 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
        console.i18n("ms.plugin.manager.stage", { stage, plugin: plugin.description.name, version: plugin.description.version, author: plugin.description.author })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private runPluginStage(plugin: plugin.Plugin, stage: string, ext: Function) {
 | 
			
		||||
    private runPluginStage(plugin: plugin.Plugin, stage: string) {
 | 
			
		||||
        if (!plugin) { throw new Error(`can't run runPluginStage ${stage} because plugin is ${plugin}`) }
 | 
			
		||||
        try {
 | 
			
		||||
            this.logStage(plugin, i18n.translate(`ms.plugin.manager.stage.${stage}`))
 | 
			
		||||
            ext()
 | 
			
		||||
            process.emit(`plugin.before.${stage}`, plugin)
 | 
			
		||||
            this.runCatch(plugin, stage)
 | 
			
		||||
            this.runCatch(plugin, `${this.serverType}${stage}`)
 | 
			
		||||
            plugin.description.loadMetadata.loader[stage](plugin)
 | 
			
		||||
            process.emit(`plugin.after.${stage}`, plugin)
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
            console.i18n("ms.plugin.manager.stage.exec.error", { plugin: plugin.description.name, executor: stage, error: ex })
 | 
			
		||||
        }
 | 
			
		||||
@@ -108,14 +114,24 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
        if (loadMetadata.loaded) { throw new Error(`Plugin ${loadMetadata.name} is already loaded by ${loadMetadata.loader?.type}!`) }
 | 
			
		||||
        try {
 | 
			
		||||
            for (const [, loader] of this.loaderMap) {
 | 
			
		||||
                if (this.loaderRequirePlugin(loadMetadata, loader)?.loaded) return loadMetadata.metadata
 | 
			
		||||
            }
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            console.i18n("ms.plugin.manager.initialize.error", { name: loadMetadata.file, ex: error })
 | 
			
		||||
            console.ex(error)
 | 
			
		||||
        }
 | 
			
		||||
        console.console(`§6scanner: §b${loadMetadata.scanner.type} §ccan\'t load §6file §b${loadMetadata.file}. §eskip!`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private loaderRequirePlugin(loadMetadata: plugin.PluginLoadMetadata, loader: plugin.PluginLoader) {
 | 
			
		||||
        try {
 | 
			
		||||
            if (loader.require(loadMetadata).loaded) {
 | 
			
		||||
                loadMetadata.loader = loader
 | 
			
		||||
                let metadata = loadMetadata.metadata
 | 
			
		||||
                this.metadataMap.set(metadata.name, metadata)
 | 
			
		||||
                metadata.loadMetadata = loadMetadata
 | 
			
		||||
                        return metadata
 | 
			
		||||
            }
 | 
			
		||||
            return loadMetadata
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            if (global.debug) {
 | 
			
		||||
                console.console(`§6Loader §b${loader.type} §6load §a${loadMetadata.file} §cerror. §4Err: §c${error}`)
 | 
			
		||||
@@ -125,12 +141,6 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            console.i18n("ms.plugin.manager.initialize.error", { name: loadMetadata.file, ex: error })
 | 
			
		||||
            console.ex(error)
 | 
			
		||||
        }
 | 
			
		||||
        console.console(`§6scanner: §b${loadMetadata.scanner.type} §ccan\'t load §6file §b${loadMetadata.file}. §eskip!`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 从文件加载插件
 | 
			
		||||
@@ -147,36 +157,21 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    load(...args: any[]): void {
 | 
			
		||||
        this.checkAndGet(args[0]).forEach((plugin: plugin.Plugin) => {
 | 
			
		||||
            this.runPluginStage(plugin, 'load', () => {
 | 
			
		||||
                this.loadConfig(plugin)
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
        this.checkAndGet(args[0]).forEach((plugin: plugin.Plugin) => this.runPluginStage(plugin, 'load'))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable(...args: any[]): void {
 | 
			
		||||
        this.checkAndGet(args[0]).forEach((plugin: plugin.Plugin) => {
 | 
			
		||||
            this.runPluginStage(plugin, 'enable', () => {
 | 
			
		||||
                this.registryCommand(plugin)
 | 
			
		||||
                this.registryListener(plugin)
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
        this.checkAndGet(args[0]).forEach((plugin: plugin.Plugin) => this.runPluginStage(plugin, 'enable'))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    disable(...args: any[]): void {
 | 
			
		||||
        this.checkAndGet(args[0]).forEach((plugin: plugin.Plugin) => {
 | 
			
		||||
            this.runPluginStage(plugin, 'disable', () => {
 | 
			
		||||
                this.saveConfig(plugin)
 | 
			
		||||
                this.unregistryCommand(plugin)
 | 
			
		||||
                this.unregistryListener(plugin)
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
        this.checkAndGet(args[0]).forEach((plugin: plugin.Plugin) => this.runPluginStage(plugin, 'disable'))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    reload(...args: any[]): void {
 | 
			
		||||
        this.checkAndGet(args[0]).forEach((pl: plugin.Plugin) => {
 | 
			
		||||
            this.disable(pl)
 | 
			
		||||
            this.loadFromFile(pl.description.source.toString(), pl.description.loadMetadata.scanner)
 | 
			
		||||
            this.loadFromFile(pl.description.loadMetadata.file, pl.description.loadMetadata.scanner)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -206,19 +201,6 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
        throw new Error(`Plugin ${JSON.stringify(name)} not exist!`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private allowProcess(servers: string[]) {
 | 
			
		||||
        // Not set servers -> allow
 | 
			
		||||
        if (!servers || !servers.length) return true
 | 
			
		||||
        // include !type -> deny
 | 
			
		||||
        let denyServers = servers.filter(svr => svr.startsWith("!"))
 | 
			
		||||
        if (denyServers.length !== 0) {
 | 
			
		||||
            return !denyServers.includes(`!${this.serverType}`)
 | 
			
		||||
        } else {
 | 
			
		||||
            // only include -> allow
 | 
			
		||||
            return servers.includes(this.serverType)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private buildPlugins() {
 | 
			
		||||
        for (const [, metadata] of this.metadataMap) {
 | 
			
		||||
            let pluginInstance: plugin.Plugin
 | 
			
		||||
@@ -231,77 +213,4 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
            this.instanceMap.set(metadata.name, pluginInstance)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private loadConfig(plugin: plugin.Plugin) {
 | 
			
		||||
        let configs = getPluginConfigMetadata(plugin)
 | 
			
		||||
        for (let [_, config] of configs) {
 | 
			
		||||
            try {
 | 
			
		||||
                let configFile = fs.concat(root, this.pluginFolder, plugin.description.name, config.name + '.' + config.format)
 | 
			
		||||
                let configFactory = getConfigLoader(config.format)
 | 
			
		||||
                if (!fs.exists(configFile)) {
 | 
			
		||||
                    base.save(configFile, configFactory.dump(plugin[config.variable]))
 | 
			
		||||
                    console.i18n("ms.plugin.manager.config.save.default", { plugin: plugin.description.name, name: config.name, format: config.format })
 | 
			
		||||
                } else {
 | 
			
		||||
                    plugin[config.variable] = configFactory.load(base.read(configFile))
 | 
			
		||||
                    plugin[config.variable].save = () => {
 | 
			
		||||
                        let result = configFactory.dump(plugin[config.variable])
 | 
			
		||||
                        base.save(configFile, result)
 | 
			
		||||
                        console.debug(`[${plugin.description.name}] Save Config ${config.variable} to file ${configFile} result ${result}`)
 | 
			
		||||
                    }
 | 
			
		||||
                    console.debug(`[${plugin.description.name}] Load Config ${config.variable} from file ${configFile} result ${JSON.stringify(plugin[config.variable])}`)
 | 
			
		||||
                }
 | 
			
		||||
            } catch (error) {
 | 
			
		||||
                console.i18n("ms.plugin.manager.config.load.error", { plugin: plugin.description.name, name: config.name, format: config.format, error })
 | 
			
		||||
                console.ex(error)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private saveConfig(plugin: plugin.Plugin) {
 | 
			
		||||
        let configs = getPluginConfigMetadata(plugin)
 | 
			
		||||
        for (let [_, config] of configs) {
 | 
			
		||||
            try {
 | 
			
		||||
                let configFile = fs.concat(root, this.pluginFolder, plugin.description.name, config.name + '.' + config.format)
 | 
			
		||||
                let configFactory = getConfigLoader(config.format)
 | 
			
		||||
                if (!config.readonly) { base.save(configFile, configFactory.dump(plugin[config.variable])) }
 | 
			
		||||
            } catch (error) {
 | 
			
		||||
                console.i18n("ms.plugin.manager.config.save.error", { plugin: plugin.description.name, name: config.name, format: config.format, error })
 | 
			
		||||
                console.ex(error)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private registryCommand(pluginInstance: plugin.Plugin) {
 | 
			
		||||
        let cmds = getPluginCommandMetadata(pluginInstance)
 | 
			
		||||
        let tabs = getPluginTabCompleterMetadata(pluginInstance)
 | 
			
		||||
        for (const [_, cmd] of cmds) {
 | 
			
		||||
            let tab = tabs.get(cmd.name)
 | 
			
		||||
            if (!this.allowProcess(cmd.servers)) { continue }
 | 
			
		||||
            this.CommandManager.on(pluginInstance, cmd.name, {
 | 
			
		||||
                cmd: pluginInstance[cmd.executor].bind(pluginInstance),
 | 
			
		||||
                tab: tab ? pluginInstance[tab.executor].bind(pluginInstance) : undefined
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private registryListener(pluginInstance: plugin.Plugin) {
 | 
			
		||||
        let events = getPluginListenerMetadata(pluginInstance)
 | 
			
		||||
        for (const event of events) {
 | 
			
		||||
            // ignore space listener
 | 
			
		||||
            if (!this.allowProcess(event.servers)) { continue }
 | 
			
		||||
            // here must bind this to pluginInstance
 | 
			
		||||
            this.EventManager.listen(pluginInstance, event.name, pluginInstance[event.executor].bind(pluginInstance))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private unregistryCommand(pluginInstance: plugin.Plugin) {
 | 
			
		||||
        let cmds = getPluginCommandMetadata(pluginInstance)
 | 
			
		||||
        cmds.forEach(cmd => {
 | 
			
		||||
            this.CommandManager.off(pluginInstance, cmd.name)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private unregistryListener(pluginInstance: plugin.Plugin) {
 | 
			
		||||
        this.EventManager.disable(pluginInstance)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user