chore: 备份插件
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
parent
d5c2a825fc
commit
08ba1c1a98
@ -3,10 +3,12 @@
|
|||||||
import { plugin as pluginApi, server, task, constants, command } from '@ccms/api'
|
import { plugin as pluginApi, server, task, constants, command } from '@ccms/api'
|
||||||
import { plugin, interfaces, cmd, tab, enable, config, disable, PluginConfig } from '@ccms/plugin'
|
import { plugin, interfaces, cmd, tab, enable, config, disable, PluginConfig } from '@ccms/plugin'
|
||||||
import { ContainerInstance, Container, Autowired } from '@ccms/container'
|
import { ContainerInstance, Container, Autowired } from '@ccms/container'
|
||||||
import io, { Server as SocketIOServer, Socket as SocketIOSocket } from '@ccms/websocket'
|
import io from '@ccms/websocket'
|
||||||
import * as fs from '@ccms/common/dist/fs'
|
import * as fs from '@ccms/common/dist/fs'
|
||||||
import * as reflect from '@ccms/common/dist/reflect'
|
import * as reflect from '@ccms/common/dist/reflect'
|
||||||
|
|
||||||
|
import type { Namespace, Server as SocketIOServer, Socket as SocketIOSocket } from '@ccms/websocket'
|
||||||
|
|
||||||
const suffixMap = {
|
const suffixMap = {
|
||||||
ts: 'typescript',
|
ts: 'typescript',
|
||||||
js: 'javascript',
|
js: 'javascript',
|
||||||
@ -58,7 +60,7 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
this.token = Java.type('java.util.UUID').randomUUID().toString()
|
this.token = Java.type('java.util.UUID').randomUUID().toString()
|
||||||
this.logger.console(`§6已生成随机Token: §3${this.token} §c重启后或重新生成后失效!`)
|
this.logger.console(`§6已生成随机Token: §3${this.token} §c重启后或重新生成后失效!`)
|
||||||
}
|
}
|
||||||
process.on('message', (msg) => {
|
process.on('message', (msg: string) => {
|
||||||
this.logCache.push(msg)
|
this.logCache.push(msg)
|
||||||
if (this.logCache.length > 100) {
|
if (this.logCache.length > 100) {
|
||||||
this.logCache = this.logCache.slice(this.logCache.length - 100, this.logCache.length)
|
this.logCache = this.logCache.slice(this.logCache.length - 100, this.logCache.length)
|
||||||
@ -191,6 +193,7 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
disable() {
|
disable() {
|
||||||
if (this.socketIOServer) {
|
if (this.socketIOServer) {
|
||||||
this.socketIOServer.close()
|
this.socketIOServer.close()
|
||||||
|
process.removeAllListeners('websocket.create')
|
||||||
process.removeAllListeners('message')
|
process.removeAllListeners('message')
|
||||||
}
|
}
|
||||||
if (this.container.isBound(io.Instance)) {
|
if (this.container.isBound(io.Instance)) {
|
||||||
@ -230,30 +233,43 @@ export class MiaoConsole extends interfaces.Plugin {
|
|||||||
this.socketIOServer = io(this.instance, {
|
this.socketIOServer = io(this.instance, {
|
||||||
path: '/ws',
|
path: '/ws',
|
||||||
root: fs.concat(root, 'wwwroot')
|
root: fs.concat(root, 'wwwroot')
|
||||||
})
|
} as any)
|
||||||
this.container.bind(io.Instance).toConstantValue(this.socketIOServer)
|
this.container.bind(io.Instance).toConstantValue(this.socketIOServer)
|
||||||
process.emit('websocket.create', this.socketIOServer)
|
process.emit('websocket.create', this.socketIOServer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registryWebSocketNamespace(namespace: string, initialization: (namespace: Namespace) => void) {
|
||||||
|
if (this.socketIOServer) {
|
||||||
|
initialization(this.socketIOServer.of(namespace))
|
||||||
|
} else {
|
||||||
|
process.once('websocket.create', (server) => initialization(server.of(namespace)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkWebSocketClient(client: SocketIOSocket) {
|
||||||
|
if (!this.token) {
|
||||||
|
this.logger.console(`§6客户端 §b${client.id} §a请求连接 §4服务器尚未设置 Token 无法连接!`)
|
||||||
|
client.emit('unauthorized', () => client.disconnect(true))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (this.token != client.handshake.query.token) {
|
||||||
|
this.logger.console(`§6客户端 §b${client.id} §c无效请求 §4请提供正确Token后再次连接!`)
|
||||||
|
client.emit('unauthorized', () => client.disconnect(true))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
startSocketIOServer() {
|
startSocketIOServer() {
|
||||||
let namespace = this.socketIOServer.of('/MiaoConsole')
|
let namespace = this.socketIOServer.of('/MiaoConsole')
|
||||||
process.on('message', (msg) => namespace.emit('log', msg))
|
process.on('message', (msg) => namespace.emit('log', msg))
|
||||||
namespace.on('connection', (client: SocketIOSocket) => {
|
namespace.on('connection', (client: SocketIOSocket) => {
|
||||||
if (!this.token) {
|
if (this.checkWebSocketClient(client)) {
|
||||||
this.logger.console(`§6客户端 §b${client.id} §a请求连接 §4服务器尚未设置 Token 无法连接!`)
|
this.initWebSocketClient(client)
|
||||||
client.emit('unauthorized', () => client.disconnect(true))
|
this.logCache.forEach(msg => client.emit('log', msg))
|
||||||
return
|
this.logger.console(`§6客户端 §b${client.id} §a新建连接 ${this.rootLogger ? '启动日志转发' : '§4转发日志启动失败'}...`)
|
||||||
}
|
}
|
||||||
if (this.token != client.handshake.query.token) {
|
|
||||||
this.logger.console(`§6客户端 §b${client.id} §c无效请求 §4请提供正确Token后再次连接!`)
|
|
||||||
client.emit('unauthorized', () => client.disconnect(true))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.initWebSocketClient(client)
|
|
||||||
this.logCache.forEach(msg => client.emit('log', msg))
|
|
||||||
this.logger.console(`§6客户端 §b${client.id} §a新建连接 ${this.rootLogger ? '启动日志转发' : '§4转发日志启动失败'}...`)
|
|
||||||
})
|
})
|
||||||
process.emit('websocket.start', this.socketIOServer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private initWebSocketClient(client: SocketIOSocket) {
|
private initWebSocketClient(client: SocketIOSocket) {
|
||||||
|
303
packages/plugins/src/MiaoDashboard.ts
Normal file
303
packages/plugins/src/MiaoDashboard.ts
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
/// <reference types="@javatypes/bungee-api" />
|
||||||
|
/// <reference types="@javatypes/bukkit-api" />
|
||||||
|
/// <reference types="@javatypes/sponge-api" />
|
||||||
|
|
||||||
|
import { plugin, server, task } from '@ccms/api'
|
||||||
|
import { Autowired } from '@ccms/container'
|
||||||
|
import { Config, interfaces, JSPlugin, PluginConfig } from '@ccms/plugin'
|
||||||
|
|
||||||
|
import http from '@ccms/common/dist/http'
|
||||||
|
|
||||||
|
import type { Socket as SocketIOSocket, Namespace } from '@ccms/websocket'
|
||||||
|
import type { MiaoConsole } from './MiaoConsole'
|
||||||
|
|
||||||
|
const defaultConfig = {
|
||||||
|
statistics: {
|
||||||
|
max: 300
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultDataConfig = {
|
||||||
|
server_online: "%server_online%",
|
||||||
|
server_tps: "%server_tps_1%",
|
||||||
|
server_ram_used: "%server_ram_used%",
|
||||||
|
server_total_chunks: "%server_total_chunks%",
|
||||||
|
server_total_living_entities: "%server_total_living_entities%",
|
||||||
|
server_total_entities: "%server_total_entities%",
|
||||||
|
}
|
||||||
|
|
||||||
|
@JSPlugin({ prefix: 'Dashboard', version: '1.0.0', author: 'MiaoWoo', source: __filename, depends: ['MiaoConsole'] })
|
||||||
|
export class MiaoDashboard extends interfaces.Plugin {
|
||||||
|
@Autowired()
|
||||||
|
private server: server.Server
|
||||||
|
@Autowired()
|
||||||
|
private nativePluginManager: server.NativePluginManager
|
||||||
|
@Autowired()
|
||||||
|
private pluginManager: plugin.PluginManager
|
||||||
|
@Autowired()
|
||||||
|
private taskManager: task.TaskManager
|
||||||
|
|
||||||
|
private namespace: Namespace
|
||||||
|
|
||||||
|
@Config()
|
||||||
|
private config: PluginConfig & typeof defaultConfig = defaultConfig
|
||||||
|
@Config()
|
||||||
|
private dataConfig: PluginConfig & typeof defaultDataConfig = defaultDataConfig
|
||||||
|
@Config({ autosave: true })
|
||||||
|
private dataCache: { [key: string]: { time: string, value: Number }[] } = {}
|
||||||
|
private statisticTimer: task.Task
|
||||||
|
|
||||||
|
private PlaceholderAPI: { setPlaceholders: (player: any, str: string) => string }
|
||||||
|
|
||||||
|
load() {
|
||||||
|
for (const key of Object.keys(this.dataConfig)) {
|
||||||
|
this.dataCache[key] = this.dataCache[key] ?? []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enable() {
|
||||||
|
let consolePlugin: MiaoConsole = this.pluginManager.getPlugin('MiaoConsole') as MiaoConsole
|
||||||
|
consolePlugin.registryWebSocketNamespace('/MiaoDashboard', (namespace: Namespace) => {
|
||||||
|
this.namespace = namespace
|
||||||
|
this.namespace.on('connection', (client: SocketIOSocket) => {
|
||||||
|
if (consolePlugin.checkWebSocketClient(client)) {
|
||||||
|
this.initWebSocketClient(client)
|
||||||
|
this.logger.console(`§6客户端 §b${client.id} §a新建连接...`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.PlaceholderAPI = base.getClass("me.clip.placeholderapi.PlaceholderAPI").static
|
||||||
|
this.statisticTimer = this.taskManager.create(() => {
|
||||||
|
for (const key of Object.keys(this.dataConfig)) {
|
||||||
|
let dataArray = this.dataCache[key]
|
||||||
|
dataArray.push({
|
||||||
|
time: this.dateFormat('HH:MM:SS'),
|
||||||
|
value: parseFloat(this.taskManager.callSyncMethod(() => this.PlaceholderAPI['setPlaceholders(Player,String)'](null, this.dataConfig[key]))) ?? 0
|
||||||
|
})
|
||||||
|
if (dataArray.length > this.config.statistics.max) {
|
||||||
|
this.dataCache[key] = dataArray.slice(dataArray.length - this.config.statistics.max, dataArray.length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, this).async().timer(20 * 10).submit()
|
||||||
|
}
|
||||||
|
|
||||||
|
private dateFormat(fmt: string, date = new Date()) {
|
||||||
|
let ret: RegExpExecArray
|
||||||
|
const opt = {
|
||||||
|
"Y+": date.getFullYear().toString(), // 年
|
||||||
|
"m+": (date.getMonth() + 1).toString(), // 月
|
||||||
|
"d+": date.getDate().toString(), // 日
|
||||||
|
"H+": date.getHours().toString(), // 时
|
||||||
|
"M+": date.getMinutes().toString(), // 分
|
||||||
|
"S+": date.getSeconds().toString() // 秒
|
||||||
|
// 有其他格式化字符需求可以继续添加,必须转化成字符串
|
||||||
|
}
|
||||||
|
for (let k in opt) {
|
||||||
|
ret = new RegExp("(" + k + ")").exec(fmt)
|
||||||
|
if (ret) {
|
||||||
|
fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return fmt
|
||||||
|
}
|
||||||
|
|
||||||
|
disable() {
|
||||||
|
this.namespace?.close()
|
||||||
|
this.statisticTimer.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
private wrapper(fn, data) {
|
||||||
|
fn({ status: 0, data })
|
||||||
|
}
|
||||||
|
|
||||||
|
private initWebSocketClient(client: SocketIOSocket) {
|
||||||
|
client.on('message', (...args) => {
|
||||||
|
console.log(args)
|
||||||
|
})
|
||||||
|
this.initStatistics(client)
|
||||||
|
this.initPlayers(client)
|
||||||
|
this.initPlugins(client)
|
||||||
|
this.initServices(client)
|
||||||
|
client.on('error', (error) => {
|
||||||
|
this.logger.console(`§6客户端 §b${client.id} §c触发异常: ${error}`)
|
||||||
|
this.logger.error(error)
|
||||||
|
})
|
||||||
|
client.on('disconnect', () => {
|
||||||
|
this.logger.console(`§6客户端 §b${client.id} §c断开连接...`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private initStatistics(client: SocketIOSocket) {
|
||||||
|
client.on('statistics', (data, callback) => {
|
||||||
|
let result = {}
|
||||||
|
data.keys.map((key: string) => result[key] = this.dataCache[key])
|
||||||
|
this.wrapper(callback, { time: Date.now(), data: result })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
private initPlayers(client: SocketIOSocket) {
|
||||||
|
client.on('players', (callback) => {
|
||||||
|
let players = Java.from(this.server.getOnlinePlayers()).map((player: org.bukkit.entity.Player) => {
|
||||||
|
let loc = player.getLocation()
|
||||||
|
return {
|
||||||
|
name: player.getName(),
|
||||||
|
location: {
|
||||||
|
world: loc.getWorld().getName(),
|
||||||
|
x: loc.getX().toFixed(0),
|
||||||
|
y: loc.getY().toFixed(0),
|
||||||
|
z: loc.getZ().toFixed(0)
|
||||||
|
},
|
||||||
|
health: player.getHealth().toFixed(0),
|
||||||
|
foodlevel: player.getFoodLevel().toFixed(0),
|
||||||
|
gamemode: player.getGameMode().name(),
|
||||||
|
ip: player.getAddress().getAddress().getHostAddress()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.wrapper(callback, {
|
||||||
|
items: players
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.initPlayerModify(client)
|
||||||
|
client.on('players.heal', ({ name }, callback) => {
|
||||||
|
let player: org.bukkit.entity.Player = this.server.getPlayer(name)
|
||||||
|
if (!player) {
|
||||||
|
return callback({
|
||||||
|
status: 1,
|
||||||
|
msg: '玩家 ' + name + ' 不在线!'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
player.setHealth(player.getMaxHealth())
|
||||||
|
player.setFoodLevel(20)
|
||||||
|
player.sendMessage('§a您已被治疗 §7- 来自MiaoDashboard')
|
||||||
|
return callback({
|
||||||
|
status: 0,
|
||||||
|
msg: '操作成功!'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
client.on('players.kick', ({ name, reason }, callback) => {
|
||||||
|
let player: org.bukkit.entity.Player = this.server.getPlayer(name)
|
||||||
|
if (!player) {
|
||||||
|
return callback({
|
||||||
|
status: 1,
|
||||||
|
msg: '玩家 ' + name + ' 不在线!'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
player.kickPlayer(reason)
|
||||||
|
return callback({
|
||||||
|
status: 0,
|
||||||
|
msg: '操作成功!'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
private initPlayerModify(client: SocketIOSocket) {
|
||||||
|
client.on('players.modify.gamemode', ({ name, gamemode }, callback) => {
|
||||||
|
let player: org.bukkit.entity.Player = this.server.getPlayer(name)
|
||||||
|
if (!player) {
|
||||||
|
return callback({
|
||||||
|
status: 1,
|
||||||
|
msg: '玩家 ' + name + ' 不在线!'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let GameMode = Java.type('org.bukkit.GameMode')
|
||||||
|
let mode = GameMode.valueOf(gamemode)
|
||||||
|
this.taskManager.callSyncMethod(() => player.setGameMode(mode))
|
||||||
|
player.sendMessage('§a您的游戏模式已被修改为 ' + gamemode + ' §7- 来自MiaoDashboard')
|
||||||
|
return callback({
|
||||||
|
status: 0,
|
||||||
|
msg: '操作成功!'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
private initPlugins(client: SocketIOSocket) {
|
||||||
|
this.initNativePlugins(client)
|
||||||
|
this.initScriptPlugins(client)
|
||||||
|
}
|
||||||
|
private initServices(client: SocketIOSocket) {
|
||||||
|
client.on('services.plugins', (callback) => {
|
||||||
|
this.wrapper(callback, http.get('http://w.yumc.pw/api/free_plugin/find').data.map(plugin => {
|
||||||
|
let installed = this.nativePluginManager.get(plugin.name)
|
||||||
|
if (installed) {
|
||||||
|
plugin.installed = true
|
||||||
|
plugin.installedVersion = installed.version
|
||||||
|
}
|
||||||
|
plugin.installed = this.nativePluginManager.has(plugin.name)
|
||||||
|
return plugin
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
client.on('services.plugins.install', ({ name }, callback) => {
|
||||||
|
return callback({
|
||||||
|
status: 0,
|
||||||
|
msg: `插件 ${name} 安装成功!`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
client.on('services.plugins.update', ({ name }, callback) => {
|
||||||
|
return callback({
|
||||||
|
status: 0,
|
||||||
|
msg: `插件 ${name} 安装成功!`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
private initNativePlugins(client: SocketIOSocket) {
|
||||||
|
client.on('plugins.natives', callback => {
|
||||||
|
this.wrapper(callback, this.nativePluginManager.list().map(plugin => {
|
||||||
|
plugin.status = plugin.enable ? 1 : 0
|
||||||
|
return plugin
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
client.on('plugins.natives.reload', ({ name }, callback) => {
|
||||||
|
return callback({
|
||||||
|
status: 0,
|
||||||
|
msg: `插件 ${name} 不存在`
|
||||||
|
})
|
||||||
|
return callback({
|
||||||
|
status: 0,
|
||||||
|
msg: `插件 ${name} 安装完成`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
client.on('plugins.natives.install', ({ name }, callback) => {
|
||||||
|
return callback({
|
||||||
|
status: 0,
|
||||||
|
msg: `插件 ${name} 不存在`
|
||||||
|
})
|
||||||
|
return callback({
|
||||||
|
status: 0,
|
||||||
|
msg: `插件 ${name} 安装完成`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private initScriptPlugins(client: SocketIOSocket) {
|
||||||
|
client.on('plugins.scripts', (callback) => {
|
||||||
|
let plugins = []
|
||||||
|
this.pluginManager.getPlugins().forEach((plugin) => {
|
||||||
|
plugins.push({
|
||||||
|
name: plugin.description.name,
|
||||||
|
version: plugin.description.version,
|
||||||
|
author: plugin.description.author,
|
||||||
|
source: plugin.description.source.toString().replace(root, ''),
|
||||||
|
type: plugin.description.type,
|
||||||
|
scanner: plugin.description.loadMetadata.scanner.type,
|
||||||
|
loader: plugin.description.loadMetadata.loader.type,
|
||||||
|
status: 1
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.wrapper(callback, {
|
||||||
|
items: plugins,
|
||||||
|
total: plugins.length
|
||||||
|
})
|
||||||
|
})
|
||||||
|
client.on('plugins.scripts.reload', ({ name }, callback) => {
|
||||||
|
let plugin: any = this.pluginManager.getPlugin(name)
|
||||||
|
if (!plugin) {
|
||||||
|
return callback({
|
||||||
|
status: 404,
|
||||||
|
msg: `插件 ${name} 不存在`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.pluginManager.reload(plugin)
|
||||||
|
return callback({
|
||||||
|
status: 0,
|
||||||
|
msg: `插件 ${name} 重载完成`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,8 @@ import { Server as SocketIOServer, Socket as SocketIOSocket, Namespace } from '@
|
|||||||
|
|
||||||
import * as fs from '@ccms/common/dist/fs'
|
import * as fs from '@ccms/common/dist/fs'
|
||||||
|
|
||||||
|
import type { MiaoConsole } from './MiaoConsole'
|
||||||
|
|
||||||
const FileFilter = Java.type('java.io.FileFilter')
|
const FileFilter = Java.type('java.io.FileFilter')
|
||||||
const ByteArrayInputStream = java.io.ByteArrayInputStream
|
const ByteArrayInputStream = java.io.ByteArrayInputStream
|
||||||
const ByteArrayOutputStream = java.io.ByteArrayOutputStream
|
const ByteArrayOutputStream = java.io.ByteArrayOutputStream
|
||||||
@ -16,14 +18,13 @@ const StandardCharsets = Java.type("java.nio.charset.StandardCharsets")
|
|||||||
const GZIPInputStream = Java.type('java.util.zip.GZIPInputStream')
|
const GZIPInputStream = Java.type('java.util.zip.GZIPInputStream')
|
||||||
const ByteArray = Java.type("byte[]")
|
const ByteArray = Java.type("byte[]")
|
||||||
|
|
||||||
@JSPlugin({ prefix: 'Explorer', version: '1.0.0', author: 'MiaoWoo', source: __filename })
|
@JSPlugin({ prefix: 'Explorer', version: '1.0.0', author: 'MiaoWoo', source: __filename, depends: ['MiaoConsole'] })
|
||||||
export class MiaoExplorer extends interfaces.Plugin {
|
export class MiaoExplorer extends interfaces.Plugin {
|
||||||
@Autowired()
|
@Autowired()
|
||||||
private Server: server.Server
|
private Server: server.Server
|
||||||
@Autowired()
|
@Autowired()
|
||||||
private pluginManager: plugin.PluginManager
|
private pluginManager: plugin.PluginManager
|
||||||
|
|
||||||
private token: string
|
|
||||||
private namespace: any
|
private namespace: any
|
||||||
private chunkCacheMap: Map<string, Array<string>>
|
private chunkCacheMap: Map<string, Array<string>>
|
||||||
|
|
||||||
@ -32,39 +33,20 @@ export class MiaoExplorer extends interfaces.Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enable() {
|
enable() {
|
||||||
let consolePlugin: any = this.pluginManager.getPlugin('MiaoConsole')
|
let consolePlugin: MiaoConsole = this.pluginManager.getPlugin('MiaoConsole') as MiaoConsole
|
||||||
if (consolePlugin.socketIOServer) {
|
consolePlugin.registryWebSocketNamespace('/MiaoExplorer', (namespace: Namespace) => {
|
||||||
this.startWebSocketServer(consolePlugin.socketIOServer)
|
this.namespace = namespace
|
||||||
} else {
|
this.namespace.on('connection', (client: SocketIOSocket) => {
|
||||||
process.on('websocket.create', (server: SocketIOServer) => {
|
if (consolePlugin.checkWebSocketClient(client)) {
|
||||||
this.startWebSocketServer(server)
|
this.initWebSocketClient(client)
|
||||||
|
this.logger.console(`§6客户端 §b${client.id} §a新建连接...`)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private startWebSocketServer(server: SocketIOServer) {
|
|
||||||
let consolePlugin: any = this.pluginManager.getPlugin('MiaoConsole')
|
|
||||||
this.token = consolePlugin.token
|
|
||||||
this.namespace = server.of('/MiaoExplorer')
|
|
||||||
this.namespace.on('connection', (client: SocketIOSocket) => {
|
|
||||||
if (!this.token) {
|
|
||||||
this.logger.console(`§6客户端 §b${client.id} §a请求连接 §4服务器尚未设置 Token 无法连接!`)
|
|
||||||
client.emit('unauthorized', () => client.disconnect(true))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.token != client.handshake.query.token) {
|
|
||||||
this.logger.console(`§6客户端 §b${client.id} §c无效请求 §4请提供正确Token后再次连接!`)
|
|
||||||
client.emit('unauthorized', () => client.disconnect(true))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.initWebSocketClient(client)
|
|
||||||
this.logger.console(`§6客户端 §b${client.id} §a新建连接...`)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
disable() {
|
disable() {
|
||||||
this.namespace.removeAllListeners('connect')
|
this.namespace?.close()
|
||||||
this.namespace.close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readDir(dir) {
|
private readDir(dir) {
|
||||||
@ -161,15 +143,4 @@ export class MiaoExplorer extends interfaces.Plugin {
|
|||||||
this.logger.console(`§6客户端 §b${client.id} §c断开连接...`)
|
this.logger.console(`§6客户端 §b${client.id} §c断开连接...`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cmd()
|
|
||||||
msme(sender: any, command: string, args: string[]) {
|
|
||||||
this.logger.log(sender, command, args)
|
|
||||||
sender.sendMessage(JSON.stringify({ command, ...args }))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Tab()
|
|
||||||
tabmsme(_sender: any, _command: string, _args: string[]) {
|
|
||||||
return ['world']
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ const defaultConfig = {
|
|||||||
joinTip: true
|
joinTip: true
|
||||||
}
|
}
|
||||||
|
|
||||||
@JSPlugin({ prefix: 'MRD', version: '1.5.9', author: 'MiaoWoo', servers: [constants.ServerType.Bukkit], nativeDepends: ['ProtocolLib', 'PlaceholderAPI'], source: __filename })
|
@JSPlugin({ prefix: 'MRD', version: '1.6.0', author: 'MiaoWoo', servers: [constants.ServerType.Bukkit], nativeDepends: ['ProtocolLib', 'PlaceholderAPI'], source: __filename })
|
||||||
export class MiaoReward extends interfaces.Plugin {
|
export class MiaoReward extends interfaces.Plugin {
|
||||||
public serverInfo: ServerInfo
|
public serverInfo: ServerInfo
|
||||||
private notifyError = true
|
private notifyError = true
|
||||||
@ -79,6 +79,7 @@ export class MiaoReward extends interfaces.Plugin {
|
|||||||
private playerInfoCache = new Map<string, UserInfo>()
|
private playerInfoCache = new Map<string, UserInfo>()
|
||||||
|
|
||||||
private downgrade = false
|
private downgrade = false
|
||||||
|
private subversion = 0
|
||||||
|
|
||||||
@Autowired()
|
@Autowired()
|
||||||
private chat: chat.Chat
|
private chat: chat.Chat
|
||||||
@ -132,6 +133,7 @@ export class MiaoReward extends interfaces.Plugin {
|
|||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
this.logger.prefix = this.config.prefix
|
this.logger.prefix = this.config.prefix
|
||||||
this.downgrade = this.Bukkit.server.class.name.split('.')[3] == "v1_7_R4"
|
this.downgrade = this.Bukkit.server.class.name.split('.')[3] == "v1_7_R4"
|
||||||
|
this.subversion = parseInt(this.Bukkit.server.class.name.split('.')[3].split('_')[1])
|
||||||
this.updateServerInfo(null, () => this.updateOnlinePlayersInfo())
|
this.updateServerInfo(null, () => this.updateOnlinePlayersInfo())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,29 +250,50 @@ export class MiaoReward extends interfaces.Plugin {
|
|||||||
if (!this.ProtocolLibrary) {
|
if (!this.ProtocolLibrary) {
|
||||||
return this.logger.console(`§4服务器未安装 ProtocolLib 无法扫码功能 请安装后重试!`)
|
return this.logger.console(`§4服务器未安装 ProtocolLib 无法扫码功能 请安装后重试!`)
|
||||||
}
|
}
|
||||||
this.adapter = this.createPacketAdapter((event) => {
|
let writer = undefined
|
||||||
|
if (this.downgrade) {
|
||||||
|
writer = (packet, bytes) => {
|
||||||
|
// let xbytes = new Bytes(131)
|
||||||
|
let origin = packet.getByteArrays().read(0)
|
||||||
|
// xbytes[1] = origin[1]
|
||||||
|
// xbytes[2] = origin[2]
|
||||||
|
for (let y = 0; y < 128; ++y) {
|
||||||
|
origin[y + 3] = bytes[y * 128 + origin[1]]
|
||||||
|
}
|
||||||
|
packet.getByteArrays().write(0, origin)
|
||||||
|
}
|
||||||
|
} else if (this.subversion < 17) {
|
||||||
|
writer = (packet, bytes) => {
|
||||||
|
packet.getByteArrays().write(0, bytes)
|
||||||
|
packet.getIntegers().write(3, 128)
|
||||||
|
packet.getIntegers().write(4, 128)
|
||||||
|
}
|
||||||
|
} else if (this.subversion > 16) {
|
||||||
|
writer = (packet, bytes) => {
|
||||||
|
let b = packet.getModifier().read(4)
|
||||||
|
if (b) {
|
||||||
|
let bi = Java.type(b.class.name)
|
||||||
|
packet.getModifier().write(4, new bi(b.a, b.b, 128, 128, bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (writer) {
|
||||||
|
this.adapter = this.createPacketAdapter(this.getPacketAdapter(writer))
|
||||||
|
this.ProtocolLibrary.getProtocolManager().addPacketListener(this.adapter)
|
||||||
|
} else {
|
||||||
|
console.console('§4当前服务器不支持虚拟地图发包 将无法使用扫码功能!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getPacketAdapter(writer: (packet: any, bytes: number[]) => void) {
|
||||||
|
return (event) => {
|
||||||
let integers = event.getPacket().getIntegers().getValues()
|
let integers = event.getPacket().getIntegers().getValues()
|
||||||
let mapId = integers.get(0)
|
let mapId = integers.get(0)
|
||||||
let player = event.getPlayer()
|
let player = event.getPlayer()
|
||||||
if (mapId == this.zeroMapView.getId() && this.playerImageCache.has(player.getName())) {
|
if (mapId == this.zeroMapView.getId() && this.playerImageCache.has(player.getName())) {
|
||||||
let bytes = this.playerImageCache.get(player.getName())
|
writer(event.getPacket(), this.playerImageCache.get(player.getName()))
|
||||||
if (!this.downgrade) {
|
|
||||||
event.getPacket().getByteArrays().write(0, bytes)
|
|
||||||
event.getPacket().getIntegers().write(3, 128)
|
|
||||||
event.getPacket().getIntegers().write(4, 128)
|
|
||||||
} else {
|
|
||||||
// let xbytes = new Bytes(131)
|
|
||||||
let origin = event.getPacket().getByteArrays().read(0)
|
|
||||||
// xbytes[1] = origin[1]
|
|
||||||
// xbytes[2] = origin[2]
|
|
||||||
for (let y = 0; y < 128; ++y) {
|
|
||||||
origin[y + 3] = bytes[y * 128 + origin[1]]
|
|
||||||
}
|
|
||||||
event.getPacket().getByteArrays().write(0, origin)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
this.ProtocolLibrary.getProtocolManager().addPacketListener(this.adapter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private sendWindowItems(player: org.bukkit.entity.Player, mapItem: any) {
|
private sendWindowItems(player: org.bukkit.entity.Player, mapItem: any) {
|
||||||
|
Loading…
Reference in New Issue
Block a user