Init: Create & Init ms Project...
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
		
							
								
								
									
										4
									
								
								packages/api/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/api/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
/node_modules
 | 
			
		||||
/dist
 | 
			
		||||
/package-lock.json
 | 
			
		||||
/yarn.lock
 | 
			
		||||
							
								
								
									
										22
									
								
								packages/api/.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/api/.npmignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
src
 | 
			
		||||
test
 | 
			
		||||
typings
 | 
			
		||||
bundled
 | 
			
		||||
build
 | 
			
		||||
coverage
 | 
			
		||||
docs
 | 
			
		||||
wiki
 | 
			
		||||
gulpfile.js
 | 
			
		||||
bower.json
 | 
			
		||||
karma.conf.js
 | 
			
		||||
tsconfig.json
 | 
			
		||||
typings.json
 | 
			
		||||
CONTRIBUTING.md
 | 
			
		||||
ISSUE_TEMPLATE.md
 | 
			
		||||
PULL_REQUEST_TEMPLATE.md
 | 
			
		||||
tslint.json
 | 
			
		||||
wallaby.js
 | 
			
		||||
.travis.yml
 | 
			
		||||
.gitignore
 | 
			
		||||
.vscode
 | 
			
		||||
type_definitions
 | 
			
		||||
							
								
								
									
										33
									
								
								packages/api/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								packages/api/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@ms/api",
 | 
			
		||||
    "version": "0.0.0",
 | 
			
		||||
    "description": "MiaoScript api package",
 | 
			
		||||
    "keywords": [
 | 
			
		||||
        "miaoscript",
 | 
			
		||||
        "minecraft",
 | 
			
		||||
        "bukkit",
 | 
			
		||||
        "sponge"
 | 
			
		||||
    ],
 | 
			
		||||
    "author": "MiaoWoo <admin@yumc.pw>",
 | 
			
		||||
    "homepage": "https://github.com/circlecloud/ms.git",
 | 
			
		||||
    "license": "ISC",
 | 
			
		||||
    "main": "dist/index.js",
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "registry": "https://repo.yumc.pw/repository/npm/"
 | 
			
		||||
    },
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "clean": "rimraf dist",
 | 
			
		||||
        "watch": "npx tsc --watch",
 | 
			
		||||
        "build": "yarn clean && npx tsc",
 | 
			
		||||
        "test": "echo \"Error: run tests from root\" && exit 1"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@ms/common": "^0.0.0",
 | 
			
		||||
        "inversify": "^5.0.1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "reflect-metadata": "^0.1.13",
 | 
			
		||||
        "rimraf": "^3.0.0",
 | 
			
		||||
        "typescript": "^3.6.2"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								packages/api/src/command.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								packages/api/src/command.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
import { PluginInfo } from './typings/plugin';
 | 
			
		||||
export namespace command {
 | 
			
		||||
    export abstract class Command {
 | 
			
