fix: command registry error

Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
MiaoWoo 2020-09-24 10:33:16 +08:00
parent 51fb5aece3
commit f8046e38be
8 changed files with 46 additions and 41 deletions

View File

@ -62,9 +62,9 @@ export namespace command {
var complete = tabCompleter(sender, command, Java.from(args)) || []
return this.copyPartialMatches(complete, token)
} catch (ex) {
console.i18n("ms.api.command.tab.completer.error", { sender: sender.name, plugin: plugin.description.name, command, args: Java.from(args).join(' '), ex })
console.i18n("ms.api.command.tab.completer.error", { player: sender.name, plugin: plugin.description.name, command, args: Java.from(args).join(' '), ex })
console.ex(ex)
console.sender(sender, [i18n.translate("ms.api.command.tab.completer.error", { sender: sender.name, plugin: plugin.description.name, command, args: Java.from(args).join(' '), ex }), ...console.stack(ex)])
console.sender(sender, [i18n.translate("ms.api.command.tab.completer.error", { player: sender.name, plugin: plugin.description.name, command, args: Java.from(args).join(' '), ex }), ...console.stack(ex)])
return []
}
}

View File

@ -2,7 +2,7 @@
import "reflect-metadata"
import { initContainer, getContainer } from './decorators'
import { interfaces, Container } from 'inversify'
import { interfaces, Container, inject, named } from 'inversify'
import { fluentProvide } from 'inversify-binding-decorators'
import { ioc } from "./constants"
@ -59,22 +59,20 @@ export const JSClass = (className: string) => {
*
* @param className
*/
export const Autowired = (className?: string | any) => {
export const Autowired = (className?: any) => {
return function (target: any, propertyKey: string, index?: number) {
let container = getContainer()
if (className instanceof Symbol || className instanceof Function) {
return inject(className)(target, propertyKey, index)
}
let type = Reflect.getMetadata('design:type', target, propertyKey)
if (type && type !== Object) {
try {
return target[propertyKey] = container.getNamed(type, className || propertyKey)
} catch (error) {
try {
return target[propertyKey] = container.get(type)
} catch (error) {
}
}
}
if (container.isBound(ioc.Autowired)) {
inject(type)(target, propertyKey, index)
named(className || propertyKey)(target, propertyKey, index)
} else if (container.isBound(ioc.Autowired)) {
target[propertyKey] = container.getNamed(ioc.Autowired, className || propertyKey)
} else {
throw new Error(`No matching bindings found for target: ${target.constructor.name} type: ${type} named: ${className || propertyKey}`)
}
}
}

View File

@ -1,5 +1,5 @@
import { command, plugin, server } from '@ccms/api'
import { provideSingleton, postConstruct, inject } from '@ccms/container'
import { provideSingleton, inject } from '@ccms/container'
import { getPluginCommandMetadata, getPluginTabCompleterMetadata } from './utils'
@provideSingleton(PluginCommandManager)
@ -17,13 +17,19 @@ export class PluginCommandManager {
private registryCommand(pluginInstance: plugin.Plugin) {
let cmds = getPluginCommandMetadata(pluginInstance)
let tabs = getPluginTabCompleterMetadata(pluginInstance)
for (const [_, cmd] of cmds) {
for (const cmd of cmds) {
let tab = tabs.get(cmd.name)
if (!this.ServerChecker.check(cmd.servers)) { continue }
this.CommandManager.on(pluginInstance, cmd.name, {
if (!this.ServerChecker.check(cmd.servers)) {
console.debug(`[${pluginInstance.description.name}] ${cmd.target.constructor.name} incompatible command ${cmd.name} server(${cmd.servers}) ignore.`)
continue
}
let exec = {
cmd: pluginInstance[cmd.executor].bind(pluginInstance),
tab: tab ? pluginInstance[tab.executor].bind(pluginInstance) : undefined
})
}
for (let command of [cmd.name, ...cmd.alias]) {
this.CommandManager.on(pluginInstance, command, exec)
}
}
}

View File

@ -30,13 +30,11 @@ export function plugin(metadata: pluginApi.PluginMetadata | any) {
export function cmd(metadata: interfaces.CommandMetadata = {}) {
return function (target: any, key: string, value: any) {
metadata.name = metadata.name || key
metadata.alias = metadata.alias || []
metadata.target = target
metadata.executor = key
metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key)
const previousMetadata: Map<string, interfaces.CommandMetadata> = getPluginCommandMetadata(target)
previousMetadata.set(metadata.name, metadata)
metadata.alias?.forEach((name) => previousMetadata.set(name, metadata))
Reflect.defineMetadata(METADATA_KEY.cmd, previousMetadata, target.constructor)
Reflect.defineMetadata(METADATA_KEY.cmd, [metadata, ...getPluginCommandMetadata(target)], target.constructor)
}
}
@ -48,10 +46,11 @@ export function tab(metadata: interfaces.CommandMetadata = {}) {
return function (target: any, key: string, value: any) {
metadata.name = metadata.name || (key.startsWith('tab') ? key.split('tab', 2)[1] : key)
if (!metadata.name) { return }
metadata.alias = metadata.alias || []
metadata.target = target
metadata.executor = key
metadata.paramtypes = Reflect.getMetadata("design:paramtypes", target, key)
const previousMetadata: Map<string, interfaces.CommandMetadata> = getPluginTabCompleterMetadata(target)
let previousMetadata = getPluginTabCompleterMetadata(target)
previousMetadata.set(metadata.name, metadata)
metadata.alias?.forEach((name) => previousMetadata.set(name, metadata))
Reflect.defineMetadata(METADATA_KEY.tab, previousMetadata, target.constructor)
@ -67,8 +66,7 @@ export function listener(metadata: interfaces.ListenerMetadata = {}) {
metadata.name = metadata.name || key
metadata.target = target
metadata.executor = key
const previousMetadata: interfaces.ListenerMetadata[] = getPluginListenerMetadata(target)
Reflect.defineMetadata(METADATA_KEY.listener, [metadata, ...previousMetadata], target.constructor)
Reflect.defineMetadata(METADATA_KEY.listener, [metadata, ...getPluginListenerMetadata(target)], target.constructor)
Reflect.defineMetadata(METADATA_KEY.listener, metadata, target[key])
}
}
@ -79,7 +77,7 @@ export function config(metadata: interfaces.ConfigMetadata = {}) {
metadata.variable = key
metadata.version = metadata.version ?? 1
metadata.format = metadata.format ?? 'yml'
const previousMetadata: Map<string, interfaces.ConfigMetadata> = getPluginConfigMetadata(target)
let previousMetadata = getPluginConfigMetadata(target)
previousMetadata.set(metadata.name, metadata)
Reflect.defineMetadata(METADATA_KEY.config, previousMetadata, target.constructor)
}
@ -90,8 +88,7 @@ function stage(stage: string) {
return function (target: any, key: string, value: any) {
metadata.name = metadata.name || key
metadata.executor = key
const previousMetadata: interfaces.ExecMetadata[] = getPluginStageMetadata(target, stage)
Reflect.defineMetadata(METADATA_KEY.stage[stage], [metadata, ...previousMetadata], target.constructor)
Reflect.defineMetadata(METADATA_KEY.stage[stage], [metadata, ...getPluginStageMetadata(target, stage)], target.constructor)
}
}
}

View File

@ -18,7 +18,10 @@ export class PluginEventManager {
let events = getPluginListenerMetadata(pluginInstance)
for (const event of events) {
// ignore space listener
if (!this.ServerChecker.check(event.servers)) { continue }
if (!this.ServerChecker.check(event.servers)) {
console.debug(`[${pluginInstance.description.name}] ${event.target.constructor.name} incompatible event ${event.name} server(${event.servers}) ignore.`)
continue
}
// here must bind this to pluginInstance
let exec = event.target[event.executor]
let execBinded = exec.bind(pluginInstance)

View File

@ -37,10 +37,10 @@ function getPluginMetadata(target: any) {
}
function getPluginCommandMetadata(target: any) {
let commandMetadata: Map<string, interfaces.CommandMetadata> = Reflect.getMetadata(
let commandMetadata: interfaces.CommandMetadata[] = Reflect.getMetadata(
METADATA_KEY.cmd,
target.constructor
) || new Map<string, interfaces.CommandMetadata>()
) || []
return commandMetadata
}

View File

@ -49,11 +49,11 @@ class SimpleCommandCallable {
this.callable = new CommandCallable({
//CommandResult process(CommandSource source, String arguments) throws CommandException
process: (sender: any, args) => {
return this.executor(sender, '', command, Java.to(args.split(" ").filter(e => e))) ? CommandResult.success() : CommandResult.empty()
return this.executor(sender, '', command, Java.to(args.split(" "))) ? CommandResult.success() : CommandResult.empty()
},
//List<String> getSuggestions(CommandSource source, String arguments, @Nullable Location<World> targetPosition) throws CommandException
getSuggestions: (sender: any, args, target) => {
return this.tabCompleter(sender, '', command, Java.to(args.split(" ").filter(e => e)))
return this.tabCompleter(sender, '', command, Java.to(args.split(" ")))
},
//boolean testPermission(CommandSource source)
testPermission: () => {

View File

@ -3,13 +3,14 @@
import { server } from '@ccms/api'
import { Container } from '@ccms/container'
import { SpongeConsole } from './console';
import './event';
import './server';
import './command';
import './channel';
import './task';
import { SpongeConsole } from './console'
import './chat'
import './task'
import './event'
import './server'
import './command'
import './channel'
export default function SpongeImpl(container: Container) {
container.bind(server.Console).toConstantValue(SpongeConsole);
container.bind(server.Console).toConstantValue(SpongeConsole)
}