feat: optimize framework & support depends check
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
import i18n from '@ccms/i18n'
 | 
			
		||||
import { injectable } from "@ccms/container"
 | 
			
		||||
import { plugin } from './interfaces'
 | 
			
		||||
import { plugin } from './plugin'
 | 
			
		||||
 | 
			
		||||
export namespace command {
 | 
			
		||||
    @injectable()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,14 @@
 | 
			
		||||
export namespace constants {
 | 
			
		||||
    export namespace ServiceIdentifier {
 | 
			
		||||
        /**
 | 
			
		||||
         * Runtime Server NettyPipeline
 | 
			
		||||
         */
 | 
			
		||||
        export const NettyPipeline = Symbol("NettyPipeline")
 | 
			
		||||
        /**
 | 
			
		||||
         * Runtime Server RootLogger
 | 
			
		||||
         */
 | 
			
		||||
        export const RootLogger = Symbol("RootLogger")
 | 
			
		||||
    }
 | 
			
		||||
    export namespace Reflect {
 | 
			
		||||
        export const Method = {
 | 
			
		||||
            getServerConnection: [/*spigot 1.8.8*/'aq',/*spigot 1.12.2*/ 'an', /*spigot 1.14.4+*/'getServerConnection', /*catserver 1.12.2*/'func_147137_ag']
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,15 @@
 | 
			
		||||
import "@ccms/nashorn"
 | 
			
		||||
 | 
			
		||||
export * from './web'
 | 
			
		||||
export * from './amqp'
 | 
			
		||||
export * from './chat'
 | 
			
		||||
export * from './task'
 | 
			
		||||
export * from './event'
 | 
			
		||||
export * from './proxy'
 | 
			
		||||
export * from './plugin'
 | 
			
		||||
export * from './server'
 | 
			
		||||
export * from './console'
 | 
			
		||||
export * from './channel'
 | 
			
		||||
export * from './command'
 | 
			
		||||
export * from './database'
 | 
			
		||||
export * from './constants'
 | 
			
		||||
export * from './interfaces'
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
export * from './web'
 | 
			
		||||
export * from './amqp'
 | 
			
		||||
export * from './plugin'
 | 
			
		||||
export * from './server'
 | 
			
		||||
export * from './database'
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
export interface NativePluginManager {
 | 
			
		||||
    load(name: string): boolean;
 | 
			
		||||
    unload(name: string): boolean;
 | 
			
		||||
    reload(name: string): boolean;
 | 
			
		||||
    delete(name: string): boolean;
 | 
			
		||||
}
 | 
			
		||||
@@ -162,6 +162,14 @@ export namespace plugin {
 | 
			
		||||
         * 插件作者 不填默认为 Unknow
 | 
			
		||||
         */
 | 
			
		||||
        author?: string | string[]
 | 
			
		||||
        /**
 | 
			
		||||
         * 脚本依赖
 | 
			
		||||
         */
 | 
			
		||||
        depends?: string[]
 | 
			
		||||
        /**
 | 
			
		||||
         * 插件依赖
 | 
			
		||||
         */
 | 
			
		||||
        nativeDepends?: string[]
 | 
			
		||||
        /**
 | 
			
		||||
         * 插件源文件 必须指定为 __filename
 | 
			
		||||
         */
 | 
			
		||||
@@ -1,10 +1,7 @@
 | 
			
		||||
import * as reflect from '@ccms/common/dist/reflect'
 | 
			
		||||
import { injectable, inject } from '@ccms/container'
 | 
			
		||||
import { injectable, Autowired, ContainerInstance, Container, postConstruct } from '@ccms/container'
 | 
			
		||||
 | 
			
		||||
import { NativePluginManager } from './native_plugin'
 | 
			
		||||
import { constants } from '../../constants'
 | 
			
		||||
 | 
			
		||||
export { NativePluginManager } from './native_plugin'
 | 
			
		||||
import { constants } from './constants'
 | 
			
		||||
 | 
			
		||||
export namespace server {
 | 
			
		||||
    /**
 | 
			
		||||
@@ -19,6 +16,24 @@ export namespace server {
 | 
			
		||||
     * Runtime Server Instance
 | 
			
		||||
     */
 | 
			
		||||
    export const ServerInstance = Symbol("ServerInstance")
 | 
			
		||||
    @injectable()
 | 
			
		||||
    export abstract class NativePluginManager {
 | 
			
		||||
        has(name: string): boolean {
 | 
			
		||||
            return true
 | 
			
		||||
        }
 | 
			
		||||
        load(name: string): boolean {
 | 
			
		||||
            throw new Error("Method not implemented.")
 | 
			
		||||
        }
 | 
			
		||||
        unload(name: string): boolean {
 | 
			
		||||
            throw new Error("Method not implemented.")
 | 
			
		||||
        }
 | 
			
		||||
        reload(name: string): boolean {
 | 
			
		||||
            throw new Error("Method not implemented.")
 | 
			
		||||
        }
 | 
			
		||||
        delete(name: string): boolean {
 | 
			
		||||
            throw new Error("Method not implemented.")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * MiaoScript Server
 | 
			
		||||
     */
 | 
			
		||||
@@ -48,9 +63,6 @@ export namespace server {
 | 
			
		||||
        getPluginsFolder(): string {
 | 
			
		||||
            throw new Error("Method not implemented.")
 | 
			
		||||
        }
 | 
			
		||||
        getNativePluginManager(): NativePluginManager {
 | 
			
		||||
            throw new Error("Method not implemented.")
 | 
			
		||||
        }
 | 
			
		||||
        getDedicatedServer?(): any {
 | 
			
		||||
            throw new Error("Method not implemented.")
 | 
			
		||||
        }
 | 
			
		||||
@@ -63,8 +75,9 @@ export namespace server {
 | 
			
		||||
    }
 | 
			
		||||
    @injectable()
 | 
			
		||||
    export class ServerChecker {
 | 
			
		||||
        @inject(ServerType)
 | 
			
		||||
        @Autowired(ServerType)
 | 
			
		||||
        private serverType: string
 | 
			
		||||
 | 
			
		||||
        check(servers: string[]) {
 | 
			
		||||
            // Not set servers -> allow
 | 
			
		||||
            if (!servers || !servers.length) return true
 | 
			
		||||
@@ -80,14 +93,17 @@ export namespace server {
 | 
			
		||||
    }
 | 
			
		||||
    @injectable()
 | 
			
		||||
    export abstract class ReflectServer extends server.Server {
 | 
			
		||||
        @Autowired(ContainerInstance)
 | 
			
		||||
        private container: Container
 | 
			
		||||
 | 
			
		||||
        protected pipeline: any
 | 
			
		||||
        protected rootLogger: any
 | 
			
		||||
 | 
			
		||||
        constructor() {
 | 
			
		||||
            super()
 | 
			
		||||
            this.reflect()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @postConstruct()
 | 
			
		||||
        protected reflect() {
 | 
			
		||||
            try {
 | 
			
		||||
                let consoleServer = this.getDedicatedServer()
 | 
			
		||||
@@ -107,7 +123,11 @@ export namespace server {
 | 
			
		||||
                    if (connection.class.name.indexOf('ServerConnection') !== -1
 | 
			
		||||
                        || connection.class.name.indexOf('NetworkSystem') !== -1) { break }
 | 
			
		||||
                    connection = undefined
 | 
			
		||||
                } catch (error) { }
 | 
			
		||||
                } catch (error) {
 | 
			
		||||
                    if (global.debug) {
 | 
			
		||||
                        console.ex(error)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (!connection) { console.error("Can't found ServerConnection!"); return }
 | 
			
		||||
            for (const field of constants.Reflect.Field.listeningChannels) {
 | 
			
		||||
@@ -115,16 +135,30 @@ export namespace server {
 | 
			
		||||
                    promise = reflect.on(connection).get(field).get().get(0)
 | 
			
		||||
                    if (promise.class.name.indexOf('Promise') !== -1) { break }
 | 
			
		||||
                    promise = undefined
 | 
			
		||||
                } catch (error) { }
 | 
			
		||||
                } catch (error) {
 | 
			
		||||
                    if (global.debug) {
 | 
			
		||||
                        console.ex(error)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (!promise) { console.error("Can't found listeningChannels!"); return }
 | 
			
		||||
            this.pipeline = reflect.on(promise).get('channel').get().pipeline()
 | 
			
		||||
            this.container.bind(constants.ServiceIdentifier.NettyPipeline).toConstantValue(this.pipeline)
 | 
			
		||||
        }
 | 
			
		||||
        protected reflectRootLogger(consoleServer: any) {
 | 
			
		||||
            try {
 | 
			
		||||
                this.rootLogger = reflect.on(consoleServer).get('LOGGER').get().parent
 | 
			
		||||
            } catch (error) {
 | 
			
		||||
                try { this.rootLogger = reflect.on(consoleServer).get(0).get().parent } catch (error) { }
 | 
			
		||||
                if (global.debug) {
 | 
			
		||||
                    console.ex(error)
 | 
			
		||||
                }
 | 
			
		||||
                try {
 | 
			
		||||
                    this.rootLogger = reflect.on(consoleServer).get(0).get().parent
 | 
			
		||||
                } catch (error) {
 | 
			
		||||
                    if (global.debug) {
 | 
			
		||||
                        console.ex(error)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (this.rootLogger && this.rootLogger.class.name.indexOf('Logger') === -1) {
 | 
			
		||||
                console.error('Error Logger Class: ' + this.rootLogger.class.name)
 | 
			
		||||
@@ -135,6 +169,7 @@ export namespace server {
 | 
			
		||||
                this.rootLogger = this.rootLogger.parent
 | 
			
		||||
            }
 | 
			
		||||
            if (!this.rootLogger) { console.error("Can't found rootLogger!") }
 | 
			
		||||
            this.container.bind(constants.ServiceIdentifier.RootLogger).toConstantValue(this.rootLogger)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +1,15 @@
 | 
			
		||||
/// <reference types="@javatypes/jdk" />
 | 
			
		||||
 | 
			
		||||
const JavaClass = Java.type('java.lang.Class')
 | 
			
		||||
const JavaObject = Java.type('java.lang.Object')
 | 
			
		||||
const NoSuchFieldException = Java.type('java.lang.NoSuchFieldException')
 | 
			
		||||
const fieldCache = new Map<string, java.lang.reflect.Field>()
 | 
			
		||||
const methodCache = new Map<string, java.lang.reflect.Method>()
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 反射工具类
 | 
			
		||||
 * Created by MiaoWoo on 2017/2/9 0009.
 | 
			
		||||
 */
 | 
			
		||||
const JavaClass = Java.type('java.lang.Class')
 | 
			
		||||
const JavaObject = Java.type('java.lang.Object')
 | 
			
		||||
const NoSuchFieldException = Java.type('java.lang.NoSuchFieldException')
 | 
			
		||||
const methodCache = []
 | 
			
		||||
 | 
			
		||||
class Reflect {
 | 
			
		||||
    private obj: java.lang.Object
 | 
			
		||||
    private class: java.lang.Class<any>
 | 
			
		||||
@@ -34,23 +35,34 @@ class Reflect {
 | 
			
		||||
        return Java.from(declaredMethods(this.class))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    field(name: string | java.lang.String): Reflect {
 | 
			
		||||
    field(nameOrIndex: string | java.lang.String | number, declared = false): java.lang.reflect.Field {
 | 
			
		||||
        if (nameOrIndex == undefined || nameOrIndex == null) throw new Error(`reflect field name can't be ${nameOrIndex} from ${this.class.getName()}!`)
 | 
			
		||||
        let key = this.class.getName() + ':' + nameOrIndex + ':' + declared
 | 
			
		||||
        if (fieldCache.has(key)) {
 | 
			
		||||
            return fieldCache.get(key)
 | 
			
		||||
        }
 | 
			
		||||
        let field = null
 | 
			
		||||
        if (typeof nameOrIndex == "number") {
 | 
			
		||||
            field = this.fields(declared)[nameOrIndex]
 | 
			
		||||
        } else {
 | 
			
		||||
            try {
 | 
			
		||||
                // Try getting a public field
 | 
			
		||||
            let field = this.class.getField(name)
 | 
			
		||||
            return on(field.get(this.obj))
 | 
			
		||||
                field = this.class.getField(nameOrIndex)
 | 
			
		||||
            } catch (ex) {
 | 
			
		||||
                // Try again, getting a non-public field
 | 
			
		||||
            return on(accessible(declaredField(this.class, name)).get(this.obj))
 | 
			
		||||
                field = declaredField(this.class, nameOrIndex)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!field) throw new Error(`can't reflect field ${typeof nameOrIndex == "number" ? 'index' : 'name'} ${nameOrIndex} from ${this.class.getName()}!`)
 | 
			
		||||
        return accessible(field)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fields(declared = false): java.lang.reflect.Field[] {
 | 
			
		||||
        return Java.from(declared ? this.class.getDeclaredFields() : this.class.getFields())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    values(declared = false) {
 | 
			
		||||
        return this.fields(declared).reduce((cache, field) => { return cache[field.getName()] = this.field(field.getName()).get() }, {}) as any
 | 
			
		||||
        return this.fields(declared).reduce((cache, field) => { return cache[field.getName()] = this.get(field.getName()).get() }, {}) as any
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    call(...args: any[]): Reflect {
 | 
			
		||||
@@ -64,17 +76,12 @@ class Reflect {
 | 
			
		||||
    get(index: number, declared?: boolean): Reflect
 | 
			
		||||
    get(prop: string): Reflect
 | 
			
		||||
    get(param?: string | number, declared: boolean = true): Reflect | any {
 | 
			
		||||
        if (param == undefined || param == null) return this.obj
 | 
			
		||||
        if (typeof param == "number") {
 | 
			
		||||
            return on(accessible(this.fields(declared)[param]).get(this.obj))
 | 
			
		||||
        }
 | 
			
		||||
        if (typeof param == "string") {
 | 
			
		||||
            return this.field(param)
 | 
			
		||||
        }
 | 
			
		||||
        if (arguments.length === 0) return this.obj
 | 
			
		||||
        return on(this.field(param, declared).get(this.obj))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set(name: any, value: any): Reflect {
 | 
			
		||||
        accessible(declaredField(this.class, name)).set(this.obj, value)
 | 
			
		||||
    set(param: string | number, value: any, declared: boolean = true): Reflect {
 | 
			
		||||
        this.field(param, declared).set(this.obj, value)
 | 
			
		||||
        return this
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -136,64 +143,43 @@ function declaredField(clazz: java.lang.Class<any>, name: string | java.lang.Str
 | 
			
		||||
    return field
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function declaredMethod(clazz: java.lang.Class<any>, name: string, ...clazzs: java.lang.Class<any>[]): java.lang.reflect.Method {
 | 
			
		||||
    let key = clazz.getName() + '.' + name + ':' + (clazzs || []).join(':')
 | 
			
		||||
    if (!methodCache[key]) {
 | 
			
		||||
function declaredMethod(clazz: java.lang.Class<any>, nameOrIndex: string | number, ...clazzs: java.lang.Class<any>[]): java.lang.reflect.Method {
 | 
			
		||||
    let key = clazz.getName() + '.' + nameOrIndex + ':' + (clazzs || []).map(c => c.getName()).join(':')
 | 
			
		||||
    if (methodCache.has(key)) { return methodCache.get(key) }
 | 
			
		||||
    if (typeof nameOrIndex === "number") {
 | 
			
		||||
        methodCache.set(key, declaredMethods(clazz)[nameOrIndex])
 | 
			
		||||
    } else {
 | 
			
		||||
        try {
 | 
			
		||||
            // @ts-ignore
 | 
			
		||||
            methodCache[key] = clazz.getMethod(name, clazzs)
 | 
			
		||||
            methodCache.set(key, clazz.getMethod(nameOrIndex, clazzs as any))
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
            try {
 | 
			
		||||
                methodCache[key] = clazz.getDeclaredMethod(name, clazzs as any)
 | 
			
		||||
                methodCache.set(key, clazz.getDeclaredMethod(nameOrIndex, clazzs as any))
 | 
			
		||||
            } catch (ex) {
 | 
			
		||||
                for (const m of Java.from(declaredMethods(clazz))) {
 | 
			
		||||
                    if (m.getName() == name) {
 | 
			
		||||
                        methodCache[key] = m
 | 
			
		||||
                    if (m.getName() == nameOrIndex) {
 | 
			
		||||
                        methodCache.set(key, m)
 | 
			
		||||
                        break
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return methodCache[key]
 | 
			
		||||
    if (!methodCache.has(key)) throw new Error(`can't reflect method ${typeof nameOrIndex == "number" ? 'index' : 'name'} ${nameOrIndex} from ${clazz.getName()}!`)
 | 
			
		||||
    return methodCache.get(key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function declaredMethods(clazz: java.lang.Class<any>) {
 | 
			
		||||
    return clazz.getDeclaredMethods()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let classMethodsCache: any[] = []
 | 
			
		||||
 | 
			
		||||
function mapToObject(javaObj) {
 | 
			
		||||
    if (!javaObj || !javaObj.class) { throw new TypeError(`参数 ${javaObj} 不是一个Java对象!`) }
 | 
			
		||||
    let target = {}
 | 
			
		||||
    getJavaObjectMethods(javaObj).forEach(t => mapMethod(target, javaObj, t))
 | 
			
		||||
    if (!Java.isJavaObject(javaObj)) { throw new TypeError(`参数 ${javaObj} 不是一个Java对象!`) }
 | 
			
		||||
    let target = Proxy.newProxy(javaObj, {
 | 
			
		||||
        apply: (target, name, args) => { return args ? javaObj[name](args) : javaObj[name]() }
 | 
			
		||||
    })
 | 
			
		||||
    return target
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getJavaObjectMethods(javaObj) {
 | 
			
		||||
    let className = javaObj.class.name
 | 
			
		||||
    if (!classMethodsCache[className]) {
 | 
			
		||||
        let names: any[] = []
 | 
			
		||||
        let methods = javaObj.class.methods
 | 
			
		||||
        for (let i in methods) {
 | 
			
		||||
            names.push(methods[i].name)
 | 
			
		||||
        }
 | 
			
		||||
        classMethodsCache[className] = names
 | 
			
		||||
    }
 | 
			
		||||
    return classMethodsCache[className]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function mapMethod(target, source, name) {
 | 
			
		||||
    target[name] = function __SimpleDynamicMethod__(...args) {
 | 
			
		||||
        if (args.length > 0) {
 | 
			
		||||
            return source[name](args)
 | 
			
		||||
        } else {
 | 
			
		||||
            return source[name]()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function on(obj) {
 | 
			
		||||
    // if (!obj || !obj.class) { throw new TypeError(`参数 ${obj} 不是一个Java对象!`) }
 | 
			
		||||
    return new Reflect(obj)
 | 
			
		||||
 
 | 
			
		||||
@@ -99,6 +99,7 @@ function initialize() {
 | 
			
		||||
        console.i18n("ms.core.initialize.detect", { scope: global.scope, type })
 | 
			
		||||
        container.bind(server.ServerType).toConstantValue(type)
 | 
			
		||||
        container.bind(server.ServerChecker).toSelf().inSingletonScope()
 | 
			
		||||
        container.bind(server.NativePluginManager).toSelf().inSingletonScope()
 | 
			
		||||
        console.i18n("ms.core.package.initialize", { scope: global.scope, type })
 | 
			
		||||
        require(`${global.scope}/${type}`).default(container)
 | 
			
		||||
        require(`${global.scope}/plugin`)
 | 
			
		||||
 
 | 
			
		||||
@@ -81,8 +81,18 @@ declare global {
 | 
			
		||||
        i18n(name: string, ...params: any[]): void
 | 
			
		||||
    }
 | 
			
		||||
    interface ProxyConstructor {
 | 
			
		||||
        newProxy<T extends object>(target: T, handler: ProxyHandler<T>): T
 | 
			
		||||
        newProxy<T extends object>(target: T, handler: ProxyHandle<T>): T
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ProxyHandle<T = any> extends ProxyHandler<any> {
 | 
			
		||||
    setPrototypeOf?(target: T, v: any): any
 | 
			
		||||
    // get: (target: any, name: string) => any
 | 
			
		||||
    // set: (target: any, name: string, value: any) => boolean
 | 
			
		||||
    // construct: (target: any, ...args: any[]) => any
 | 
			
		||||
    // has: (target: any, name: string) => boolean
 | 
			
		||||
    // ownKeys: (target: any) => string[]
 | 
			
		||||
    values?: (target: T) => any[]
 | 
			
		||||
    // call: (target: any, name: string, ...args: any[]) => any
 | 
			
		||||
    // deleteProperty: (target: any, name: string) => boolean
 | 
			
		||||
}
 | 
			
		||||
export { }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,9 @@
 | 
			
		||||
import { ProxyHandle } from '@ccms/nashorn'
 | 
			
		||||
 | 
			
		||||
// Nashorn JSAdapter See https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions-JSAdapterconstructor
 | 
			
		||||
let createProxy = eval(`
 | 
			
		||||
    function(handle){ return new JSAdapter(handle) }
 | 
			
		||||
`)
 | 
			
		||||
export interface ProxyHandle extends ProxyHandler<any> {
 | 
			
		||||
    // get: (target: any, name: string) => any
 | 
			
		||||
    // set: (target: any, name: string, value: any) => boolean
 | 
			
		||||
    // construct: (target: any, ...args: any[]) => any
 | 
			
		||||
    // has: (target: any, name: string) => boolean
 | 
			
		||||
    // ownKeys: (target: any) => string[]
 | 
			
		||||
    values: (target: any) => any[];
 | 
			
		||||
    // call: (target: any, name: string, ...args: any[]) => any
 | 
			
		||||
    // deleteProperty: (target: any, name: string) => boolean
 | 
			
		||||
}
 | 
			
		||||
export class Proxy {
 | 
			
		||||
    static newProxy(target: any, handle: Partial<ProxyHandle>): any {
 | 
			
		||||
        return new Proxy(target, handle)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
import i18n from '@ccms/i18n'
 | 
			
		||||
import { plugin, server, event } from '@ccms/api'
 | 
			
		||||
import { inject, provideSingleton, Container, ContainerInstance, Autowired } from '@ccms/container'
 | 
			
		||||
import { plugin, server } from '@ccms/api'
 | 
			
		||||
import { provideSingleton, Container, ContainerInstance, Autowired } from '@ccms/container'
 | 
			
		||||
 | 
			
		||||
import './config'
 | 
			
		||||
import { interfaces } from './interfaces'
 | 
			
		||||
@@ -13,15 +13,17 @@ const Thread = Java.type('java.lang.Thread')
 | 
			
		||||
 | 
			
		||||
@provideSingleton(plugin.PluginManager)
 | 
			
		||||
export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
    @inject(ContainerInstance)
 | 
			
		||||
    @Autowired(ContainerInstance)
 | 
			
		||||
    private container: Container
 | 
			
		||||
    @inject(plugin.PluginInstance)
 | 
			
		||||
    @Autowired(plugin.PluginInstance)
 | 
			
		||||
    private pluginInstance: any
 | 
			
		||||
    @inject(server.ServerType)
 | 
			
		||||
    @Autowired(server.ServerType)
 | 
			
		||||
    private serverType: string
 | 
			
		||||
 | 
			
		||||
    @Autowired()
 | 
			
		||||
    private serverChecker: server.ServerChecker
 | 
			
		||||
    @Autowired()
 | 
			
		||||
    private nativePluginManager: server.NativePluginManager
 | 
			
		||||
 | 
			
		||||
    @Autowired()
 | 
			
		||||
    private taskManager: PluginTaskManager
 | 
			
		||||
@@ -224,15 +226,28 @@ export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
            try {
 | 
			
		||||
                this.buildPlugin(metadata)
 | 
			
		||||
            } catch (error) {
 | 
			
		||||
                console.console(error)
 | 
			
		||||
                console.console(`§4无法加载插件 §b${metadata.name} §4构建插件失败!`)
 | 
			
		||||
                console.ex(error)
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private checkDepends(depends: string | string[]) {
 | 
			
		||||
        if (!depends) return true
 | 
			
		||||
        for (const depend of depends) { if (!this.metadataMap.has(depend)) return false }
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
    private checkNativeDepends(depends: string | string[]) {
 | 
			
		||||
        if (!depends) return true
 | 
			
		||||
        for (const depend of depends) { if (!this.nativePluginManager.has(depend)) return false }
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
    private buildPlugin(metadata: plugin.PluginMetadata) {
 | 
			
		||||
        if (!this.loaderMap.has(metadata.type)) { throw new Error(`§4无法加载插件 §c${metadata.name} §4请检查 §c${metadata.type} §4加载器是否正常启用!`) }
 | 
			
		||||
        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.serverChecker.check(metadata.servers)) { throw new Error(`§6插件 §b${metadata.name} §c服务器类型不兼容(${metadata.servers.join(',')}) §6忽略加载...`) }
 | 
			
		||||
        if (!this.checkDepends(metadata.depends)) { throw new Error(`§4无法加载插件 §b${metadata.name} §4请检查依赖 §3${metadata.depends.join(',')} §4是否安装完整!`) }
 | 
			
		||||
        if (!this.checkNativeDepends(metadata.nativeDepends)) { throw new Error(`§4无法加载插件 §b${metadata.name} §4请检查插件依赖 §3${metadata.nativeDepends.join(',')} §4是否安装完整!`) }
 | 
			
		||||
        let pluginInstance = this.loaderMap.get(metadata.type).build(metadata)
 | 
			
		||||
        if (!pluginInstance) { throw new Error(`§4加载器 §c${metadata.type} §4加载插件 §c${metadata.name} §4失败!`) }
 | 
			
		||||
        this.instanceMap.set(metadata.name, pluginInstance)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +1,32 @@
 | 
			
		||||
import { server } from '@ccms/api'
 | 
			
		||||
import { provideSingleton, inject } from '@ccms/container'
 | 
			
		||||
import { NativePluginManager } from '@ccms/api'
 | 
			
		||||
import { constants, server } from '@ccms/api'
 | 
			
		||||
import { provideSingleton, postConstruct, Autowired, Container, ContainerInstance } from '@ccms/container'
 | 
			
		||||
import { CommandMap } from './internal/command'
 | 
			
		||||
 | 
			
		||||
@provideSingleton(server.Server)
 | 
			
		||||
export class SpringServer implements server.Server {
 | 
			
		||||
    @inject(CommandMap)
 | 
			
		||||
export class SpringServer extends server.Server {
 | 
			
		||||
    @Autowired(ContainerInstance)
 | 
			
		||||
    private container: Container
 | 
			
		||||
    @Autowired()
 | 
			
		||||
    private commandMap: CommandMap
 | 
			
		||||
 | 
			
		||||
    private nettyPipeline = base.getInstance().getAutowireCapableBeanFactory()
 | 
			
		||||
    private rootLogger = Packages.org.slf4j.LoggerFactory.getLogger("root") || global.logger
 | 
			
		||||
 | 
			
		||||
    @postConstruct()
 | 
			
		||||
    initialize() {
 | 
			
		||||
        this.container.bind(constants.ServiceIdentifier.NettyPipeline).toConstantValue(this.nettyPipeline)
 | 
			
		||||
        this.container.bind(constants.ServiceIdentifier.RootLogger).toConstantValue(this.rootLogger)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getVersion(): string {
 | 
			
		||||
        return "SpringFramework"
 | 
			
		||||
    }
 | 
			
		||||
    getPlayer(name: string) {
 | 
			
		||||
        throw new Error("Method not implemented.")
 | 
			
		||||
    }
 | 
			
		||||
    getOnlinePlayers(): any[] {
 | 
			
		||||
        throw new Error("Method not implemented.")
 | 
			
		||||
    }
 | 
			
		||||
    getConsoleSender() {
 | 
			
		||||
        return {
 | 
			
		||||
            name: 'CONSOLE',
 | 
			
		||||
            sendMessage: (message: string) => console.console(message)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    getService(service: string) {
 | 
			
		||||
        throw new Error("Method not implemented.")
 | 
			
		||||
    }
 | 
			
		||||
    dispatchCommand(sender: any, command: string): boolean {
 | 
			
		||||
        let cmd_args = command.split(" ")
 | 
			
		||||
        return this.commandMap.dispatch(sender, cmd_args.shift(), cmd_args || [])
 | 
			
		||||
@@ -33,16 +34,10 @@ export class SpringServer implements server.Server {
 | 
			
		||||
    dispatchConsoleCommand(command: string): boolean {
 | 
			
		||||
        return this.dispatchCommand(this.getConsoleSender(), command)
 | 
			
		||||
    }
 | 
			
		||||
    getPluginsFolder(): string {
 | 
			
		||||
        throw new Error("Method not implemented.")
 | 
			
		||||
    }
 | 
			
		||||
    getNativePluginManager(): NativePluginManager {
 | 
			
		||||
        throw new Error("Method not implemented.")
 | 
			
		||||
    }
 | 
			
		||||
    getNettyPipeline() {
 | 
			
		||||
        return base.getInstance().getAutowireCapableBeanFactory()
 | 
			
		||||
        return this.nettyPipeline
 | 
			
		||||
    }
 | 
			
		||||
    getRootLogger() {
 | 
			
		||||
        return Packages.org.slf4j.LoggerFactory.getLogger("root") || global.logger
 | 
			
		||||
        return this.rootLogger
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user