feat: optimize framework & support depends check
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
parent
47c85f70eb
commit
e02f673c82
@ -1,6 +1,6 @@
|
|||||||
import i18n from '@ccms/i18n'
|
import i18n from '@ccms/i18n'
|
||||||
import { injectable } from "@ccms/container"
|
import { injectable } from "@ccms/container"
|
||||||
import { plugin } from './interfaces'
|
import { plugin } from './plugin'
|
||||||
|
|
||||||
export namespace command {
|
export namespace command {
|
||||||
@injectable()
|
@injectable()
|
||||||
|
@ -1,4 +1,14 @@
|
|||||||
export namespace constants {
|
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 namespace Reflect {
|
||||||
export const Method = {
|
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']
|
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"
|
import "@ccms/nashorn"
|
||||||
|
|
||||||
|
export * from './web'
|
||||||
|
export * from './amqp'
|
||||||
export * from './chat'
|
export * from './chat'
|
||||||
export * from './task'
|
export * from './task'
|
||||||
export * from './event'
|
export * from './event'
|
||||||
export * from './proxy'
|
export * from './proxy'
|
||||||
|
export * from './plugin'
|
||||||
|
export * from './server'
|
||||||
export * from './console'
|
export * from './console'
|
||||||
export * from './channel'
|
export * from './channel'
|
||||||
export * from './command'
|
export * from './command'
|
||||||
|
export * from './database'
|
||||||
export * from './constants'
|
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
|
* 插件作者 不填默认为 Unknow
|
||||||
*/
|
*/
|
||||||
author?: string | string[]
|
author?: string | string[]
|
||||||
|
/**
|
||||||
|
* 脚本依赖
|
||||||
|
*/
|
||||||
|
depends?: string[]
|
||||||
|
/**
|
||||||
|
* 插件依赖
|
||||||
|
*/
|
||||||
|
nativeDepends?: string[]
|
||||||
/**
|
/**
|
||||||
* 插件源文件 必须指定为 __filename
|
* 插件源文件 必须指定为 __filename
|
||||||
*/
|
*/
|
@ -1,10 +1,7 @@
|
|||||||
import * as reflect from '@ccms/common/dist/reflect'
|
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'
|
||||||
import { constants } from '../../constants'
|
|
||||||
|
|
||||||
export { NativePluginManager } from './native_plugin'
|
|
||||||
|
|
||||||
export namespace server {
|
export namespace server {
|
||||||
/**
|
/**
|
||||||
@ -19,6 +16,24 @@ export namespace server {
|
|||||||
* Runtime Server Instance
|
* Runtime Server Instance
|
||||||
*/
|
*/
|
||||||
export const ServerInstance = Symbol("ServerInstance")
|
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
|
* MiaoScript Server
|
||||||
*/
|
*/
|
||||||
@ -48,9 +63,6 @@ export namespace server {
|
|||||||
getPluginsFolder(): string {
|
getPluginsFolder(): string {
|
||||||
throw new Error("Method not implemented.")
|
throw new Error("Method not implemented.")
|
||||||
}
|
}
|
||||||
getNativePluginManager(): NativePluginManager {
|
|
||||||
throw new Error("Method not implemented.")
|
|
||||||
}
|
|
||||||
getDedicatedServer?(): any {
|
getDedicatedServer?(): any {
|
||||||
throw new Error("Method not implemented.")
|
throw new Error("Method not implemented.")
|
||||||
}
|
}
|
||||||
@ -63,8 +75,9 @@ export namespace server {
|
|||||||
}
|
}
|
||||||
@injectable()
|
@injectable()
|
||||||
export class ServerChecker {
|
export class ServerChecker {
|
||||||
@inject(ServerType)
|
@Autowired(ServerType)
|
||||||
private serverType: string
|
private serverType: string
|
||||||
|
|
||||||
check(servers: string[]) {
|
check(servers: string[]) {
|
||||||
// Not set servers -> allow
|
// Not set servers -> allow
|
||||||
if (!servers || !servers.length) return true
|
if (!servers || !servers.length) return true
|
||||||
@ -80,14 +93,17 @@ export namespace server {
|
|||||||
}
|
}
|
||||||
@injectable()
|
@injectable()
|
||||||
export abstract class ReflectServer extends server.Server {
|
export abstract class ReflectServer extends server.Server {
|
||||||
|
@Autowired(ContainerInstance)
|
||||||
|
private container: Container
|
||||||
|
|
||||||
protected pipeline: any
|
protected pipeline: any
|
||||||
protected rootLogger: any
|
protected rootLogger: any
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
this.reflect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@postConstruct()
|
||||||
protected reflect() {
|
protected reflect() {
|
||||||
try {
|
try {
|
||||||
let consoleServer = this.getDedicatedServer()
|
let consoleServer = this.getDedicatedServer()
|
||||||
@ -107,7 +123,11 @@ export namespace server {
|
|||||||
if (connection.class.name.indexOf('ServerConnection') !== -1
|
if (connection.class.name.indexOf('ServerConnection') !== -1
|
||||||
|| connection.class.name.indexOf('NetworkSystem') !== -1) { break }
|
|| connection.class.name.indexOf('NetworkSystem') !== -1) { break }
|
||||||
connection = undefined
|
connection = undefined
|
||||||
} catch (error) { }
|
} catch (error) {
|
||||||
|
if (global.debug) {
|
||||||
|
console.ex(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!connection) { console.error("Can't found ServerConnection!"); return }
|
if (!connection) { console.error("Can't found ServerConnection!"); return }
|
||||||
for (const field of constants.Reflect.Field.listeningChannels) {
|
for (const field of constants.Reflect.Field.listeningChannels) {
|
||||||
@ -115,16 +135,30 @@ export namespace server {
|
|||||||
promise = reflect.on(connection).get(field).get().get(0)
|
promise = reflect.on(connection).get(field).get().get(0)
|
||||||
if (promise.class.name.indexOf('Promise') !== -1) { break }
|
if (promise.class.name.indexOf('Promise') !== -1) { break }
|
||||||
promise = undefined
|
promise = undefined
|
||||||
} catch (error) { }
|
} catch (error) {
|
||||||
|
if (global.debug) {
|
||||||
|
console.ex(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!promise) { console.error("Can't found listeningChannels!"); return }
|
if (!promise) { console.error("Can't found listeningChannels!"); return }
|
||||||
this.pipeline = reflect.on(promise).get('channel').get().pipeline()
|
this.pipeline = reflect.on(promise).get('channel').get().pipeline()
|
||||||
|
this.container.bind(constants.ServiceIdentifier.NettyPipeline).toConstantValue(this.pipeline)
|
||||||
}
|
}
|
||||||
protected reflectRootLogger(consoleServer: any) {
|
protected reflectRootLogger(consoleServer: any) {
|
||||||
try {
|
try {
|
||||||
this.rootLogger = reflect.on(consoleServer).get('LOGGER').get().parent
|
this.rootLogger = reflect.on(consoleServer).get('LOGGER').get().parent
|
||||||
} catch (error) {
|
} 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) {
|
if (this.rootLogger && this.rootLogger.class.name.indexOf('Logger') === -1) {
|
||||||
console.error('Error Logger Class: ' + this.rootLogger.class.name)
|
console.error('Error Logger Class: ' + this.rootLogger.class.name)
|
||||||
@ -135,6 +169,7 @@ export namespace server {
|
|||||||
this.rootLogger = this.rootLogger.parent
|
this.rootLogger = this.rootLogger.parent
|
||||||
}
|
}
|
||||||
if (!this.rootLogger) { console.error("Can't found rootLogger!") }
|
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" />
|
/// <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.
|
* 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 {
|
class Reflect {
|
||||||
private obj: java.lang.Object
|
private obj: java.lang.Object
|
||||||
private class: java.lang.Class<any>
|
private class: java.lang.Class<any>
|
||||||
@ -34,15 +35,26 @@ class Reflect {
|
|||||||
return Java.from(declaredMethods(this.class))
|
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 {
|
||||||
try {
|
if (nameOrIndex == undefined || nameOrIndex == null) throw new Error(`reflect field name can't be ${nameOrIndex} from ${this.class.getName()}!`)
|
||||||
// Try getting a public field
|
let key = this.class.getName() + ':' + nameOrIndex + ':' + declared
|
||||||
let field = this.class.getField(name)
|
if (fieldCache.has(key)) {
|
||||||
return on(field.get(this.obj))
|
return fieldCache.get(key)
|
||||||
} catch (ex) {
|
|
||||||
// Try again, getting a non-public field
|
|
||||||
return on(accessible(declaredField(this.class, name)).get(this.obj))
|
|
||||||
}
|
}
|
||||||
|
let field = null
|
||||||
|
if (typeof nameOrIndex == "number") {
|
||||||
|
field = this.fields(declared)[nameOrIndex]
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
// Try getting a public field
|
||||||
|
field = this.class.getField(nameOrIndex)
|
||||||
|
} catch (ex) {
|
||||||
|
// Try again, getting a non-public field
|
||||||
|
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[] {
|
fields(declared = false): java.lang.reflect.Field[] {
|
||||||
@ -50,7 +62,7 @@ class Reflect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
values(declared = false) {
|
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 {
|
call(...args: any[]): Reflect {
|
||||||
@ -64,17 +76,12 @@ class Reflect {
|
|||||||
get(index: number, declared?: boolean): Reflect
|
get(index: number, declared?: boolean): Reflect
|
||||||
get(prop: string): Reflect
|
get(prop: string): Reflect
|
||||||
get(param?: string | number, declared: boolean = true): Reflect | any {
|
get(param?: string | number, declared: boolean = true): Reflect | any {
|
||||||
if (param == undefined || param == null) return this.obj
|
if (arguments.length === 0) return this.obj
|
||||||
if (typeof param == "number") {
|
return on(this.field(param, declared).get(this.obj))
|
||||||
return on(accessible(this.fields(declared)[param]).get(this.obj))
|
|
||||||
}
|
|
||||||
if (typeof param == "string") {
|
|
||||||
return this.field(param)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set(name: any, value: any): Reflect {
|
set(param: string | number, value: any, declared: boolean = true): Reflect {
|
||||||
accessible(declaredField(this.class, name)).set(this.obj, value)
|
this.field(param, declared).set(this.obj, value)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,64 +143,43 @@ function declaredField(clazz: java.lang.Class<any>, name: string | java.lang.Str
|
|||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
|
|
||||||
function declaredMethod(clazz: java.lang.Class<any>, name: string, ...clazzs: java.lang.Class<any>[]): java.lang.reflect.Method {
|
function declaredMethod(clazz: java.lang.Class<any>, nameOrIndex: string | number, ...clazzs: java.lang.Class<any>[]): java.lang.reflect.Method {
|
||||||
let key = clazz.getName() + '.' + name + ':' + (clazzs || []).join(':')
|
let key = clazz.getName() + '.' + nameOrIndex + ':' + (clazzs || []).map(c => c.getName()).join(':')
|
||||||
if (!methodCache[key]) {
|
if (methodCache.has(key)) { return methodCache.get(key) }
|
||||||
|
if (typeof nameOrIndex === "number") {
|
||||||
|
methodCache.set(key, declaredMethods(clazz)[nameOrIndex])
|
||||||
|
} else {
|
||||||
try {
|
try {
|
||||||
// @ts-ignore
|
methodCache.set(key, clazz.getMethod(nameOrIndex, clazzs as any))
|
||||||
methodCache[key] = clazz.getMethod(name, clazzs)
|
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
try {
|
try {
|
||||||
methodCache[key] = clazz.getDeclaredMethod(name, clazzs as any)
|
methodCache.set(key, clazz.getDeclaredMethod(nameOrIndex, clazzs as any))
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
for (const m of Java.from(declaredMethods(clazz))) {
|
for (const m of Java.from(declaredMethods(clazz))) {
|
||||||
if (m.getName() == name) {
|
if (m.getName() == nameOrIndex) {
|
||||||
methodCache[key] = m
|
methodCache.set(key, m)
|
||||||
break
|
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>) {
|
function declaredMethods(clazz: java.lang.Class<any>) {
|
||||||
return clazz.getDeclaredMethods()
|
return clazz.getDeclaredMethods()
|
||||||
}
|
}
|
||||||
|
|
||||||
let classMethodsCache: any[] = []
|
|
||||||
|
|
||||||
function mapToObject(javaObj) {
|
function mapToObject(javaObj) {
|
||||||
if (!javaObj || !javaObj.class) { throw new TypeError(`参数 ${javaObj} 不是一个Java对象!`) }
|
if (!Java.isJavaObject(javaObj)) { throw new TypeError(`参数 ${javaObj} 不是一个Java对象!`) }
|
||||||
let target = {}
|
let target = Proxy.newProxy(javaObj, {
|
||||||
getJavaObjectMethods(javaObj).forEach(t => mapMethod(target, javaObj, t))
|
apply: (target, name, args) => { return args ? javaObj[name](args) : javaObj[name]() }
|
||||||
|
})
|
||||||
return target
|
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) {
|
function on(obj) {
|
||||||
// if (!obj || !obj.class) { throw new TypeError(`参数 ${obj} 不是一个Java对象!`) }
|
// if (!obj || !obj.class) { throw new TypeError(`参数 ${obj} 不是一个Java对象!`) }
|
||||||
return new Reflect(obj)
|
return new Reflect(obj)
|
||||||
|
@ -99,6 +99,7 @@ function initialize() {
|
|||||||
console.i18n("ms.core.initialize.detect", { scope: global.scope, type })
|
console.i18n("ms.core.initialize.detect", { scope: global.scope, type })
|
||||||
container.bind(server.ServerType).toConstantValue(type)
|
container.bind(server.ServerType).toConstantValue(type)
|
||||||
container.bind(server.ServerChecker).toSelf().inSingletonScope()
|
container.bind(server.ServerChecker).toSelf().inSingletonScope()
|
||||||
|
container.bind(server.NativePluginManager).toSelf().inSingletonScope()
|
||||||
console.i18n("ms.core.package.initialize", { scope: global.scope, type })
|
console.i18n("ms.core.package.initialize", { scope: global.scope, type })
|
||||||
require(`${global.scope}/${type}`).default(container)
|
require(`${global.scope}/${type}`).default(container)
|
||||||
require(`${global.scope}/plugin`)
|
require(`${global.scope}/plugin`)
|
||||||
|
@ -81,8 +81,18 @@ declare global {
|
|||||||
i18n(name: string, ...params: any[]): void
|
i18n(name: string, ...params: any[]): void
|
||||||
}
|
}
|
||||||
interface ProxyConstructor {
|
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 { }
|
export { }
|
||||||
|
@ -1,17 +1,9 @@
|
|||||||
|
import { ProxyHandle } from '@ccms/nashorn'
|
||||||
|
|
||||||
// Nashorn JSAdapter See https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions-JSAdapterconstructor
|
// Nashorn JSAdapter See https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions-JSAdapterconstructor
|
||||||
let createProxy = eval(`
|
let createProxy = eval(`
|
||||||
function(handle){ return new JSAdapter(handle) }
|
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 {
|
export class Proxy {
|
||||||
static newProxy(target: any, handle: Partial<ProxyHandle>): any {
|
static newProxy(target: any, handle: Partial<ProxyHandle>): any {
|
||||||
return new Proxy(target, handle)
|
return new Proxy(target, handle)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import i18n from '@ccms/i18n'
|
import i18n from '@ccms/i18n'
|
||||||
import { plugin, server, event } from '@ccms/api'
|
import { plugin, server } from '@ccms/api'
|
||||||
import { inject, provideSingleton, Container, ContainerInstance, Autowired } from '@ccms/container'
|
import { provideSingleton, Container, ContainerInstance, Autowired } from '@ccms/container'
|
||||||
|
|
||||||
import './config'
|
import './config'
|
||||||
import { interfaces } from './interfaces'
|
import { interfaces } from './interfaces'
|
||||||
@ -13,15 +13,17 @@ const Thread = Java.type('java.lang.Thread')
|
|||||||
|
|
||||||
@provideSingleton(plugin.PluginManager)
|
@provideSingleton(plugin.PluginManager)
|
||||||
export class PluginManagerImpl implements plugin.PluginManager {
|
export class PluginManagerImpl implements plugin.PluginManager {
|
||||||
@inject(ContainerInstance)
|
@Autowired(ContainerInstance)
|
||||||
private container: Container
|
private container: Container
|
||||||
@inject(plugin.PluginInstance)
|
@Autowired(plugin.PluginInstance)
|
||||||
private pluginInstance: any
|
private pluginInstance: any
|
||||||
@inject(server.ServerType)
|
@Autowired(server.ServerType)
|
||||||
private serverType: string
|
private serverType: string
|
||||||
|
|
||||||
@Autowired()
|
@Autowired()
|
||||||
private serverChecker: server.ServerChecker
|
private serverChecker: server.ServerChecker
|
||||||
|
@Autowired()
|
||||||
|
private nativePluginManager: server.NativePluginManager
|
||||||
|
|
||||||
@Autowired()
|
@Autowired()
|
||||||
private taskManager: PluginTaskManager
|
private taskManager: PluginTaskManager
|
||||||
@ -224,15 +226,28 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
try {
|
try {
|
||||||
this.buildPlugin(metadata)
|
this.buildPlugin(metadata)
|
||||||
} catch (error) {
|
} 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) {
|
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.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.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)
|
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失败!`) }
|
||||||
this.instanceMap.set(metadata.name, pluginInstance)
|
this.instanceMap.set(metadata.name, pluginInstance)
|
||||||
|
@ -1,31 +1,32 @@
|
|||||||
import { server } from '@ccms/api'
|
import { constants, server } from '@ccms/api'
|
||||||
import { provideSingleton, inject } from '@ccms/container'
|
import { provideSingleton, postConstruct, Autowired, Container, ContainerInstance } from '@ccms/container'
|
||||||
import { NativePluginManager } from '@ccms/api'
|
|
||||||
import { CommandMap } from './internal/command'
|
import { CommandMap } from './internal/command'
|
||||||
|
|
||||||
@provideSingleton(server.Server)
|
@provideSingleton(server.Server)
|
||||||
export class SpringServer implements server.Server {
|
export class SpringServer extends server.Server {
|
||||||
@inject(CommandMap)
|
@Autowired(ContainerInstance)
|
||||||
|
private container: Container
|
||||||
|
@Autowired()
|
||||||
private commandMap: CommandMap
|
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 {
|
getVersion(): string {
|
||||||
return "SpringFramework"
|
return "SpringFramework"
|
||||||
}
|
}
|
||||||
getPlayer(name: string) {
|
|
||||||
throw new Error("Method not implemented.")
|
|
||||||
}
|
|
||||||
getOnlinePlayers(): any[] {
|
|
||||||
throw new Error("Method not implemented.")
|
|
||||||
}
|
|
||||||
getConsoleSender() {
|
getConsoleSender() {
|
||||||
return {
|
return {
|
||||||
name: 'CONSOLE',
|
name: 'CONSOLE',
|
||||||
sendMessage: (message: string) => console.console(message)
|
sendMessage: (message: string) => console.console(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getService(service: string) {
|
|
||||||
throw new Error("Method not implemented.")
|
|
||||||
}
|
|
||||||
dispatchCommand(sender: any, command: string): boolean {
|
dispatchCommand(sender: any, command: string): boolean {
|
||||||
let cmd_args = command.split(" ")
|
let cmd_args = command.split(" ")
|
||||||
return this.commandMap.dispatch(sender, cmd_args.shift(), cmd_args || [])
|
return this.commandMap.dispatch(sender, cmd_args.shift(), cmd_args || [])
|
||||||
@ -33,16 +34,10 @@ export class SpringServer implements server.Server {
|
|||||||
dispatchConsoleCommand(command: string): boolean {
|
dispatchConsoleCommand(command: string): boolean {
|
||||||
return this.dispatchCommand(this.getConsoleSender(), command)
|
return this.dispatchCommand(this.getConsoleSender(), command)
|
||||||
}
|
}
|
||||||
getPluginsFolder(): string {
|
|
||||||
throw new Error("Method not implemented.")
|
|
||||||
}
|
|
||||||
getNativePluginManager(): NativePluginManager {
|
|
||||||
throw new Error("Method not implemented.")
|
|
||||||
}
|
|
||||||
getNettyPipeline() {
|
getNettyPipeline() {
|
||||||
return base.getInstance().getAutowireCapableBeanFactory()
|
return this.nettyPipeline
|
||||||
}
|
}
|
||||||
getRootLogger() {
|
getRootLogger() {
|
||||||
return Packages.org.slf4j.LoggerFactory.getLogger("root") || global.logger
|
return this.rootLogger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user