@@ -17,6 +17,7 @@ declare global {
 | 
			
		||||
    function engineLoad(str: string): any;
 | 
			
		||||
    interface Core {
 | 
			
		||||
        getClass(name: String): any;
 | 
			
		||||
        getProxyClass(): any;
 | 
			
		||||
        getInstance(): any;
 | 
			
		||||
        read(path: string): string;
 | 
			
		||||
        save(path: string, content: string): void;
 | 
			
		||||
 
 | 
			
		||||
@@ -12,8 +12,8 @@ const StandardCopyOption = Java.type("java.nio.file.StandardCopyOption");
 | 
			
		||||
/**
 | 
			
		||||
 * 用文件分割符合并路径
 | 
			
		||||
 */
 | 
			
		||||
export function concat() {
 | 
			
		||||
    return Array.prototype.join.call(arguments, separatorChar);
 | 
			
		||||
export function concat(...args: string[]) {
 | 
			
		||||
    return args.join(separatorChar);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -23,12 +23,12 @@ export function concat() {
 | 
			
		||||
 * @returns {*}
 | 
			
		||||
 */
 | 
			
		||||
export function file(...opts: any[]): any {
 | 
			
		||||
    if (!arguments[0]) {
 | 
			
		||||
    if (!opts[0]) {
 | 
			
		||||
        console.warn("文件名称不得为 undefined 或者 null !");
 | 
			
		||||
    }
 | 
			
		||||
    switch (arguments.length) {
 | 
			
		||||
    switch (opts.length) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            var f = arguments[0];
 | 
			
		||||
            var f = opts[0];
 | 
			
		||||
            if (f instanceof File) {
 | 
			
		||||
                return f;
 | 
			
		||||
            }
 | 
			
		||||
@@ -40,7 +40,7 @@ export function file(...opts: any[]): any {
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            return new File(file(arguments[0]), arguments[1]);
 | 
			
		||||
            return new File(file(opts[0]), opts[1]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -48,7 +48,7 @@ export function file(...opts: any[]): any {
 | 
			
		||||
 * 创建目录
 | 
			
		||||
 * @param path
 | 
			
		||||
 */
 | 
			
		||||
export function mkdirs(path) {
 | 
			
		||||
export function mkdirs(path: any) {
 | 
			
		||||
    // noinspection JSUnresolvedVariable
 | 
			
		||||
    file(path).parentFile.mkdirs();
 | 
			
		||||
}
 | 
			
		||||
@@ -57,7 +57,7 @@ export function mkdirs(path) {
 | 
			
		||||
 * 创建文件
 | 
			
		||||
 * @param file
 | 
			
		||||
 */
 | 
			
		||||
export function create(path) {
 | 
			
		||||
export function create(path: any) {
 | 
			
		||||
    var f = file(path);
 | 
			
		||||
    if (!f.exists()) {
 | 
			
		||||
        mkdirs(f);
 | 
			
		||||
@@ -70,7 +70,7 @@ export function create(path) {
 | 
			
		||||
 * @param file
 | 
			
		||||
 * @returns {*}
 | 
			
		||||
 */
 | 
			
		||||
export function path(f) {
 | 
			
		||||
export function path(f: any) {
 | 
			
		||||
    return file(f).canonicalPath;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -80,7 +80,7 @@ export function path(f) {
 | 
			
		||||
 * @param target 目标文件
 | 
			
		||||
 * @param override 是否覆盖
 | 
			
		||||
 */
 | 
			
		||||
export function copy(inputStream, target, override) {
 | 
			
		||||
export function copy(inputStream: any, target: any, override: any) {
 | 
			
		||||
    Files.copy(inputStream, target.toPath(), StandardCopyOption[override ? 'REPLACE_EXISTING' : 'ATOMIC_MOVE']);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ var main = avalon.define({
 | 
			
		||||
    server: window.localStorage.getItem(serverKey) || location.host,
 | 
			
		||||
    type: 'unknow',
 | 
			
		||||
    logs: '',
 | 
			
		||||
    codes: ["default", "bukkit", "sponge", "common", "test", "dev", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
 | 
			
		||||
    codes: ["default", "bukkit", "sponge", "bungee", "common", "test", "dev", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
 | 
			
		||||
    code: 'default',
 | 
			
		||||
    classes: {
 | 
			
		||||
        total: 0,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,7 @@
 | 
			
		||||
/// <reference types="@ms/types/dist/typings/bukkit" />
 | 
			
		||||
/// <reference types="@ms/types/dist/typings/sponge" />
 | 
			
		||||
/// <reference types="@ms/types/dist/typings/bungee" />
 | 
			
		||||
 | 
			
		||||
import { plugin, interfaces, cmd, listener, tab } from '@ms/plugin'
 | 
			
		||||
 | 
			
		||||
@plugin({ name: 'HelloWorld', version: '1.0.0', author: 'MiaoWoo', source: __filename })
 | 
			
		||||
@@ -32,6 +36,16 @@ export class HelloWorld extends interfaces.Plugin {
 | 
			
		||||
        this.logger.log('Disable When ServerType is Sponge!')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bungeeload() {
 | 
			
		||||
        this.logger.log('Load When ServerType is BungeeCord!')
 | 
			
		||||
    }
 | 
			
		||||
    bungeeenable() {
 | 
			
		||||
        this.logger.log('Enable When ServerType is BungeeCord!')
 | 
			
		||||
    }
 | 
			
		||||
    bungeedisable() {
 | 
			
		||||
        this.logger.log('Disable When ServerType is BungeeCord!')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @cmd()
 | 
			
		||||
    hello(sender: any, command: string, args: string[]) {
 | 
			
		||||
        this.logger.log(sender, command, args);
 | 
			
		||||
@@ -44,14 +58,22 @@ export class HelloWorld extends interfaces.Plugin {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @listener({ servertype: 'bukkit' })
 | 
			
		||||
    playerjoin(event: any) {
 | 
			
		||||
        this.logger.console(`§aBukkit PlayerJoinEvent: §b${event.player.name}`)
 | 
			
		||||
        setTimeout(() => this.logger.sender(event.player, `§a欢迎来到 §bMiaoScript §a的世界!`), 10);
 | 
			
		||||
    playerjoin(event: org.bukkit.event.player.PlayerJoinEvent) {
 | 
			
		||||
        let plyaer = event.getPlayer();
 | 
			
		||||
        this.logger.console(`§cBukkit §aPlayerJoinEvent: §b${plyaer.getName()}`)
 | 
			
		||||
        setTimeout(() => this.logger.sender(plyaer, `§a欢迎来到 §bMiaoScript §a的世界!`), 10);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @listener({ servertype: 'sponge' })
 | 
			
		||||
    clientconnectionevent$join(event: any) {
 | 
			
		||||
        this.logger.console(`§aSponge ClientConnectionEvent.Join: §b${event.targetEntity.name}`)
 | 
			
		||||
        setTimeout(() => this.logger.sender(event.targetEntity, `§a欢迎来到 §bMiaoScript §a的世界!`), 10);
 | 
			
		||||
    clientconnectionevent$join(event: org.spongepowered.api.event.network.ClientConnectionEvent.Join) {
 | 
			
		||||
        this.logger.console(`§cSponge §aClientConnectionEvent.Join: §b${event.getTargetEntity().getName()}`)
 | 
			
		||||
        setTimeout(() => this.logger.sender(event.getTargetEntity(), `§a欢迎来到 §bMiaoScript §a的世界!`), 10);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @listener({ servertype: 'bungee' })
 | 
			
		||||
    serverconnected(e: any) {
 | 
			
		||||
        let event = e as net.md_5.bungee.api.event.ServerConnectedEvent
 | 
			
		||||
        this.logger.console(`§cBungeeCord §aServerConnectedEvent: §b${event.getPlayer().getDisplayName()}`)
 | 
			
		||||
        setTimeout(() => this.logger.sender(event.getPlayer(), `§a欢迎来到 §bMiaoScript §a的世界 §6来自 §cBungeeCord §6的问候!`), 10);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										271
									
								
								packages/plugins/src/MiaoChat.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								packages/plugins/src/MiaoChat.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,271 @@
 | 
			
		||||
/// <reference types="@ms/types/dist/typings/bukkit" />
 | 
			
		||||
/// <reference types="@ms/types/dist/typings/sponge" />
 | 
			
		||||
 | 
			
		||||
import { server } from '@ms/api'
 | 
			
		||||
import { inject } from '@ms/container';
 | 
			
		||||
import { plugin, interfaces, cmd, listener, tab } from '@ms/plugin'
 | 
			
		||||
import Tellraw from '@ms/common/dist/tellraw'
 | 
			
		||||
 | 
			
		||||
@plugin({ name: 'MiaoChat', version: '1.0.0', author: 'MiaoWoo', source: __filename })
 | 
			
		||||
export class MiaoChat extends interfaces.Plugin {
 | 
			
		||||
    @inject(server.Server)
 | 
			
		||||
    private Server: server.Server
 | 
			
		||||
 | 
			
		||||
    private config = {
 | 
			
		||||
        Version: "1.8.5",
 | 
			
		||||
        BungeeCord: true,
 | 
			
		||||
        Server: "生存服",
 | 
			
		||||
        ChatFormats: {
 | 
			
		||||
            default: {
 | 
			
		||||
                index: 50,
 | 
			
		||||
                permission: "MiaoChat.default",
 | 
			
		||||
                range: 0,
 | 
			
		||||
                format: "[world][player]: ",
 | 
			
		||||
                item: true,
 | 
			
		||||
                itemformat: "&6[&b%s&6]&r"
 | 
			
		||||
            },
 | 
			
		||||
            admin: {
 | 
			
		||||
                index: 49,
 | 
			
		||||
                permission: "MiaoChat.admin",
 | 
			
		||||
                format: "[admin][world][player][help]: ",
 | 
			
		||||
                range: 0,
 | 
			
		||||
                item: true,
 | 
			
		||||
                itemformat: "&6[&b%s&6]&r"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        StyleFormats: {
 | 
			
		||||
            world: {
 | 
			
		||||
                text: "&6[&a%player_world%&6]",
 | 
			
		||||
                hover: [
 | 
			
		||||
                    "&6当前所在位置:",
 | 
			
		||||
                    "&6世界: &d%player_world%",
 | 
			
		||||
                    "&6坐标: &aX:%player_x% Y: %player_y% Z: %player_z%",
 | 
			
		||||
                    "",
 | 
			
		||||
                    "&c点击即可TP我!"
 | 
			
		||||
                ],
 | 
			
		||||
                click: {
 | 
			
		||||
                    type: "COMMAND",
 | 
			
		||||
                    command: "/tpa %player_name%"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            player: {
 | 
			
		||||
                text: "&b%player_name%",
 | 
			
		||||
                hover: [
 | 
			
		||||
                    "&6玩家名称: &b%player_name%",
 | 
			
		||||
                    "&6玩家等级: &a%player_level%",
 | 
			
		||||
                    "&6玩家血量: &c%player_health%",
 | 
			
		||||
                    "&6玩家饥饿: &d%player_food_level%",
 | 
			
		||||
                    "&6游戏模式: &4%player_gamemode%",
 | 
			
		||||
                    "",
 | 
			
		||||
                    "&c点击与我聊天"
 | 
			
		||||
                ],
 | 
			
		||||
                click: {
 | 
			
		||||
                    type: "SUGGEST",
 | 
			
		||||
                    command: "/tell %player_name%"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            admin: {
 | 
			
		||||
                text: "&6[&c管理员&6]"
 | 
			
		||||
            },
 | 
			
		||||
            help: {
 | 
			
		||||
                text: "&4[求助]",
 | 
			
		||||
                hover: [
 | 
			
		||||
                    "点击求助OP"
 | 
			
		||||
                ],
 | 
			
		||||
                click: {
 | 
			
		||||
                    type: "COMMAND",
 | 
			
		||||
                    command: "管理员@%player_name% 我需要你的帮助!"
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private chatFormats: any[];
 | 
			
		||||
    private styleFormats: any;
 | 
			
		||||
    // 用于匹配 '[xx]' 聊天格式
 | 
			
		||||
    private FORMAT_PATTERN = /[\[]([^\[\]]+)[\]]/ig;
 | 
			
		||||
 | 
			
		||||
    private PlaceholderAPI: { setPlaceholders: (player: any, str: string) => string };
 | 
			
		||||
 | 
			
		||||
    load() {
 | 
			
		||||
        if (!Object.values) {
 | 
			
		||||
            Object.defineProperty(Object, "values", {
 | 
			
		||||
                enumerable: false,
 | 
			
		||||
                configurable: true,
 | 
			
		||||
                writable: true,
 | 
			
		||||
                value: function(target) {
 | 
			
		||||
                    "use strict";
 | 
			
		||||
                    var values = [];
 | 
			
		||||
                    for (var key in target) {
 | 
			
		||||
                        var desc = Object.getOwnPropertyDescriptor(target, key);
 | 
			
		||||
                        if (desc !== undefined && desc.enumerable) values.push(target[key]);
 | 
			
		||||
                    }
 | 
			
		||||
                    return values;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        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];
 | 
			
		||||
            if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
 | 
			
		||||
                val1 = Number(val1);
 | 
			
		||||
                val2 = Number(val2);
 | 
			
		||||
            }
 | 
			
		||||
            if (val1 < val2) {
 | 
			
		||||
                return -1;
 | 
			
		||||
            } else if (val1 > val2) {
 | 
			
		||||
                return 1;
 | 
			
		||||
            } else {
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable() {
 | 
			
		||||
    }
 | 
			
		||||
    disable() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bukkitenable() {
 | 
			
		||||
        // 尝试加载 Bukkit 的 PlaceholderAPI
 | 
			
		||||
        try {
 | 
			
		||||
            //@ts-ignore
 | 
			
		||||
            this.PlaceholderAPI = base.getClass("me.clip.placeholderapi.PlaceholderAPI").static;
 | 
			
		||||
            console.log('[PAPI] Found Bukkit PlaceholderAPI Hooking...')
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    spongeenable() {
 | 
			
		||||
        // 尝试加载 Sponge 的 PlaceholderAPI
 | 
			
		||||
        try {
 | 
			
		||||
            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));
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
                console.log('[PAPI] Found Sponge PlaceholderAPI Hooking...')
 | 
			
		||||
            }
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @cmd()
 | 
			
		||||
    mchat(sender: any, command: string, args: string[]) {
 | 
			
		||||
        this.logger.log(sender, command, args);
 | 
			
		||||
        sender.sendMessage(JSON.stringify({ command, ...args }))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @tab()
 | 
			
		||||
    tabmchat(_sender: any, _command: string, _args: string[]) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @listener({ servertype: 'bukkit' })
 | 
			
		||||
    AsyncPlayerChatEvent(event: org.bukkit.event.player.AsyncPlayerChatEvent) {
 | 
			
		||||
        this.sendChat(event.getPlayer(), event.getMessage(), function() {
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @listener({ servertype: '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);
 | 
			
		||||
        if (player == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        var plain = event.getRawMessage().toPlain();
 | 
			
		||||
        if (plain.startsWith(Tellraw.duplicateChar)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        this.sendChat(player, plain, function() {
 | 
			
		||||
            event.setMessageCancelled(true)
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    initFormat(chatFormats: any[]) {
 | 
			
		||||
        chatFormats.forEach(chatFormat => {
 | 
			
		||||
            var chat_format_str = chatFormat.format;
 | 
			
		||||
            var temp = [];
 | 
			
		||||
            var r: any[];
 | 
			
		||||
            while (r = this.FORMAT_PATTERN.exec(chat_format_str)) {
 | 
			
		||||
                temp.push(r[1]);
 | 
			
		||||
            }
 | 
			
		||||
            var format_list = [];
 | 
			
		||||
            temp.forEach(function splitStyle(t) {
 | 
			
		||||
                var arr = chat_format_str.split('[' + t + ']', 2);
 | 
			
		||||
                if (arr[0]) {
 | 
			
		||||
                    format_list.push(arr[0]);
 | 
			
		||||
                }
 | 
			
		||||
                format_list.push(t);
 | 
			
		||||
                chat_format_str = arr[1];
 | 
			
		||||
            });
 | 
			
		||||
            if (chat_format_str) {
 | 
			
		||||
                format_list.push(chat_format_str);
 | 
			
		||||
            }
 | 
			
		||||
            chatFormat.format_list = format_list;
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sendChat(player: any, plain: string, callback: { (): void; }) {
 | 
			
		||||
        var chat_format = this.getChatFormat(player);
 | 
			
		||||
        if (!chat_format) {
 | 
			
		||||
            console.debug('未获得用户', player.getName(), '的 ChatRule 跳过执行...');
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        callback();
 | 
			
		||||
        var tr = Tellraw.create();
 | 
			
		||||
        chat_format.format_list.forEach((format) => {
 | 
			
		||||
            var style = this.styleFormats[format];
 | 
			
		||||
            if (style) {
 | 
			
		||||
                tr.then(this.replace(player, style.text));
 | 
			
		||||
                if (style.hover) {
 | 
			
		||||
                    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);
 | 
			
		||||
                    switch (style.click.type.toUpperCase()) {
 | 
			
		||||
                        case "COMMAND":
 | 
			
		||||
                            tr.command(command);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "OPENURL":
 | 
			
		||||
                            tr.link(command);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "SUGGEST":
 | 
			
		||||
                            tr.suggest(command);
 | 
			
		||||
                            break;
 | 
			
		||||
                        default:
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                tr.then(this.replace(player, format));
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        let json = tr.then(this.replace(player, plain)).json()
 | 
			
		||||
        this.Server.getOnlinePlayers().forEach(player => this.Server.sendJson(player, json))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getChatFormat(player: any) {
 | 
			
		||||
        for (var i in this.chatFormats) {
 | 
			
		||||
            var format = this.chatFormats[i];
 | 
			
		||||
            if (player.hasPermission(format.permission)) {
 | 
			
		||||
                return format;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    replace(player: any, target: string) {
 | 
			
		||||
        return this.PlaceholderAPI.setPlaceholders(player, target)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +1,8 @@
 | 
			
		||||
import { plugin as pluginApi, task } from '@ms/api'
 | 
			
		||||
import { plugin as pluginApi, task, server } from '@ms/api'
 | 
			
		||||
 | 
			
		||||
import * as fs from '@ms/common/dist/fs'
 | 
			
		||||
import { inject } from '@ms/container';
 | 
			
		||||
import { plugin, cmd, tab } from '@ms/plugin'
 | 
			
		||||
import { interfaces, plugin, cmd, tab } from '@ms/plugin'
 | 
			
		||||
 | 
			
		||||
let help = [
 | 
			
		||||
    '§6========= §6[§aMiaoScriptPackageManager§6] 帮助 §aBy §b喵♂呜 §6=========',
 | 
			
		||||
@@ -16,23 +17,21 @@ let help = [
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
@plugin({ name: 'MiaoScriptPackageManager', prefix: 'PM', version: '1.0.0', author: 'MiaoWoo', source: __filename })
 | 
			
		||||
export class MiaoScriptPackageManager {
 | 
			
		||||
export class MiaoScriptPackageManager extends interfaces.Plugin {
 | 
			
		||||
    @inject(pluginApi.PluginManager)
 | 
			
		||||
    private pluginManager: pluginApi.PluginManager;
 | 
			
		||||
    @inject(task.TaskManager)
 | 
			
		||||
    private taskManager: task.TaskManager;
 | 
			
		||||
    @inject(server.ServerType)
 | 
			
		||||
    private serverType: string;
 | 
			
		||||
    @inject(server.Server)
 | 
			
		||||
    private server: server.Server
 | 
			
		||||
 | 
			
		||||
    private pluginCache = [];
 | 
			
		||||
    private packageCache = [];
 | 
			
		||||
    private packageNameCache = [];
 | 
			
		||||
    private packageCache: any[] = [];
 | 
			
		||||
    private packageNameCache: any[] = [];
 | 
			
		||||
 | 
			
		||||
    load() {
 | 
			
		||||
        this.taskManager.create(() => {
 | 
			
		||||
            this.pluginCache = [...this.pluginManager.getPlugins().keys()];
 | 
			
		||||
            // JSON.parse(http.get(self.config.center)).data.forEach(function cachePackageName(pkg) {
 | 
			
		||||
            //     packageCache[pkg.name] = pkg;
 | 
			
		||||
            // })
 | 
			
		||||
            // packageNameCache = Object.keys(packageCache);
 | 
			
		||||
        }).async().submit();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -47,19 +46,19 @@ export class MiaoScriptPackageManager {
 | 
			
		||||
 | 
			
		||||
    main(sender: any, command: string, args: string[]) {
 | 
			
		||||
        if (!args[0] || args[1] === 'help') {
 | 
			
		||||
            console.sender(sender, help);
 | 
			
		||||
            this.logger.sender(sender, help);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        switch (args[0]) {
 | 
			
		||||
            case "list":
 | 
			
		||||
                if (args[1]) {
 | 
			
		||||
                    console.sender(sender, '§6当前 §bMiaoScript §6已安装下列插件:');
 | 
			
		||||
                    this.pluginCache.forEach(function listInfo(pluginName) {
 | 
			
		||||
                        // var desc = manager.plugins[pluginName].description;
 | 
			
		||||
                        // console.sender(sender, `§6插件名称: §b${desc.name} §6版本: §a${desc.version|| '1.0'} §6作者: §3${desc.author || '未知'}`)
 | 
			
		||||
                    this.logger.sender(sender, '§6当前 §bMiaoScript §6已安装下列插件:');
 | 
			
		||||
                    this.pluginManager.getPlugins().forEach((plugin) => {
 | 
			
		||||
                        var desc = plugin.description;
 | 
			
		||||
                        this.logger.sender(sender, `§6插件名称: §b${desc.name} §6版本: §a${desc.version || '1.0'} §6作者: §3${desc.author || '未知'}`)
 | 
			
		||||
                    })
 | 
			
		||||
                } else {
 | 
			
		||||
                    console.sender(sender, '§6当前 §bMiaoScriptPackageCenter §6中存在下列插件:');
 | 
			
		||||
                    this.logger.sender(sender, '§6当前 §bMiaoScriptPackageCenter §6中存在下列插件:');
 | 
			
		||||
                    for (var pkgName in this.packageCache) {
 | 
			
		||||
                        var pkg = this.packageCache[pkgName];
 | 
			
		||||
                        // console.sender(sender, '§6插件名称: §b%s §6版本: §a%s §6作者: §3%s'.format(pkg.name, pkg.version || '1.0', pkg.author || '未知'))
 | 
			
		||||
@@ -82,6 +81,9 @@ export class MiaoScriptPackageManager {
 | 
			
		||||
                // }
 | 
			
		||||
                break;
 | 
			
		||||
            case "upgrade":
 | 
			
		||||
                if (args[3] === "engine") {
 | 
			
		||||
                    fs.del(fs.concat(root, '', ''))
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case "delete":
 | 
			
		||||
                // if (args.length > 1) {
 | 
			
		||||
@@ -91,57 +93,59 @@ export class MiaoScriptPackageManager {
 | 
			
		||||
                // }
 | 
			
		||||
                break;
 | 
			
		||||
            case "reload":
 | 
			
		||||
                // if (args.length > 1) {
 | 
			
		||||
                //     var pname = args[1];
 | 
			
		||||
                //     if (pluginCache.indexOf(pname) !== -1) {
 | 
			
		||||
                //         manager.reload(pname)
 | 
			
		||||
                //         console.sender(sender, '§6插件 §b%s §a重载完成!'.format(pname))
 | 
			
		||||
                //     } else {
 | 
			
		||||
                //         console.sender(sender, '§c插件 §b%s §c不存在!'.format(pname))
 | 
			
		||||
                //     }
 | 
			
		||||
                // } else {
 | 
			
		||||
                //     self.reloadConfig();
 | 
			
		||||
                //     load();
 | 
			
		||||
                // }
 | 
			
		||||
                if (args.length > 1) {
 | 
			
		||||
                    var pname = args[1];
 | 
			
		||||
                    if (!this.pluginManager.getPlugins().has(pname)) {
 | 
			
		||||
                        this.logger.sender(sender, `§6插件 §b${pname} §c不存在!`)
 | 
			
		||||
                        return
 | 
			
		||||
                    }
 | 
			
		||||
                    this.pluginManager.reload(pname);
 | 
			
		||||
                    this.logger.sender(sender, `§6插件 §b${pname} §a重载完成!`)
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case "restart":
 | 
			
		||||
                if (this.serverType === "sponge") {
 | 
			
		||||
                    setTimeout(() => this.server.dispatchConsoleCommand('sponge plugins reload'), 0)
 | 
			
		||||
                    return
 | 
			
		||||
                }
 | 
			
		||||
                try {
 | 
			
		||||
                    console.sender(sender, '§6Reloading §3MiaoScript Engine...');
 | 
			
		||||
                    this.logger.sender(sender, '§6Reloading §3MiaoScript Engine...');
 | 
			
		||||
                    ScriptEngineContextHolder.disableEngine();
 | 
			
		||||
                    ScriptEngineContextHolder.enableEngine();
 | 
			
		||||
                    console.sender(sender, '§3MiaoScript Engine §6Reload §aSuccessful...');
 | 
			
		||||
                    this.logger.sender(sender, '§3MiaoScript Engine §6Reload §aSuccessful...');
 | 
			
		||||
                } catch (ex) {
 | 
			
		||||
                    console.sender(sender, "§3MiaoScript Engine §6Reload §cError! ERR: " + ex);
 | 
			
		||||
                    console.sender(sender, console.stack(ex));
 | 
			
		||||
                    this.logger.sender(sender, "§3MiaoScript Engine §6Reload §cError! ERR: " + ex);
 | 
			
		||||
                    this.logger.sender(sender, this.logger.stack(ex));
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case "run":
 | 
			
		||||
                args.shift();
 | 
			
		||||
                try {
 | 
			
		||||
                    var script = args.join(' ')
 | 
			
		||||
                    console.sender(sender, '§b运行脚本:§r', script)
 | 
			
		||||
                    console.sender(sender, '§a返回结果:§r', eval(script) || '§4没有返回结果!');
 | 
			
		||||
                    var script = args.join(' ');
 | 
			
		||||
                    this.logger.sender(sender, '§b运行脚本:§r', script);
 | 
			
		||||
                    this.logger.sender(sender, '§a返回结果:§r', eval(script) || '§4没有返回结果!');
 | 
			
		||||
                } catch (ex) {
 | 
			
		||||
                    console.sender(sender, console.stack(ex))
 | 
			
		||||
                    this.logger.sender(sender, this.logger.stack(ex));
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case "create":
 | 
			
		||||
                this.logger.sender(sender, `§4当前暂不支持生成插件模板!`);
 | 
			
		||||
                // var name = args[1];
 | 
			
		||||
                // if (!name) {
 | 
			
		||||
                //     console.sender(sender, '§4参数错误 /mpm create <插件名称> [作者] [版本] [主命令]');
 | 
			
		||||
                //     this.logger.sender(sender, '§4参数错误 /mpm create <插件名称> [作者] [版本] [主命令]');
 | 
			
		||||
                //     return;
 | 
			
		||||
                // }
 | 
			
		||||
                // var result = template.create(http.get(self.config.template)).render({
 | 
			
		||||
                //     name: name,
 | 
			
		||||
                //     author: args[2] || 'MiaoWoo',
 | 
			
		||||
                //     version: args[3] || '1.0',
 | 
			
		||||
                //     command: args[4] || name.toLowerCase(),
 | 
			
		||||
                // });
 | 
			
		||||
                // fs.save(fs.file(__dirname, name + '.js'), result);
 | 
			
		||||
                // console.sender(sender, '§6插件 §a' + name + ' §6已生成到插件目录...');
 | 
			
		||||
                // // var result = template.create(http.get(self.config.template)).render({
 | 
			
		||||
                // //     name: name,
 | 
			
		||||
                // //     author: args[2] || 'MiaoWoo',
 | 
			
		||||
                // //     version: args[3] || '1.0',
 | 
			
		||||
                // //     command: args[4] || name.toLowerCase(),
 | 
			
		||||
                // // });
 | 
			
		||||
                // // fs.save(fs.file(__dirname, name + '.js'), result);
 | 
			
		||||
                // this.logger.sender(sender, '§6插件 §a' + name + ' §6已生成到插件目录...');
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                console.sender(sender, help);
 | 
			
		||||
                this.logger.sender(sender, help);
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -156,8 +160,8 @@ export class MiaoScriptPackageManager {
 | 
			
		||||
                case "update":
 | 
			
		||||
                case "upgrade":
 | 
			
		||||
                case "reload":
 | 
			
		||||
                    return this.pluginCache;
 | 
			
		||||
                    return [...this.pluginManager.getPlugins().keys()];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,9 @@ import { plugin as pluginApi } from '@ms/api'
 | 
			
		||||
import { plugin, interfaces, cmd, listener, tab } from '@ms/plugin'
 | 
			
		||||
import { inject } from '@ms/container';
 | 
			
		||||
 | 
			
		||||
import * as reflect from '@ms/common/dist/reflect';
 | 
			
		||||
import http from '@ms/common/dist/http';
 | 
			
		||||
 | 
			
		||||
@plugin({ name: 'Test', version: '1.0.0', author: 'MiaoWoo', source: __filename })
 | 
			
		||||
export class Test extends interfaces.Plugin {
 | 
			
		||||
    @inject(pluginApi.PluginManager)
 | 
			
		||||
@@ -51,7 +54,18 @@ export class Test extends interfaces.Plugin {
 | 
			
		||||
                setTimeout(() => location.block.type = Java.type('org.bukkit.Material').STONE, 8);
 | 
			
		||||
                break;
 | 
			
		||||
            case "add":
 | 
			
		||||
                require('js-yaml1');
 | 
			
		||||
                break;
 | 
			
		||||
            case "get":
 | 
			
		||||
                let result = http.get('https://www.baidu.com');
 | 
			
		||||
                this.logger.sender(sender, JSON.stringify(result));
 | 
			
		||||
                // 好了 扯结束 继续咸鱼
 | 
			
		||||
                break;
 | 
			
		||||
            case "ws":
 | 
			
		||||
                let Sponge = Java.type('org.spongepowered.api.Sponge');
 | 
			
		||||
                // let promise = reflect.on(Bukkit.server).get('console').get('field_147144_o').get('field_151274_e').get().get(0);
 | 
			
		||||
                console.log(reflect.on(Sponge.server).get('field_147144_o').get())
 | 
			
		||||
                // let channel = reflect.on(promise).get('channel').get().pipeline().first();
 | 
			
		||||
                // console.log(channel);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                this.logger.log(sender, command, args);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
/// <reference types="@ms/types/dist/typings/bukkit" />
 | 
			
		||||
/// <reference types="@ms/types/dist/typings/sponge" />
 | 
			
		||||
import { plugin as pluginApi, server } from '@ms/api'
 | 
			
		||||
/// <reference types="@ms/types/dist/typings/bungee" />
 | 
			
		||||
 | 
			
		||||
import { plugin as pluginApi, server, task } from '@ms/api'
 | 
			
		||||
import { plugin, interfaces, cmd } from '@ms/plugin'
 | 
			
		||||
import { DefaultContainer as container, inject, postConstruct } from '@ms/container'
 | 
			
		||||
import * as reflect from '@ms/common/dist/reflect'
 | 
			
		||||
@@ -8,25 +10,31 @@ import * as reflect from '@ms/common/dist/reflect'
 | 
			
		||||
let clients: any[] = []
 | 
			
		||||
let SPLIT_LINE = '\\M\\W\\S|T|S|S/L/T/'
 | 
			
		||||
const refList: Array<{ server: string, future: string }> = [
 | 
			
		||||
    { server: 'an', future: 'g' },
 | 
			
		||||
    { server: 'getServerConnection', future: 'f' },
 | 
			
		||||
    { server: 'func_147137_ag', future: 'field_151274_e' }
 | 
			
		||||
    { server: 'an', future: 'g' },//spigot 1.12.2
 | 
			
		||||
    { server: 'getServerConnection', future: 'f' },//spigot 1.14.4
 | 
			
		||||
    { server: 'func_147137_ag', future: 'field_151274_e' }//catserver 1.12.2
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const Callable = Java.type('java.util.concurrent.Callable')
 | 
			
		||||
const Runnable = Java.type('java.lang.Runnable')
 | 
			
		||||
 | 
			
		||||
@plugin({ name: 'WebSocket', version: '1.0.0', author: 'MiaoWoo', source: __filename })
 | 
			
		||||
export class WebSocket extends interfaces.Plugin {
 | 
			
		||||
@plugin({ name: 'MiaoConsole', version: '1.0.0', author: 'MiaoWoo', source: __filename })
 | 
			
		||||
export class MiaoConsole extends interfaces.Plugin {
 | 
			
		||||
    @inject(pluginApi.PluginManager)
 | 
			
		||||
    private PluginManager: pluginApi.PluginManager
 | 
			
		||||
    @inject(server.ServerType)
 | 
			
		||||
    private ServerType: string
 | 
			
		||||
    @inject(server.Server)
 | 
			
		||||
    private Server: server.Server
 | 
			
		||||
    @inject(task.TaskManager)
 | 
			
		||||
    private Task: task.TaskManager
 | 
			
		||||
    @inject(pluginApi.PluginInstance)
 | 
			
		||||
    private pluginInstance: any
 | 
			
		||||
 | 
			
		||||
    private pipeline: any
 | 
			
		||||
 | 
			
		||||
    @cmd()
 | 
			
		||||
    ws(sender: any, command: string, args: string[]) {
 | 
			
		||||
    mconsole(sender: any, command: string, args: string[]) {
 | 
			
		||||
        switch (args[0]) {
 | 
			
		||||
            case "reload":
 | 
			
		||||
                this.PluginManager.reload(this)
 | 
			
		||||
@@ -37,7 +45,9 @@ export class WebSocket extends interfaces.Plugin {
 | 
			
		||||
 | 
			
		||||
    disable() {
 | 
			
		||||
        if (this.pipeline) {
 | 
			
		||||
            this.pipeline.remove('miao_detect')
 | 
			
		||||
            if (this.pipeline.names().contains('miao_detect')) {
 | 
			
		||||
                this.pipeline.remove('miao_detect')
 | 
			
		||||
            }
 | 
			
		||||
            clients.forEach(c => c.close())
 | 
			
		||||
            container.unbind('onmessage')
 | 
			
		||||
        }
 | 
			
		||||
@@ -46,13 +56,28 @@ export class WebSocket extends interfaces.Plugin {
 | 
			
		||||
    bukkitenable() {
 | 
			
		||||
        let Bukkit = Java.type('org.bukkit.Bukkit')
 | 
			
		||||
        let consoleServer = reflect.on(Bukkit.getServer()).get('console').get()
 | 
			
		||||
        this.injectMiaoDetect(this.reflectPromise(consoleServer))
 | 
			
		||||
        this.reflectChannel(this.reflectPromise(consoleServer))
 | 
			
		||||
        this.injectMiaoDetect()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    spongeenable() {
 | 
			
		||||
        let Sponge = Java.type('org.spongepowered.api.Sponge')
 | 
			
		||||
        let consoleServer = reflect.on(Sponge.getServer()).get()
 | 
			
		||||
        this.injectMiaoDetect(this.reflectPromise(consoleServer))
 | 
			
		||||
        this.reflectChannel(this.reflectPromise(consoleServer))
 | 
			
		||||
        this.injectMiaoDetect()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bungeeenable() {
 | 
			
		||||
        let wait = this.Task.create(() => {
 | 
			
		||||
            try {
 | 
			
		||||
                // @ts-ignore
 | 
			
		||||
                this.pipeline = reflect.on(base.getInstance().getProxy()).get('listeners').get().toArray()[0].pipeline()
 | 
			
		||||
                this.injectMiaoDetect()
 | 
			
		||||
                wait.cancel();
 | 
			
		||||
            } catch (ex) {
 | 
			
		||||
                this.logger.warn('Wait BungeeCord start ready to get netty channel pipeline. Err: ' + ex)
 | 
			
		||||
            }
 | 
			
		||||
        }).later(300).timer(500).submit()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    reflectPromise(consoleServer) {
 | 
			
		||||
@@ -61,16 +86,20 @@ export class WebSocket extends interfaces.Plugin {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    injectMiaoDetect(promise) {
 | 
			
		||||
    reflectChannel(promise) {
 | 
			
		||||
        if (!promise) { throw Error(`Can't found ServerConnection or ChannelFuture !`) }
 | 
			
		||||
        this.pipeline = reflect.on(promise).get('channel').get().pipeline()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    injectMiaoDetect() {
 | 
			
		||||
        this.pipeline.addFirst('miao_detect', new MiaoDetectHandler())
 | 
			
		||||
        container.bind('onmessage').toFunction(this.onmessage.bind(this))
 | 
			
		||||
        this.logger.info('Netty Channel Pipeline Inject MiaoDetectHandler Successful!')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onmessage(ctx: any, msg: any) {
 | 
			
		||||
        let text: string = msg.text()
 | 
			
		||||
        const [type, content] = text.split('\\M\\W\\S|T|S|S/L/T/')
 | 
			
		||||
        const [type, content] = text.split(SPLIT_LINE)
 | 
			
		||||
        try {
 | 
			
		||||
            var result = this[type](ctx, content)
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
@@ -80,13 +109,7 @@ export class WebSocket extends interfaces.Plugin {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    execCommand(ctx: any, cmd: string) {
 | 
			
		||||
        switch (this.ServerType) {
 | 
			
		||||
            case "bukkit":
 | 
			
		||||
                org.bukkit.Bukkit.dispatchCommand(org.bukkit.Bukkit.getConsoleSender(), cmd)
 | 
			
		||||
                break
 | 
			
		||||
            case "sponge":
 | 
			
		||||
                break
 | 
			
		||||
        }
 | 
			
		||||
        setTimeout(() => this.Server.dispatchConsoleCommand(cmd), 0)
 | 
			
		||||
        return `§6命令: §b${cmd} §a执行成功!`
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -95,16 +118,17 @@ export class WebSocket extends interfaces.Plugin {
 | 
			
		||||
            case "bukkit":
 | 
			
		||||
                return org.bukkit.Bukkit.getScheduler().callSyncMethod(this.pluginInstance, new Callable({ call: () => eval(code) })).get() || '无返回结果'
 | 
			
		||||
            case "sponge":
 | 
			
		||||
                return ''
 | 
			
		||||
                return org.spongepowered.api.Sponge.getScheduler().createSyncExecutor(this.pluginInstance).schedule(new Runnable({ run: () => eval(code) }), 0, {})
 | 
			
		||||
            case "bungee":
 | 
			
		||||
                return eval(code)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    execDetect(ctx: any, cmd: string) {
 | 
			
		||||
        switch (cmd) {
 | 
			
		||||
            case "type":
 | 
			
		||||
                let version = this.ServerType == 'bukkit' ? org.bukkit.Bukkit.getServer().getVersion() : org.spongepowered.api.Sponge.getPlatform().getMinecraftVersion()
 | 
			
		||||
                this.sendResult(ctx, "type", this.ServerType)
 | 
			
		||||
                return `Currect Server Version is ${version}`
 | 
			
		||||
                return `Currect Server Version is ${this.Server.getVersion()}`
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -196,7 +220,7 @@ const WebSocketHandler = Java.extend(ChannelInboundHandlerAdapter, {
 | 
			
		||||
        let channel = ctx.channel()
 | 
			
		||||
        let pipeline = channel.pipeline()
 | 
			
		||||
        if (message.indexOf('HTTP/1.1') > 0) {
 | 
			
		||||
            channel.pipeline().names().forEach(f => {
 | 
			
		||||
            pipeline.names().forEach(f => {
 | 
			
		||||
                if (f == 'miaowebsocket' || f.indexOf('DefaultChannelPipeline') > -1) { return }
 | 
			
		||||
                pipeline.remove(f)
 | 
			
		||||
            })
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user