@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					src
 | 
				
			||||||
test
 | 
					test
 | 
				
			||||||
typings
 | 
					typings
 | 
				
			||||||
bundled
 | 
					bundled
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -133,7 +133,12 @@ export namespace event {
 | 
				
			|||||||
            // @ts-ignore
 | 
					            // @ts-ignore
 | 
				
			||||||
            let executor = exec.name || exec.executor || '[anonymous]'
 | 
					            let executor = exec.name || exec.executor || '[anonymous]'
 | 
				
			||||||
            // noinspection JSUnusedGlobalSymbols
 | 
					            // noinspection JSUnusedGlobalSymbols
 | 
				
			||||||
            var listener = this.register(eventCls, this.execute(name, exec, eventCls), priority, ignoreCancel)
 | 
					            var listener = this.register(
 | 
				
			||||||
 | 
					                eventCls,
 | 
				
			||||||
 | 
					                this.execute(name, exec, eventCls),
 | 
				
			||||||
 | 
					                priority,
 | 
				
			||||||
 | 
					                ignoreCancel
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
            var listenerMap = this.listenerMap
 | 
					            var listenerMap = this.listenerMap
 | 
				
			||||||
            // add to cache Be used for close plugin to close event
 | 
					            // add to cache Be used for close plugin to close event
 | 
				
			||||||
            if (!listenerMap[name]) listenerMap[name] = []
 | 
					            if (!listenerMap[name]) listenerMap[name] = []
 | 
				
			||||||
@@ -141,11 +146,21 @@ export namespace event {
 | 
				
			|||||||
                if (off['offed']) return
 | 
					                if (off['offed']) return
 | 
				
			||||||
                off['offed'] = true
 | 
					                off['offed'] = true
 | 
				
			||||||
                this.unregister(eventCls, listener)
 | 
					                this.unregister(eventCls, listener)
 | 
				
			||||||
                console.debug(i18n.translate("ms.api.event.unregister", { name, event: this.class2Name(eventCls), exec: executor }))
 | 
					                console.debug(i18n.translate("ms.api.event.unregister", {
 | 
				
			||||||
 | 
					                    name,
 | 
				
			||||||
 | 
					                    event: this.class2Name(eventCls),
 | 
				
			||||||
 | 
					                    exec: executor
 | 
				
			||||||
 | 
					                }))
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            listenerMap[name].push(off)
 | 
					            listenerMap[name].push(off)
 | 
				
			||||||
            // noinspection JSUnresolvedVariable
 | 
					            // noinspection JSUnresolvedVariable
 | 
				
			||||||
            console.debug(i18n.translate("ms.api.event.register", { name, event: this.class2Name(eventCls), exec: executor }))
 | 
					            console.debug(i18n.translate("ms.api.event.register", {
 | 
				
			||||||
 | 
					                name,
 | 
				
			||||||
 | 
					                event: this.class2Name(eventCls),
 | 
				
			||||||
 | 
					                exec: executor,
 | 
				
			||||||
 | 
					                priority,
 | 
				
			||||||
 | 
					                ignore: ignoreCancel
 | 
				
			||||||
 | 
					            }))
 | 
				
			||||||
            return off
 | 
					            return off
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +0,0 @@
 | 
				
			|||||||
function exit() {
 | 
					 | 
				
			||||||
    var http = require('@ccms/common/dist/http').default
 | 
					 | 
				
			||||||
    function upgradeModules(core) {
 | 
					 | 
				
			||||||
        if (base.version && global.ScriptEngineVersion != core['dist-tags']['latest']) {
 | 
					 | 
				
			||||||
            var Paths = Java.type('java.nio.file.Paths')
 | 
					 | 
				
			||||||
            base.save(Paths.get(root, "upgrade"), core['dist-tags']['latest'])
 | 
					 | 
				
			||||||
            console.info('@ccms/core found new version ' + core['dist-tags']['latest'] + ' will upgrade after reboot!')
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    upgradeModules(http.get('https://registry.npmmirror.com/@ccms/core'))
 | 
					 | 
				
			||||||
    console.debug('exit finish!')
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
exit()
 | 
					 | 
				
			||||||
@@ -50,14 +50,7 @@ class MiaoScriptCore {
 | 
				
			|||||||
        this.pluginManager.disable(this.pluginManager.getPlugins())
 | 
					        this.pluginManager.disable(this.pluginManager.getPlugins())
 | 
				
			||||||
        this.taskManager.disable()
 | 
					        this.taskManager.disable()
 | 
				
			||||||
        process.emit('core.after.disable')
 | 
					        process.emit('core.after.disable')
 | 
				
			||||||
        try {
 | 
					        loadCoreScript('exit')
 | 
				
			||||||
            engineLoad({
 | 
					 | 
				
			||||||
                script: http.get("https://ms.yumc.pw/api/plugin/download/name/exit"),
 | 
					 | 
				
			||||||
                name: 'core/exit.js'
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        } catch (error: any) {
 | 
					 | 
				
			||||||
            console.debug(error)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        process.emit('core.before.exit')
 | 
					        process.emit('core.before.exit')
 | 
				
			||||||
        process.exit(0)
 | 
					        process.exit(0)
 | 
				
			||||||
        console.i18n("ms.core.engine.disable.finish", {
 | 
					        console.i18n("ms.core.engine.disable.finish", {
 | 
				
			||||||
@@ -98,18 +91,27 @@ function detectServer(): constants.ServerType {
 | 
				
			|||||||
    throw Error('Unknow Server Type...')
 | 
					    throw Error('Unknow Server Type...')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function initialize() {
 | 
					function loadCoreScript(name) {
 | 
				
			||||||
    process.emit('core.before.initialize')
 | 
					 | 
				
			||||||
    global.ScriptSlowExecuteTime = 30
 | 
					 | 
				
			||||||
    global.ScriptEngineVersion = require('../package.json').version
 | 
					 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
 | 
					        let scriptname = name + (global.debug ? '-debug' : '')
 | 
				
			||||||
        engineLoad({
 | 
					        engineLoad({
 | 
				
			||||||
            script: http.get("https://ms.yumc.pw/api/plugin/download/name/initialize"),
 | 
					            script: http.get(`https://ms.yumc.pw/api/plugin/download/name/${scriptname}`),
 | 
				
			||||||
            name: 'core/initialize.js'
 | 
					            name: `core/${scriptname}.js`
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    } catch (error: any) {
 | 
					    } catch (error: any) {
 | 
				
			||||||
 | 
					        if (global.debug) {
 | 
				
			||||||
            console.debug(error)
 | 
					            console.debug(error)
 | 
				
			||||||
 | 
					            console.ex(error)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function initialize() {
 | 
				
			||||||
 | 
					    process.emit('core.before.initialize')
 | 
				
			||||||
 | 
					    global.ScriptSlowExecuteTime = 50
 | 
				
			||||||
 | 
					    global.ScriptEngineVersion = require('../package.json').version
 | 
				
			||||||
 | 
					    global.setGlobal('loadCoreScript', loadCoreScript)
 | 
				
			||||||
 | 
					    loadCoreScript('initialize')
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
        let corePackageStartTime = new Date().getTime()
 | 
					        let corePackageStartTime = new Date().getTime()
 | 
				
			||||||
        container.bind(ContainerInstance).toConstantValue(container)
 | 
					        container.bind(ContainerInstance).toConstantValue(container)
 | 
				
			||||||
@@ -141,8 +143,12 @@ function initialize() {
 | 
				
			|||||||
        process.emit('core.after.initialize')
 | 
					        process.emit('core.after.initialize')
 | 
				
			||||||
        return disable
 | 
					        return disable
 | 
				
			||||||
    } catch (error: any) {
 | 
					    } catch (error: any) {
 | 
				
			||||||
 | 
					        if (console.console) {
 | 
				
			||||||
            console.i18n("ms.core.initialize.error", { error })
 | 
					            console.i18n("ms.core.initialize.error", { error })
 | 
				
			||||||
            console.ex(error)
 | 
					            console.ex(error)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            error.printStackTrace()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        return () => console.i18n('ms.core.engine.disable.abnormal')
 | 
					        return () => console.i18n('ms.core.engine.disable.abnormal')
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,68 +0,0 @@
 | 
				
			|||||||
global.initialize = function () {
 | 
					 | 
				
			||||||
    var mspmc = 'https://ms.yumc.pw/api/plugin/download/name/'
 | 
					 | 
				
			||||||
    var artifact = 'https://ci.yumc.pw/job/Minecraft/job/MiaoScript/lastSuccessfulBuild/artifact'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    var fs = require('@ccms/common/dist/fs')
 | 
					 | 
				
			||||||
    var http = require('@ccms/common/dist/http').default
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function updateJar() {
 | 
					 | 
				
			||||||
        var DocumentBuilderFactory = Java.type('javax.xml.parsers.DocumentBuilderFactory')
 | 
					 | 
				
			||||||
        var URLDecoder = Java.type('java.net.URLDecoder')
 | 
					 | 
				
			||||||
        var pom = DocumentBuilderFactory.newInstance().newDocumentBuilder()
 | 
					 | 
				
			||||||
            .parse(artifact + "/pom.xml")
 | 
					 | 
				
			||||||
        var latestVersion = pom.getElementsByTagName("version").item(0).getTextContent()
 | 
					 | 
				
			||||||
        if (base.version != latestVersion) {
 | 
					 | 
				
			||||||
            var pluginFolder = fs.file(fs.concat(root, '..'))
 | 
					 | 
				
			||||||
            var updateFolder = fs.concat(pluginFolder, 'update')
 | 
					 | 
				
			||||||
            fs.mkdirs(updateFolder)
 | 
					 | 
				
			||||||
            var filePath = base.getInstance().class.classLoader.getURLs()[0]
 | 
					 | 
				
			||||||
            var pluginFile = fs.file(URLDecoder.decode(filePath.getFile(), "UTF-8"))
 | 
					 | 
				
			||||||
            var updateFile = fs.file(updateFolder, pluginFile.getName())
 | 
					 | 
				
			||||||
            http.download(artifact + "/target/MiaoScript.jar", updateFile.getAbsolutePath())
 | 
					 | 
				
			||||||
            console.info('MiaoScript found new version ' + latestVersion + ' will upgrade after reboot!')
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    function upgradeModules(core) {
 | 
					 | 
				
			||||||
        if (base.version && global.ScriptEngineVersion != core['dist-tags']['latest']) {
 | 
					 | 
				
			||||||
            var Paths = Java.type('java.nio.file.Paths')
 | 
					 | 
				
			||||||
            base.save(Paths.get(root, "upgrade"), core['dist-tags']['latest'])
 | 
					 | 
				
			||||||
            console.info('@ccms/core found new version ' + core['dist-tags']['latest'] + ' will upgrade after reboot!')
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    var pluginFolder = fs.concat(root, 'plugins')
 | 
					 | 
				
			||||||
    var updateFolder = fs.concat(pluginFolder, 'update')
 | 
					 | 
				
			||||||
    var pluginFile = fs.concat(pluginFolder, 'MiaoScriptPackageManager.js')
 | 
					 | 
				
			||||||
    if (!fs.exists(pluginFile)) {
 | 
					 | 
				
			||||||
        fs.mkdirs(pluginFile)
 | 
					 | 
				
			||||||
        base.save(fs.concat(updateFolder, 'MiaoScriptPackageManager.auto.install'), '.')
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    fs.list(updateFolder).forEach(function (path) {
 | 
					 | 
				
			||||||
        var file = path.toFile()
 | 
					 | 
				
			||||||
        if (file.exists()) {
 | 
					 | 
				
			||||||
            var filename = file.getName()
 | 
					 | 
				
			||||||
            if (filename.endsWith(".auto.install")) {
 | 
					 | 
				
			||||||
                var pluginName = filename.replace('.auto.install', '')
 | 
					 | 
				
			||||||
                var pluginFile = fs.concat(pluginFolder, pluginName + '.js')
 | 
					 | 
				
			||||||
                if (!fs.exists(pluginFile)) {
 | 
					 | 
				
			||||||
                    var pluginTemp = pluginFile + '.tmp'
 | 
					 | 
				
			||||||
                    http.download(mspmc + pluginName, pluginTemp)
 | 
					 | 
				
			||||||
                    fs.move(pluginTemp, pluginFile, true)
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                base.delete(file)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
        Java.type("org.bukkit.Bukkit")
 | 
					 | 
				
			||||||
        updateJar()
 | 
					 | 
				
			||||||
    } catch (error) {
 | 
					 | 
				
			||||||
        console.debug(error)
 | 
					 | 
				
			||||||
        if (global.debug) {
 | 
					 | 
				
			||||||
            console.ex(error)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    upgradeModules(http.get('https://registry.npmmirror.com/@ccms/core'))
 | 
					 | 
				
			||||||
    console.debug('initialize finish!')
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
global.initialize()
 | 
					 | 
				
			||||||
delete global.initialize
 | 
					 | 
				
			||||||
@@ -12,6 +12,7 @@ ms.core.plugin.initialize: "Initialization MiaoScript Plugin System. Please wait
 | 
				
			|||||||
ms.core.plugin.completed: "MiaoScript Plugin System loading completed({time}s)!"
 | 
					ms.core.plugin.completed: "MiaoScript Plugin System loading completed({time}s)!"
 | 
				
			||||||
ms.core.engine.completed: "MiaoScript ScriptEngine loading completed... Done({time}s)!"
 | 
					ms.core.engine.completed: "MiaoScript ScriptEngine loading completed... Done({time}s)!"
 | 
				
			||||||
ms.core.engine.disable: "Disable MiaoScript Engine..."
 | 
					ms.core.engine.disable: "Disable MiaoScript Engine..."
 | 
				
			||||||
 | 
					ms.core.engine.disable.finish: "MiaoScript framework {loader} engine {version} 关闭完成... 耗时({time}s)!"
 | 
				
			||||||
ms.core.engine.disable.abnormal: "abnormal Initialization MiaoScript Engine. Skip disable step..."
 | 
					ms.core.engine.disable.abnormal: "abnormal Initialization MiaoScript Engine. Skip disable step..."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ms.api.event.resource.not.found: "Can't Mapping Event Because not found Resources {resource}!"
 | 
					ms.api.event.resource.not.found: "Can't Mapping Event Because not found Resources {resource}!"
 | 
				
			||||||
@@ -21,16 +22,20 @@ ms.api.event.not.found: "§6Plugin §b{name} §6register {event} error. event no
 | 
				
			|||||||
ms.api.event.execute.slow: "§cWARN! §6Plugin §b{name} §6execute §d{event} §6evnet §ccost §4{cost}ms !"
 | 
					ms.api.event.execute.slow: "§cWARN! §6Plugin §b{name} §6execute §d{event} §6evnet §ccost §4{cost}ms !"
 | 
				
			||||||
ms.api.event.execute.error: "§6Plugin §b{name} §6execute §d{event} §6event error §4{ex}"
 | 
					ms.api.event.execute.error: "§6Plugin §b{name} §6execute §d{event} §6event error §4{ex}"
 | 
				
			||||||
ms.api.event.listen.plugin.name.empty: "Plugin name can't be empty!"
 | 
					ms.api.event.listen.plugin.name.empty: "Plugin name can't be empty!"
 | 
				
			||||||
ms.api.event.register: "[{name}] register event {event}"
 | 
					ms.api.event.register: "[{name}] register event {event} priority {priority} ignoreCancelled {ignore}"
 | 
				
			||||||
ms.api.event.unregister: "[{name}] unregister event {event}"
 | 
					ms.api.event.unregister: "[{name}] unregister event {event}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ms.api.command.register.input.error: "CommandExec Must be a function... Input: {exec}"
 | 
					ms.api.command.register.input.error: "CommandExec Must be a function... Input: {exec}"
 | 
				
			||||||
ms.api.command.register: "[{plugin}] register command {name}({cmd})..."
 | 
					ms.api.command.register: "[{plugin}] register command {name}({cmd})..."
 | 
				
			||||||
ms.api.command.unregister: "[{plugin}] unregister command {name}..."
 | 
					ms.api.command.unregister: "[{plugin}] unregister command {name}..."
 | 
				
			||||||
 | 
					ms.api.command.execute.slow: "§cWarn. §6Player §a{player} §6exec §b{plugin} §6Plugin §d{command} {args} §6Command §cCost §4{cost}ms !"
 | 
				
			||||||
ms.api.command.execute.error: "§6Player {player} §6exec §b{plugin} §6Plugin Command §d{command} {args} §6error §4{ex}"
 | 
					ms.api.command.execute.error: "§6Player {player} §6exec §b{plugin} §6Plugin Command §d{command} {args} §6error §4{ex}"
 | 
				
			||||||
 | 
					ms.api.command.tab.completer.slow: "§cWarn. §6Player §a{player} §6exec §b{plugin} §6Plugin §d{command} {args} §6TabComplete §cCost §4{cost}ms !"
 | 
				
			||||||
ms.api.command.tab.completer.error: "§6Player {player} §6exec §b{plugin} §6Plugin TabComplete §d{command} {args} §6error §4{ex}"
 | 
					ms.api.command.tab.completer.error: "§6Player {player} §6exec §b{plugin} §6Plugin TabComplete §d{command} {args} §6error §4{ex}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ms.plugin.initialize: "Initialization MiaoScript Plugin System: Plugin: {plugin} Loader: {loader}..."
 | 
					ms.plugin.initialize: "Initialization MiaoScript Plugin System: Plugin: {plugin} Loader: {loader}..."
 | 
				
			||||||
ms.plugin.event.map: "Total {count} {type} Event Mapping Complate..."
 | 
					ms.plugin.event.map: "Total {count} {type} Event Mapping Complate..."
 | 
				
			||||||
 | 
					ms.plugin.event.map.error: "Mapping {type} Event Failed. Error: {error}"
 | 
				
			||||||
ms.plugin.manager.scan: "Scanner {scanner} Scanning Plugins in {folder} ..."
 | 
					ms.plugin.manager.scan: "Scanner {scanner} Scanning Plugins in {folder} ..."
 | 
				
			||||||
ms.plugin.manager.scan.finish: "Scanner {scanner} Found {size} Plugins in {folder} Start Build..."
 | 
					ms.plugin.manager.scan.finish: "Scanner {scanner} Found {size} Plugins in {folder} Start Build..."
 | 
				
			||||||
ms.plugin.manager.initialize.error: "§6Plugin §b{name} §6initialize error §4{ex}"
 | 
					ms.plugin.manager.initialize.error: "§6Plugin §b{name} §6initialize error §4{ex}"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,8 +22,9 @@ ms.api.event.not.found: "§6插件 §b{name} §6注册事件 §c{event} §6失
 | 
				
			|||||||
ms.api.event.execute.slow: "§c注意! §6插件 §b{name} §6处理 §d{event} §6事件 §c耗时 §4{cost}ms !"
 | 
					ms.api.event.execute.slow: "§c注意! §6插件 §b{name} §6处理 §d{event} §6事件 §c耗时 §4{cost}ms !"
 | 
				
			||||||
ms.api.event.execute.error: "§6插件 §b{name} §6处理 §d{event} §6事件时发生异常 §4{ex}"
 | 
					ms.api.event.execute.error: "§6插件 §b{name} §6处理 §d{event} §6事件时发生异常 §4{ex}"
 | 
				
			||||||
ms.api.event.listen.plugin.name.empty: "插件名称为空 请检查传入参数!"
 | 
					ms.api.event.listen.plugin.name.empty: "插件名称为空 请检查传入参数!"
 | 
				
			||||||
ms.api.event.register: "[{name}] 注册事件 {event} => 执行器 {exec}"
 | 
					ms.api.event.register: "[{name}] 注册事件 {event} => 执行器 {exec} 优先级 {priority} 忽略取消 {ignore}"
 | 
				
			||||||
ms.api.event.unregister: "[{name}] 注销事件 {event} => 执行器 {exec}"
 | 
					ms.api.event.unregister: "[{name}] 注销事件 {event} => 执行器 {exec}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ms.api.command.register.input.error: "CommandExec 必须为一个函数... 输入: {exec}"
 | 
					ms.api.command.register.input.error: "CommandExec 必须为一个函数... 输入: {exec}"
 | 
				
			||||||
ms.api.command.register: "[{plugin}] 注册命令 {name}({cmd})..."
 | 
					ms.api.command.register: "[{plugin}] 注册命令 {name}({cmd})..."
 | 
				
			||||||
ms.api.command.unregister: "[{plugin}] 注销命令 {name}..."
 | 
					ms.api.command.unregister: "[{plugin}] 注销命令 {name}..."
 | 
				
			||||||
@@ -34,6 +35,7 @@ ms.api.command.tab.completer.error: "§6玩家 §a{player} §6执行 §b{plugin}
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
ms.plugin.initialize: "初始化 MiaoScript 插件系统: 实例: {plugin} 加载器: {loader}..."
 | 
					ms.plugin.initialize: "初始化 MiaoScript 插件系统: 实例: {plugin} 加载器: {loader}..."
 | 
				
			||||||
ms.plugin.event.map: "总计 {count} 个 {type} 事件 映射完成..."
 | 
					ms.plugin.event.map: "总计 {count} 个 {type} 事件 映射完成..."
 | 
				
			||||||
 | 
					ms.plugin.event.map.error: "映射 {type} 事件 异常 将无法使用事件简称. Error: {error}"
 | 
				
			||||||
ms.plugin.manager.scan: "扫描器 {scanner} 扫描 {folder} 中的插件..."
 | 
					ms.plugin.manager.scan: "扫描器 {scanner} 扫描 {folder} 中的插件..."
 | 
				
			||||||
ms.plugin.manager.scan.finish: "扫描器 {scanner} 在 {folder} 中 发现 {size} 个插件 开始构建..."
 | 
					ms.plugin.manager.scan.finish: "扫描器 {scanner} 在 {folder} 中 发现 {size} 个插件 开始构建..."
 | 
				
			||||||
ms.plugin.manager.initialize.error: "§6插件 §b{name} §6初始化错误 §4{ex}"
 | 
					ms.plugin.manager.initialize.error: "§6插件 §b{name} §6初始化错误 §4{ex}"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@
 | 
				
			|||||||
        "test": "echo \"Error: run tests from root\" && exit 1"
 | 
					        "test": "echo \"Error: run tests from root\" && exit 1"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "devDependencies": {
 | 
					    "devDependencies": {
 | 
				
			||||||
 | 
					        "@types/crypto-js": "^4.1.1",
 | 
				
			||||||
        "@types/js-yaml": "^4.0.5",
 | 
					        "@types/js-yaml": "^4.0.5",
 | 
				
			||||||
        "reflect-metadata": "^0.1.13",
 | 
					        "reflect-metadata": "^0.1.13",
 | 
				
			||||||
        "rimraf": "^3.0.2",
 | 
					        "rimraf": "^3.0.2",
 | 
				
			||||||
@@ -30,7 +31,6 @@
 | 
				
			|||||||
        "@ccms/container": "^0.19.0",
 | 
					        "@ccms/container": "^0.19.0",
 | 
				
			||||||
        "@ccms/i18n": "^0.19.0",
 | 
					        "@ccms/i18n": "^0.19.0",
 | 
				
			||||||
        "crypto-js": "^4.1.1",
 | 
					        "crypto-js": "^4.1.1",
 | 
				
			||||||
        "js-yaml": "^4.1.0",
 | 
					        "js-yaml": "^4.1.0"
 | 
				
			||||||
        "yaml": "^1.10.2"
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,14 +54,8 @@ export class PluginCommandManager {
 | 
				
			|||||||
            cmdExecutor = (sender: any, command: string, args: string[]) => {
 | 
					            cmdExecutor = (sender: any, command: string, args: string[]) => {
 | 
				
			||||||
                let subcommand = args[0]
 | 
					                let subcommand = args[0]
 | 
				
			||||||
                let cmdKey = 'cmd' + subcommand
 | 
					                let cmdKey = 'cmd' + subcommand
 | 
				
			||||||
                let subcommandexec = pluginInstance[cmdKey]
 | 
					                if (!cmdSubCache.includes(subcommand)) {
 | 
				
			||||||
                if (!subcommandexec) {
 | 
					                    if (!pluginInstance[cmd.executor].apply(pluginInstance, [sender, command, args])) {
 | 
				
			||||||
                    subcommandexec = pluginInstance['cmdmain']
 | 
					 | 
				
			||||||
                    subcommand = 'main'
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    args.shift()
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                if (!subcommandexec) {
 | 
					 | 
				
			||||||
                        subcommand && pluginInstance.logger.sender(sender, '§4未知的子命令: §c' + subcommand)
 | 
					                        subcommand && pluginInstance.logger.sender(sender, '§4未知的子命令: §c' + subcommand)
 | 
				
			||||||
                        pluginInstance.logger.sender(
 | 
					                        pluginInstance.logger.sender(
 | 
				
			||||||
                            sender,
 | 
					                            sender,
 | 
				
			||||||
@@ -72,19 +66,22 @@ export class PluginCommandManager {
 | 
				
			|||||||
                                    `§6版本: §a${pluginInstance.description.version}`
 | 
					                                    `§6版本: §a${pluginInstance.description.version}`
 | 
				
			||||||
                                ]
 | 
					                                ]
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    return
 | 
					                    return
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                let subcommandexec = pluginInstance[cmdKey]
 | 
				
			||||||
                let permission: string
 | 
					                let permission: string
 | 
				
			||||||
                if (cmd.permission && sender.hasPermission) {
 | 
					                if (cmd.permission && sender.hasPermission) {
 | 
				
			||||||
                    if (typeof cmd.permission == "string") {
 | 
					                    if (typeof cmd.permission == "string") {
 | 
				
			||||||
                        permission = cmd.permission as string
 | 
					                        permission = cmd.permission as string
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        permission = `${pluginInstance.description.name.toLocaleLowerCase()}.${command}.${subcommand}`
 | 
					                        permission = `${pluginInstance.description.name.toLocaleLowerCase()}.${command}.${subcommand || 'main'}`
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if (!sender.hasPermission(permission)) {
 | 
					                    if (!sender.hasPermission(permission)) {
 | 
				
			||||||
                        return pluginInstance.logger.sender(sender, `§c你需要 ${permission} 权限 才可执行此命令.`)
 | 
					                        return pluginInstance.logger.sender(sender, `§c你需要 ${permission} 权限 才可执行此命令.`)
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                args.shift()
 | 
				
			||||||
                return subcommandexec.apply(pluginInstance, [sender, ...args])
 | 
					                return subcommandexec.apply(pluginInstance, [sender, ...args])
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            let originCompleter = cmdCompleter
 | 
					            let originCompleter = cmdCompleter
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,59 +1,36 @@
 | 
				
			|||||||
import * as yaml from 'js-yaml'
 | 
					 | 
				
			||||||
import * as fs from '@ccms/common/dist/fs'
 | 
					 | 
				
			||||||
import { plugin } from '@ccms/api'
 | 
					import { plugin } from '@ccms/api'
 | 
				
			||||||
import { provideSingleton } from '@ccms/container'
 | 
					import { Autowired, Container, ContainerInstance, postConstruct, provideSingleton } from '@ccms/container'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import * as fs from '@ccms/common/dist/fs'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { interfaces } from './interfaces'
 | 
					import { interfaces } from './interfaces'
 | 
				
			||||||
import { getPluginConfigMetadata } from './utils'
 | 
					import { getPluginConfigMetadata } from './utils'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface PluginConfigLoader {
 | 
					import { PluginConfigLoader } from './config/interfaces'
 | 
				
			||||||
    load(content: string): any
 | 
					import './config/loader/json-loader'
 | 
				
			||||||
    dump(variable: any): string
 | 
					import './config/loader/yaml-loader'
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export class YamlPluginConfig implements PluginConfigLoader {
 | 
					 | 
				
			||||||
    load(content: string) {
 | 
					 | 
				
			||||||
        return yaml.load(content)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    dump(variable: any): string {
 | 
					 | 
				
			||||||
        return yaml.dump(variable, { skipInvalid: true, lineWidth: 120 })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export class JsonPluginConfig implements PluginConfigLoader {
 | 
					 | 
				
			||||||
    load(content: string) {
 | 
					 | 
				
			||||||
        return JSON.parse(content)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    dump(variable: any): string {
 | 
					 | 
				
			||||||
        return JSON.stringify(variable, undefined, 4)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export interface PluginConfig {
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Save Config to File
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    readonly save?: () => void
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Reload Config from File
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    readonly reload?: () => void
 | 
					 | 
				
			||||||
    [key: string]: any
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
@provideSingleton(PluginConfigManager)
 | 
					@provideSingleton(PluginConfigManager)
 | 
				
			||||||
export class PluginConfigManager {
 | 
					export class PluginConfigManager {
 | 
				
			||||||
 | 
					    @Autowired(ContainerInstance)
 | 
				
			||||||
 | 
					    private container: Container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private configLoaderMap = new Map<string, PluginConfigLoader>()
 | 
					    private configLoaderMap = new Map<string, PluginConfigLoader>()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor() {
 | 
					    constructor() {
 | 
				
			||||||
        this.configLoaderMap.set("json", new JsonPluginConfig())
 | 
					 | 
				
			||||||
        let yaml = new YamlPluginConfig()
 | 
					 | 
				
			||||||
        this.configLoaderMap.set("yml", yaml)
 | 
					 | 
				
			||||||
        this.configLoaderMap.set("yaml", yaml)
 | 
					 | 
				
			||||||
        process.on('plugin.before.load', this.loadConfig.bind(this))
 | 
					        process.on('plugin.before.load', this.loadConfig.bind(this))
 | 
				
			||||||
        process.on('plugin.after.disable', this.saveConfig.bind(this))
 | 
					        process.on('plugin.after.disable', this.saveConfig.bind(this))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @postConstruct()
 | 
				
			||||||
 | 
					    initialize() {
 | 
				
			||||||
 | 
					        let configLoader = this.container.getAll<PluginConfigLoader>(PluginConfigLoader)
 | 
				
			||||||
 | 
					        configLoader.forEach((scanner) => {
 | 
				
			||||||
 | 
					            console.debug(`loading config loader ${scanner.type}...`)
 | 
				
			||||||
 | 
					            this.configLoaderMap.set(scanner.type, scanner)
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    getConfigLoader(format: string) {
 | 
					    getConfigLoader(format: string) {
 | 
				
			||||||
        if (!this.configLoaderMap.has(format)) { throw new Error(`Unsupport config format ${format} !`) }
 | 
					        if (!this.configLoaderMap.has(format)) { throw new Error(`Unsupport config format ${format} !`) }
 | 
				
			||||||
        return this.configLoaderMap.get(format)
 | 
					        return this.configLoaderMap.get(format)
 | 
				
			||||||
@@ -73,13 +50,17 @@ export class PluginConfigManager {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private defienConfigProp(plugin: plugin.Plugin, metadata: interfaces.ConfigMetadata, value: any) {
 | 
					    createConfig(plugin: plugin.Plugin, metadata: interfaces.ConfigMetadata, value: any) {
 | 
				
			||||||
        Object.defineProperties(value, {
 | 
					        Object.defineProperties(value, {
 | 
				
			||||||
            'save': { value: () => this.saveConfig0(plugin, metadata) },
 | 
					            'save': { value: () => this.saveConfig0(plugin, metadata) },
 | 
				
			||||||
            'reload': { value: () => this.loadConfig0(plugin, metadata) }
 | 
					            'reload': { value: () => this.loadConfig0(plugin, metadata) }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
 | 
					        return value
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private defienConfigProp(plugin: plugin.Plugin, metadata: interfaces.ConfigMetadata, value: any) {
 | 
				
			||||||
        Object.defineProperty(plugin, metadata.variable, {
 | 
					        Object.defineProperty(plugin, metadata.variable, {
 | 
				
			||||||
            value,
 | 
					            value: this.createConfig(plugin, metadata, value),
 | 
				
			||||||
            configurable: true
 | 
					            configurable: true
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										65
									
								
								packages/plugin/src/config/file-config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								packages/plugin/src/config/file-config.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
				
			|||||||
 | 
					import * as fs from '@ccms/common/dist/fs'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { PluginConfig, PluginConfigLoader } from './interfaces'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class PluginFileConfig implements PluginConfig {
 | 
				
			||||||
 | 
					    private loader: PluginConfigLoader
 | 
				
			||||||
 | 
					    private file: string
 | 
				
			||||||
 | 
					    constructor(loader: PluginConfigLoader, file: string, def = {}) {
 | 
				
			||||||
 | 
					        this.loader = loader
 | 
				
			||||||
 | 
					        this.file = file
 | 
				
			||||||
 | 
					        if (fs.exists(file)) {
 | 
				
			||||||
 | 
					            this.reload()
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            Object.assign(this, def)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.initialize()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    initialize() {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    save() {
 | 
				
			||||||
 | 
					        base.save(this.file, this.loader.dump(this))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reload() {
 | 
				
			||||||
 | 
					        Object.assign(this, this.loader.load(base.read(this.file)))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class PluginConfigFolder {
 | 
				
			||||||
 | 
					    private loader: PluginConfigLoader
 | 
				
			||||||
 | 
					    private folder: string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private configCache = new Map<string, PluginFileConfig>()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor(loader: PluginConfigLoader, folder: string) {
 | 
				
			||||||
 | 
					        this.loader = loader
 | 
				
			||||||
 | 
					        this.folder = folder
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    createConfig(path: string, def = {}) {
 | 
				
			||||||
 | 
					        return new PluginFileConfig(this.loader, path, def)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getConfig(name: string, def = {}) {
 | 
				
			||||||
 | 
					        let path = fs.concat(this.folder, name)
 | 
				
			||||||
 | 
					        if (!this.configCache.has(path)) {
 | 
				
			||||||
 | 
					            this.configCache.set(path, this.createConfig(path, def))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return this.configCache.get(path)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    clear() {
 | 
				
			||||||
 | 
					        this.configCache.clear()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    save() {
 | 
				
			||||||
 | 
					        this.configCache.forEach((config) => config.save())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reload() {
 | 
				
			||||||
 | 
					        this.configCache.forEach((config) => config.reload())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								packages/plugin/src/config/interfaces.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								packages/plugin/src/config/interfaces.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					export const PluginConfigLoader = Symbol.for('PluginConfigLoader')
 | 
				
			||||||
 | 
					export interface PluginConfigLoader {
 | 
				
			||||||
 | 
					    type: string
 | 
				
			||||||
 | 
					    load(content: string): any
 | 
				
			||||||
 | 
					    dump(variable: any): string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface PluginConfig {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Save Config to File
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    readonly save?: () => void
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Reload Config from File
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    readonly reload?: () => void
 | 
				
			||||||
 | 
					    [key: string]: any
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								packages/plugin/src/config/loader/json-loader.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								packages/plugin/src/config/loader/json-loader.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					import { provideSingletonNamed } from '@ccms/container'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { PluginConfigLoader } from '../interfaces'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const LOADER_TYPE_NAME = 'json'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@provideSingletonNamed(PluginConfigLoader, LOADER_TYPE_NAME)
 | 
				
			||||||
 | 
					export class JsonPluginConfig implements PluginConfigLoader {
 | 
				
			||||||
 | 
					    type: string = LOADER_TYPE_NAME
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    load(content: string) {
 | 
				
			||||||
 | 
					        return JSON.parse(content)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dump(variable: any): string {
 | 
				
			||||||
 | 
					        return JSON.stringify(variable, undefined, 4)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										19
									
								
								packages/plugin/src/config/loader/yaml-loader.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								packages/plugin/src/config/loader/yaml-loader.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					import * as yaml from 'js-yaml'
 | 
				
			||||||
 | 
					import { provideSingletonNamed } from '@ccms/container'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { PluginConfigLoader } from '../interfaces'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const LOADER_TYPE_NAME = 'yml'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@provideSingletonNamed(PluginConfigLoader, LOADER_TYPE_NAME)
 | 
				
			||||||
 | 
					export class YamlPluginConfig implements PluginConfigLoader {
 | 
				
			||||||
 | 
					    type: string = LOADER_TYPE_NAME
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    load(content: string) {
 | 
				
			||||||
 | 
					        return yaml.load(content)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dump(variable: any): string {
 | 
				
			||||||
 | 
					        return yaml.dump(variable, { skipInvalid: true, lineWidth: 120 })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
 | 
					import './scanner/ms-scanner'
 | 
				
			||||||
import './scanner/js-scanner'
 | 
					import './scanner/js-scanner'
 | 
				
			||||||
import './scanner/mjs-scanner'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import './loader/ioc-loader'
 | 
					import './loader/ioc-loader'
 | 
				
			||||||
import './loader/basic-loader'
 | 
					import './loader/basic-loader'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,9 +64,13 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
    initialize() {
 | 
					    initialize() {
 | 
				
			||||||
        if (this.pluginInstance === undefined) { throw new Error("Can't found Plugin Instance!") }
 | 
					        if (this.pluginInstance === undefined) { throw new Error("Can't found Plugin Instance!") }
 | 
				
			||||||
        if (this.initialized !== true) {
 | 
					        if (this.initialized !== true) {
 | 
				
			||||||
            process.emit('plugin.manager.before.initialize')
 | 
					            process.emit('plugin.manager.before.initialize', this)
 | 
				
			||||||
            console.i18n('ms.plugin.initialize', { plugin: this.pluginInstance, loader: Thread.currentThread().contextClassLoader })
 | 
					            console.i18n('ms.plugin.initialize', { plugin: this.pluginInstance, loader: Thread.currentThread().contextClassLoader })
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
                console.i18n('ms.plugin.event.map', { count: this.eventManager.mapEventName(), type: this.serverType })
 | 
					                console.i18n('ms.plugin.event.map', { count: this.eventManager.mapEventName(), type: this.serverType })
 | 
				
			||||||
 | 
					            } catch (error) {
 | 
				
			||||||
 | 
					                console.i18n('ms.plugin.event.map.error', { error })
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            let pluginScanner = this.container.getAll<plugin.PluginScanner>(plugin.PluginScanner)
 | 
					            let pluginScanner = this.container.getAll<plugin.PluginScanner>(plugin.PluginScanner)
 | 
				
			||||||
            pluginScanner.forEach((scanner) => {
 | 
					            pluginScanner.forEach((scanner) => {
 | 
				
			||||||
                console.debug(`loading plugin sacnner ${scanner.type}...`)
 | 
					                console.debug(`loading plugin sacnner ${scanner.type}...`)
 | 
				
			||||||
@@ -78,14 +82,14 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
                this.loaderMap.set(loader.type, loader)
 | 
					                this.loaderMap.set(loader.type, loader)
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
            this.initialized = true
 | 
					            this.initialized = true
 | 
				
			||||||
            process.emit('plugin.manager.after.initialize')
 | 
					            process.emit('plugin.manager.after.initialize', this)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    scan(folder: string): void {
 | 
					    scan(folder: string): void {
 | 
				
			||||||
        if (!folder) { throw new Error('plugin scan folder can\'t be empty!') }
 | 
					        if (!folder) { throw new Error('plugin scan folder can\'t be empty!') }
 | 
				
			||||||
        this.initialize()
 | 
					        this.initialize()
 | 
				
			||||||
        process.emit('plugin.manager.before.scan', folder)
 | 
					        process.emit('plugin.manager.before.scan', folder, this)
 | 
				
			||||||
        for (const [, scanner] of this.sacnnerMap) {
 | 
					        for (const [, scanner] of this.sacnnerMap) {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                console.i18n('ms.plugin.manager.scan', { scanner: scanner.type, folder })
 | 
					                console.i18n('ms.plugin.manager.scan', { scanner: scanner.type, folder })
 | 
				
			||||||
@@ -104,13 +108,13 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
                console.ex(error)
 | 
					                console.ex(error)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        process.emit('plugin.manager.after.scan', folder)
 | 
					        process.emit('plugin.manager.after.scan', folder, this)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    build(): void {
 | 
					    build(): void {
 | 
				
			||||||
        process.emit('plugin.manager.before.build')
 | 
					        process.emit('plugin.manager.before.build', this)
 | 
				
			||||||
        this.buildPlugins()
 | 
					        this.buildPlugins()
 | 
				
			||||||
        process.emit('plugin.manager.after.build')
 | 
					        process.emit('plugin.manager.after.build', this)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private logStage(plugin: plugin.Plugin, stage: string) {
 | 
					    private logStage(plugin: plugin.Plugin, stage: string) {
 | 
				
			||||||
@@ -144,7 +148,6 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
            console.i18n("ms.plugin.manager.initialize.error", { name: loadMetadata.file, ex: error })
 | 
					            console.i18n("ms.plugin.manager.initialize.error", { name: loadMetadata.file, ex: error })
 | 
				
			||||||
            console.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) {
 | 
					    private loaderRequirePlugin(loadMetadata: plugin.PluginLoadMetadata, loader: plugin.PluginLoader) {
 | 
				
			||||||
@@ -195,7 +198,9 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
        let scanner = this.sacnnerMap.get(ext)
 | 
					        let scanner = this.sacnnerMap.get(ext)
 | 
				
			||||||
        if (!scanner) { throw new Error(`plugin scanner ${ext} can't found in sacnnerMap.`) }
 | 
					        if (!scanner) { throw new Error(`plugin scanner ${ext} can't found in sacnnerMap.`) }
 | 
				
			||||||
        let metadata = this.loadAndRequirePlugin(scanner.read(file))
 | 
					        let metadata = this.loadAndRequirePlugin(scanner.read(file))
 | 
				
			||||||
        let plugin = this.buildPlugin(metadata)
 | 
					        this.buildPlugin(metadata)
 | 
				
			||||||
 | 
					        let plugin = metadata.target
 | 
				
			||||||
 | 
					        if (!plugin) { throw new Error(`plugin scanner ${ext} can't found in sacnnerMap.`) }
 | 
				
			||||||
        this.load(plugin)
 | 
					        this.load(plugin)
 | 
				
			||||||
        this.enable(plugin)
 | 
					        this.enable(plugin)
 | 
				
			||||||
        return plugin
 | 
					        return plugin
 | 
				
			||||||
@@ -255,10 +260,10 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
            if (metadata?.depends?.length) {
 | 
					            if (metadata?.depends?.length) {
 | 
				
			||||||
                this.lazyMetadataMap.set(key, metadata)
 | 
					                this.lazyMetadataMap.set(key, metadata)
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                this.buildPlugin(metadata)
 | 
					                this.tryBuildPlugin(metadata)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        this.lazyMetadataMap.forEach((metadata, key) => this.buildPlugin(metadata))
 | 
					        this.lazyMetadataMap.forEach((metadata, key) => this.tryBuildPlugin(metadata))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private checkDepends(depends: string | string[]) {
 | 
					    private checkDepends(depends: string | string[]) {
 | 
				
			||||||
@@ -273,9 +278,18 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
        for (const depend of depends) { if (!this.nativePluginManager.has(depend)) loseDepends.push(depend) }
 | 
					        for (const depend of depends) { if (!this.nativePluginManager.has(depend)) loseDepends.push(depend) }
 | 
				
			||||||
        return loseDepends
 | 
					        return loseDepends
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private tryBuildPlugin(metadata: plugin.PluginMetadata) {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            return this.buildPlugin(metadata)
 | 
				
			||||||
 | 
					        } catch (error: any) {
 | 
				
			||||||
 | 
					            console.console(`§4无法加载插件 §b${metadata.name} §4构建插件失败!`)
 | 
				
			||||||
 | 
					            console.ex(error)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private buildPlugin(metadata: plugin.PluginMetadata) {
 | 
					    private buildPlugin(metadata: plugin.PluginMetadata) {
 | 
				
			||||||
        process.emit(`plugin.before.build`, metadata)
 | 
					        process.emit(`plugin.before.build`, metadata)
 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
        if (this.instanceMap.has(metadata.name)) { throw new Error(`Plugin ${metadata.name} is already load from ${metadata.source}...`) }
 | 
					        if (this.instanceMap.has(metadata.name)) { throw new Error(`Plugin ${metadata.name} is already load from ${metadata.source}...`) }
 | 
				
			||||||
        if (!this.loaderMap.has(metadata.type)) { throw new Error(`§4无法加载插件 §b${metadata.name} §4请检查 §c${metadata.type} §4加载器是否正常启用!`) }
 | 
					        if (!this.loaderMap.has(metadata.type)) { throw new Error(`§4无法加载插件 §b${metadata.name} §4请检查 §c${metadata.type} §4加载器是否正常启用!`) }
 | 
				
			||||||
        if (!this.serverChecker.check(metadata.servers)) { throw new Error(`§6插件 §b${metadata.name} §c服务器类型不兼容(${metadata.servers.join(',')}) §6忽略加载...`) }
 | 
					        if (!this.serverChecker.check(metadata.servers)) { throw new Error(`§6插件 §b${metadata.name} §c服务器类型不兼容(${metadata.servers.join(',')}) §6忽略加载...`) }
 | 
				
			||||||
@@ -285,12 +299,9 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
				
			|||||||
        if (loseNativeDepends.length) { throw new Error(`§4无法加载插件 §b${metadata.name} §4请检查插件依赖 §3[${loseNativeDepends.join(',')}] §4是否安装完整!`) }
 | 
					        if (loseNativeDepends.length) { throw new Error(`§4无法加载插件 §b${metadata.name} §4请检查插件依赖 §3[${loseNativeDepends.join(',')}] §4是否安装完整!`) }
 | 
				
			||||||
        let pluginInstance = this.loaderMap.get(metadata.type).build(metadata)
 | 
					        let pluginInstance = this.loaderMap.get(metadata.type).build(metadata)
 | 
				
			||||||
        if (!pluginInstance) { throw new Error(`§4加载器 §c${metadata.type} §4加载插件 §c${metadata.name} §4失败!`) }
 | 
					        if (!pluginInstance) { throw new Error(`§4加载器 §c${metadata.type} §4加载插件 §c${metadata.name} §4失败!`) }
 | 
				
			||||||
 | 
					        metadata.target = pluginInstance
 | 
				
			||||||
        this.instanceMap.set(metadata.name, pluginInstance)
 | 
					        this.instanceMap.set(metadata.name, pluginInstance)
 | 
				
			||||||
        process.emit(`plugin.after.build`, metadata, pluginInstance)
 | 
					        process.emit(`plugin.after.build`, metadata, pluginInstance)
 | 
				
			||||||
        return pluginInstance
 | 
					        return pluginInstance
 | 
				
			||||||
        } catch (error: any) {
 | 
					 | 
				
			||||||
            console.console(`§4无法加载插件 §b${metadata.name} §4构建插件失败!`)
 | 
					 | 
				
			||||||
            console.ex(error)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,6 @@
 | 
				
			|||||||
 * Module dependencies.
 | 
					 * Module dependencies.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import * as server from "../server"
 | 
					 | 
				
			||||||
// const http = require("http")
 | 
					// const http = require("http")
 | 
				
			||||||
// const Server = require("./server")
 | 
					// const Server = require("./server")
 | 
				
			||||||
import { Server } from './server'
 | 
					import { Server } from './server'
 | 
				
			||||||
@@ -18,7 +17,7 @@ import { Server } from './server'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function attach(srv, options) {
 | 
					function attach(srv, options) {
 | 
				
			||||||
    const engine = new Server(options)
 | 
					    const engine = new Server(options)
 | 
				
			||||||
    engine.attach(server.attach(srv, options), options)
 | 
					    engine.attach(srv, options)
 | 
				
			||||||
    return engine
 | 
					    return engine
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
/// <reference types="@ccms/nashorn" />
 | 
					/// <reference types="@ccms/nashorn" />
 | 
				
			||||||
/// <reference types="@javatypes/tomcat-websocket-api" />
 | 
					/// <reference types="@javatypes/tomcat-websocket-api" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import * as server from './server'
 | 
				
			||||||
import { Server, ServerOptions } from './socket.io'
 | 
					import { Server, ServerOptions } from './socket.io'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface SocketIOStatic {
 | 
					interface SocketIOStatic {
 | 
				
			||||||
@@ -38,9 +39,21 @@ interface SocketIOStatic {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type SocketStatic = SocketIOStatic & { Instance?: symbol }
 | 
					type SocketStatic = SocketIOStatic & { Instance?: symbol }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let singletonServer: Server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// @ts-ignore
 | 
					// @ts-ignore
 | 
				
			||||||
let io: SocketStatic = function (pipeline: any, options: Partial<ServerOptions>) {
 | 
					let io: SocketStatic = function io(pipeline: any, options: Partial<JavaServerOptions>, singleton = true) {
 | 
				
			||||||
    return new Server(pipeline, options)
 | 
					    if (singleton) {
 | 
				
			||||||
 | 
					        if (!singletonServer) {
 | 
				
			||||||
 | 
					            singletonServer = new Server(server.attach(pipeline, options), options)
 | 
				
			||||||
 | 
					            process.emit('websocket.create', singletonServer)
 | 
				
			||||||
 | 
					            process.on('exit', () => {
 | 
				
			||||||
 | 
					                singletonServer.close()
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return singletonServer
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return new Server(server.attach(pipeline, options), options)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
io.Instance = Symbol("@ccms/websocket")
 | 
					io.Instance = Symbol("@ccms/websocket")
 | 
				
			||||||
export default io
 | 
					export default io
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@ export enum ServerEvent {
 | 
				
			|||||||
export interface JavaServerOptions extends ServerOptions {
 | 
					export interface JavaServerOptions extends ServerOptions {
 | 
				
			||||||
    event?: EventEmitter
 | 
					    event?: EventEmitter
 | 
				
			||||||
    root?: string
 | 
					    root?: string
 | 
				
			||||||
 | 
					    httpRequestHandler?: (ctx, request) => void
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export abstract class WebSocketServer extends EventEmitter {
 | 
					export abstract class WebSocketServer extends EventEmitter {
 | 
				
			||||||
@@ -30,7 +31,6 @@ export abstract class WebSocketServer extends EventEmitter {
 | 
				
			|||||||
        this.instance = instance
 | 
					        this.instance = instance
 | 
				
			||||||
        this.options = options
 | 
					        this.options = options
 | 
				
			||||||
        this.clients = new Map()
 | 
					        this.clients = new Map()
 | 
				
			||||||
        console.debug('create websocket server from ' + this.constructor.name)
 | 
					 | 
				
			||||||
        this.initialize()
 | 
					        this.initialize()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    protected onconnect(handler: any) {
 | 
					    protected onconnect(handler: any) {
 | 
				
			||||||
@@ -56,7 +56,7 @@ export abstract class WebSocketServer extends EventEmitter {
 | 
				
			|||||||
        if (this.clients.has(id)) {
 | 
					        if (this.clients.has(id)) {
 | 
				
			||||||
            this.clients.has(id) && callback(this.clients.get(id))
 | 
					            this.clients.has(id) && callback(this.clients.get(id))
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            console.debug('ignore execute', handler, 'callback', callback)
 | 
					            console.trace('ignore execute', handler, 'callback', callback)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public close() {
 | 
					    public close() {
 | 
				
			||||||
@@ -75,7 +75,7 @@ export const attach = (instance, options) => {
 | 
				
			|||||||
    options = Object.assign({
 | 
					    options = Object.assign({
 | 
				
			||||||
        event: new EventEmitter(),
 | 
					        event: new EventEmitter(),
 | 
				
			||||||
        path: '/ws',
 | 
					        path: '/ws',
 | 
				
			||||||
        root: root + '/wwwroot',
 | 
					        root: root + Java.type("java.io.File").separatorChar + 'wwwroot',
 | 
				
			||||||
    }, options)
 | 
					    }, options)
 | 
				
			||||||
    let WebSocketServerImpl = undefined
 | 
					    let WebSocketServerImpl = undefined
 | 
				
			||||||
    if (instance.class.name.startsWith('io.netty.channel')) {
 | 
					    if (instance.class.name.startsWith('io.netty.channel')) {
 | 
				
			||||||
@@ -83,5 +83,6 @@ export const attach = (instance, options) => {
 | 
				
			|||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        WebSocketServerImpl = require("./tomcat").TomcatWebSocketServer
 | 
					        WebSocketServerImpl = require("./tomcat").TomcatWebSocketServer
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    console.debug('create websocket server from ' + WebSocketServerImpl.name)
 | 
				
			||||||
    return new WebSocketServerImpl(instance, options)
 | 
					    return new WebSocketServerImpl(instance, options)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,12 +23,19 @@ export class HttpRequestHandler extends HttpRequestHandlerAdapter {
 | 
				
			|||||||
        super()
 | 
					        super()
 | 
				
			||||||
        this.root = options.root
 | 
					        this.root = options.root
 | 
				
			||||||
        this.ws = options.path
 | 
					        this.ws = options.path
 | 
				
			||||||
 | 
					        if (options.httpRequestHandler) {
 | 
				
			||||||
 | 
					            this.httpRequestHandler = options.httpRequestHandler
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    channelRead0(ctx: any, request: any) {
 | 
					    channelRead0(ctx: any, request: any) {
 | 
				
			||||||
        if (request.getUri().startsWith(this.ws)) {
 | 
					        if (request.getUri().startsWith(this.ws)) {
 | 
				
			||||||
            ctx.channel().attr(AttributeKeys.Request).set(request)
 | 
					            ctx.channel().attr(AttributeKeys.Request).set(request)
 | 
				
			||||||
            ctx.fireChannelRead(request.retain())
 | 
					            ctx.fireChannelRead(request.retain())
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
 | 
					            this.httpRequestHandler(ctx, request)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    httpRequestHandler(ctx: any, request: any) {
 | 
				
			||||||
        ctx.executor().execute(new Runnable({
 | 
					        ctx.executor().execute(new Runnable({
 | 
				
			||||||
            run: () => {
 | 
					            run: () => {
 | 
				
			||||||
                if (HttpHeaders.is100ContinueExpected(request)) {
 | 
					                if (HttpHeaders.is100ContinueExpected(request)) {
 | 
				
			||||||
@@ -58,5 +65,4 @@ export class HttpRequestHandler extends HttpRequestHandlerAdapter {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }))
 | 
					        }))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user