feat: 新增 Console 和 reflect 部分完善 command
Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
parent
59b2824413
commit
d0b43487c2
@ -58,7 +58,7 @@ public class MiaoScript extends JavaPlugin implements Executor {
|
||||
}
|
||||
|
||||
private void saveScript() {
|
||||
P.saveFile(true, "core", "modules", "plugins");
|
||||
P.saveFile(true, "core", "modules", "kit");
|
||||
}
|
||||
|
||||
private void loadEngine() {
|
||||
|
@ -18,7 +18,8 @@ var disable;
|
||||
} catch (ex) {
|
||||
log.w("MiaoScript 初始化失败! %s", ex);
|
||||
throw ex;
|
||||
} finally {
|
||||
disable = disablePlugins
|
||||
}
|
||||
disable = disablePlugins
|
||||
};
|
||||
})();
|
21
src/main/resources/core/console.js
Normal file
21
src/main/resources/core/console.js
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* 控制台输出类
|
||||
*/
|
||||
/*global base*/
|
||||
var log = base.getLog().static;
|
||||
var Level = Java.type('java.util.logging.Level');
|
||||
var console = {
|
||||
log: function () {
|
||||
log.i(arguments.join(' '));
|
||||
},
|
||||
warn: function () {
|
||||
log.w(arguments.join(' '));
|
||||
},
|
||||
error: function () {
|
||||
log.log(Level.SEVERE, arguments.join(' '));
|
||||
},
|
||||
debug: function () {
|
||||
log.d(arguments.join(' '));
|
||||
}
|
||||
};
|
||||
global.console = console;
|
@ -10,7 +10,7 @@ var ext = {};
|
||||
* @returns {*}
|
||||
*/
|
||||
ext.getStatic = function (name) {
|
||||
return base.getClass(name).static;
|
||||
return base.class(name).static;
|
||||
};
|
||||
/**
|
||||
* 获得随机数
|
||||
|
@ -96,7 +96,7 @@ exports.list = function (path) {
|
||||
if (dir.isDirectory()) {
|
||||
return Files.list(dir.toPath());
|
||||
}
|
||||
log.w("路径 %s 不是一个目录 返回空数组!");
|
||||
log.w("路径 %s 不是一个目录 返回空数组!", path);
|
||||
return [];
|
||||
};
|
||||
/**
|
||||
|
@ -30,7 +30,6 @@ function initDir() {
|
||||
function loadCore() {
|
||||
// 加载基础模块
|
||||
load(core_dir + '/ext.js');
|
||||
load(core_dir + '/static.js');
|
||||
load(core_dir + '/console.js');
|
||||
}
|
||||
|
||||
@ -39,7 +38,7 @@ function loadCore() {
|
||||
*/
|
||||
function loadRequire() {
|
||||
// 初始化加载器
|
||||
global.require = load(core_dir + '/require.js')(root, core_dir, miao_module_dir);
|
||||
global.require = load(core_dir + '/require.js')(root);
|
||||
}
|
||||
|
||||
function loadLib4Bukkit() {
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
*/
|
||||
/*global Java, base*/
|
||||
(function (parent, core_dir, miao_module_dir) {
|
||||
(function (parent) {
|
||||
'use strict';
|
||||
var File = Java.type("java.io.File");
|
||||
|
||||
@ -16,35 +16,37 @@
|
||||
* 模块目录 /modules
|
||||
* @param name 模块名称
|
||||
*/
|
||||
function findModule(name) {
|
||||
function resolve(name) {
|
||||
if (_canonical(name)) {
|
||||
name = _canonical(name);
|
||||
}
|
||||
// 如果不是 .js 结尾就加上
|
||||
if (!name.match(/.*\.js/)) {
|
||||
name += ".js";
|
||||
name = normalizeName(name, '.js');
|
||||
return resolveAsFile(parent, name) ||
|
||||
resolveAsFile(name) ||
|
||||
resolveAsFile(core_dir, name) ||
|
||||
resolveAsFile(miao_module_dir, name) ||
|
||||
undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析文件
|
||||
* @constructor(file)
|
||||
* @constructor(dir,file)
|
||||
* @returns {*}
|
||||
*/
|
||||
function resolveAsFile() {
|
||||
var file = arguments.length > 1 ? new File(arguments[0], arguments[1]) : new File(arguments[0]);
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
var jsFile = new File(name);
|
||||
if (jsFile.exists()) {
|
||||
return jsFile;
|
||||
}
|
||||
|
||||
function normalizeName(fileName, ext) {
|
||||
var extension = ext || '.js';
|
||||
if (fileName.endsWith(extension)) {
|
||||
return fileName;
|
||||
}
|
||||
var parentFile = new File(parent, name);
|
||||
if (parentFile.exists()) {
|
||||
return parentFile;
|
||||
}
|
||||
var coreFile = new File(core_dir, name);
|
||||
if (coreFile.exists()) {
|
||||
return coreFile;
|
||||
}
|
||||
var moduleFile = new File(miao_module_dir, name);
|
||||
if (moduleFile.exists()) {
|
||||
return moduleFile;
|
||||
}
|
||||
log.w("模块 %s 加载失败! 下列目录中未找到该模块!", name);
|
||||
log.w("当前目录: %s", _canonical(jsFile));
|
||||
log.w("上级目录: %s", _canonical(parentFile));
|
||||
log.w("核心目录: %s", _canonical(coreFile));
|
||||
log.w("模块目录: %s", _canonical(moduleFile));
|
||||
return fileName + extension;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,11 +57,43 @@
|
||||
function compileJs(file) {
|
||||
var cacheFile = _cacheFile(file);
|
||||
base.save(cacheFile, "(function (module, exports, require) {" + base.read(file) + "});");
|
||||
// 使用 load 可以保留行号和文件名称
|
||||
var obj = load(cacheFile);
|
||||
base.delete(cacheFile);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编译模块
|
||||
* @param id
|
||||
* @param name
|
||||
* @param file
|
||||
* @returns {Object}
|
||||
*/
|
||||
function compileModule(id, name, file) {
|
||||
log.d('加载模块 %s 位于 %s', name, id);
|
||||
// noinspection JSUnresolvedVariable
|
||||
var module = {
|
||||
id: id,
|
||||
exports: {},
|
||||
loaded: false,
|
||||
require: exports(file.parentFile)
|
||||
};
|
||||
try {
|
||||
// 预编译模块
|
||||
var compiledWrapper = compileJs(file);
|
||||
compiledWrapper.apply(module.exports, [
|
||||
module, module.exports, module.require
|
||||
]);
|
||||
log.d('模块 %s 编译成功!', name);
|
||||
module.loaded = true;
|
||||
} catch (ex) {
|
||||
log.w("模块 %s 编译失败!", name);
|
||||
log.d(ex);
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得文件规范路径
|
||||
* @param file
|
||||
@ -83,7 +117,11 @@
|
||||
* @private
|
||||
*/
|
||||
function _require(name, path) {
|
||||
var file = findModule(name, path);
|
||||
var file = resolve(name, path);
|
||||
if (file === undefined) {
|
||||
log.w("模块 %s 加载失败! 未找到该模块!", name);
|
||||
return;
|
||||
}
|
||||
// 重定向文件名称
|
||||
name = file.name.split(".")[0];
|
||||
var id = _canonical(file);
|
||||
@ -91,27 +129,7 @@
|
||||
if (module) {
|
||||
return module;
|
||||
}
|
||||
log.d('加载模块 %s 位于 %s', name, id);
|
||||
// noinspection JSUnresolvedVariable
|
||||
module = {
|
||||
loaded: false,
|
||||
id: id,
|
||||
exports: {},
|
||||
require: exports(file.parentFile)
|
||||
};
|
||||
try {
|
||||
// 预编译模块
|
||||
var compiledWrapper = compileJs(file);
|
||||
compiledWrapper.apply(module.exports, [
|
||||
module, module.exports, module.require
|
||||
]);
|
||||
log.d('模块 %s 编译成功!', name);
|
||||
module.loaded = true;
|
||||
} catch (ex) {
|
||||
log.w("模块 %s 编译失败!", name);
|
||||
log.d(ex);
|
||||
}
|
||||
cacheModules[id] = module;
|
||||
cacheModules[id] = module = compileModule(id, name, file);
|
||||
return module;
|
||||
}
|
||||
|
||||
@ -126,7 +144,7 @@
|
||||
};
|
||||
}
|
||||
|
||||
var cacheDir = parent + "/cache";
|
||||
var cacheDir = parent + "/runtime";
|
||||
|
||||
// 等于 undefined 说明 parent 是一个字符串 需要转成File
|
||||
// 可能有更加准确的方案
|
||||
|
@ -1,24 +0,0 @@
|
||||
/**
|
||||
* 基础静态类
|
||||
* Created by 蒋天蓓 on 2017/2/9 0009.
|
||||
*/
|
||||
/**
|
||||
* 日志类
|
||||
*/
|
||||
var log = base.getLog().static;
|
||||
/**
|
||||
* ActionBar类
|
||||
*/
|
||||
var actionbar = base.getActionBar().static;
|
||||
/**
|
||||
* Title类
|
||||
*/
|
||||
var title = base.getTitle().static;
|
||||
/**
|
||||
* 玩家兼容类
|
||||
*/
|
||||
var cplayer = base.getPlayer().static;
|
||||
/**
|
||||
* 工具类
|
||||
*/
|
||||
var mctools = base.getTools().static;
|
119
src/main/resources/kit/reflect.js
Normal file
119
src/main/resources/kit/reflect.js
Normal file
@ -0,0 +1,119 @@
|
||||
'use strict';
|
||||
/**
|
||||
* 反射工具类
|
||||
* Created by 蒋天蓓 on 2017/2/9 0009.
|
||||
*/
|
||||
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var Class = Java.type('java.lang.Class');
|
||||
var NoSuchFieldException = Java.type('java.lang.NoSuchFieldException');
|
||||
|
||||
function Reflect(obj) {
|
||||
this.obj = obj;
|
||||
this.class = obj instanceof Class ? obj : obj.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of types for an array of objects
|
||||
*/
|
||||
function types(values) {
|
||||
if (values === null) {
|
||||
return [];
|
||||
}
|
||||
var result = [];
|
||||
values.forEach(function (t) {
|
||||
result.push(t === null ? Object.class : t.class)
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function accessible(accessible) {
|
||||
if (accessible === null) {
|
||||
return null;
|
||||
}
|
||||
if (!accessible.isAccessible()) {
|
||||
accessible.setAccessible(true);
|
||||
}
|
||||
return accessible;
|
||||
}
|
||||
|
||||
function declaredConstructor() {
|
||||
return accessible(arguments[0].declaredConstructor(arguments.slice(1)));
|
||||
}
|
||||
|
||||
function declaredField(clazz, name) {
|
||||
var field = null;
|
||||
// noinspection JSUnresolvedVariable
|
||||
while (clazz !== java.lang.Object.class) {
|
||||
try {
|
||||
field = clazz.declaredField(name);
|
||||
if (field !== null) {
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
clazz = clazz.superclass();
|
||||
}
|
||||
}
|
||||
if (field === null) {
|
||||
throw new NoSuchFieldException(name + " is not found in " + clazz.name);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
Reflect.field = function (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
|
||||
try {
|
||||
return on(accessible(declaredField(this.class, name)).get(this.obj));
|
||||
} catch (ex) {
|
||||
throw new NoSuchFieldException(ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reflect.method = function () {
|
||||
var name = arguments[0];
|
||||
var clazzs = arguments.slice(1);
|
||||
try {
|
||||
return this.class.method(name, clazzs);
|
||||
} catch (ex) {
|
||||
return this.class.declaredMethod(name, clazzs);
|
||||
}
|
||||
};
|
||||
|
||||
var methodCache = [];
|
||||
|
||||
Reflect.cacheMethod = function () {
|
||||
var name = arguments[0];
|
||||
var mkey = this.class.name + '.' + name;
|
||||
if (!methodCache[mkey]) {
|
||||
methodCache[mkey] = this.method(name, arguments.slice(1));
|
||||
}
|
||||
return methodCache[mkey];
|
||||
};
|
||||
|
||||
Reflect.call = function () {
|
||||
var name = arguments[0];
|
||||
var params = arguments.slice(1);
|
||||
var method = this.method(name, types(params));
|
||||
return exports.on(method.invoke(this.get(), params));
|
||||
};
|
||||
|
||||
Reflect.get = function () {
|
||||
return arguments.length === 1 ? this.field(arguments[0]) : this.obj;
|
||||
};
|
||||
|
||||
Reflect.create = function () {
|
||||
return on(declaredConstructor(this.class, arguments).newInstance(arguments));
|
||||
};
|
||||
|
||||
function on(obj) {
|
||||
return new Reflect(obj);
|
||||
}
|
||||
|
||||
exports.on = on;
|
||||
exports.accessible = accessible;
|
@ -2,4 +2,49 @@
|
||||
/**
|
||||
* Bukkit 命令相关类
|
||||
*/
|
||||
|
||||
/*global Java, base, module, exports, require, __FILE__*/
|
||||
var plugin = base.plugin;
|
||||
var bukkit = require('bukkit');
|
||||
var ref = require('kit/reflect');
|
||||
var lookupNames = ref.on(bukkit.plugin.manager).get('lookupNames').get();
|
||||
var knownCommands = ref.on(bukkit.plugin.manager).get('commandMap').get('knownCommands').get();
|
||||
var PluginCommand = Java.type('org.bukkit.command.PluginCommand');
|
||||
|
||||
function create(jsp, name) {
|
||||
var cmd = ref.on(PluginCommand).create(name, plugin).get();
|
||||
register(jsp, name, cmd);
|
||||
}
|
||||
|
||||
function register(jsp, name, cmd) {
|
||||
if (name.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
knownCommands.put(name, cmd);
|
||||
knownCommands.computeIfAbsent(jsp.description.name + ":" + name, function () {
|
||||
return cmd;
|
||||
});
|
||||
knownCommands.computeIfAbsent('ms:' + jsp.description.name + ":" + name, function () {
|
||||
return cmd;
|
||||
});
|
||||
lookupNames.put(name, plugin);
|
||||
}
|
||||
|
||||
// var exec = {
|
||||
// onCommand: function (sender, cmd, command, args) {
|
||||
//
|
||||
// },
|
||||
// onTabComplete: function (sender, cmd, command, args) {
|
||||
//
|
||||
// }
|
||||
// };
|
||||
|
||||
exports.on = function (plugin, name, exec) {
|
||||
var c = create(plugin, name);
|
||||
if (exec.onCommand) {
|
||||
c.setExecutor(exec);
|
||||
}
|
||||
if (exec.onTabComplete) {
|
||||
c.setTabCompleter(exec);
|
||||
}
|
||||
};
|
@ -80,7 +80,7 @@ function listen(event, exec, priority, ignoreCancel) {
|
||||
try {
|
||||
eventCls = base.getClass(eventCls);
|
||||
} catch (ex) {
|
||||
log.w("事件 %s 未找到!");
|
||||
log.w("事件 %s 未找到!", event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -11,15 +11,19 @@ var fs = require('core/fs');
|
||||
* @param path
|
||||
*/
|
||||
function loadPlugins(path) {
|
||||
path = fs.file(path);
|
||||
log.i("开始扫描 %s 下的插件...", path);
|
||||
updatePlugins(path);
|
||||
var files = [];
|
||||
fs.list(path).forEach(function (file) {
|
||||
files.push(file.toFile());
|
||||
});
|
||||
loadZipPlugin(files);
|
||||
loadJsPlugin(files);
|
||||
var plugin = fs.file(path);
|
||||
if (!plugin) {
|
||||
log.i("首次加载 创建文件夹 %s ...", path);
|
||||
} else {
|
||||
log.i("开始扫描 %s 下的插件 ...", path);
|
||||
updatePlugins(path);
|
||||
var files = [];
|
||||
fs.list(path).forEach(function (file) {
|
||||
files.push(file.toFile());
|
||||
});
|
||||
loadZipPlugin(files);
|
||||
loadJsPlugin(files);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,9 +32,13 @@ function loadPlugins(path) {
|
||||
*/
|
||||
function updatePlugins(path) {
|
||||
var update = fs.file(path, "update");
|
||||
fs.list(update).forEach(function (file) {
|
||||
fs.move(fs.file(update, file.name), fs.file(path, file.name), true);
|
||||
})
|
||||
if (!update.exists()) {
|
||||
update.mkdirs();
|
||||
} else {
|
||||
fs.list(update).forEach(function (file) {
|
||||
fs.move(fs.file(update, file.name), fs.file(path, file.name), true);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,7 +4,6 @@
|
||||
*/
|
||||
/*global Java, base, module, exports, require*/
|
||||
|
||||
var papi = require("modules/ext/papi");
|
||||
var event = require('modules/event');
|
||||
var join;
|
||||
|
||||
@ -14,17 +13,17 @@ var description = {
|
||||
};
|
||||
|
||||
function load() {
|
||||
log.i('载入 Hello Wrold 测试插件!');
|
||||
console.log('载入 Hello Wrold 测试插件!');
|
||||
}
|
||||
|
||||
function enable() {
|
||||
log.i('启用 Hello Wrold 测试插件!');
|
||||
console.log('启用 Hello Wrold 测试插件!');
|
||||
join = event.on('playerloginevent', function join(event) {
|
||||
// noinspection JSUnresolvedVariable
|
||||
log.d('玩家 %s 触发事件 %s', event.player.name, event.name);
|
||||
setTimeout(function () {
|
||||
// noinspection JSUnresolvedVariable
|
||||
event.player.sendMessage(papi.$(event.player, "§a欢迎来到 §bMiaoScript §a的世界! 当前在线: %server_online%"));
|
||||
event.player.sendMessage(require("plugins/ext/papi").$(event.player, "§a欢迎来到 §bMiaoScript §a的世界! 当前在线: %server_online%"));
|
||||
}, 10);
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user