From f9458e66c1050fbf41095115699e00ce44b1b4aa Mon Sep 17 00:00:00 2001 From: MiaoWoo Date: Wed, 1 Apr 2020 11:08:15 +0800 Subject: [PATCH] feat: add pipeline reflect Signed-off-by: MiaoWoo --- packages/api/src/interfaces/server/index.ts | 1 + packages/bukkit/src/server.ts | 25 ++++++++++++++++ packages/bungee/src/server.ts | 33 +++++++++++++++++++-- packages/bungee/src/task.ts | 4 +-- packages/common/src/reflect.ts | 2 +- packages/nukkit/src/server.ts | 3 ++ packages/sponge/src/server.ts | 26 ++++++++++++++-- 7 files changed, 87 insertions(+), 7 deletions(-) diff --git a/packages/api/src/interfaces/server/index.ts b/packages/api/src/interfaces/server/index.ts index ed1c6a0b..016e6454 100644 --- a/packages/api/src/interfaces/server/index.ts +++ b/packages/api/src/interfaces/server/index.ts @@ -30,6 +30,7 @@ export namespace server { dispatchConsoleCommand(command: string): boolean; getPluginsFolder(): string; getNativePluginManager(): NativePluginManager; + getNettyPipeline(): any; sendJson(sender: string | any, json: object | string): void; } } diff --git a/packages/bukkit/src/server.ts b/packages/bukkit/src/server.ts index 54aaa1f7..df90bcdc 100644 --- a/packages/bukkit/src/server.ts +++ b/packages/bukkit/src/server.ts @@ -1,16 +1,25 @@ import { server } from '@ms/api' import { provideSingleton } from '@ms/container'; +import * as reflect from '@ms/common/dist/reflect' import chat from './enhance/chat' +const refList: Array<{ server: string, future: string }> = [ + { server: 'an', future: 'g' },//spigot 1.12.2 + { server: 'getServerConnection', future: 'f' },//after spigot 1.14.4 + { server: 'func_147137_ag', future: 'field_151274_e' }//catserver 1.12.2 +] + let Bukkit = org.bukkit.Bukkit; @provideSingleton(server.Server) export class BukkitServer implements server.Server { private pluginsFolder: string; + private pipeline: any; constructor() { this.pluginsFolder = Bukkit.getUpdateFolderFile().getParentFile().getCanonicalPath(); + this.reflectPipeline() } getPlayer(name: string) { @@ -43,6 +52,9 @@ export class BukkitServer implements server.Server { getNativePluginManager() { return Bukkit.getPluginManager() as any; } + getNettyPipeline() { + return this.pipeline; + } sendJson(sender: string | any, json: object | string): void { if (typeof sender === "string") { sender = this.getPlayer(sender) @@ -52,4 +64,17 @@ export class BukkitServer implements server.Server { this.dispatchConsoleCommand(result) } } + + private reflectPipeline() { + let consoleServer = reflect.on(Bukkit.getServer()).get('console').get() + let promise: any; + for (const ref of refList) { + try { + promise = reflect.on(consoleServer).call(ref.server).get(ref.future).get().get(0); break; + } catch (error) { + } + } + if (!promise) { throw Error(`Can't found ServerConnection or ChannelFuture !`) } + this.pipeline = reflect.on(promise).get('channel').get().pipeline() + } } diff --git a/packages/bungee/src/server.ts b/packages/bungee/src/server.ts index 71076214..b01c6371 100644 --- a/packages/bungee/src/server.ts +++ b/packages/bungee/src/server.ts @@ -1,16 +1,42 @@ -import { server } from '@ms/api' -import { provideSingleton } from '@ms/container'; +import { server, task } from '@ms/api' +import { provideSingleton, inject, postConstruct } from '@ms/container' + +import * as reflect from '@ms/common/dist/reflect' let Bungee: net.md_5.bungee.api.ProxyServer = base.getInstance().getProxy(); @provideSingleton(server.Server) export class BungeeServer implements server.Server { private pluginsFolder: string; + private pipeline: any; + + @inject(task.TaskManager) + private task: task.TaskManager constructor() { this.pluginsFolder = Bungee.getPluginsFolder().getCanonicalPath(); } + @postConstruct() + initialize() { + let count = 0; + let wait = this.task.create(() => { + try { + // @ts-ignore + this.pipeline = reflect.on(base.getInstance().getProxy()).get('listeners').get().toArray()[0].pipeline() + wait.cancel(); + } catch (ex) { + count++ + if (count > 50) { + console.error('Reflect BungeeCord netty channel pipeline error time > 50times. Err: ' + ex) + wait.cancel() + } else { + console.warn('Wait BungeeCord start ready to get netty channel pipeline. Err: ' + ex) + } + } + }).later(10).timer(20).submit() + } + getPlayer(name: string) { return Bungee.getPlayer(name); } @@ -41,6 +67,9 @@ export class BungeeServer implements server.Server { getNativePluginManager() { return Bungee.getPluginManager() as any } + getNettyPipeline() { + return this.pipeline; + } sendJson(sender: string | any, json: string): void { throw new Error("Method not implemented."); } diff --git a/packages/bungee/src/task.ts b/packages/bungee/src/task.ts index 3deb1abe..c87921bb 100644 --- a/packages/bungee/src/task.ts +++ b/packages/bungee/src/task.ts @@ -25,9 +25,9 @@ export class BungeeTask extends task.Task { return this.plugin.getProxy().getScheduler().runAsync(this.plugin, run) } if (this.interval) { - return this.plugin.getProxy().getScheduler().schedule(this.plugin, run, this.laterTime, this.interval, TimeUnit.MILLISECONDS) + return this.plugin.getProxy().getScheduler().schedule(this.plugin, run, this.laterTime * 50, this.interval * 50, TimeUnit.MILLISECONDS) } else { - return this.plugin.getProxy().getScheduler().schedule(this.plugin, run, this.laterTime, TimeUnit.MILLISECONDS) + return this.plugin.getProxy().getScheduler().schedule(this.plugin, run, this.laterTime * 50, TimeUnit.MILLISECONDS) } } } diff --git a/packages/common/src/reflect.ts b/packages/common/src/reflect.ts index f111bfcb..bbadccd7 100644 --- a/packages/common/src/reflect.ts +++ b/packages/common/src/reflect.ts @@ -198,4 +198,4 @@ export = { accessible, declaredMethods, mapToObject -}; +} diff --git a/packages/nukkit/src/server.ts b/packages/nukkit/src/server.ts index 32d191b2..d88f23da 100644 --- a/packages/nukkit/src/server.ts +++ b/packages/nukkit/src/server.ts @@ -42,6 +42,9 @@ export class NukkitServer implements server.Server { getNativePluginManager() { return Nukkit.getPluginManager() as any; } + getNettyPipeline() { + throw new Error("Method not implemented."); + } sendJson(sender: string | any, json: object | string): void { throw new Error("Method not implemented."); } diff --git a/packages/sponge/src/server.ts b/packages/sponge/src/server.ts index 23444594..923033f9 100644 --- a/packages/sponge/src/server.ts +++ b/packages/sponge/src/server.ts @@ -1,19 +1,26 @@ import { server } from '@ms/api' import { provideSingleton } from '@ms/container'; -import * as fs from '@ms/common/dist/fs' +import * as reflect from '@ms/common/dist/reflect' + +const refList: Array<{ server: string, future: string }> = [ + { server: 'an', future: 'g' },//spigot 1.12.2 + { server: 'getServerConnection', future: 'f' },//after spigot 1.14.4 + { server: 'func_147137_ag', future: 'field_151274_e' }//catserver 1.12.2 +] const Sponge = org.spongepowered.api.Sponge; const TextSerializers = org.spongepowered.api.text.serializer.TextSerializers; -const URL = Java.type("java.net.URL"); const File = Java.type("java.io.File"); @provideSingleton(server.Server) export class SpongeServer implements server.Server { private pluginsFolder: string; + private pipeline: any; constructor() { this.pluginsFolder = new File(base.getInstance().getClass().getProtectionDomain().getCodeSource().getLocation().getPath()).getParentFile().getCanonicalPath() + this.reflectPipeline() } getPlayer(name: string) { @@ -46,10 +53,25 @@ export class SpongeServer implements server.Server { getNativePluginManager() { return Sponge.getPluginManager() as any; } + getNettyPipeline() { + return this.pipeline; + } sendJson(sender: string | any, json: string): void { if (typeof sender === "string") { sender = this.getPlayer(sender) } sender.sendMessage(TextSerializers.JSON.deserialize(json)) } + private reflectPipeline() { + let consoleServer = reflect.on(Sponge.getServer()).get() + let promise: any; + for (const ref of refList) { + try { + promise = reflect.on(consoleServer).call(ref.server).get(ref.future).get().get(0); break; + } catch (error) { + } + } + if (!promise) { throw Error(`Can't found ServerConnection or ChannelFuture !`) } + this.pipeline = reflect.on(promise).get('channel').get().pipeline() + } }