@@ -2,16 +2,16 @@
 | 
			
		||||
/// <reference types="@javatypes/spigot-api" />
 | 
			
		||||
/// <reference types="@javatypes/sponge-api" />
 | 
			
		||||
 | 
			
		||||
import { server, plugin as pluginApi, channel, constants } from '@ccms/api'
 | 
			
		||||
import { inject, optional } from '@ccms/container';
 | 
			
		||||
import { server, plugin as pluginApi, channel, constants, chat } from '@ccms/api'
 | 
			
		||||
import { inject, optional } from '@ccms/container'
 | 
			
		||||
import { plugin, interfaces, cmd, listener, tab, config, enable } from '@ccms/plugin'
 | 
			
		||||
import Tellraw from '@ccms/common/dist/tellraw'
 | 
			
		||||
 | 
			
		||||
const ByteArrayInputStream = Java.type("java.io.ByteArrayInputStream");
 | 
			
		||||
const ByteArrayOutputStream = Java.type("java.io.ByteArrayOutputStream");
 | 
			
		||||
const StandardCharsets = Java.type("java.nio.charset.StandardCharsets");
 | 
			
		||||
const GZIPInputStream = Java.type("java.util.zip.GZIPInputStream");
 | 
			
		||||
const GZIPOutputStream = Java.type("java.util.zip.GZIPOutputStream");
 | 
			
		||||
const ByteArrayInputStream = Java.type("java.io.ByteArrayInputStream")
 | 
			
		||||
const ByteArrayOutputStream = Java.type("java.io.ByteArrayOutputStream")
 | 
			
		||||
const StandardCharsets = Java.type("java.nio.charset.StandardCharsets")
 | 
			
		||||
const GZIPInputStream = Java.type("java.util.zip.GZIPInputStream")
 | 
			
		||||
const GZIPOutputStream = Java.type("java.util.zip.GZIPOutputStream")
 | 
			
		||||
const BiConsumer = Java.type('java.util.function.BiConsumer')
 | 
			
		||||
const ByteArray = Java.type("byte[]")
 | 
			
		||||
 | 
			
		||||