		||||
        on(plugin: PluginInfo, name: string, exec: { cmd: Function, tab?: Function }) {
 | 
			
		||||
            var cmd = this.create(plugin, { name: name });
 | 
			
		||||
            console.debug(`插件 ${plugin.description.name} 创建命令 ${name}(${cmd})...`)
 | 
			
		||||
            if (exec.cmd && typeof exec.cmd === "function") {
 | 
			
		||||
                this.onCommand(plugin, cmd, exec.cmd)
 | 
			
		||||
            } else {
 | 
			
		||||
                throw Error("CommandExec Must be a function... Input: " + exec.cmd)
 | 
			
		||||
            }
 | 
			
		||||
            if (exec.tab && typeof exec.tab === "function") {
 | 
			
		||||
                this.onTabComplete(plugin, cmd, exec.tab)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        /**
 | 
			
		||||
         * Create Server Command Object
 | 
			
		||||
         */
 | 
			
		||||
        abstract create(plugin: object, opts: { name: string });
 | 
			
		||||
        abstract onCommand(plugin: object, command: any, opts: { name: string });
 | 
			
		||||
        abstract onTabComplete(plugin: object, command: any, opts: { name: string });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										146
									
								
								packages/api/src/console.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								packages/api/src/console.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,146 @@
 | 
			
		||||
let Arrays = Java.type('java.util.Arrays');
 | 
			
		||||
let Level = Java.type('java.util.logging.Level');
 | 
			
		||||
let ignoreLogPrefix = ['java.', 'net.minecraft.', 'org.bukkit.', 'jdk.nashorn.'];
 | 
			
		||||
 | 
			
		||||
export class MiaoScriptConsole implements Console {
 | 
			
		||||
    Console: NodeJS.ConsoleConstructor;
 | 
			
		||||
 | 
			
		||||
    private _name: string = '';
 | 
			
		||||
    private logger: any;
 | 
			
		||||
 | 
			
		||||
    protected prefix: string = '§6[§bMiaoScript§6]§r ';
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.logger = global.logger;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get name() {
 | 
			
		||||
        return this._name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set name(name: string) {
 | 
			
		||||
        if (name) {
 | 
			
		||||
            this._name = `[${name}] `;
 | 
			
		||||
            // noinspection JSUnusedGlobalSymbols
 | 
			
		||||
            this.prefix = `§6[§cMS§6][§b${name}§6]§r `;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    log(...args): void {
 | 
			
		||||
        this.logger.info(this.name + args.join(' '));
 | 
			
		||||
    }
 | 
			
		||||
    info(...args) {
 | 
			
		||||
        this.logger.info(this.name + args.join(' '));
 | 
			
		||||
    };
 | 
			
		||||
    warn(...args) {
 | 
			
		||||
        this.logger.warning(this.name + args.join(' '));
 | 
			
		||||
    };
 | 
			
		||||
    error(...args) {
 | 
			
		||||
        this.logger.log(Level.SEVERE, this.name + args.join(' '));
 | 
			
		||||
    };
 | 
			
		||||
    debug(...args) {
 | 
			
		||||
        if (global.debug) {
 | 
			
		||||
            this.logger.info(this.name + '[DEBUG] ' + args.join(' '));
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    sender(...args) {
 | 
			
		||||
        this.info(args)
 | 
			
		||||
    }
 | 
			
		||||
    console(...args) {
 | 
			
		||||
        this.info(args)
 | 
			
		||||
    }
 | 
			
		||||
    object(obj) {
 | 
			
		||||
        for (var i in obj) {
 | 
			
		||||
            this.logger(i, '=>', obj[i])
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    ex(ex: Error) {
 | 
			
		||||
        this.stack(ex).forEach(line => this.console(line))
 | 
			
		||||
    };
 | 
			
		||||
    stack(ex: Error | any): string[] {
 | 
			
		||||
        var stack = ex.getStackTrace();
 | 
			
		||||
        var cache = ['§4' + ex];
 | 
			
		||||
        if (stack.class) {
 | 
			
		||||
            stack = Arrays.asList(stack)
 | 
			
		||||
        }
 | 
			
		||||
        stack.forEach(function(trace) {
 | 
			
		||||
            if (trace.className.startsWith('<')) {
 | 
			
		||||
                var fileName = trace.fileName
 | 
			
		||||
                fileName = fileName.indexOf('runtime') > -1 ? fileName.split('runtime')[1] : fileName;
 | 
			
		||||
                cache.push(`    §e->§c ${fileName} => §4${trace.methodName}:${trace.lineNumber}`)
 | 
			
		||||
            } else {
 | 
			
		||||
                var className = trace.className;
 | 
			
		||||
                if (className.startsWith('jdk.nashorn.internal.scripts')) {
 | 
			
		||||
                    className = className.substr(className.lastIndexOf('$') + 1)
 | 
			
		||||
                } else {
 | 
			
		||||
                    for (var prefix in ignoreLogPrefix) {
 | 
			
		||||
                        if (className.startsWith(ignoreLogPrefix[prefix])) {
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                cache.push(`    §e->§c ${className}.${trace.methodName}(§4${trace.fileName}:${trace.lineNumber}§c)`);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return cache;
 | 
			
		||||
    }
 | 
			
		||||
    assert(value: any, message?: string, ...optionalParams: any[]): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    clear(): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    count(label?: string): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    countReset(label?: string): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    dir(obj: any, options?: NodeJS.InspectOptions): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    dirxml(...data: any[]): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    group(...label: any[]): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    groupCollapsed(...label: any[]): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    groupEnd(): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    table(tabularData: any, properties?: string[]): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    time(label?: string): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    timeEnd(label?: string): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    timeLog(label?: string, ...data: any[]): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    trace(message?: any, ...optionalParams: any[]): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    markTimeline(label?: string): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    profile(label?: string): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    profileEnd(label?: string): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    timeStamp(label?: string): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    timeline(label?: string): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
    timelineEnd(label?: string): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										154
									
								
								packages/api/src/event.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								packages/api/src/event.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
/**
 | 
			
		||||
 * MiaoScript Event处理类
 | 
			
		||||
 */
 | 
			
		||||
import '@ms/core'
 | 
			
		||||
import '@ms/nashorn'
 | 
			
		||||
import { injectable } from 'inversify'
 | 
			
		||||
 | 
			
		||||
const Thread = Java.type("java.lang.Thread");
 | 
			
		||||
 | 
			
		||||
@injectable()
 | 
			
		||||
abstract class EventService {
 | 
			
		||||
    private plugin;
 | 
			
		||||
    private mapEvent = [];
 | 
			
		||||
    private listenerMap = [];
 | 
			
		||||
    private baseEventDir = '';
 | 
			
		||||
    constructor(baseEventDir: string) {
 | 
			
		||||
        this.baseEventDir = baseEventDir;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * 扫描包 org.bukkit.event 下的所有事件
 | 
			
		||||
     * 映射简写名称 org.bukkit.event.player.PlayerLoginEvent => playerloginevent
 | 
			
		||||
     */
 | 
			
		||||
    mapEventName() {
 | 
			
		||||
        if (this.baseEventDir === "") {
 | 
			
		||||
            throw new Error("事件基础包名为空 无法进行事件映射!");
 | 
			
		||||
        }
 | 
			
		||||
        var count = 0;
 | 
			
		||||
        var dirs = Thread.currentThread().getContextClassLoader().getResources(this.baseEventDir);
 | 
			
		||||
        while (dirs.hasMoreElements()) {
 | 
			
		||||
            var url = dirs.nextElement();
 | 
			
		||||
            var protocol = url.protocol;
 | 
			
		||||
            if (protocol === "jar") {
 | 
			
		||||
                // noinspection JSUnresolvedVariable
 | 
			
		||||
                var jar = url.openConnection().jarFile;
 | 
			
		||||
                var entries = jar.entries();
 | 
			
		||||
                while (entries.hasMoreElements()) {
 | 
			
		||||
                    var entry = entries.nextElement();
 | 
			
		||||
                    var name = entry.name;
 | 
			
		||||
                    // 以 org/bukkit/event 开头 并且以 .class 结尾
 | 
			
		||||
                    if (name.startsWith(this.baseEventDir) && name.endsWith(".class")) {
 | 
			
		||||
                        var i = name.replaceAll('/', '.');
 | 
			
		||||
                        try {
 | 
			
		||||
                            var clz = base.getClass(i.substring(0, i.length - 6));
 | 
			
		||||
                            // 继承于 org.bukkit.event.Event 访问符为Public
 | 
			
		||||
                            if (this.isValidEvent(clz)) {
 | 
			
		||||
                                var simpleName = this.class2Name(clz).toLowerCase();
 | 
			
		||||
                                console.debug(`Mapping Event [${clz.canonicalName}] => ${simpleName}`);
 | 
			
		||||
                                this.mapEvent[simpleName] = clz;
 | 
			
		||||
                                count++;
 | 
			
		||||
                            }
 | 
			
		||||
                        } catch (ex) {
 | 
			
		||||
                            //ignore already loaded class
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return count;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    class2Name(clazz) {
 | 
			
		||||
        return clazz.simpleName;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    name2Class(name, event) {
 | 
			
		||||
        var eventCls = this.mapEvent[event.toLowerCase()] || this.mapEvent[event.toLowerCase() + 'event'];
 | 
			
		||||
        if (!eventCls) {
 | 
			
		||||
            try {
 | 
			
		||||
                eventCls = base.getClass(eventCls);
 | 
			
		||||
                this.mapEvent[event] = eventCls;
 | 
			
		||||
            } catch (ex) {
 | 
			
		||||
                console.console(`§6插件 §b${name} §6注册事件 §c${event} §6失败 §4事件未找到!`);
 | 
			
		||||
                console.ex(new Error(`插件 ${name} 注册事件 ${event} 失败 事件未找到!`));
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return eventCls;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    execute(name, exec, eventCls) {
 | 
			
		||||
        return (...args) => {
 | 
			
		||||
            try {
 | 
			
		||||
                var time = new Date().getTime()
 | 
			
		||||
                exec(args[args.length - 1]);
 | 
			
		||||
                var cost = new Date().getTime() - time;
 | 
			
		||||
                if (cost > 20) {
 | 
			
		||||
                    console.console(`§c注意! §6插件 §b${name} §6处理 §d${this.class2Name(eventCls)} §6事件 §c耗时 §4${cost}ms !`)
 | 
			
		||||
                }
 | 
			
		||||
            } catch (ex) {
 | 
			
		||||
                console.console(`§6插件 §b${name} §6处理 §d${this.class2Name(eventCls)} §6事件时发生异常 §4${ex}`);
 | 
			
		||||
                console.ex(ex);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * 添加事件监听
 | 
			
		||||
    * @param jsp
 | 
			
		||||
    * @param event
 | 
			
		||||
    * @param exec {function}
 | 
			
		||||
    * @param priority [LOWEST,LOW,NORMAL,HIGH,HIGHEST,MONITOR]
 | 
			
		||||
    * @param ignoreCancel
 | 
			
		||||
    */
 | 
			
		||||
    listen(jsp, event, exec, priority, ignoreCancel) {
 | 
			
		||||
        if (!jsp || !jsp.description || !jsp.description.name) throw new TypeError('插件名称为空 请检查传入参数!');
 | 
			
		||||
        var name = jsp.description.name;
 | 
			
		||||
        var eventCls = this.name2Class(name, event);
 | 
			
		||||
        if (!eventCls) { return; }
 | 
			
		||||
        if (typeof priority === 'boolean') {
 | 
			
		||||
            ignoreCancel = priority;
 | 
			
		||||
            priority = 'NORMAL';
 | 
			
		||||
        }
 | 
			
		||||
        priority = priority || 'NORMAL';
 | 
			
		||||
        ignoreCancel = ignoreCancel || false;
 | 
			
		||||
        // noinspection JSUnusedGlobalSymbols
 | 
			
		||||
        var listener = this.register(eventCls, this.execute(name, exec, eventCls), priority, ignoreCancel);
 | 
			
		||||
        var listenerMap = this.listenerMap;
 | 
			
		||||
        // 添加到缓存 用于关闭插件的时候关闭事件
 | 
			
		||||
        if (!listenerMap[name]) listenerMap[name] = [];
 | 
			
		||||
        var offExec = () => {
 | 
			
		||||
            this.unregister(eventCls, listener);
 | 
			
		||||
            console.debug(`插件 ${name} 注销事件 ${this.class2Name(eventCls)}`);
 | 
			
		||||
        };
 | 
			
		||||
        var off = {
 | 
			
		||||
            event: eventCls,
 | 
			
		||||
            listener: listener,
 | 
			
		||||
            off: offExec
 | 
			
		||||
        };
 | 
			
		||||
        listenerMap[name].push(off);
 | 
			
		||||
        // noinspection JSUnresolvedVariable
 | 
			
		||||
        console.debug(`插件 ${name} 注册事件 ${this.class2Name(eventCls)} => ${exec.name || '匿名方法'}`);
 | 
			
		||||
        return off;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    abstract isValidEvent(clazz: any): boolean;
 | 
			
		||||
    abstract register(eventCls: any, exec: Function, priority, ignoreCancel);
 | 
			
		||||
    abstract unregister(event, listener);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var EventHandler = Object.assign(new EventHandler(), require('event'));
 | 
			
		||||
// 映射事件名称
 | 
			
		||||
console.info(`bukkit 事件映射完毕 共计 ${EventHandler.mapEventName().toFixed(0)} 个事件!`);
 | 
			
		||||
module.exports = {
 | 
			
		||||
    on: EventHandler.listen.bind(EventHandler),
 | 
			
		||||
    disable: function(jsp) {
 | 
			
		||||
        var eventCache = EventHandler.listenerMap[jsp.description.name];
 | 
			
		||||
        if (eventCache) {
 | 
			
		||||
            eventCache.forEach(t => t.off());
 | 
			
		||||
            delete EventHandler.listenerMap[jsp.description.name];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										5
									
								
								packages/api/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packages/api/src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
import './typings/global'
 | 
			
		||||
 | 
			
		||||
export * from './command'
 | 
			
		||||
export * from './interfaces'
 | 
			
		||||
export * from './console'
 | 
			
		||||
							
								
								
									
										2
									
								
								packages/api/src/interfaces/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								packages/api/src/interfaces/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
export * from './plugin'
 | 
			
		||||
export * from './server'
 | 
			
		||||
							
								
								
									
										25
									
								
								packages/api/src/interfaces/plugin.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								packages/api/src/interfaces/plugin.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
import { Container } from "inversify";
 | 
			
		||||
 | 
			
		||||
export namespace plugin {
 | 
			
		||||
    /**
 | 
			
		||||
     * MiaoScript Plugin
 | 
			
		||||
     */
 | 
			
		||||
    export const Plugin = Symbol("Plugin");
 | 
			
		||||
    /**
 | 
			
		||||
     * Runtime Plugin Instance
 | 
			
		||||
     */
 | 
			
		||||
    export const PluginInstance = Symbol("PluginInstance");
 | 
			
		||||
    /**
 | 
			
		||||
     * MiaoScript Plugin Manager
 | 
			
		||||
     */
 | 
			
		||||
    export const PluginManager = Symbol("PluginManager");
 | 
			
		||||
    /**
 | 
			
		||||
     * MiaoScript Plugin Manager
 | 
			
		||||
     */
 | 
			
		||||
    export interface PluginManager {
 | 
			
		||||
        scan(folder: string): void;
 | 
			
		||||
        load(container: Container): void;
 | 
			
		||||
        enable(): void;
 | 
			
		||||
        disable(): void;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								packages/api/src/interfaces/server.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/api/src/interfaces/server.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
export namespace server {
 | 
			
		||||
    export const ServerType = Symbol("ServerType");
 | 
			
		||||
    export const Console = Symbol("Console");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								packages/api/src/typings/global.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								packages/api/src/typings/global.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
declare global {
 | 
			
		||||
    namespace NodeJS {
 | 
			
		||||
        interface Global {
 | 
			
		||||
            logger: any;
 | 
			
		||||
            debug: boolean;
 | 
			
		||||
            noop: Function;
 | 
			
		||||
            console: Console;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    var root: string;
 | 
			
		||||
    var base: Core;
 | 
			
		||||
    var ScriptEngineContextHolder: any;
 | 
			
		||||
    function engineLoad(str: string): any;
 | 
			
		||||
    interface Core {
 | 
			
		||||
        getClass(name: String);
 | 
			
		||||
    }
 | 
			
		||||
    interface Console {
 | 
			
		||||
        ex(err: Error): void;
 | 
			
		||||
        stack(err: Error): string[];
 | 
			
		||||
        sender(...args: any): void;
 | 
			
		||||
        console(...args: any): void;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
export { }
 | 
			
		||||
							
								
								
									
										13
									
								
								packages/api/src/typings/plugin.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								packages/api/src/typings/plugin.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
export interface CommandInfo {
 | 
			
		||||
    aliases: string[];
 | 
			
		||||
    description: string;
 | 
			
		||||
}
 | 
			
		||||
export interface PluginInfo {
 | 
			
		||||
    description: PluginDescription;
 | 
			
		||||
}
 | 
			
		||||
export interface PluginDescription {
 | 
			
		||||
    name: string;
 | 
			
		||||
    version: string;
 | 
			
		||||
    author: string;
 | 
			
		||||
    commands: { [key: string]: CommandInfo };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								packages/api/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/api/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "extends": "../../tsconfig.json",
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "baseUrl": "src",
 | 
			
		||||
        "outDir": "dist"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								packages/bukkit/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/bukkit/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
/node_modules
 | 
			
		||||
/dist
 | 
			
		||||
/package-lock.json
 | 
			
		||||
/yarn.lock
 | 
			
		||||
							
								
								
									
										22
									
								
								packages/bukkit/.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/bukkit/.npmignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
src
 | 
			
		||||
test
 | 
			
		||||
typings
 | 
			
		||||
bundled
 | 
			
		||||
build
 | 
			
		||||
coverage
 | 
			
		||||
docs
 | 
			
		||||
wiki
 | 
			
		||||
gulpfile.js
 | 
			
		||||
bower.json
 | 
			
		||||
karma.conf.js
 | 
			
		||||
tsconfig.json
 | 
			
		||||
typings.json
 | 
			
		||||
CONTRIBUTING.md
 | 
			
		||||
ISSUE_TEMPLATE.md
 | 
			
		||||
PULL_REQUEST_TEMPLATE.md
 | 
			
		||||
tslint.json
 | 
			
		||||
wallaby.js
 | 
			
		||||
.travis.yml
 | 
			
		||||
.gitignore
 | 
			
		||||
.vscode
 | 
			
		||||
type_definitions
 | 
			
		||||
							
								
								
									
										33
									
								
								packages/bukkit/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								packages/bukkit/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@ms/bukkit",
 | 
			
		||||
    "version": "0.0.0",
 | 
			
		||||
    "description": "MiaoScript api package",
 | 
			
		||||
    "keywords": [
 | 
			
		||||
        "miaoscript",
 | 
			
		||||
        "minecraft",
 | 
			
		||||
        "bukkit",
 | 
			
		||||
        "sponge"
 | 
			
		||||
    ],
 | 
			
		||||
    "author": "MiaoWoo <admin@yumc.pw>",
 | 
			
		||||
    "homepage": "https://github.com/circlecloud/ms.git",
 | 
			
		||||
    "license": "ISC",
 | 
			
		||||
    "main": "dist/index.js",
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "registry": "https://repo.yumc.pw/repository/npm/"
 | 
			
		||||
    },
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "clean": "rimraf dist",
 | 
			
		||||
        "watch": "npx tsc --watch",
 | 
			
		||||
        "build": "yarn clean && npx tsc",
 | 
			
		||||
        "test": "echo \"Error: run tests from root\" && exit 1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "reflect-metadata": "^0.1.13",
 | 
			
		||||
        "rimraf": "^3.0.0",
 | 
			
		||||
        "typescript": "^3.6.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@ms/api": "^0.0.0",
 | 
			
		||||
        "inversify": "^5.0.1"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										98
									
								
								packages/bukkit/src/command.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								packages/bukkit/src/command.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
import '@ms/nashorn'
 | 
			
		||||
 | 
			
		||||
import { injectable, postConstruct, inject } from 'inversify'
 | 
			
		||||
import { command } from '@ms/api'
 | 
			
		||||
import * as ref from '@ms/common/dist/reflect'
 | 
			
		||||
 | 
			
		||||
var bukkit = require('./server');
 | 
			
		||||
var plugin = bukkit.plugin.self;
 | 
			
		||||
var commandMap = ref.on(bukkit.plugin.manager).get('commandMap').get();
 | 
			
		||||
var PluginCommand = Java.type('org.bukkit.command.PluginCommand');
 | 
			
		||||
 | 
			
		||||
var Arrays = Java.type('java.util.Arrays');
 | 
			
		||||
var TabCompleter = Java.type("org.bukkit.command.TabCompleter");
 | 
			
		||||
var CommandExecutor = Java.type("org.bukkit.command.CommandExecutor");
 | 
			
		||||
 | 
			
		||||
@injectable()
 | 
			
		||||
export class BukkitCommand extends command.Command {
 | 
			
		||||
    @inject("Plugin.Self")
 | 
			
		||||
    private plugin: any
 | 
			
		||||
 | 
			
		||||
    @postConstruct()
 | 
			
		||||
    init() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable(jsp) {
 | 
			
		||||
        var commands = jsp.description.commands;
 | 
			
		||||
        if (commands) {
 | 
			
		||||
            var pluginCommands = [];
 | 
			
		||||
            for (var name in commands) {
 | 
			
		||||
                // noinspection JSUnfilteredForInLoop
 | 
			
		||||
                var command = commands[name];
 | 
			
		||||
                if (typeof command !== 'object') continue;
 | 
			
		||||
                command.name = name;
 | 
			
		||||
                // noinspection JSUnfilteredForInLoop
 | 
			
		||||
                var newCmd = this.create(jsp, command);
 | 
			
		||||
                if (command.description) newCmd.setDescription(command.description);
 | 
			
		||||
                if (command.usage) newCmd.setUsage(command.usage);
 | 
			
		||||
                /** @namespace command.aliases */
 | 
			
		||||
                if (command.aliases) newCmd.setAliases(Arrays.asList(command.aliases));
 | 
			
		||||
                if (command.permission) newCmd.setPermission(command.permission);
 | 
			
		||||
                if (command['permission-message']) newCmd.setPermissionMessage(command['permission-message']);
 | 
			
		||||
                pluginCommands.push(newCmd);
 | 
			
		||||
                // noinspection JSUnfilteredForInLoop
 | 
			
		||||
                console.debug(`插件 ${jsp.description.name} 注册命令 ${name} ...`);
 | 
			
		||||
            }
 | 
			
		||||
            commandMap.registerAll(jsp.description.name, Arrays.asList(pluginCommands));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    disable(jsp) {
 | 
			
		||||
        var commands = jsp.description.commands;
 | 
			
		||||
        if (commands) {
 | 
			
		||||
            for (var name in commands) {
 | 
			
		||||
                //TODO 删除插件命令
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    create(jsp, command) {
 | 
			
		||||
        var cmd = commandMap.getCommand(command.name)
 | 
			
		||||
        if (cmd && cmd instanceof PluginCommand) { return cmd };
 | 
			
		||||
        cmd = ref.on(PluginCommand).create(command.name, plugin).get();
 | 
			
		||||
        commandMap.register(jsp.description.name, cmd);
 | 
			
		||||
        return cmd;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onCommand(jsp, c, cmd) {
 | 
			
		||||
        // 必须指定需要实现的接口类型 否则MOD服会报错
 | 
			
		||||
        c.setExecutor(new CommandExecutor({
 | 
			
		||||
            onCommand: function(sender, _, command, args) {
 | 
			
		||||
                try {
 | 
			
		||||
                    return cmd(sender, command, Java.from(args));
 | 
			
		||||
                } catch (ex) {
 | 
			
		||||
                    console.console(`§6玩家 §a${sender.name} §6执行 §b${jsp.description.name} §6插件 §d${command} ${Java.from(args).join(' ')} §6命令时发生异常 §4${ex}`);
 | 
			
		||||
                    console.ex(ex);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onTabComplete(jsp, c, tab) {
 | 
			
		||||
        // 必须指定需要实现的接口类型 否则MOD服会报错
 | 
			
		||||
        // noinspection JSUnusedGlobalSymbols
 | 
			
		||||
        c.setTabCompleter(new TabCompleter({
 | 
			
		||||
            onTabComplete: function(sender, _, command, args) {
 | 
			
		||||
                try {
 | 
			
		||||
                    var token = args[args.length - 1];
 | 
			
		||||
                    var complete = tab(sender, command, Java.from(args)) || [];
 | 
			
		||||
                    return Arrays.asList(complete.copyPartialMatches(token, []));
 | 
			
		||||
                } catch (ex) {
 | 
			
		||||
                    console.console(`§6玩家 §a${sender.name} §6执行 §b${jsp.description.name} §6插件 §d${command} ${Java.from(args).join(' ')} §6补全时发生异常 §4${ex}`);
 | 
			
		||||
                    console.ex(ex);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								packages/bukkit/src/console.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								packages/bukkit/src/console.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
import { MiaoScriptConsole } from '@ms/api'
 | 
			
		||||
 | 
			
		||||
let Bukkit = Java.type("org.bukkit.Bukkit");
 | 
			
		||||
let CommandSender = Java.type("org.bukkit.command.CommandSender");
 | 
			
		||||
 | 
			
		||||
export class BukkitConsole extends MiaoScriptConsole {
 | 
			
		||||
    sender(sender, ...args) {
 | 
			
		||||
        if (!(sender instanceof CommandSender)) {
 | 
			
		||||
            this.error("第一个参数未实现 org.bukkit.command.CommandSender 无法发送消息!")
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (args[0].toString() === "[object Array]") {
 | 
			
		||||
            args[0].forEach(line => sender.sendMessage(this.prefix + line))
 | 
			
		||||
        } else {
 | 
			
		||||
            sender.sendMessage(this.prefix + args.join(' '));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    console(...args): void {
 | 
			
		||||
        this.sender(Bukkit.consoleSender, args.join(' '));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								packages/bukkit/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								packages/bukkit/src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
import { server, plugin } from '@ms/api'
 | 
			
		||||
import { DefaultContainer as container } from '@ms/container'
 | 
			
		||||
 | 
			
		||||
import { BukkitConsole } from './console'
 | 
			
		||||
 | 
			
		||||
let BukkitServerType = 'bukkit';
 | 
			
		||||
let Bukkit = Java.type("org.bukkit.Bukkit");
 | 
			
		||||
 | 
			
		||||
container.bind(server.Console).toConstantValue(BukkitConsole);
 | 
			
		||||
container.bind(server.ServerType).toConstantValue(BukkitServerType);
 | 
			
		||||
container.bind(plugin.PluginInstance).toConstantValue(Bukkit.pluginManager.getPlugin('MiaoScript'));
 | 
			
		||||
							
								
								
									
										7
									
								
								packages/bukkit/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/bukkit/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "extends": "../../tsconfig.json",
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "baseUrl": "src",
 | 
			
		||||
        "outDir": "dist"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								packages/common/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/common/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
/node_modules
 | 
			
		||||
/dist
 | 
			
		||||
/package-lock.json
 | 
			
		||||
/yarn.lock
 | 
			
		||||
							
								
								
									
										22
									
								
								packages/common/.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/common/.npmignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
src
 | 
			
		||||
test
 | 
			
		||||
typings
 | 
			
		||||
bundled
 | 
			
		||||
build
 | 
			
		||||
coverage
 | 
			
		||||
docs
 | 
			
		||||
wiki
 | 
			
		||||
gulpfile.js
 | 
			
		||||
bower.json
 | 
			
		||||
karma.conf.js
 | 
			
		||||
tsconfig.json
 | 
			
		||||
typings.json
 | 
			
		||||
CONTRIBUTING.md
 | 
			
		||||
ISSUE_TEMPLATE.md
 | 
			
		||||
PULL_REQUEST_TEMPLATE.md
 | 
			
		||||
tslint.json
 | 
			
		||||
wallaby.js
 | 
			
		||||
.travis.yml
 | 
			
		||||
.gitignore
 | 
			
		||||
.vscode
 | 
			
		||||
type_definitions
 | 
			
		||||
							
								
								
									
										32
									
								
								packages/common/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								packages/common/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@ms/common",
 | 
			
		||||
    "version": "0.0.0",
 | 
			
		||||
    "description": "MiaoScript api package",
 | 
			
		||||
    "keywords": [
 | 
			
		||||
        "miaoscript",
 | 
			
		||||
        "minecraft",
 | 
			
		||||
        "bukkit",
 | 
			
		||||
        "sponge"
 | 
			
		||||
    ],
 | 
			
		||||
    "author": "MiaoWoo <admin@yumc.pw>",
 | 
			
		||||
    "homepage": "https://github.com/circlecloud/ms.git",
 | 
			
		||||
    "license": "ISC",
 | 
			
		||||
    "main": "dist/index.js",
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "registry": "https://repo.yumc.pw/repository/npm/"
 | 
			
		||||
    },
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "clean": "rimraf dist",
 | 
			
		||||
        "watch": "npx tsc --watch",
 | 
			
		||||
        "build": "yarn clean && npx tsc",
 | 
			
		||||
        "test": "echo \"Error: run tests from root\" && exit 1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "reflect-metadata": "^0.1.13",
 | 
			
		||||
        "rimraf": "^3.0.0",
 | 
			
		||||
        "typescript": "^3.6.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@ms/nashorn": "^0.0.0"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										155
									
								
								packages/common/src/fs.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								packages/common/src/fs.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,155 @@
 | 
			
		||||
import '@ms/nashorn'
 | 
			
		||||
 | 
			
		||||
/*global Java, base, module, exports, require, __FILE__*/
 | 
			
		||||
const Path = Java.type("java.nio.file.Path");
 | 
			
		||||
const JavaString = Java.type("java.lang.String");
 | 
			
		||||
const File = Java.type("java.io.File");
 | 
			
		||||
const Files = Java.type("java.nio.file.Files");
 | 
			
		||||
const Collector = Java.type("java.util.stream.Collector")
 | 
			
		||||
const separatorChar = File.separatorChar;
 | 
			
		||||
const StandardCopyOption = Java.type("java.nio.file.StandardCopyOption");
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 用文件分割符合并路径
 | 
			
		||||
 */
 | 
			
		||||
export function concat() {
 | 
			
		||||
    return Array.prototype.join.call(arguments, separatorChar);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 获得文件
 | 
			
		||||
 * @constructor(file)
 | 
			
		||||
 * @constructor(dir,file)
 | 
			
		||||
 * @returns {*}
 | 
			
		||||
 */
 | 
			
		||||
export function file(...opts: any[]): any {
 | 
			
		||||
    if (!arguments[0]) {
 | 
			
		||||
        console.warn("文件名称不得为 undefined 或者 null !");
 | 
			
		||||
    }
 | 
			
		||||
    switch (arguments.length) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            var f = arguments[0];
 | 
			
		||||
            if (f instanceof File) {
 | 
			
		||||
                return f;
 | 
			
		||||
            }
 | 
			
		||||
            if (typeof f === "string") {
 | 
			
		||||
                return new File(f);
 | 
			
		||||
            }
 | 
			
		||||
            if (f instanceof Path) {
 | 
			
		||||
                return f.toFile();
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            return new File(file(arguments[0]), arguments[1]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 创建目录
 | 
			
		||||
 * @param path
 | 
			
		||||
 */
 | 
			
		||||
export function mkdirs(path) {
 | 
			
		||||
    // noinspection JSUnresolvedVariable
 | 
			
		||||
    file(path).parentFile.mkdirs();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 创建文件
 | 
			
		||||
 * @param file
 | 
			
		||||
 */
 | 
			
		||||
export function create(path) {
 | 
			
		||||
    var f = file(path);
 | 
			
		||||
    if (!f.exists()) {
 | 
			
		||||
        mkdirs(f);
 | 
			
		||||
        f.createNewFile();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 获得文件规范路径
 | 
			
		||||
 * @param file
 | 
			
		||||
 * @returns {*}
 | 
			
		||||
 */
 | 
			
		||||
export function path(f) {
 | 
			
		||||
    return file(f).canonicalPath;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 复制文件
 | 
			
		||||
 * @param inputStream 输入流
 | 
			
		||||
 * @param target 目标文件
 | 
			
		||||
 * @param override 是否覆盖
 | 
			
		||||
 */
 | 
			
		||||
export function copy(inputStream, target, override) {
 | 
			
		||||
    Files.copy(inputStream, target.toPath(), StandardCopyOption[override ? 'REPLACE_EXISTING' : 'ATOMIC_MOVE']);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 读取文件
 | 
			
		||||
 * @param path 文件路径
 | 
			
		||||
 */
 | 
			
		||||
export function read(path) {
 | 
			
		||||
    var file = file(path);
 | 
			
		||||
    if (!file.exists()) {
 | 
			
		||||
        console.warn('读取文件', file, '错误 文件不存在!');
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    // noinspection JSPrimitiveTypeWrapperUsage
 | 
			
		||||
    return new JavaString(Files.readAllBytes(file.toPath()), "UTF-8");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 保存内容文件
 | 
			
		||||
 * @param path 路径
 | 
			
		||||
 * @param content 内容
 | 
			
		||||
 * @param override 是否覆盖
 | 
			
		||||
 */
 | 
			
		||||
export function save(path, content, override) {
 | 
			
		||||
    var file = file(path);
 | 
			
		||||
    if (file.parentFile) {
 | 
			
		||||
        file.parentFile.mkdirs();
 | 
			
		||||
    }
 | 
			
		||||
    Files.write(file.toPath(), new JavaString(content).getBytes("UTF-8"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 列出目录文件
 | 
			
		||||
 * @param path
 | 
			
		||||
 */
 | 
			
		||||
export function list(path) {
 | 
			
		||||
    var dir = file(path);
 | 
			
		||||
    // noinspection JSValidateTypes
 | 
			
		||||
    if (dir.isDirectory()) {
 | 
			
		||||
        return Files.list(dir.toPath());
 | 
			
		||||
    }
 | 
			
		||||
    console.debug('路径', path, '不是一个目录 返回空数组!');
 | 
			
		||||
    return [];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 移动文件
 | 
			
		||||
 * @param src 原始目录
 | 
			
		||||
 * @param des 目标目录
 | 
			
		||||
 * @param override 是否覆盖
 | 
			
		||||
 */
 | 
			
		||||
export function move(src, des, override) {
 | 
			
		||||
    Files.move(file(src).toPath(), file(des).toPath(),
 | 
			
		||||
        override ? StandardCopyOption['REPLACE_EXISTING'] : StandardCopyOption['ATOMIC_MOVE'])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function del(file) {
 | 
			
		||||
    file = file(file);
 | 
			
		||||
    if (!file.exists()) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (file.isDirectory()) {
 | 
			
		||||
        Files.list(file.toPath()).collect(Collector.toList()).forEach(function(f) {
 | 
			
		||||
            del(f);
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
    Files.delete(file.toPath());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function exists(f) {
 | 
			
		||||
    return file(f).exists()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										155
									
								
								packages/common/src/http.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								packages/common/src/http.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,155 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
/**
 | 
			
		||||
 * HTTP 网络类
 | 
			
		||||
 * Created by 蒋天蓓 on 2017/2/9 0009.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*global Java, base, module, exports, require, __FILE__*/
 | 
			
		||||
 | 
			
		||||
var URL = Java.type("java.net.URL");
 | 
			
		||||
var UUID = Java.type("java.util.UUID");
 | 
			
		||||
var System = Java.type("java.lang.System");
 | 
			
		||||
var Files = Java.type("java.nio.file.Files");
 | 
			
		||||
var Paths = Java.type("java.nio.file.Paths");
 | 
			
		||||
var JavaString = Java.type("java.lang.String");
 | 
			
		||||
var SecureRandom = Java.type("java.security.SecureRandom");
 | 
			
		||||
 | 
			
		||||
var SSLContext = Java.type("javax.net.ssl.SSLContext");
 | 
			
		||||
var HttpsURLConnection = Java.type("javax.net.ssl.HttpsURLConnection");
 | 
			
		||||
 | 
			
		||||
var HostnameVerifier = Java.type("javax.net.ssl.HostnameVerifier");
 | 
			
		||||
var X509TrustManager = Java.type("javax.net.ssl.X509TrustManager");
 | 
			
		||||
 | 
			
		||||
// noinspection JSUnusedGlobalSymbols,JSUnusedLocalSymbols
 | 
			
		||||
var TrustAnyHostnameVerifier = new HostnameVerifier({
 | 
			
		||||
    verify: function(hostname, session) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var SSLSocketFactory = function initSSLSocketFactory() {
 | 
			
		||||
    var sslContext = SSLContext.getInstance("TLS");
 | 
			
		||||
    // noinspection JSUnusedGlobalSymbols
 | 
			
		||||
    sslContext.init(null, [new X509TrustManager({
 | 
			
		||||
        getAcceptedIssuers: function() {
 | 
			
		||||
            return null;
 | 
			
		||||
        },
 | 
			
		||||
        checkClientTrusted: function(chain, authType) {
 | 
			
		||||
        },
 | 
			
		||||
        checkServerTrusted: function(chain, authType) {
 | 
			
		||||
        }
 | 
			
		||||
    })], new SecureRandom());
 | 
			
		||||
    return sslContext.getSocketFactory();
 | 
			
		||||
}();
 | 
			
		||||
 | 
			
		||||
var config = {
 | 
			
		||||
    Charset: 'UTF-8',
 | 
			
		||||
    ConnectTimeout: 10000,
 | 
			
		||||
    ReadTimeout: 10000,
 | 
			
		||||
    Debug: false
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function open(url, method, header) {
 | 
			
		||||
    // conn.setRequestProperty
 | 
			
		||||
    var conn = new URL(url).openConnection();
 | 
			
		||||
    if (conn instanceof HttpsURLConnection) {
 | 
			
		||||
        conn.setHostnameVerifier(TrustAnyHostnameVerifier);
 | 
			
		||||
        conn.setSSLSocketFactory(SSLSocketFactory);
 | 
			
		||||
    }
 | 
			
		||||
    conn.setRequestMethod(method);
 | 
			
		||||
    conn.setDoOutput(true);
 | 
			
		||||
    conn.setDoInput(true);
 | 
			
		||||
    conn.setConnectTimeout(config.ConnectTimeout);
 | 
			
		||||
    conn.setReadTimeout(config.ReadTimeout);
 | 
			
		||||
    if (header) {
 | 
			
		||||
        for (var key in header) {
 | 
			
		||||
            // noinspection JSUnfilteredForInLoop
 | 
			
		||||
            conn.setRequestProperty(key, header[key]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return conn;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function buildUrl(url, params) {
 | 
			
		||||
    if (params && Object.keys(params).length > 0) {
 | 
			
		||||
        var queryStart = url.indexOf('?');
 | 
			
		||||
        if (queryStart === -1) {
 | 
			
		||||
            url += '?';
 | 
			
		||||
        }
 | 
			
		||||
        return url += object2URLSearchParams(params);
 | 
			
		||||
    }
 | 
			
		||||
    return url;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function request(config) {
 | 
			
		||||
    var conn = open(buildUrl(config.url, config.query), config.method, config.header);
 | 
			
		||||
    try {
 | 
			
		||||
        conn.connect();
 | 
			
		||||
        var data = config.data;
 | 
			
		||||
        if (data) {
 | 
			
		||||
            var out = conn.getOutputStream();
 | 
			
		||||
            if (typeof data === "object") {
 | 
			
		||||
                var type = config.header['Content-Type'];
 | 
			
		||||
                switch (type) {
 | 
			
		||||
                    case "application/x-www-form-urlencoded":
 | 
			
		||||
                        data = object2URLSearchParams(data);
 | 
			
		||||
                        break;
 | 
			
		||||
                    default:
 | 
			
		||||
                        data = JSON.stringify(data)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            out.write(new JavaString(data).getBytes(config.Charset));
 | 
			
		||||
            out.flush();
 | 
			
		||||
            out.close();
 | 
			
		||||
        }
 | 
			
		||||
        return response(conn);
 | 
			
		||||
    } finally {
 | 
			
		||||
        conn.disconnect();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function response(conn) {
 | 
			
		||||
    var temp = Paths.get(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString());
 | 
			
		||||
    Files.copy(conn.getInputStream(), temp);
 | 
			
		||||
    var result = new JavaString(Files.readAllBytes(temp), config.Charset);
 | 
			
		||||
    var tempFile = temp.toFile();
 | 
			
		||||
    tempFile.delete() || tempFile.deleteOnExit();
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function object2URLSearchParams(params) {
 | 
			
		||||
    var temp: string[] = [];
 | 
			
		||||
    for (var key in params) {
 | 
			
		||||
        temp.push(`${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
 | 
			
		||||
    }
 | 
			
		||||
    return temp.join('&')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var http = {
 | 
			
		||||
    config: config,
 | 
			
		||||
    request: request
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
['GET', 'DELETE', 'HEAD', 'OPTIONS'].forEach(function(method) {
 | 
			
		||||
    http[method.toLowerCase()] = function __likeGet__(url, data, config = {}) {
 | 
			
		||||
        return this.request({
 | 
			
		||||
            ...config,
 | 
			
		||||
            url: url,
 | 
			
		||||
            method: method,
 | 
			
		||||
            query: data
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
['POST', 'PUT', 'PATCH'].forEach(function(method) {
 | 
			
		||||
    http[method.toLowerCase()] = function __likePost__(url, data, config) {
 | 
			
		||||
        return this.request({
 | 
			
		||||
            ...config,
 | 
			
		||||
            url: url,
 | 
			
		||||
            method: method,
 | 
			
		||||
            data: data
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export = http;
 | 
			
		||||
							
								
								
									
										191
									
								
								packages/common/src/reflect.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								packages/common/src/reflect.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,191 @@
 | 
			
		||||
import '@ms/core'
 | 
			
		||||
/**
 | 
			
		||||
 * 反射工具类
 | 
			
		||||
 * Created by 蒋天蓓 on 2017/2/9 0009.
 | 
			
		||||
 */
 | 
			
		||||
var JavaClass = Java.type('java.lang.Class');
 | 
			
		||||
var JavaObject = Java.type('java.lang.Object')
 | 
			
		||||
var NoSuchFieldException = Java.type('java.lang.NoSuchFieldException');
 | 
			
		||||
var methodCache = [];
 | 
			
		||||
 | 
			
		||||
class Reflect {
 | 
			
		||||
    private obj: any;
 | 
			
		||||
    private class: any
 | 
			
		||||
 | 
			
		||||
    constructor(obj: any) {
 | 
			
		||||
        if (obj instanceof JavaClass) {
 | 
			
		||||
            this.obj = null;
 | 
			
		||||
            this.class = obj;
 | 
			
		||||
        } else {
 | 
			
		||||
            this.obj = obj;
 | 
			
		||||
            this.class = obj.class;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    method(...args: any[]) {
 | 
			
		||||
        return declaredMethod(this.class, args[0], types(args.slice(1)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    methods() {
 | 
			
		||||
        return Java.from(declaredMethods(this.class));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    field(name) {
 | 
			
		||||
        try {
 | 
			
		||||
            // Try getting a public field
 | 
			
		||||
            var field = this.class.field(name);
 | 
			
		||||
            return on(field.get(this.obj));
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
            // Try again, getting a non-public field
 | 
			
		||||
            return on(accessible(declaredField(this.class, name)).get(this.obj));
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    fields(declared) {
 | 
			
		||||
        return Java.from(declared ? this.class.declaredFields : this.class.fields);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    values(declared) {
 | 
			
		||||
        var cache = {};
 | 
			
		||||
        var feds = declared ? this.class.declaredFields : this.class.fields;
 | 
			
		||||
        Java.from(feds).forEach(function(fed) {
 | 
			
		||||
            cache[fed.name] = this.field(fed.name).get();
 | 
			
		||||
        }.bind(this))
 | 
			
		||||
        return cache;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    call(...args) {
 | 
			
		||||
        var params = args.slice(1);
 | 
			
		||||
        var method = declaredMethod(this.class, args[0], types(params));
 | 
			
		||||
        return on(method.invoke(this.get(), params));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    get(...args) {
 | 
			
		||||
        return args.length === 1 ? this.field(args[0]) : this.obj;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // noinspection JSUnusedGlobalSymbols
 | 
			
		||||
    set(name, value) {
 | 
			
		||||
        accessible(declaredField(this.class, name)).set(this.obj, value);
 | 
			
		||||
        return this;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    create(...args) {
 | 
			
		||||
        return on(declaredConstructor(this.class, args).newInstance(args));
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get an array of types for an array of objects
 | 
			
		||||
 */
 | 
			
		||||
function types(values, def?) {
 | 
			
		||||
    if (values === null) {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
    var result = [];
 | 
			
		||||
    values.forEach(t => result.push((t || def) ? JavaObject.class : t instanceof JavaClass ? t : t.class));
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function accessible(accessible) {
 | 
			
		||||
    if (accessible === null) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
    if (!accessible.isAccessible()) {
 | 
			
		||||
        accessible.setAccessible(true);
 | 
			
		||||
    }
 | 
			
		||||
    return accessible;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function declaredConstructor(clazz, param) {
 | 
			
		||||
    var constructor;
 | 
			
		||||
    try {
 | 
			
		||||
        constructor = clazz.getDeclaredConstructor(types(param));
 | 
			
		||||
    } catch (ex) {
 | 
			
		||||
        try {
 | 
			
		||||
            constructor = clazz.getDeclaredConstructor(types(param, true));
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
            constructor = clazz.getDeclaredConstructors()[0];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return accessible(constructor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function declaredField(clazz, name) {
 | 
			
		||||
    var field = null;
 | 
			
		||||
    // noinspection JSUnresolvedVariable
 | 
			
		||||
    while (clazz !== JavaObject.class) {
 | 
			
		||||
        try {
 | 
			
		||||
            field = clazz.getDeclaredField(name);
 | 
			
		||||
            if (field !== null) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            clazz = clazz.getSuperclass();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (field === null) {
 | 
			
		||||
        throw new NoSuchFieldException(name + " is not found in " + clazz.name);
 | 
			
		||||
    }
 | 
			
		||||
    return field;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function declaredMethod(clazz, name, clazzs) {
 | 
			
		||||
    var key = clazz.name + '.' + name + ':' + (clazzs || []).join(':');
 | 
			
		||||
    if (!methodCache[key]) {
 | 
			
		||||
        try {
 | 
			
		||||
            methodCache[key] = clazz.getMethod(name, clazzs);
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
            methodCache[key] = clazz.getDeclaredMethod(name, clazzs);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return methodCache[key];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function declaredMethods(clazz) {
 | 
			
		||||
    return clazz.declaredMethods;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var classMethodsCache = [];
 | 
			
		||||
 | 
			
		||||
function mapToObject(javaObj) {
 | 
			
		||||
    if (!javaObj || !javaObj.class) { throw new TypeError(`参数 ${javaObj} 不是一个Java对象!`) }
 | 
			
		||||
    var target = {};
 | 
			
		||||
    getJavaObjectMethods(javaObj).forEach(t => mapMethod(target, javaObj, t));
 | 
			
		||||
    return target;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getJavaObjectMethods(javaObj) {
 | 
			
		||||
    var className = javaObj.class.name;
 | 
			
		||||
    if (!classMethodsCache[className]) {
 | 
			
		||||
        var names = [];
 | 
			
		||||
        var methods = javaObj.class.methods;
 | 
			
		||||
        for (var i in methods) {
 | 
			
		||||
            names.push(methods[i].name);
 | 
			
		||||
        }
 | 
			
		||||
        classMethodsCache[className] = names;
 | 
			
		||||
    }
 | 
			
		||||
    return classMethodsCache[className];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function mapMethod(target, source, name) {
 | 
			
		||||
    target[name] = function __SimpleDynamicMethod__(...args) {
 | 
			
		||||
        if (args.length > 0) {
 | 
			
		||||
            return source[name](args);
 | 
			
		||||
        } else {
 | 
			
		||||
            return source[name]();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function on(obj) {
 | 
			
		||||
    if (!obj || !obj.class) { throw new TypeError(`参数 ${obj} 不是一个Java对象!`) }
 | 
			
		||||
    return new Reflect(obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export = {
 | 
			
		||||
    on,
 | 
			
		||||
    accessible,
 | 
			
		||||
    declaredMethods,
 | 
			
		||||
    mapToObject
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										29
									
								
								packages/common/src/template.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								packages/common/src/template.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
function Template(tpl: string) {
 | 
			
		||||
    var match: RegExpExecArray;
 | 
			
		||||
    var code = ['var r=[];'];
 | 
			
		||||
    var re = /\{\{\s*([a-zA-Z\.\_0-9()]+)\s*\}\}/m;
 | 
			
		||||
    function addLine(text: string) {
 | 
			
		||||
        code.push('r.push(\'' + text.replace(/\'/g, '\\\'').replace(/\n/g, '\\n').replace(/\r/g, '\\r') + '\');');
 | 
			
		||||
    };
 | 
			
		||||
    while (match = re.exec(tpl)) {
 | 
			
		||||
        if (match.index > 0) {
 | 
			
		||||
            addLine(tpl.slice(0, match.index));
 | 
			
		||||
        }
 | 
			
		||||
        code.push('r.push(this.' + match[1] + ');');
 | 
			
		||||
        tpl = tpl.substring(match.index + match[0].length);
 | 
			
		||||
    }
 | 
			
		||||
    addLine(tpl);
 | 
			
		||||
    code.push('return r.join(\'\');');
 | 
			
		||||
    // 创建函数:
 | 
			
		||||
    var fn = new Function(code.join('\n'));
 | 
			
		||||
    // 用render()调用函数并绑定this参数:
 | 
			
		||||
    this.render = function(model) {
 | 
			
		||||
        return fn.apply(model);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export = {
 | 
			
		||||
    create: function(tpl: string) {
 | 
			
		||||
        return new Template(tpl);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								packages/common/src/tgz.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								packages/common/src/tgz.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
import '@ms/nashorn'
 | 
			
		||||
 | 
			
		||||
let Files = Java.type("java.nio.file.Files");
 | 
			
		||||
let Paths = Java.type("java.nio.file.Paths");
 | 
			
		||||
let StandardCopyOption = Java.type("java.nio.file.StandardCopyOption");
 | 
			
		||||
 | 
			
		||||
let TarInputStream = Java.type("org.kamranzafar.jtar.TarInputStream");
 | 
			
		||||
let GZIPInputStream = Java.type("java.util.zip.GZIPInputStream");
 | 
			
		||||
let BufferedInputStream = Java.type("java.io.BufferedInputStream");
 | 
			
		||||
 | 
			
		||||
function decompression(input: any, target: string) {
 | 
			
		||||
    let tis = new TarInputStream(new BufferedInputStream(new GZIPInputStream(input)));
 | 
			
		||||
    let entry: any;
 | 
			
		||||
    while ((entry = tis.getNextEntry()) != null) {
 | 
			
		||||
        let targetPath = Paths.get(target + "/" + entry.getName().substring("package/".length));
 | 
			
		||||
        targetPath.toFile().getParentFile().mkdirs();
 | 
			
		||||
        Files.copy(tis, targetPath, StandardCopyOption.REPLACE_EXISTING);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export = {
 | 
			
		||||
    decompression
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								packages/common/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								packages/common/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
{
 | 
			
		||||
    "extends": "../../tsconfig.json",
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "baseUrl": "src",
 | 
			
		||||
        "outDir": "dist",
 | 
			
		||||
        "declaration": true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								packages/container/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/container/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
/node_modules
 | 
			
		||||
/dist
 | 
			
		||||
/package-lock.json
 | 
			
		||||
/yarn.lock
 | 
			
		||||
							
								
								
									
										22
									
								
								packages/container/.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/container/.npmignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
src
 | 
			
		||||
test
 | 
			
		||||
typings
 | 
			
		||||
bundled
 | 
			
		||||
build
 | 
			
		||||
coverage
 | 
			
		||||
docs
 | 
			
		||||
wiki
 | 
			
		||||
gulpfile.js
 | 
			
		||||
bower.json
 | 
			
		||||
karma.conf.js
 | 
			
		||||
tsconfig.json
 | 
			
		||||
typings.json
 | 
			
		||||
CONTRIBUTING.md
 | 
			
		||||
ISSUE_TEMPLATE.md
 | 
			
		||||
PULL_REQUEST_TEMPLATE.md
 | 
			
		||||
tslint.json
 | 
			
		||||
wallaby.js
 | 
			
		||||
.travis.yml
 | 
			
		||||
.gitignore
 | 
			
		||||
.vscode
 | 
			
		||||
type_definitions
 | 
			
		||||
							
								
								
									
										32
									
								
								packages/container/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								packages/container/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@ms/container",
 | 
			
		||||
    "version": "0.0.0",
 | 
			
		||||
    "description": "MiaoScript container package",
 | 
			
		||||
    "keywords": [
 | 
			
		||||
        "miaoscript",
 | 
			
		||||
        "minecraft",
 | 
			
		||||
        "bukkit",
 | 
			
		||||
        "sponge"
 | 
			
		||||
    ],
 | 
			
		||||
    "author": "MiaoWoo <admin@yumc.pw>",
 | 
			
		||||
    "homepage": "https://github.com/circlecloud/ms.git",
 | 
			
		||||
    "license": "ISC",
 | 
			
		||||
    "main": "dist/index.js",
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "registry": "https://repo.yumc.pw/repository/npm/"
 | 
			
		||||
    },
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "clean": "rimraf dist",
 | 
			
		||||
        "watch": "npx tsc --watch",
 | 
			
		||||
        "build": "yarn clean && npx tsc",
 | 
			
		||||
        "test": "echo \"Error: run tests from root\" && exit 1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "reflect-metadata": "^0.1.13",
 | 
			
		||||
        "rimraf": "^3.0.0",
 | 
			
		||||
        "typescript": "^3.6.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "inversify-binding-decorators": "^4.0.0"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								packages/container/src/decorators.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								packages/container/src/decorators.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
import { interfaces, Container } from "inversify";
 | 
			
		||||
 | 
			
		||||
let _container: Container;
 | 
			
		||||
 | 
			
		||||
const CONTAINER = Symbol.for("@ms/ioc:Container");
 | 
			
		||||
const INJECTION = Symbol.for("INJECTION");
 | 
			
		||||
 | 
			
		||||
function _proxyGetter(
 | 
			
		||||
    proto: any,
 | 
			
		||||
    key: string,
 | 
			
		||||
    resolve: () => any,
 | 
			
		||||
    doCache: boolean
 | 
			
		||||
) {
 | 
			
		||||
    function getter() {
 | 
			
		||||
        if (doCache && !Reflect.hasMetadata(INJECTION, this, key)) {
 | 
			
		||||
            Reflect.defineMetadata(INJECTION, resolve(), this, key);
 | 
			
		||||
        }
 | 
			
		||||
        if (Reflect.hasMetadata(INJECTION, this, key)) {
 | 
			
		||||
            return Reflect.getMetadata(INJECTION, this, key);
 | 
			
		||||
        } else {
 | 
			
		||||
            return resolve();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setter(newVal: any) {
 | 
			
		||||
        Reflect.defineMetadata(INJECTION, newVal, this, key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Object.defineProperty(proto, key, {
 | 
			
		||||
        configurable: true,
 | 
			
		||||
        enumerable: true,
 | 
			
		||||
        get: getter,
 | 
			
		||||
        set: setter
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function initContainer(container: Container) {
 | 
			
		||||
    Reflect.defineMetadata(CONTAINER, container, Reflect);
 | 
			
		||||
    _container = container;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getContainer(): Container {
 | 
			
		||||
    return _container || Reflect.getMetadata(CONTAINER, Reflect)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function makePropertyInjectDecorator(doCache: boolean) {
 | 
			
		||||
    return function(serviceIdentifier: interfaces.ServiceIdentifier<any>) {
 | 
			
		||||
        return function(proto: any, key: string): void {
 | 
			
		||||
            let resolve = () => {
 | 
			
		||||
                return getContainer().get(serviceIdentifier);
 | 
			
		||||
            };
 | 
			
		||||
            _proxyGetter(proto, key, resolve, doCache);
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function makePropertyInjectNamedDecorator(doCache: boolean) {
 | 
			
		||||
    return function(serviceIdentifier: interfaces.ServiceIdentifier<any>, named: string) {
 | 
			
		||||
        return function(proto: any, key: string): void {
 | 
			
		||||
            let resolve = () => {
 | 
			
		||||
                return getContainer().getNamed(serviceIdentifier, named);
 | 
			
		||||
            };
 | 
			
		||||
            _proxyGetter(proto, key, resolve, doCache);
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function makePropertyInjectTaggedDecorator(doCache: boolean) {
 | 
			
		||||
    return function(serviceIdentifier: interfaces.ServiceIdentifier<any>, key: string, value: any) {
 | 
			
		||||
        return function(proto: any, propertyName: string): void {
 | 
			
		||||
            let resolve = () => {
 | 
			
		||||
                return getContainer().getTagged(serviceIdentifier, key, value);
 | 
			
		||||
            };
 | 
			
		||||
            _proxyGetter(proto, propertyName, resolve, doCache);
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function makePropertyMultiInjectDecorator(doCache: boolean) {
 | 
			
		||||
    return function(serviceIdentifier: interfaces.ServiceIdentifier<any>) {
 | 
			
		||||
        return function(proto: any, key: string): void {
 | 
			
		||||
            let resolve = () => {
 | 
			
		||||
                return getContainer().getAll(serviceIdentifier);
 | 
			
		||||
            };
 | 
			
		||||
            _proxyGetter(proto, key, resolve, doCache);
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let doCache = true;
 | 
			
		||||
 | 
			
		||||
let lazyInject = makePropertyInjectDecorator(doCache)
 | 
			
		||||
let lazyInjectNamed = makePropertyInjectNamedDecorator(doCache)
 | 
			
		||||
let lazyInjectTagged = makePropertyInjectTaggedDecorator(doCache)
 | 
			
		||||
let lazyMultiInject = makePropertyMultiInjectDecorator(doCache)
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
    initContainer,
 | 
			
		||||
    getContainer,
 | 
			
		||||
    lazyInject,
 | 
			
		||||
    lazyInjectNamed,
 | 
			
		||||
    lazyInjectTagged,
 | 
			
		||||
    lazyMultiInject
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										23
									
								
								packages/container/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								packages/container/src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
import "reflect-metadata";
 | 
			
		||||
import { interfaces, Container } from 'inversify';
 | 
			
		||||
import { fluentProvide } from 'inversify-binding-decorators';
 | 
			
		||||
 | 
			
		||||
const provideNamed = (identifier: interfaces.ServiceIdentifier<any>, name: string) => {
 | 
			
		||||
    return fluentProvide(identifier).whenTargetNamed(name).done();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const provideSingleton = (identifier: interfaces.ServiceIdentifier<any>) => {
 | 
			
		||||
    return fluentProvide(identifier).inSingletonScope().done();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const DefaultContainer = new Container();
 | 
			
		||||
 | 
			
		||||
export * from 'inversify'
 | 
			
		||||
export * from './decorators'
 | 
			
		||||
export * from 'inversify-binding-decorators'
 | 
			
		||||
export {
 | 
			
		||||
    fluentProvide,
 | 
			
		||||
    provideNamed,
 | 
			
		||||
    provideSingleton,
 | 
			
		||||
    DefaultContainer
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										7
									
								
								packages/container/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/container/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "extends": "../../tsconfig.json",
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "baseUrl": "src",
 | 
			
		||||
        "outDir": "dist"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								packages/core/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/core/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
/node_modules
 | 
			
		||||
/dist
 | 
			
		||||
/package-lock.json
 | 
			
		||||
/yarn.lock
 | 
			
		||||
							
								
								
									
										22
									
								
								packages/core/.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/core/.npmignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
src
 | 
			
		||||
test
 | 
			
		||||
typings
 | 
			
		||||
bundled
 | 
			
		||||
build
 | 
			
		||||
coverage
 | 
			
		||||
docs
 | 
			
		||||
wiki
 | 
			
		||||
gulpfile.js
 | 
			
		||||
bower.json
 | 
			
		||||
karma.conf.js
 | 
			
		||||
tsconfig.json
 | 
			
		||||
typings.json
 | 
			
		||||
CONTRIBUTING.md
 | 
			
		||||
ISSUE_TEMPLATE.md
 | 
			
		||||
PULL_REQUEST_TEMPLATE.md
 | 
			
		||||
tslint.json
 | 
			
		||||
wallaby.js
 | 
			
		||||
.travis.yml
 | 
			
		||||
.gitignore
 | 
			
		||||
.vscode
 | 
			
		||||
type_definitions
 | 
			
		||||
							
								
								
									
										33
									
								
								packages/core/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								packages/core/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@ms/core",
 | 
			
		||||
    "version": "0.0.0",
 | 
			
		||||
    "description": "MiaoScript api package",
 | 
			
		||||
    "keywords": [
 | 
			
		||||
        "miaoscript",
 | 
			
		||||
        "minecraft",
 | 
			
		||||
        "bukkit",
 | 
			
		||||
        "sponge"
 | 
			
		||||
    ],
 | 
			
		||||
    "author": "MiaoWoo <admin@yumc.pw>",
 | 
			
		||||
    "homepage": "https://github.com/circlecloud/ms.git",
 | 
			
		||||
    "license": "ISC",
 | 
			
		||||
    "main": "dist/index.js",
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "registry": "https://repo.yumc.pw/repository/npm/"
 | 
			
		||||
    },
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "clean": "rimraf dist",
 | 
			
		||||
        "watch": "npx tsc --watch",
 | 
			
		||||
        "build": "yarn clean && npx tsc",
 | 
			
		||||
        "test": "echo \"Error: run tests from root\" && exit 1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "reflect-metadata": "^0.1.13",
 | 
			
		||||
        "rimraf": "^3.0.0",
 | 
			
		||||
        "typescript": "^3.6.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@ms/container": "^0.0.0",
 | 
			
		||||
        "@ms/plugin": "^0.0.0"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								packages/core/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								packages/core/src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
import '@ms/nashorn'
 | 
			
		||||
 | 
			
		||||
import { plugin, server, MiaoScriptConsole } from '@ms/api'
 | 
			
		||||
import { DefaultContainer as container } from '@ms/container'
 | 
			
		||||
import { PluginManagerImpl } from '@ms/plugin'
 | 
			
		||||
 | 
			
		||||
import '@ms/bukkit'
 | 
			
		||||
 | 
			
		||||
let Console: MiaoScriptConsole = container.get(server.Console);
 | 
			
		||||
global.console = new Console();
 | 
			
		||||
 | 
			
		||||
container.bind(plugin.PluginManager).to(PluginManagerImpl).inSingletonScope();
 | 
			
		||||
 | 
			
		||||
let manager = container.get<plugin.PluginManager>(plugin.PluginManager);
 | 
			
		||||
manager.scan('plugins');
 | 
			
		||||
manager.load(container);
 | 
			
		||||
manager.enable();
 | 
			
		||||
							
								
								
									
										7
									
								
								packages/core/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/core/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "extends": "../../tsconfig.json",
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "baseUrl": "src",
 | 
			
		||||
        "outDir": "dist"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								packages/nashorn/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/nashorn/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
/node_modules
 | 
			
		||||
/dist
 | 
			
		||||
/package-lock.json
 | 
			
		||||
/yarn.lock
 | 
			
		||||
							
								
								
									
										22
									
								
								packages/nashorn/.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/nashorn/.npmignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
src
 | 
			
		||||
test
 | 
			
		||||
typings
 | 
			
		||||
bundled
 | 
			
		||||
build
 | 
			
		||||
coverage
 | 
			
		||||
docs
 | 
			
		||||
wiki
 | 
			
		||||
gulpfile.js
 | 
			
		||||
bower.json
 | 
			
		||||
karma.conf.js
 | 
			
		||||
tsconfig.json
 | 
			
		||||
typings.json
 | 
			
		||||
CONTRIBUTING.md
 | 
			
		||||
ISSUE_TEMPLATE.md
 | 
			
		||||
PULL_REQUEST_TEMPLATE.md
 | 
			
		||||
tslint.json
 | 
			
		||||
wallaby.js
 | 
			
		||||
.travis.yml
 | 
			
		||||
.gitignore
 | 
			
		||||
.vscode
 | 
			
		||||
type_definitions
 | 
			
		||||
							
								
								
									
										30
									
								
								packages/nashorn/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								packages/nashorn/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@ms/nashorn",
 | 
			
		||||
    "version": "0.0.0",
 | 
			
		||||
    "description": "MiaoScript api package",
 | 
			
		||||
    "keywords": [
 | 
			
		||||
        "miaoscript",
 | 
			
		||||
        "minecraft",
 | 
			
		||||
        "bukkit",
 | 
			
		||||
        "sponge"
 | 
			
		||||
    ],
 | 
			
		||||
    "author": "MiaoWoo <admin@yumc.pw>",
 | 
			
		||||
    "homepage": "https://github.com/circlecloud/ms.git",
 | 
			
		||||
    "license": "ISC",
 | 
			
		||||
    "main": "dist/index.js",
 | 
			
		||||
    "types": "dist/index.d.ts",
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "registry": "https://repo.yumc.pw/repository/npm/"
 | 
			
		||||
    },
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "clean": "rimraf dist",
 | 
			
		||||
        "watch": "npx tsc --watch",
 | 
			
		||||
        "build": "yarn clean && npx tsc",
 | 
			
		||||
        "test": "echo \"Error: run tests from root\" && exit 1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "reflect-metadata": "^0.1.13",
 | 
			
		||||
        "rimraf": "^3.0.0",
 | 
			
		||||
        "typescript": "^3.6.2"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								packages/nashorn/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								packages/nashorn/src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
declare global {
 | 
			
		||||
    namespace Java {
 | 
			
		||||
        function type(clazz: string): any;
 | 
			
		||||
        function from(javaObj: any): any[];
 | 
			
		||||
        function to(array: any[]): any;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { };
 | 
			
		||||
							
								
								
									
										7
									
								
								packages/nashorn/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/nashorn/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "extends": "../../tsconfig.json",
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "baseUrl": "src",
 | 
			
		||||
        "outDir": "dist"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								packages/plugin/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/plugin/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
/node_modules
 | 
			
		||||
/dist
 | 
			
		||||
/package-lock.json
 | 
			
		||||
/yarn.lock
 | 
			
		||||
							
								
								
									
										22
									
								
								packages/plugin/.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/plugin/.npmignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
src
 | 
			
		||||
test
 | 
			
		||||
typings
 | 
			
		||||
bundled
 | 
			
		||||
build
 | 
			
		||||
coverage
 | 
			
		||||
docs
 | 
			
		||||
wiki
 | 
			
		||||
gulpfile.js
 | 
			
		||||
bower.json
 | 
			
		||||
karma.conf.js
 | 
			
		||||
tsconfig.json
 | 
			
		||||
typings.json
 | 
			
		||||
CONTRIBUTING.md
 | 
			
		||||
ISSUE_TEMPLATE.md
 | 
			
		||||
PULL_REQUEST_TEMPLATE.md
 | 
			
		||||
tslint.json
 | 
			
		||||
wallaby.js
 | 
			
		||||
.travis.yml
 | 
			
		||||
.gitignore
 | 
			
		||||
.vscode
 | 
			
		||||
type_definitions
 | 
			
		||||
							
								
								
									
										34
									
								
								packages/plugin/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								packages/plugin/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@ms/plugin",
 | 
			
		||||
    "version": "0.0.0",
 | 
			
		||||
    "description": "MiaoScript api package",
 | 
			
		||||
    "keywords": [
 | 
			
		||||
        "miaoscript",
 | 
			
		||||
        "minecraft",
 | 
			
		||||
        "bukkit",
 | 
			
		||||
        "sponge"
 | 
			
		||||
    ],
 | 
			
		||||
    "author": "MiaoWoo <admin@yumc.pw>",
 | 
			
		||||
    "homepage": "https://github.com/circlecloud/ms.git",
 | 
			
		||||
    "license": "ISC",
 | 
			
		||||
    "main": "dist/index.js",
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "registry": "https://repo.yumc.pw/repository/npm/"
 | 
			
		||||
    },
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "clean": "rimraf dist",
 | 
			
		||||
        "watch": "npx tsc --watch",
 | 
			
		||||
        "build": "yarn clean && npx tsc",
 | 
			
		||||
        "test": "echo \"Error: run tests from root\" && exit 1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "reflect-metadata": "^0.1.13",
 | 
			
		||||
        "rimraf": "^3.0.0",
 | 
			
		||||
        "typescript": "^3.6.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@ms/api": "^0.0.0",
 | 
			
		||||
        "es6-map": "^0.1.5",
 | 
			
		||||
        "inversify": "^5.0.1"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								packages/plugin/src/constants.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								packages/plugin/src/constants.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
export const METADATA_KEY = {
 | 
			
		||||
    plugin: "@ms/plugin:plugin",
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										20
									
								
								packages/plugin/src/decorators.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								packages/plugin/src/decorators.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
import { interfaces } from './interfaces'
 | 
			
		||||
import { METADATA_KEY } from './constants'
 | 
			
		||||
import { injectable, decorate } from "inversify";
 | 
			
		||||
import { getPluginMetadatas } from './utils'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MiaoScript plugin
 | 
			
		||||
 * @param name namespace name default is '/'
 | 
			
		||||
 * @param middleware middleware array
 | 
			
		||||
 */
 | 
			
		||||
export function plugin(currentMetadata: interfaces.PluginMetadata) {
 | 
			
		||||
    return function(target: any) {
 | 
			
		||||
        target.description = currentMetadata;
 | 
			
		||||
        currentMetadata.target = target;
 | 
			
		||||
        decorate(injectable(), target);
 | 
			
		||||
        Reflect.defineMetadata(METADATA_KEY.plugin, currentMetadata, target);
 | 
			
		||||
        const previousMetadata: interfaces.PluginMetadata[] = getPluginMetadatas();
 | 
			
		||||
        Reflect.defineMetadata(METADATA_KEY.plugin, [currentMetadata, ...previousMetadata], Reflect);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								packages/plugin/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								packages/plugin/src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
export * from './manager'
 | 
			
		||||
export * from './decorators'
 | 
			
		||||
export * from './interfaces'
 | 
			
		||||
							
								
								
									
										25
									
								
								packages/plugin/src/interfaces.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								packages/plugin/src/interfaces.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
import { injectable, postConstruct } from "inversify";
 | 
			
		||||
import { getPluginMetadata } from './utils'
 | 
			
		||||
 | 
			
		||||
export namespace interfaces {
 | 
			
		||||
    @injectable()
 | 
			
		||||
    export abstract class Plugin {
 | 
			
		||||
        public description: PluginMetadata;
 | 
			
		||||
        protected logger: Console;
 | 
			
		||||
 | 
			
		||||
        @postConstruct()
 | 
			
		||||
        private init() {
 | 
			
		||||
            this.logger = global.console;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public load() { }
 | 
			
		||||
        public enable() { }
 | 
			
		||||
        public disable() { }
 | 
			
		||||
    }
 | 
			
		||||
    export interface PluginMetadata {
 | 
			
		||||
        name: string;
 | 
			
		||||
        version: string;
 | 
			
		||||
        author: string | string[];
 | 
			
		||||
        target?: any;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										136
									
								
								packages/plugin/src/manager.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								packages/plugin/src/manager.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,136 @@
 | 
			
		||||
import { plugin, server } from '@ms/api'
 | 
			
		||||
import { injectable, inject, postConstruct, Container } from '@ms/container'
 | 
			
		||||
import * as fs from '@ms/common/dist/fs'
 | 
			
		||||
 | 
			
		||||
import { getPluginMetadatas } from './utils'
 | 
			
		||||
import { interfaces } from './interfaces';
 | 
			
		||||
 | 
			
		||||
@injectable()
 | 
			
		||||
export class PluginManagerImpl implements plugin.PluginManager {
 | 
			
		||||
    @inject(plugin.PluginInstance)
 | 
			
		||||
    private pluginInstance: any;
 | 
			
		||||
    @inject(server.ServerType)
 | 
			
		||||
    private serverType: string;
 | 
			
		||||
 | 
			
		||||
    private pluginMap: Map<string, interfaces.Plugin>;
 | 
			
		||||
 | 
			
		||||
    @postConstruct()
 | 
			
		||||
    init() {
 | 
			
		||||
        if (this.pluginInstance !== null) {
 | 
			
		||||
            // 如果plugin不等于null 则代表是正式环境
 | 
			
		||||
            console.info(`Initialization MiaoScript Plugin System: ${this.pluginInstance} ...`);
 | 
			
		||||
            this.pluginMap = new Map();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    scan(folder: string): void {
 | 
			
		||||
        var plugin = fs.file(root, folder);
 | 
			
		||||
        var files = []
 | 
			
		||||
            // load common plugin
 | 
			
		||||
            .concat(this.scanFloder(plugin))
 | 
			
		||||
            // load space plugin
 | 
			
		||||
            .concat(this.scanFloder(fs.file(plugin, this.serverType)))
 | 
			
		||||
        this.loadPlugins(files);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    load(container: Container): void {
 | 
			
		||||
        this.buildPlugins(container);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enable(): void {
 | 
			
		||||
        this.pluginMap.forEach(pl => this.runCatch(pl, 'load'));
 | 
			
		||||
        this.pluginMap.forEach(pl => this.runCatch(pl, 'enable'));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    disable(): void {
 | 
			
		||||
        throw new Error("Method not implemented.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private runCatch(pl: any, func: string) {
 | 
			
		||||
        console.log(JSON.stringify(pl));
 | 
			
		||||
        try {
 | 
			
		||||
            pl[func].call(pl);
 | 
			
		||||
        } catch (ex) {
 | 
			
		||||
            console.console(`§6插件 §b${pl.description.name} §6执行 §d${func} §6方法时发生错误 §4${ex}`);
 | 
			
		||||
            console.ex(ex);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private scanFloder(plugin: any): string[] {
 | 
			
		||||
        var files = [];
 | 
			
		||||
        console.info(`Start Scan Plugins in ${plugin} ...`);
 | 
			
		||||
        this.checkUpdateFolder(plugin);
 | 
			
		||||
        fs.list(plugin).forEach(function searchPlugin(file) {
 | 
			
		||||
            files.push(file.toFile());
 | 
			
		||||
        });
 | 
			
		||||
        return files;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 更新插件
 | 
			
		||||
     * @param path
 | 
			
		||||
     */
 | 
			
		||||
    private checkUpdateFolder(path) {
 | 
			
		||||
        var update = fs.file(path, "update");
 | 
			
		||||
        if (!update.exists()) {
 | 
			
		||||
            update.mkdirs();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private loadPlugins(files: any[]): void {
 | 
			
		||||
        this.loadJsPlugins(files);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * JS类型插件预加载
 | 
			
		||||
    */
 | 
			
		||||
    private loadJsPlugins(files: any[]) {
 | 
			
		||||
        files.filter(file => file.name.endsWith(".js")).forEach(file => {
 | 
			
		||||
            try {
 | 
			
		||||
                this.loadPlugin(file)
 | 
			
		||||
            } catch (ex) {
 | 
			
		||||
                console.console(`§6插件 §b${file.name} §6初始化时发生错误 §4${ex.message}`);
 | 
			
		||||
                console.ex(ex);
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private loadPlugin(file: any) {
 | 
			
		||||
        this.updatePlugin(file);
 | 
			
		||||
        this.createPlugin(file);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private updatePlugin(file: any) {
 | 
			
		||||
        var update = fs.file(fs.file(file.parentFile, 'update'), file.name);
 | 
			
		||||
        if (update.exists()) {
 | 
			
		||||
            console.info(`Auto Update Plugin ${file.name} ...`);
 | 
			
		||||
            fs.move(update, file, true);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private createPlugin(file) {
 | 
			
		||||
        //@ts-ignore
 | 
			
		||||
        require(file, {
 | 
			
		||||
            cache: false
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private beforeLoadHook(origin) {
 | 
			
		||||
        var result = origin;
 | 
			
		||||
        // // 注入 console 对象         // 给插件注入单独的 console
 | 
			
		||||
        // result += '\nvar console = new Console(); module.exports.console = console;';
 | 
			
		||||
        // // 插件注入 self 对象
 | 
			
		||||
        // result += '\nvar self = {}; module.exports.self = self;';
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private buildPlugins(container: Container) {
 | 
			
		||||
        let pluginMetadatas = getPluginMetadatas();
 | 
			
		||||
        for (const metadata of pluginMetadatas) {
 | 
			
		||||
            container.bind(plugin.Plugin).to(metadata.target).inSingletonScope().whenTargetNamed(metadata.name);
 | 
			
		||||
            this.pluginMap.set(metadata.name, container.getNamed(plugin.Plugin, metadata.name));
 | 
			
		||||
            let pluginInstance = this.pluginMap.get(metadata.name)
 | 
			
		||||
            pluginInstance.description = metadata;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								packages/plugin/src/utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								packages/plugin/src/utils.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
import { interfaces } from './interfaces'
 | 
			
		||||
import { METADATA_KEY } from './constants'
 | 
			
		||||
 | 
			
		||||
function getPlugins() {
 | 
			
		||||
    return getPluginMetadatas().map((target) => target.target);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getPluginMetadatas() {
 | 
			
		||||
    let pluginMetadatas: interfaces.PluginMetadata[] = Reflect.getMetadata(
 | 
			
		||||
        METADATA_KEY.plugin,
 | 
			
		||||
        Reflect
 | 
			
		||||
    ) || [];
 | 
			
		||||
    return pluginMetadatas;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getPluginMetadata(target: any) {
 | 
			
		||||
    let pluginMetadata: interfaces.PluginMetadata = Reflect.getMetadata(
 | 
			
		||||
        METADATA_KEY.plugin,
 | 
			
		||||
        target
 | 
			
		||||
    ) || {};
 | 
			
		||||
    return pluginMetadata;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
    getPlugins,
 | 
			
		||||
    getPluginMetadatas,
 | 
			
		||||
    getPluginMetadata
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								packages/plugin/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/plugin/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "extends": "../../tsconfig.json",
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "baseUrl": "src",
 | 
			
		||||
        "outDir": "dist"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								packages/sponge/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/sponge/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
/node_modules
 | 
			
		||||
/dist
 | 
			
		||||
/package-lock.json
 | 
			
		||||
/yarn.lock
 | 
			
		||||
							
								
								
									
										22
									
								
								packages/sponge/.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/sponge/.npmignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
src
 | 
			
		||||
test
 | 
			
		||||
typings
 | 
			
		||||
bundled
 | 
			
		||||
build
 | 
			
		||||
coverage
 | 
			
		||||
docs
 | 
			
		||||
wiki
 | 
			
		||||
gulpfile.js
 | 
			
		||||
bower.json
 | 
			
		||||
karma.conf.js
 | 
			
		||||
tsconfig.json
 | 
			
		||||
typings.json
 | 
			
		||||
CONTRIBUTING.md
 | 
			
		||||
ISSUE_TEMPLATE.md
 | 
			
		||||
PULL_REQUEST_TEMPLATE.md
 | 
			
		||||
tslint.json
 | 
			
		||||
wallaby.js
 | 
			
		||||
.travis.yml
 | 
			
		||||
.gitignore
 | 
			
		||||
.vscode
 | 
			
		||||
type_definitions
 | 
			
		||||
							
								
								
									
										32
									
								
								packages/sponge/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								packages/sponge/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@ms/sponge",
 | 
			
		||||
    "version": "0.0.0",
 | 
			
		||||
    "description": "MiaoScript api package",
 | 
			
		||||
    "keywords": [
 | 
			
		||||
        "miaoscript",
 | 
			
		||||
        "minecraft",
 | 
			
		||||
        "bukkit",
 | 
			
		||||
        "sponge"
 | 
			
		||||
    ],
 | 
			
		||||
    "author": "MiaoWoo <admin@yumc.pw>",
 | 
			
		||||
    "homepage": "https://github.com/circlecloud/ms.git",
 | 
			
		||||
    "license": "ISC",
 | 
			
		||||
    "main": "dist/index.js",
 | 
			
		||||
    "publishConfig": {
 | 
			
		||||
        "registry": "https://repo.yumc.pw/repository/npm/"
 | 
			
		||||
    },
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "clean": "rimraf dist",
 | 
			
		||||
        "watch": "npx tsc --watch",
 | 
			
		||||
        "build": "yarn clean && npx tsc",
 | 
			
		||||
        "test": "echo \"Error: run tests from root\" && exit 1"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
        "reflect-metadata": "^0.1.13",
 | 
			
		||||
        "rimraf": "^3.0.0",
 | 
			
		||||
        "typescript": "^3.6.2"
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "inversify": "^5.0.1"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								packages/sponge/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/sponge/src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
export default {}
 | 
			
		||||
							
								
								
									
										7
									
								
								packages/sponge/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/sponge/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "extends": "../../tsconfig.json",
 | 
			
		||||
    "compilerOptions": {
 | 
			
		||||
        "baseUrl": "src",
 | 
			
		||||
        "outDir": "dist"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user