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() {
|
private void saveScript() {
|
||||||
P.saveFile(true, "core", "modules", "plugins");
|
P.saveFile(true, "core", "modules", "kit");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadEngine() {
|
private void loadEngine() {
|
||||||
|
@ -18,7 +18,8 @@ var disable;
|
|||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
log.w("MiaoScript 初始化失败! %s", ex);
|
log.w("MiaoScript 初始化失败! %s", ex);
|
||||||
throw 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 {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
ext.getStatic = function (name) {
|
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()) {
|
if (dir.isDirectory()) {
|
||||||
return Files.list(dir.toPath());
|
return Files.list(dir.toPath());
|
||||||
}
|
}
|
||||||
log.w("路径 %s 不是一个目录 返回空数组!");
|
log.w("路径 %s 不是一个目录 返回空数组!", path);
|
||||||
return [];
|
return [];
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
|
@ -30,7 +30,6 @@ function initDir() {
|
|||||||
function loadCore() {
|
function loadCore() {
|
||||||
// 加载基础模块
|
// 加载基础模块
|
||||||
load(core_dir + '/ext.js');
|
load(core_dir + '/ext.js');
|
||||||
load(core_dir + '/static.js');
|
|
||||||
load(core_dir + '/console.js');
|
load(core_dir + '/console.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +38,7 @@ function loadCore() {
|
|||||||
*/
|
*/
|
||||||
function loadRequire() {
|
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() {
|
function loadLib4Bukkit() {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/*global Java, base*/
|
/*global Java, base*/
|
||||||
(function (parent, core_dir, miao_module_dir) {
|
(function (parent) {
|
||||||
'use strict';
|
'use strict';
|
||||||
var File = Java.type("java.io.File");
|
var File = Java.type("java.io.File");
|
||||||
|
|
||||||
@ -16,35 +16,37 @@
|
|||||||
* 模块目录 /modules
|
* 模块目录 /modules
|
||||||
* @param name 模块名称
|
* @param name 模块名称
|
||||||
*/
|
*/
|
||||||
function findModule(name) {
|
function resolve(name) {
|
||||||
if (_canonical(name)) {
|
if (_canonical(name)) {
|
||||||
name = _canonical(name);
|
name = _canonical(name);
|
||||||
}
|
}
|
||||||
// 如果不是 .js 结尾就加上
|
name = normalizeName(name, '.js');
|
||||||
if (!name.match(/.*\.js/)) {
|
return resolveAsFile(parent, name) ||
|
||||||
name += ".js";
|
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);
|
return fileName + extension;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,11 +57,43 @@
|
|||||||
function compileJs(file) {
|
function compileJs(file) {
|
||||||
var cacheFile = _cacheFile(file);
|
var cacheFile = _cacheFile(file);
|
||||||
base.save(cacheFile, "(function (module, exports, require) {" + base.read(file) + "});");
|
base.save(cacheFile, "(function (module, exports, require) {" + base.read(file) + "});");
|
||||||
|
// 使用 load 可以保留行号和文件名称
|
||||||
var obj = load(cacheFile);
|
var obj = load(cacheFile);
|
||||||
base.delete(cacheFile);
|
base.delete(cacheFile);
|
||||||
return obj;
|
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
|
* @param file
|
||||||
@ -83,7 +117,11 @@
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function _require(name, path) {
|
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];
|
name = file.name.split(".")[0];
|
||||||
var id = _canonical(file);
|
var id = _canonical(file);
|
||||||
@ -91,27 +129,7 @@
|
|||||||
if (module) {
|
if (module) {
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
log.d('加载模块 %s 位于 %s', name, id);
|
cacheModules[id] = module = compileModule(id, name, file);
|
||||||
// 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;
|
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +144,7 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var cacheDir = parent + "/cache";
|
var cacheDir = parent + "/runtime";
|
||||||
|
|
||||||
// 等于 undefined 说明 parent 是一个字符串 需要转成File
|
// 等于 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 命令相关类
|
* Bukkit 命令相关类
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*global Java, base, module, exports, require, __FILE__*/
|
/*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 {
|
try {
|
||||||
eventCls = base.getClass(eventCls);
|
eventCls = base.getClass(eventCls);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
log.w("事件 %s 未找到!");
|
log.w("事件 %s 未找到!", event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,15 +11,19 @@ var fs = require('core/fs');
|
|||||||
* @param path
|
* @param path
|
||||||
*/
|
*/
|
||||||
function loadPlugins(path) {
|
function loadPlugins(path) {
|
||||||
path = fs.file(path);
|
var plugin = fs.file(path);
|
||||||
log.i("开始扫描 %s 下的插件...", path);
|
if (!plugin) {
|
||||||
updatePlugins(path);
|
log.i("首次加载 创建文件夹 %s ...", path);
|
||||||
var files = [];
|
} else {
|
||||||
fs.list(path).forEach(function (file) {
|
log.i("开始扫描 %s 下的插件 ...", path);
|
||||||
files.push(file.toFile());
|
updatePlugins(path);
|
||||||
});
|
var files = [];
|
||||||
loadZipPlugin(files);
|
fs.list(path).forEach(function (file) {
|
||||||
loadJsPlugin(files);
|
files.push(file.toFile());
|
||||||
|
});
|
||||||
|
loadZipPlugin(files);
|
||||||
|
loadJsPlugin(files);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,9 +32,13 @@ function loadPlugins(path) {
|
|||||||
*/
|
*/
|
||||||
function updatePlugins(path) {
|
function updatePlugins(path) {
|
||||||
var update = fs.file(path, "update");
|
var update = fs.file(path, "update");
|
||||||
fs.list(update).forEach(function (file) {
|
if (!update.exists()) {
|
||||||
fs.move(fs.file(update, file.name), fs.file(path, file.name), true);
|
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*/
|
/*global Java, base, module, exports, require*/
|
||||||
|
|
||||||
var papi = require("modules/ext/papi");
|
|
||||||
var event = require('modules/event');
|
var event = require('modules/event');
|
||||||
var join;
|
var join;
|
||||||
|
|
||||||
@ -14,17 +13,17 @@ var description = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function load() {
|
function load() {
|
||||||
log.i('载入 Hello Wrold 测试插件!');
|
console.log('载入 Hello Wrold 测试插件!');
|
||||||
}
|
}
|
||||||
|
|
||||||
function enable() {
|
function enable() {
|
||||||
log.i('启用 Hello Wrold 测试插件!');
|
console.log('启用 Hello Wrold 测试插件!');
|
||||||
join = event.on('playerloginevent', function join(event) {
|
join = event.on('playerloginevent', function join(event) {
|
||||||
// noinspection JSUnresolvedVariable
|
// noinspection JSUnresolvedVariable
|
||||||
log.d('玩家 %s 触发事件 %s', event.player.name, event.name);
|
log.d('玩家 %s 触发事件 %s', event.player.name, event.name);
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
// noinspection JSUnresolvedVariable
|
// 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);
|
}, 10);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user