@@ -22,31 +22,31 @@ class MiaoMessage {
 | 
			
		||||
    private static MAX_MESSAGE_LENGTH = 32000;
 | 
			
		||||
 | 
			
		||||
    private static copy(input, output) {
 | 
			
		||||
        let buffer = new ByteArray(1024);
 | 
			
		||||
        let n: number;
 | 
			
		||||
        let buffer = new ByteArray(1024)
 | 
			
		||||
        let n: number
 | 
			
		||||
        while ((n = input.read(buffer)) != -1) {
 | 
			
		||||
            output.write(buffer, 0, n);
 | 
			
		||||
            output.write(buffer, 0, n)
 | 
			
		||||
        }
 | 
			
		||||
        input.close();
 | 
			
		||||
        output.close();
 | 
			
		||||
        input.close()
 | 
			
		||||
        output.close()
 | 
			
		||||
    }
 | 
			
		||||
    public static encode(input: any): any {
 | 
			
		||||
        return new MiaoMessage(input).encode();
 | 
			
		||||
        return new MiaoMessage(input).encode()
 | 
			
		||||
    }
 | 
			
		||||
    public static decode(input: any): MiaoMessage {
 | 
			
		||||
        let baos = new ByteArrayOutputStream();
 | 
			
		||||
        MiaoMessage.copy(new GZIPInputStream(new ByteArrayInputStream(input)), baos);
 | 
			
		||||
        return new MiaoMessage(baos.toString(StandardCharsets.UTF_8.name()));
 | 
			
		||||
        let baos = new ByteArrayOutputStream()
 | 
			
		||||
        MiaoMessage.copy(new GZIPInputStream(new ByteArrayInputStream(input)), baos)
 | 
			
		||||
        return new MiaoMessage(baos.toString(StandardCharsets.UTF_8.name()))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // private String json;
 | 
			
		||||
    constructor(public json: any) { }
 | 
			
		||||
 | 
			
		||||
    public encode(): any {
 | 
			
		||||
        let baos = new ByteArrayOutputStream();
 | 
			
		||||
        MiaoMessage.copy(new ByteArrayInputStream(this.json.getBytes(StandardCharsets.UTF_8)), new GZIPOutputStream(baos));
 | 
			
		||||
        if (baos.size() > MiaoMessage.MAX_MESSAGE_LENGTH) { return null; }
 | 
			
		||||
        return baos.toByteArray();
 | 
			
		||||
        let baos = new ByteArrayOutputStream()
 | 
			
		||||
        MiaoMessage.copy(new ByteArrayInputStream(this.json.getBytes(StandardCharsets.UTF_8)), new GZIPOutputStream(baos))
 | 
			
		||||
        if (baos.size() > MiaoMessage.MAX_MESSAGE_LENGTH) { return null }
 | 
			
		||||
        return baos.toByteArray()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -54,10 +54,12 @@ class MiaoMessage {
 | 
			
		||||
export class MiaoChat extends interfaces.Plugin {
 | 
			
		||||
    @inject(server.Server)
 | 
			
		||||
    private Server: server.Server
 | 
			
		||||
    @inject(chat.Chat)
 | 
			
		||||
    private chat: chat.Chat
 | 
			
		||||
    @inject(channel.Channel)
 | 
			
		||||
    @optional() private Channel: channel.Channel
 | 
			
		||||
 | 
			
		||||
    private channelOff: { off: () => void };
 | 
			
		||||
    private channelOff: { off: () => void }
 | 
			
		||||
 | 
			
		||||
    @config()
 | 
			
		||||
    private config = {
 | 
			
		||||
@@ -129,34 +131,34 @@ export class MiaoChat extends interfaces.Plugin {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private chatFormats: any[];
 | 
			
		||||
    private styleFormats: any;
 | 
			
		||||
    private chatFormats: any[]
 | 
			
		||||
    private styleFormats: any
 | 
			
		||||
    // 用于匹配 '[xx]' 聊天格式
 | 
			
		||||
    private FORMAT_PATTERN = /[\[]([^\[\]]+)[\]]/ig;
 | 
			
		||||
 | 
			
		||||
    private PlaceholderAPI: { setPlaceholders: (player: any, str: string) => string };
 | 
			
		||||
    private PlaceholderAPI: { setPlaceholders: (player: any, str: string) => string }
 | 
			
		||||
 | 
			
		||||
    load() {
 | 
			
		||||
        this.chatFormats = Object.values(this.config.ChatFormats);
 | 
			
		||||
        this.chatFormats.sort(this.compare('index'));
 | 
			
		||||
        this.initFormat(this.chatFormats);
 | 
			
		||||
        this.styleFormats = this.config.StyleFormats;
 | 
			
		||||
        this.chatFormats = Object.values(this.config.ChatFormats)
 | 
			
		||||
        this.chatFormats.sort(this.compare('index'))
 | 
			
		||||
        this.initFormat(this.chatFormats)
 | 
			
		||||
        this.styleFormats = this.config.StyleFormats
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private compare(prop: string) {
 | 
			
		||||
        return function (obj1: { [x: string]: any; }, obj2: { [x: string]: any; }) {
 | 
			
		||||
            var val1 = obj1[prop];
 | 
			
		||||
            var val2 = obj2[prop];
 | 
			
		||||
        return function (obj1: { [x: string]: any }, obj2: { [x: string]: any }) {
 | 
			
		||||
            var val1 = obj1[prop]
 | 
			
		||||
            var val2 = obj2[prop]
 | 
			
		||||
            if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
 | 
			
		||||
                val1 = Number(val1);
 | 
			
		||||
                val2 = Number(val2);
 | 
			
		||||
                val1 = Number(val1)
 | 
			
		||||
                val2 = Number(val2)
 | 
			
		||||
            }
 | 
			
		||||
            if (val1 < val2) {
 | 
			
		||||
                return -1;
 | 
			
		||||
                return -1
 | 
			
		||||
            } else if (val1 > val2) {
 | 
			
		||||
                return 1;
 | 
			
		||||
                return 1
 | 
			
		||||
            } else {
 | 
			
		||||
                return 0;
 | 
			
		||||
                return 0
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -164,7 +166,7 @@ export class MiaoChat extends interfaces.Plugin {
 | 
			
		||||
    enable() {
 | 
			
		||||
        this.PlaceholderAPI = {
 | 
			
		||||
            setPlaceholders: (player: any, string: string) => {
 | 
			
		||||
                return string;
 | 
			
		||||
                return string
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -177,7 +179,7 @@ export class MiaoChat extends interfaces.Plugin {
 | 
			
		||||
        // 尝试加载 Bukkit 的 PlaceholderAPI
 | 
			
		||||
        try {
 | 
			
		||||
            //@ts-ignore
 | 
			
		||||
            this.PlaceholderAPI = base.getClass("me.clip.placeholderapi.PlaceholderAPI").static;
 | 
			
		||||
            this.PlaceholderAPI = base.getClass("me.clip.placeholderapi.PlaceholderAPI").static
 | 
			
		||||
            this.logger.log('[PAPI] Found Bukkit PlaceholderAPI Hooking...')
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
            this.logger.console("§cCan't found me.clip.placeholderapi.PlaceholderAPI variable will not be replaced! Err: " + ex)
 | 
			
		||||
@@ -187,14 +189,14 @@ export class MiaoChat extends interfaces.Plugin {
 | 
			
		||||
    spongeenable() {
 | 
			
		||||
        // 尝试加载 Sponge 的 PlaceholderAPI
 | 
			
		||||
        try {
 | 
			
		||||
            var spongePapi = this.Server.getService('me.rojo8399.placeholderapi.PlaceholderService');
 | 
			
		||||
            var s = org.spongepowered.api.text.serializer.TextSerializers.formattingCode('§');
 | 
			
		||||
            var spongePapi = this.Server.getService('me.rojo8399.placeholderapi.PlaceholderService')
 | 
			
		||||
            var s = org.spongepowered.api.text.serializer.TextSerializers.formattingCode('§')
 | 
			
		||||
            if (spongePapi) {
 | 
			
		||||
                this.PlaceholderAPI = {
 | 
			
		||||
                    setPlaceholders: (player: any, string: string) => {
 | 
			
		||||
                        return s.serialize(spongePapi.replacePlaceholders(string, player, player));
 | 
			
		||||
                        return s.serialize(spongePapi.replacePlaceholders(string, player, player))
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
                }
 | 
			
		||||
                this.logger.log('[PAPI] Found Sponge PlaceholderAPI Hooking...')
 | 
			
		||||
            }
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
@@ -213,7 +215,7 @@ export class MiaoChat extends interfaces.Plugin {
 | 
			
		||||
        this.channelOff = this.Channel?.listen(this, MiaoMessage.CHANNEL, (data, event: net.md_5.bungee.api.event.PluginMessageEvent) => {
 | 
			
		||||
            let bungee: net.md_5.bungee.api.ProxyServer = base.getInstance().getProxy()
 | 
			
		||||
            if (event.getTag() == MiaoMessage.CHANNEL) {
 | 
			
		||||
                let origin = event.getSender().getAddress();
 | 
			
		||||
                let origin = event.getSender().getAddress()
 | 
			
		||||
                bungee.getServers().forEach(new BiConsumer({
 | 
			
		||||
                    accept: (s, server) => {
 | 
			
		||||
                        if (server.getAddress() != origin && server.getPlayers().size() > 0) {
 | 
			
		||||
@@ -227,13 +229,13 @@ export class MiaoChat extends interfaces.Plugin {
 | 
			
		||||
 | 
			
		||||
    @cmd({ servers: ["bungee"] })
 | 
			
		||||
    mct(sender: any, command: string, args: string[]) {
 | 
			
		||||
        this.logger.log(sender, command, args);
 | 
			
		||||
        this.logger.log(sender, command, args)
 | 
			
		||||
        sender.sendMessage(JSON.stringify({ command, ...args }))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @cmd({ servers: ["!bungee"] })
 | 
			
		||||
    mchat(sender: any, command: string, args: string[]) {
 | 
			
		||||
        this.logger.log(sender, command, args);
 | 
			
		||||
        this.logger.log(sender, command, args)
 | 
			
		||||
        sender.sendMessage(JSON.stringify({ command, ...args }))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -243,102 +245,97 @@ export class MiaoChat extends interfaces.Plugin {
 | 
			
		||||
 | 
			
		||||
    @listener({ servers: ['bukkit'] })
 | 
			
		||||
    AsyncPlayerChatEvent(event: org.bukkit.event.player.AsyncPlayerChatEvent) {
 | 
			
		||||
        this.sendChat(event.getPlayer(), event.getMessage(), function () {
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        });
 | 
			
		||||
        this.sendChat(event.getPlayer(), event.getMessage(), () => event.setCancelled(true))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @listener({ servers: ['sponge'] })
 | 
			
		||||
    MessageChannelEvent$Chat(event: org.spongepowered.api.event.message.MessageChannelEvent.Chat) {
 | 
			
		||||
        //@ts-ignore
 | 
			
		||||
        var player = event.getCause().first(org.spongepowered.api.entity.living.player.Player.class).orElse(null);
 | 
			
		||||
        var player = event.getCause().first(org.spongepowered.api.entity.living.player.Player.class).orElse(null)
 | 
			
		||||
        if (player == null) {
 | 
			
		||||
            return;
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        var plain = event.getRawMessage().toPlain();
 | 
			
		||||
        var plain = event.getRawMessage().toPlain()
 | 
			
		||||
        if (plain.startsWith(Tellraw.duplicateChar)) {
 | 
			
		||||
            return;
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        this.sendChat(player, plain, function () {
 | 
			
		||||
            event.setMessageCancelled(true)
 | 
			
		||||
        });
 | 
			
		||||
        this.sendChat(player, plain, () => event.setMessageCancelled(true))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    initFormat(chatFormats: any[]) {
 | 
			
		||||
        chatFormats.forEach(chatFormat => {
 | 
			
		||||
            var chat_format_str = chatFormat.format;
 | 
			
		||||
            var temp = [];
 | 
			
		||||
            var r: any[];
 | 
			
		||||
            var chat_format_str = chatFormat.format
 | 
			
		||||
            var temp = []
 | 
			
		||||
            var r: any[]
 | 
			
		||||
            while (r = this.FORMAT_PATTERN.exec(chat_format_str)) {
 | 
			
		||||
                temp.push(r[1]);
 | 
			
		||||
                temp.push(r[1])
 | 
			
		||||
            }
 | 
			
		||||
            var format_list = [];
 | 
			
		||||
            var format_list = []
 | 
			
		||||
            temp.forEach(t => {
 | 
			
		||||
                var arr = chat_format_str.split('[' + t + ']', 2);
 | 
			
		||||
                var arr = chat_format_str.split('[' + t + ']', 2)
 | 
			
		||||
                if (arr[0]) {
 | 
			
		||||
                    format_list.push(arr[0]);
 | 
			
		||||
                    format_list.push(arr[0])
 | 
			
		||||
                }
 | 
			
		||||
                format_list.push(t);
 | 
			
		||||
                chat_format_str = arr[1];
 | 
			
		||||
            });
 | 
			
		||||
                format_list.push(t)
 | 
			
		||||
                chat_format_str = arr[1]
 | 
			
		||||
            })
 | 
			
		||||
            if (chat_format_str) {
 | 
			
		||||
                format_list.push(chat_format_str);
 | 
			
		||||
                format_list.push(chat_format_str)
 | 
			
		||||
            }
 | 
			
		||||
            chatFormat.format_list = format_list;
 | 
			
		||||
            chatFormat.format_list = format_list
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sendChat(player: any, plain: string, callback: { (): void; }) {
 | 
			
		||||
        var chat_format = this.getChatFormat(player);
 | 
			
		||||
    sendChat(player: any, plain: string, callback: { (): void }) {
 | 
			
		||||
        var chat_format = this.getChatFormat(player)
 | 
			
		||||
        if (!chat_format) {
 | 
			
		||||
            console.debug('未获得用户', player.getName(), '的 ChatRule 跳过执行...');
 | 
			
		||||
            return;
 | 
			
		||||
            console.debug('未获得用户', player.getName(), '的 ChatRule 跳过执行...')
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        callback();
 | 
			
		||||
        var tr = Tellraw.create();
 | 
			
		||||
        callback()
 | 
			
		||||
        var tr = Tellraw.create()
 | 
			
		||||
        chat_format.format_list.forEach((format) => {
 | 
			
		||||
            var style = this.styleFormats[format];
 | 
			
		||||
            var style = this.styleFormats[format]
 | 
			
		||||
            if (style) {
 | 
			
		||||
                tr.then(this.replace(player, style.text.replace(/&(\w)/g, '§$1')));
 | 
			
		||||
                tr.then(this.replace(player, style.text.replace(/&(\w)/g, '§$1')))
 | 
			
		||||
                if (style.hover) {
 | 
			
		||||
                    tr.tip(this.replace(player, style.hover.join('\n')));
 | 
			
		||||
                    tr.tip(this.replace(player, style.hover.join('\n')))
 | 
			
		||||
                }
 | 
			
		||||
                if (style.click && style.click.type && style.click.command) {
 | 
			
		||||
                    var command = this.replace(player, style.click.command);
 | 
			
		||||
                    var command = this.replace(player, style.click.command)
 | 
			
		||||
                    switch (style.click.type.toUpperCase()) {
 | 
			
		||||
                        case "COMMAND":
 | 
			
		||||
                            tr.command(command);
 | 
			
		||||
                            break;
 | 
			
		||||
                            tr.command(command)
 | 
			
		||||
                            break
 | 
			
		||||
                        case "OPENURL":
 | 
			
		||||
                            tr.link(command);
 | 
			
		||||
                            break;
 | 
			
		||||
                            tr.link(command)
 | 
			
		||||
                            break
 | 
			
		||||
                        case "SUGGEST":
 | 
			
		||||
                            tr.suggest(command);
 | 
			
		||||
                            break;
 | 
			
		||||
                            tr.suggest(command)
 | 
			
		||||
                            break
 | 
			
		||||
                        default:
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                tr.then(this.replace(player, format));
 | 
			
		||||
                tr.then(this.replace(player, format))
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        })
 | 
			
		||||
        let json = tr.then(this.replace(player, plain)).json()
 | 
			
		||||
        this.sendChatAll(json)
 | 
			
		||||
        this.Channel?.send(player, MiaoMessage.CHANNEL, MiaoMessage.encode(json))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sendChatAll(json: string) {
 | 
			
		||||
        this.Server.getOnlinePlayers().forEach(player => this.Server.sendJson(player, json))
 | 
			
		||||
        this.Server.getOnlinePlayers().forEach(player => this.chat.sendJson(player, json))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getChatFormat(player: any) {
 | 
			
		||||
        for (var i in this.chatFormats) {
 | 
			
		||||
            var format = this.chatFormats[i];
 | 
			
		||||
        for (let format of this.chatFormats) {
 | 
			
		||||
            if (player.hasPermission(format.permission)) {
 | 
			
		||||
                return format;
 | 
			
		||||
                return format
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
        return null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    replace(player: any, target: string) {
 | 
			
		||||
 
 | 
			
		||||
@@ -81,6 +81,7 @@ export class MiaoCoin extends interfaces.Plugin {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    disable() {
 | 
			
		||||
        // {"app":"com.tencent.autoreply","desc":"","view":"autoreply","ver":"0.0.0.1","prompt":"[动画表情]","meta":{"metadata":{"title":"点击蓝色字体有惊喜","buttons":[{"slot":1,"action_data":"我是傻逼","name":"点我","action":"notify"}],"type":"guest","token":"LAcV49xqyE57S17B8ZT6FU7odBveNMYJzux288tBD3c="}},"config":{"forward":1,"showSender":1}}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Cmd()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/// <reference types="@ccms/nashorn" />
 | 
			
		||||
 | 
			
		||||
import { plugin as pluginApi, server, task, constants } from '@ccms/api'
 | 
			
		||||
import { plugin as pluginApi, server, task, constants, command } from '@ccms/api'
 | 
			
		||||
import { plugin, interfaces, cmd, tab, enable, config, disable } from '@ccms/plugin'
 | 
			
		||||
import { inject, ContainerInstance, Container } from '@ccms/container'
 | 
			
		||||
import io, { Server as SocketIOServer, Socket as SocketIOSocket } from '@ccms/websocket'
 | 
			
		||||
@@ -27,6 +27,8 @@ export class MiaoConsole extends interfaces.Plugin {
 | 
			
		||||
    private serverType: string
 | 
			
		||||
    @inject(server.Server)
 | 
			
		||||
    private server: server.Server
 | 
			
		||||
    @inject(command.Command)
 | 
			
		||||
    private command: command.Command
 | 
			
		||||
    @inject(task.TaskManager)
 | 
			
		||||
    private task: task.TaskManager
 | 
			
		||||
    @inject(pluginApi.PluginManager)
 | 
			
		||||
@@ -248,7 +250,7 @@ export class MiaoConsole extends interfaces.Plugin {
 | 
			
		||||
            client.emit('log', `§6命令: §b${cmd} §a执行成功!`)
 | 
			
		||||
        })
 | 
			
		||||
        client.on('tabComplate', (input, index, callback) => {
 | 
			
		||||
            callback && callback(this.server.tabComplete(this.server.getConsoleSender(), input, index))
 | 
			
		||||
            callback?.(this.command.tabComplete(this.server.getConsoleSender(), input, index))
 | 
			
		||||
        })
 | 
			
		||||
        client.on('exec', (code) => {
 | 
			
		||||
            try {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ import { JSPlugin, interfaces, Cmd, Tab, Listener, Config } from "@ccms/plugin"
 | 
			
		||||
 | 
			
		||||
import { QRCode, QRErrorCorrectLevel } from '@ccms/common/dist/qrcode'
 | 
			
		||||
 | 
			
		||||
import { inject, JSClass, optional } from '@ccms/container'
 | 
			
		||||
import { Autowired, JSClass, optional, inject } from '@ccms/container'
 | 
			
		||||
import http from '@ccms/common/dist/http'
 | 
			
		||||
 | 
			
		||||
let MapView
 | 
			
		||||
@@ -54,9 +54,9 @@ interface PlaceholderAPI {
 | 
			
		||||
  setPlaceholders: (player: any, str: string) => string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@JSPlugin({ prefix: 'MRD', version: '1.2.0', author: 'MiaoWoo', servers: [constants.ServerType.Bukkit], source: __filename })
 | 
			
		||||
@JSPlugin({ prefix: 'MRD', version: '1.2.3', author: 'MiaoWoo', servers: [constants.ServerType.Bukkit], source: __filename })
 | 
			
		||||
export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
  private serverInfo
 | 
			
		||||
  private serverInfo: any
 | 
			
		||||
  private cacheBindUuid = ''
 | 
			
		||||
  private zeroMapView = undefined
 | 
			
		||||
  private zeroMapRender: QRCodeRender = undefined
 | 
			
		||||
@@ -67,14 +67,16 @@ export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
  private bindingNotify = new java.util.HashSet<org.bukkit.entity.Player>()
 | 
			
		||||
  private drawCooldown = new Map<string, number>()
 | 
			
		||||
 | 
			
		||||
  @inject(chat.Chat)
 | 
			
		||||
  @Autowired()
 | 
			
		||||
  private chat: chat.Chat
 | 
			
		||||
  @inject(server.Server)
 | 
			
		||||
  @Autowired()
 | 
			
		||||
  private server: server.Server
 | 
			
		||||
  @inject(task.TaskManager)
 | 
			
		||||
  @Autowired()
 | 
			
		||||
  private taskManager: task.TaskManager
 | 
			
		||||
  @inject(channel.Channel)
 | 
			
		||||
  @optional() private Channel: channel.Channel
 | 
			
		||||
  @Autowired()
 | 
			
		||||
  private channel: channel.Channel
 | 
			
		||||
  @Autowired()
 | 
			
		||||
  private bungee: channel.proxy.BungeeCord
 | 
			
		||||
 | 
			
		||||
  @Config()
 | 
			
		||||
  private config = {
 | 
			
		||||
@@ -97,6 +99,10 @@ export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
    this.config.prefix = this.config.prefix || '§6[§b广告系统§6]§r'
 | 
			
		||||
    this.config.drawCommand = this.config.drawCommand || 'p give %player_name% %amount%'
 | 
			
		||||
    this.config.drawCooldown = this.config.drawCooldown || 300
 | 
			
		||||
    this.updateServerInfo()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private updateServerInfo(player?: any) {
 | 
			
		||||
    this.taskManager.create(() => {
 | 
			
		||||
      if (this.config.serverId) {
 | 
			
		||||
        let result = this.httpPost(`https://reward.yumc.pw/server/server`, {
 | 
			
		||||
@@ -105,21 +111,61 @@ export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
        })
 | 
			
		||||
        if (result.code == 200) {
 | 
			
		||||
          this.serverInfo = result.data
 | 
			
		||||
          if (player) this.bungee.for(player).forward("ALL", "MiaoReward", { type: "updateServerInfo", data: result.data }).send()
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }).async().submit()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @JSClass('com.google.common.io.ByteStreams')
 | 
			
		||||
  private ByteStreams: any
 | 
			
		||||
 | 
			
		||||
  enable() {
 | 
			
		||||
    this.initPlaceholderAPI()
 | 
			
		||||
    this.channelOff = this.Channel?.listen(this, 'BungeeCord', () => {
 | 
			
		||||
      this.isBungeeCord = true
 | 
			
		||||
      this.PlayerJoinEvent['off']()
 | 
			
		||||
      this.channelOff.off()
 | 
			
		||||
    this.initBungeeCord()
 | 
			
		||||
    this.initZeroMap()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private initBungeeCord() {
 | 
			
		||||
    this.channelOff = this.channel?.listen(this, 'BungeeCord', (data) => {
 | 
			
		||||
      if (!this.isBungeeCord) {
 | 
			
		||||
        this.isBungeeCord = true
 | 
			
		||||
        this.PlayerJoinEvent['off']()
 | 
			
		||||
      }
 | 
			
		||||
      let input = this.ByteStreams.newDataInput(data)
 | 
			
		||||
      let subChannel = input.readUTF()
 | 
			
		||||
      switch (subChannel) {
 | 
			
		||||
        case "GetServer":
 | 
			
		||||
          this.isBungeeCord = true
 | 
			
		||||
          let serverName = input.readUTF()
 | 
			
		||||
          break
 | 
			
		||||
        case "MiaoReward":
 | 
			
		||||
          this.readForward(input)
 | 
			
		||||
          break
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    let players = this.server.getOnlinePlayers()
 | 
			
		||||
    if (players.length) this.bungeeCordDetect(players[0])
 | 
			
		||||
    this.initZeroMap()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cmdrun(sender: any, ...args: any[]) {
 | 
			
		||||
    try {
 | 
			
		||||
      let tfunc = new Function(`return '§a返回结果: §r'+ eval(${JSON.stringify(args.join(' '))});`)
 | 
			
		||||
      this.logger.sender(sender, tfunc.apply(this) + '')
 | 
			
		||||
    } catch (ex) {
 | 
			
		||||
      this.logger.sender(sender, this.logger.stack(ex))
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private readForward(input) {
 | 
			
		||||
    let message = JSON.parse(input.readUTF())
 | 
			
		||||
    console.log(message)
 | 
			
		||||
    switch (message.type) {
 | 
			
		||||
      case "updateServerInfo":
 | 
			
		||||
        this.serverInfo = message.data
 | 
			
		||||
        console.console(this.config.prefix, '§6兑换比例已更新为:§a', message.data.ratio)
 | 
			
		||||
        break
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private initPlaceholderAPI() {
 | 
			
		||||
@@ -140,11 +186,13 @@ export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private initZeroMap() {
 | 
			
		||||
    this.zeroMapRender = new QRCodeRender()
 | 
			
		||||
    this.zeroMapView = Bukkit.getMap(0) || Bukkit.createMap(Bukkit.getWorlds()[0])
 | 
			
		||||
    this.zeroMapView.setScale(MapView.Scale.FARTHEST)
 | 
			
		||||
    this.zeroMapView.getRenderers().forEach(r => this.zeroMapView.removeRenderer(r))
 | 
			
		||||
    this.zeroMapView.addRenderer(this.zeroMapRender.getHandler())
 | 
			
		||||
    this.taskManager.create(() => {
 | 
			
		||||
      this.zeroMapRender = new QRCodeRender()
 | 
			
		||||
      this.zeroMapView = Bukkit.getMap(0) || Bukkit.createMap(Bukkit.getWorlds()[0])
 | 
			
		||||
      this.zeroMapView.setScale(MapView.Scale.FARTHEST)
 | 
			
		||||
      this.zeroMapView.getRenderers().forEach(r => this.zeroMapView.removeRenderer(r))
 | 
			
		||||
      this.zeroMapView.addRenderer(this.zeroMapRender.getHandler())
 | 
			
		||||
    }).submit()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  disable() {
 | 
			
		||||
@@ -167,9 +215,10 @@ export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
 | 
			
		||||
  private scanAuth(sender: org.bukkit.entity.Player, scanType: string, scanObj: { title: string, content: string }, success: (token: string, user: any) => void, cancel?: () => void) {
 | 
			
		||||
    this.chat.sendTitle(sender, this.config.prefix, '§a正在获取授权二维码...')
 | 
			
		||||
    this.logger.sender(sender, '§a正在获取授权二维码...')
 | 
			
		||||
    let scan = this.httpPost('https://reward.yumc.pw/auth/scan', { ...scanObj, type: scanType })
 | 
			
		||||
    if (scan.code == 200) {
 | 
			
		||||
      let sync = { scaned: false, timeout: false }
 | 
			
		||||
      let sync = { scaned: false }
 | 
			
		||||
      this.taskManager.create(() => {
 | 
			
		||||
        let result = this.httpPost('https://reward.yumc.pw/auth/scanCheck', {
 | 
			
		||||
          token: scan.data.token,
 | 
			
		||||
@@ -212,14 +261,19 @@ export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
      let bindUser = Bukkit.getPlayerExact(this.bindingUser)
 | 
			
		||||
      if (bindUser && bindUser.isOnline() && this.isQrCodeItem(bindUser.getItemInHand())[0]) {
 | 
			
		||||
        this.bindingNotify.add(sender)
 | 
			
		||||
        this.logger.sender(sender, "§c当前 §a" + this.bindingUser + " §c玩家正在扫码 §6请稍候 §e" + this.bindingLeftTime + "秒 §6后重试...")
 | 
			
		||||
        this.logger.sender(sender, [
 | 
			
		||||
          "§c当前 §a" + this.bindingUser + " §c玩家正在扫码",
 | 
			
		||||
          "§6请等待 §e" + this.bindingLeftTime + "秒 §6后重试...",
 | 
			
		||||
          "§a玩家操作完成后将会通知您继续操作..."
 | 
			
		||||
        ])
 | 
			
		||||
        return true
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (this.drawCooldown.has(sender.getName())) {
 | 
			
		||||
    if (this.drawCooldown.has(sender.getName()) && !sender.isOp()) {
 | 
			
		||||
      let leftTime = cooldown - (Date.now() - this.drawCooldown.get(sender.getName())) / 1000
 | 
			
		||||
      if (leftTime > 0) {
 | 
			
		||||
        return this.logger.sender(sender, `§c扫码功能冷却中 剩余 ${leftTime} 秒!`)
 | 
			
		||||
        this.logger.sender(sender, `§c扫码功能冷却中 剩余 ${leftTime} 秒!`)
 | 
			
		||||
        return true
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    this.drawCooldown.set(sender.getName(), Date.now())
 | 
			
		||||
@@ -253,7 +307,14 @@ export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
    this.scanAuth(sender,
 | 
			
		||||
      'draw', {
 | 
			
		||||
      title: '兑换授权',
 | 
			
		||||
      content: "是否授权 " + this.serverInfo.name + " 服务器\n兑换 " + amount + " 喵币 到 " + sender.getName()
 | 
			
		||||
      content: [
 | 
			
		||||
        "是否授权 " + this.serverInfo.name + " 兑换喵币",
 | 
			
		||||
        "兑换玩家: " + sender.getName(),
 | 
			
		||||
        "兑换数量: " + amount,
 | 
			
		||||
        "兑换比例: " + parseFloat(this.serverInfo.ratio),
 | 
			
		||||
        "预计到帐: " + (amount * this.serverInfo.ratio).toFixed(0),
 | 
			
		||||
        "注意: 数据可能更新不及时 请以实际到账金额为准!"
 | 
			
		||||
      ].join('\n')
 | 
			
		||||
    }, (token: string) => {
 | 
			
		||||
      this.drawCoin(sender, amount, token)
 | 
			
		||||
    })
 | 
			
		||||
@@ -282,8 +343,8 @@ export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
        return this.sendError(sender, '§6执行命令 §3/' + command + ' §c可能存在异常')
 | 
			
		||||
      }
 | 
			
		||||
      this.logger.sender(sender, draw.msg.split('\n'))
 | 
			
		||||
      this.sendBoardcast(sender, `${this.config.prefix}§6玩家 §b${sender.getName()} §6成功将 §a${amount}喵币 §6兑换成 §c${draw.data}点券!`)
 | 
			
		||||
      this.sendBoardcast(sender, `${this.config.prefix}§c/mrd help §b查看广告系统帮助 §6快来一起看广告赚点券吧!`)
 | 
			
		||||
      this.sendBroadcast(sender, `${this.config.prefix}§6玩家 §b${sender.getName()} §6成功将 §a${amount}喵币 §6兑换成 §c${draw.data}点券!`)
 | 
			
		||||
      this.sendBroadcast(sender, `${this.config.prefix}§c/mrd help §b查看广告系统帮助 §6快来一起看广告赚点券吧!`)
 | 
			
		||||
    }).submit()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -313,7 +374,7 @@ export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
      `§6====== ${this.config.prefix} §a喵币兑换排行 §6======`,
 | 
			
		||||
    ]
 | 
			
		||||
    if (boardcast) {
 | 
			
		||||
      ranks.forEach(l => this.sendBoardcast(sender, l))
 | 
			
		||||
      ranks.forEach(l => this.sendBroadcast(sender, l))
 | 
			
		||||
    } else {
 | 
			
		||||
      this.logger.sender(sender, ranks)
 | 
			
		||||
    }
 | 
			
		||||
@@ -338,13 +399,13 @@ export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
    ])
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cmdratio(sender: any, ratio: number, confirm: string) {
 | 
			
		||||
  cmdratio(sender: any, ratioStr: string, confirm: string) {
 | 
			
		||||
    if (!sender.isOp()) { return this.logger.sender(sender, '§4你没有此命令的权限!') }
 | 
			
		||||
    let mbr = (1 / ratio).toFixed(4)
 | 
			
		||||
    let [ratio, mbr, msg] = this.ratio2string(ratioStr)
 | 
			
		||||
    if (!confirm) {
 | 
			
		||||
      return this.logger.sender(sender, [
 | 
			
		||||
        '§4警告: 您正在设置服务器喵币/点券兑换比例 设置后将实时生效!',
 | 
			
		||||
        `§6您设置的兑换比例为 §c${ratio} §6=> §a${mbr}喵币 §6兑换 §c1点券`,
 | 
			
		||||
        `§6您设置的兑换比例为 ` + msg,
 | 
			
		||||
        `§6玩家至少需要 §a${mbr}喵币 §6才可以兑换点券!`,
 | 
			
		||||
        `§6请执行 §b/mrd ratio §c${ratio} §econfirm §c确认修改!`
 | 
			
		||||
      ])
 | 
			
		||||
@@ -359,22 +420,22 @@ export class MiaoReward extends interfaces.Plugin {
 | 
			
		||||
      return this.logger.sender(sender, `§4操作异常 §6服务器返回: §c${result.msg}`)
 | 
			
		||||
    }
 | 
			
		||||
    this.logger.sender(sender, `§a操作成功 §6服务器返回: §a${result.msg}`)
 | 
			
		||||
    this.sendBoardcast(sender, `${this.config.prefix} §6当前兑换比例已调整为 §c${ratio} §6=> §a${mbr}喵币 §6兑换 §c1点券!`)
 | 
			
		||||
    this.updateServerInfo(sender)
 | 
			
		||||
    this.sendBroadcast(sender, `${this.config.prefix} §6当前兑换比例已调整为 ` + msg)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @JSClass('java.io.ByteArrayOutputStream')
 | 
			
		||||
  private ByteArrayOutputStream
 | 
			
		||||
  @JSClass('java.io.DataOutputStream')
 | 
			
		||||
  private DataOutputStream
 | 
			
		||||
  private ratio2string(ratio) {
 | 
			
		||||
    ratio = parseFloat(ratio)
 | 
			
		||||
    if (ratio > 1) {
 | 
			
		||||
      return [ratio, 1, `§c${ratio} §6就是 §a1喵币 §6=> §c${ratio}点券!`]
 | 
			
		||||
    }
 | 
			
		||||
    let mbr = Math.round(1 / ratio * 10000) / 10000
 | 
			
		||||
    return [ratio, mbr, `§c${ratio} §6就是 §a${mbr}喵币 §6=> §c1点券!`]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private sendBoardcast(player, message) {
 | 
			
		||||
  private sendBroadcast(player, message) {
 | 
			
		||||
    if (!this.isBungeeCord) { return org.bukkit.Bukkit.broadcastMessage(message) }
 | 
			
		||||
    let byteArray = new this.ByteArrayOutputStream()
 | 
			
		||||
    let out = new this.DataOutputStream(byteArray)
 | 
			
		||||
    out.writeUTF("Message")
 | 
			
		||||
    out.writeUTF("ALL")
 | 
			
		||||
    out.writeUTF(message)
 | 
			
		||||
    player.sendPluginMessage(base.getInstance(), "BungeeCord", byteArray.toByteArray())
 | 
			
		||||
    this.bungee.for(player).broadcast(message).send()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private bindServer(sender: org.bukkit.entity.Player) {
 | 
			
		||||
@@ -589,10 +650,7 @@ CAST TIME   : ${Date.now() - startTime}`)
 | 
			
		||||
 | 
			
		||||
  private bungeeCordDetect(player) {
 | 
			
		||||
    if (this.isBungeeCord === undefined && player) {
 | 
			
		||||
      let byteArray = new this.ByteArrayOutputStream()
 | 
			
		||||
      let out = new this.DataOutputStream(byteArray)
 | 
			
		||||
      out.writeUTF("GetServer")
 | 
			
		||||
      player.sendPluginMessage(base.getInstance(), "BungeeCord", byteArray.toByteArray())
 | 
			
		||||
      this.bungee.for(player).getServer().send()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -606,7 +664,6 @@ CAST TIME   : ${Date.now() - startTime}`)
 | 
			
		||||
    let [cancelled, id] = this.isQrCodeItem(event.getItemDrop().getItemStack())
 | 
			
		||||
    if (id != null && id != undefined && cancelled) {
 | 
			
		||||
      event.getItemDrop().remove()
 | 
			
		||||
      this.cancelTask(event.getPlayer())
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -616,7 +673,6 @@ CAST TIME   : ${Date.now() - startTime}`)
 | 
			
		||||
    let [cancelled, id] = this.isQrCodeItem(inv.getItem(event.getPreviousSlot() as any))
 | 
			
		||||
    if (id != null && id != undefined && cancelled) {
 | 
			
		||||
      inv.setItem(event.getPreviousSlot(), null)
 | 
			
		||||
      this.cancelTask(event.getPlayer())
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -626,7 +682,6 @@ CAST TIME   : ${Date.now() - startTime}`)
 | 
			
		||||
    let [cancelled, id] = this.isQrCodeItem(item)
 | 
			
		||||
    if (id != null && id != undefined && cancelled) {
 | 
			
		||||
      event.getInventory().setItem(event.getSlot(), null)
 | 
			
		||||
      this.cancelTask(event.getWhoClicked())
 | 
			
		||||
      event.setCancelled(true)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@@ -637,9 +692,10 @@ CAST TIME   : ${Date.now() - startTime}`)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private cancelTask(player) {
 | 
			
		||||
    console.ex(new Error())
 | 
			
		||||
    if (!this.isBinding) return
 | 
			
		||||
    this.isBinding = false
 | 
			
		||||
    this.bindingTask.cancel()
 | 
			
		||||
    this.bindingTask = undefined
 | 
			
		||||
    this.bindingUser = 'unknow'
 | 
			
		||||
    this.checkAndClear(player)
 | 
			
		||||
    this.chat.sendActionBar(player, "")
 | 
			
		||||
 
 | 
			
		||||
@@ -27,25 +27,28 @@ let langMap = {
 | 
			
		||||
    'main.command.help.tip': '§6请执行 §b/{command} §ahelp §6查看帮助!',
 | 
			
		||||
    'main.command.no.permission': '§c你没有此命令的权限!',
 | 
			
		||||
    'list.install.header': '§6当前 §bMiaoScript §6已安装下列插件:',
 | 
			
		||||
    'list.install.body': '§6插件名称: §b{name}\n§6版本: §a{version}\n§6作者: §3{author}\n§6来源: §c{from}',
 | 
			
		||||
    'list.install.body': '§6插件名称: §b{name} §6版本: §a{version}\n§6作者: §3{author} §6来源: §c{from}',
 | 
			
		||||
    'list.header': '§6当前 §bMiaoScriptPackageCenter §6中存在下列插件:',
 | 
			
		||||
    'list.body': '§6插件名称: §b{name}\n§6版本: §a{version}\n§6作者: §3{author}\n§6更新时间: §9{updated_at}',
 | 
			
		||||
    'list.body': '§6插件名称: §b{name} §6版本: §a{version}\n§6作者: §3{author} §6更新时间: §9{updated_at}',
 | 
			
		||||
    'plugin.not.exists': '§6插件 §b{name} §c不存在!',
 | 
			
		||||
    'plugin.unload.finish': '§6插件 §b{name} §a已卸载!',
 | 
			
		||||
    'plugin.reload.finish': '§6插件 §b{name} §a重载完成!',
 | 
			
		||||
    'plugin.unload.start': '§c开始卸载 §6插件 §b{name} §6版本 §3{version}!',
 | 
			
		||||
    'plugin.unload.finish': '§6插件 §b{name} §6版本 §3{version} §a已卸载!',
 | 
			
		||||
    'plugin.reload.start': '§a开始重载 §6插件 §b{name} §6版本 §3{version}!',
 | 
			
		||||
    'plugin.reload.finish': '§6插件 §b{name} §6版本 §3{version} §a重载完成!',
 | 
			
		||||
    'plugin.name.empty': '§c请输入插件名称!',
 | 
			
		||||
    'cloud.update.finish': '§6成功从 §aMiaoScriptPackageCenter §6获取到 §a{length} §6个插件!',
 | 
			
		||||
    'cloud.not.exists': '§6当前 §aMiaoScriptPackageCenter §c不存在 §a{name} §c插件!',
 | 
			
		||||
    'cloud.update.exists': '§6插件 §b{name} §a发现新版本 §3{new_version} §6当前版本 §3{old_version}!',
 | 
			
		||||
    'download.start': '§6开始下载插件: §b{name}',
 | 
			
		||||
    'download.start': '§6开始下载插件: §b{name} §6版本 §3{version}',
 | 
			
		||||
    'download.url': '§6插件下载地址: §b{url}',
 | 
			
		||||
    'download.finish': '§6插件 §b{name} §a下载完毕 开始加载 ...',
 | 
			
		||||
    'install.finish': '§6插件 §b{name} §a安装成功!',
 | 
			
		||||
    'update.finish': '§6插件 §b{name} §a更新成功!',
 | 
			
		||||
    'upgrade.confirm': '§6您正在尝试升级 §bMiaoScript §c核心 §6请执行 §b/mpm §aupgrade §cconfirm §6确认执行!',
 | 
			
		||||
    'download.finish': '§6插件 §b{name} §6版本 §3{version} §a下载完毕 开始加载 ...',
 | 
			
		||||
    'install.finish': '§6插件 §b{name} §6版本 §3{version} §a安装成功!',
 | 
			
		||||
    'update.finish': '§6插件 §b{name} §6版本 §3{version} §a更新成功!',
 | 
			
		||||
    'upgrade.confirm': '§6您正在尝试更新 §bMiaoScript §c核心 §6请执行 §b/mpm §aupgrade §cconfirm §6确认执行!',
 | 
			
		||||
    'upgrade.failed': '§6尝试热更新 §bMiaoScript §c核心 §4失败! §6请重启服务器完成更新...',
 | 
			
		||||
    'deploy.token.not.exists': '§4请先配置发布Token!',
 | 
			
		||||
    'deploy.success': '§6插件 §b{name} §a发布成功! §6服务器返回: §a{msg}',
 | 
			
		||||
    'deploy.fail': '§6插件 §b{name} §c发布失败! §6服务器返回: §c{msg}',
 | 
			
		||||
    'deploy.success': '§6插件 §b{name} §6版本 §3{version} §a发布成功! §6服务器返回: §a{msg}',
 | 
			
		||||
    'deploy.fail': '§6插件 §b{name} §6版本 §3{version} §c发布失败! §6服务器返回: §c{msg}',
 | 
			
		||||
    'run.script': '§b运行脚本:§r {script}',
 | 
			
		||||
    'run.result': '§a返回结果:§r {result}',
 | 
			
		||||
    'run.noresult': '§4没有返回结果!',
 | 
			
		||||
@@ -53,7 +56,26 @@ let langMap = {
 | 
			
		||||
 | 
			
		||||
let fallbackMap = langMap
 | 
			
		||||
 | 
			
		||||
@JSPlugin({ prefix: 'PM', version: '1.2.0', author: 'MiaoWoo', source: __filename })
 | 
			
		||||
class FakeSender {
 | 
			
		||||
    private _proxy
 | 
			
		||||
    private name: string
 | 
			
		||||
    private plugin: MiaoScriptPackageManager
 | 
			
		||||
    constructor(name: string, plugin: MiaoScriptPackageManager, superclass: any) {
 | 
			
		||||
        this.name = name
 | 
			
		||||
        this.plugin = plugin
 | 
			
		||||
        let FakeSenderAdapter = Java.extend(superclass, {
 | 
			
		||||
            getName: () => this.name,
 | 
			
		||||
            isOp: () => true,
 | 
			
		||||
            sendMessage: (message) => this.plugin.sendBungeeCordMessage(this.name, `§6[§3BPM§6][§a${this.plugin.serverName}§6] ${message}`)
 | 
			
		||||
        })
 | 
			
		||||
        this._proxy = new FakeSenderAdapter()
 | 
			
		||||
    }
 | 
			
		||||
    getHandler() {
 | 
			
		||||
        return this._proxy
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@JSPlugin({ prefix: 'PM', version: '1.3.0', author: 'MiaoWoo', source: __filename })
 | 
			
		||||
export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
    @inject(plugin.PluginManager)
 | 
			
		||||
    private pluginManager: pluginApi.PluginManager
 | 
			
		||||
@@ -78,7 +100,8 @@ export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
    private packageCache: any[] = [];
 | 
			
		||||
    private packageNameCache: string[] = [];
 | 
			
		||||
 | 
			
		||||
    private serverName: string
 | 
			
		||||
    private isBungeeCord = false
 | 
			
		||||
    public serverName: string
 | 
			
		||||
    private translate: Translate
 | 
			
		||||
    private channelOff: { off: () => void }
 | 
			
		||||
 | 
			
		||||
@@ -97,6 +120,7 @@ export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
            let subChannel = input.readUTF()
 | 
			
		||||
            switch (subChannel) {
 | 
			
		||||
                case "GetServer":
 | 
			
		||||
                    this.isBungeeCord = true
 | 
			
		||||
                    this.serverName = input.readUTF()
 | 
			
		||||
                    break
 | 
			
		||||
                case "MiaoScriptPackageManager":
 | 
			
		||||
@@ -134,8 +158,20 @@ export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
    }
 | 
			
		||||
    private readForward(input) {
 | 
			
		||||
        let message = JSON.parse(input.readUTF())
 | 
			
		||||
        this.taskManager.create(() => this.main(this.server.getConsoleSender(), message.command, message.args)).async().submit()
 | 
			
		||||
        this.sendBungeeCordMessage(message.sender, `§6[§cMS§6][§bPM§6] [§3BPM§6][§a${this.serverName}§6] §6命令 §b/mpm ${message.args?.join?.(' ')} §a执行成功!`)
 | 
			
		||||
        let fakeSender = this.getProxySender(message.sender)
 | 
			
		||||
        this.taskManager.create(() => this.main(fakeSender, message.command, message.args)).async().submit()
 | 
			
		||||
        this.logger.sender(fakeSender, `§6命令 §b/mpm ${message.args?.join?.(' ')} §a执行成功!`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private getProxySender(name: string) {
 | 
			
		||||
        switch (this.serverType) {
 | 
			
		||||
            case constants.ServerType.Bukkit:
 | 
			
		||||
                return new FakeSender(name, this, Java.type('org.bukkit.command.CommandSender')).getHandler()
 | 
			
		||||
            case constants.ServerType.Sponge:
 | 
			
		||||
                return new FakeSender(name, this, Java.type('org.spongepowered.api.command.CommandSource')).getHandler()
 | 
			
		||||
            default:
 | 
			
		||||
                return this.server.getConsoleSender()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Listener({ servers: [constants.ServerType.Bukkit] })
 | 
			
		||||
@@ -154,7 +190,7 @@ export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private sendBungeeCordMessage(sender, message) {
 | 
			
		||||
    sendBungeeCordMessage(sender, message) {
 | 
			
		||||
        let players = this.server.getOnlinePlayers()
 | 
			
		||||
        if (players.length) {
 | 
			
		||||
            let byteArray = new this.ByteArrayOutputStream()
 | 
			
		||||
@@ -172,20 +208,22 @@ export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
 | 
			
		||||
    @Cmd({ servers: [`!${constants.ServerType.Bungee}`] })
 | 
			
		||||
    bmpm(sender: any, command: string, args: string[]) {
 | 
			
		||||
        if (!sender.isOp()) { return this.i18n(sender, 'main.command.no.permission') }
 | 
			
		||||
        if (!sender?.isOp()) { return this.i18n(sender, 'main.command.no.permission') }
 | 
			
		||||
        if (!this.isBungeeCord) return this.logger.sender(sender, '§c当前服务器尚未检测到BungeeCord链接...')
 | 
			
		||||
        this.taskManager.create(() => this.main(sender, command, args)).async().submit()
 | 
			
		||||
        this.bungeeCordForward(sender, { sender: sender.getName(), command, args })
 | 
			
		||||
        this.logger.sender(sender, `§6[§3BPM§6][§a${this.serverName}§6] §6命令 §b/mpm ${args.join?.(' ')} §a发布成功!`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Cmd({ servers: [constants.ServerType.Bungee] })
 | 
			
		||||
    mpmanager(sender: any, command: string, args: string[]) {
 | 
			
		||||
        if (!sender.isOp()) { return this.i18n(sender, 'main.command.no.permission') }
 | 
			
		||||
        if (!sender?.isOp()) { return this.i18n(sender, 'main.command.no.permission') }
 | 
			
		||||
        this.taskManager.create(() => this.main(sender, command, args)).async().submit()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Cmd({ servers: [`!${constants.ServerType.Bungee}`] })
 | 
			
		||||
    mpm(sender: any, command: string, args: string[]) {
 | 
			
		||||
        if (!sender.isOp()) { return this.i18n(sender, 'main.command.no.permission') }
 | 
			
		||||
        if (!sender?.isOp()) { return this.i18n(sender, 'main.command.no.permission') }
 | 
			
		||||
        this.taskManager.create(() => this.main(sender, command, args)).async().submit()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -208,6 +246,12 @@ export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
        this.logger.sender(sender, help)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmdinfo(sender: any) {
 | 
			
		||||
        this.logger.sender(sender, [
 | 
			
		||||
 | 
			
		||||
        ])
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmdload(sender: any, name: string) {
 | 
			
		||||
        let pluginFile = fs.concat(__dirname + '', name)
 | 
			
		||||
        if (!fs.exists(pluginFile)) {
 | 
			
		||||
@@ -237,7 +281,10 @@ export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        this.download(sender, name)
 | 
			
		||||
        this.download(sender, name, false, () => {
 | 
			
		||||
            let plugin = this.pluginManager.loadFromFile(fs.concat(root, this.pluginFolder, name + '.js'))
 | 
			
		||||
            this.i18n(sender, 'install.finish', { name, version: plugin.description.version })
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmdupdate(sender: any, name: string) {
 | 
			
		||||
@@ -253,29 +300,46 @@ export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
            if (!confirm) { return this.i18n(sender, 'upgrade.confirm') }
 | 
			
		||||
            let enginePath = fs.path(fs.file(root, 'node_modules'))
 | 
			
		||||
            if (enginePath.startsWith(root)) {
 | 
			
		||||
                base.delete(enginePath)
 | 
			
		||||
                this.cmdrestart(sender)
 | 
			
		||||
                try {
 | 
			
		||||
                    base.delete(enginePath)
 | 
			
		||||
                    this.cmdrestart(sender)
 | 
			
		||||
                } catch (ex) {
 | 
			
		||||
                    if (global.debug) {
 | 
			
		||||
                        console.ex(ex)
 | 
			
		||||
                    }
 | 
			
		||||
                    if (fs.exists(enginePath)) {
 | 
			
		||||
                        this.i18n(sender, 'upgrade.failed')
 | 
			
		||||
                        fs.create(fs.file(root, 'upgrade'))
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        if (this.checkPlugin(sender, name)) {
 | 
			
		||||
            this.update(sender, name)
 | 
			
		||||
            this.pluginManager.reload(name)
 | 
			
		||||
            this.update(sender, name, () => this.reload(sender, name))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmdunload(sender: any, name: string) {
 | 
			
		||||
        if (this.checkPlugin(sender, name)) {
 | 
			
		||||
            this.pluginManager.disable(name)
 | 
			
		||||
            this.i18n(sender, 'plugin.unload.finish', { name })
 | 
			
		||||
            let plugin = this.pluginManager.getPlugins().get(name)
 | 
			
		||||
            this.i18n(sender, 'plugin.unload.start', { name, version: plugin.description.version })
 | 
			
		||||
            this.pluginManager.disable(plugin)
 | 
			
		||||
            this.i18n(sender, 'plugin.unload.finish', { name, version: plugin.description.version })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cmdreload(sender: any, name: string) {
 | 
			
		||||
        name = name || this.description.name
 | 
			
		||||
        this.reload(sender, name)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private reload(sender: any, name: string) {
 | 
			
		||||
        if (this.checkPlugin(sender, name)) {
 | 
			
		||||
            this.pluginManager.reload(name)
 | 
			
		||||
            this.i18n(sender, 'plugin.reload.finish', { name })
 | 
			
		||||
            let plugin = this.pluginManager.getPlugins().get(name)
 | 
			
		||||
            this.i18n(sender, 'plugin.reload.start', { name, version: plugin.description.version })
 | 
			
		||||
            this.pluginManager.reload(plugin)
 | 
			
		||||
            this.i18n(sender, 'plugin.reload.finish', { name, version: this.pluginManager.getPlugins().get(name).description.version })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -360,13 +424,16 @@ return '§a返回结果: §r'+ eval(${JSON.stringify(code)});`)
 | 
			
		||||
        }).async().submit()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    update(sender: any, name: string) {
 | 
			
		||||
    private update(sender: any, name: string, callback?: () => void) {
 | 
			
		||||
        if (this.checkCloudPlugin(sender, name)) {
 | 
			
		||||
            this.download(sender, name, true)
 | 
			
		||||
            this.download(sender, name, true, () => {
 | 
			
		||||
                this.i18n(sender, 'update.finish', { name, version: this.packageCache[name].version })
 | 
			
		||||
                callback?.()
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Tab()
 | 
			
		||||
    @Tab({ alias: ['bmpm'] })
 | 
			
		||||
    tabmpm(sender: any, command: any, args: string | any[]) {
 | 
			
		||||
        if (args.length === 1) { return ['list', 'install', 'update', 'upgrade', 'reload', 'restart', 'run', 'help', 'create', 'deploy'] }
 | 
			
		||||
        if (args.length > 1) {
 | 
			
		||||
@@ -405,19 +472,15 @@ return '§a返回结果: §r'+ eval(${JSON.stringify(code)});`)
 | 
			
		||||
        }).async().submit()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    download(sender: any, name: string, update: boolean = false) {
 | 
			
		||||
    download(sender: any, name: string, update: boolean, callback?: () => void) {
 | 
			
		||||
        this.taskManager.create(() => {
 | 
			
		||||
            this.i18n(sender, 'download.start', { name })
 | 
			
		||||
            this.i18n(sender, 'download.url', { url: this.packageCache[name].url })
 | 
			
		||||
            let pluginPkg = this.packageCache[name]
 | 
			
		||||
            this.i18n(sender, 'download.start', { name, version: pluginPkg.version })
 | 
			
		||||
            this.i18n(sender, 'download.url', { url: pluginPkg.url })
 | 
			
		||||
            let pluginFile = update ? fs.concat(root, this.pluginFolder, 'update', name + '.js') : fs.concat(root, this.pluginFolder, name + '.js')
 | 
			
		||||
            http.download(this.packageCache[name].url, pluginFile)
 | 
			
		||||
            this.i18n(sender, 'download.finish', { name })
 | 
			
		||||
            if (!update) {
 | 
			
		||||
                this.pluginManager.loadFromFile(fs.concat(root, this.pluginFolder, name + '.js'))
 | 
			
		||||
                this.i18n(sender, 'install.finish', { name })
 | 
			
		||||
            } else {
 | 
			
		||||
                this.i18n(sender, 'update.finish', { name })
 | 
			
		||||
            }
 | 
			
		||||
            http.download(pluginPkg.url, pluginFile)
 | 
			
		||||
            this.i18n(sender, 'download.finish', { name, version: pluginPkg.version })
 | 
			
		||||
            callback?.()
 | 
			
		||||
        }).async().submit()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user