feat: 完善任务功能 增加命令 优化代码

Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
502647092 2017-10-09 21:17:24 +08:00
parent 2fb73aee53
commit c13ef6f393
14 changed files with 328 additions and 135 deletions

View File

@ -0,0 +1,74 @@
package pw.yumc.MiaoScript;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Collectors;
import lombok.val;
import pw.yumc.YumCore.annotation.NotProguard;
import pw.yumc.YumCore.bukkit.Log;
import pw.yumc.YumCore.bukkit.compatible.C;
import pw.yumc.YumCore.mc.MinecraftTools;
/**
* Created with IntelliJ IDEA
*
* @author
* Created on 2017/10/9 12:40.
*/
@NotProguard
public class Base {
public Class getClass(String name) throws ClassNotFoundException {
return Class.forName(name);
}
public Class getLog() {
return Log.class;
}
public String read(String path) throws IOException {
Log.d("读取文件 %s ...", path);
return new String(Files.readAllBytes(new File(path).toPath()), "UTF-8");
}
public void save(String path, String content) throws IOException {
Log.d("保存文件 %s ...", path);
File file = new File(path);
file.getParentFile().mkdirs();
Files.write(file.toPath(), content.getBytes("UTF-8"));
}
public void delete(String path) throws IOException {
delete(new File(path).toPath());
}
public void delete(Path path) throws IOException {
val file = path.toFile();
if (!file.exists()) { return; }
Log.d("删除文件 %s ...", path);
if (file.isDirectory()) {
for (Path f : Files.list(file.toPath()).collect(Collectors.toList())) {
delete(f);
}
}
Files.delete(path);
}
public Class getActionBar() {
return C.ActionBar.class;
}
public Class getTitle() {
return C.Title.class;
}
public Class getPlayer() {
return C.Player.class;
}
public Class getTools() {
return MinecraftTools.class;
}
}

View File

@ -1,26 +0,0 @@
package pw.yumc.MiaoScript;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Created with IntelliJ IDEA
*
* @author
* Created on 2017/9/22 18:39.
*/
public class BaseEvent extends Event {
private static HandlerList handlerList = new HandlerList();
public BaseEvent() {
}
public static HandlerList getHandlerList() {
return handlerList;
}
@Override
public HandlerList getHandlers() {
return handlerList;
}
}

View File

@ -1,24 +1,23 @@
package pw.yumc.MiaoScript;
import java.io.File;
import java.io.IOException;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Collectors;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;
import lombok.val;
import pw.yumc.YumCore.annotation.NotProguard;
import lombok.SneakyThrows;
import pw.yumc.YumCore.bukkit.Log;
import pw.yumc.YumCore.bukkit.P;
import pw.yumc.YumCore.bukkit.compatible.C;
import pw.yumc.YumCore.commands.CommandSub;
import pw.yumc.YumCore.commands.annotation.Cmd;
import pw.yumc.YumCore.commands.annotation.Help;
import pw.yumc.YumCore.commands.interfaces.Executor;
import pw.yumc.YumCore.engine.MiaoScriptEngine;
import pw.yumc.YumCore.mc.MinecraftTools;
/**
* 喵式脚本
@ -26,22 +25,35 @@ import pw.yumc.YumCore.mc.MinecraftTools;
* @author
* @since 2016年8月29日 上午7:50:39
*/
public class MiaoScript extends JavaPlugin {
public class MiaoScript extends JavaPlugin implements Executor {
private MiaoScriptEngine engine;
@Override
public void onEnable() {
saveScript();
loadEngine();
new CommandSub("ms", this);
}
@Override
public void onDisable() {
try {
engine.invokeFunction("disable");
} catch (ScriptException | NoSuchMethodException e) {
Log.w("脚本引擎关闭失败! %s:%s", e.getClass().getName(), e.getMessage());
Log.d(e);
@Cmd
@Help("执行 JS 代码")
@SneakyThrows
public void js(CommandSender sender, String script) {
result(sender, engine.eval(script));
}
@Cmd
@Help("执行 JS 代码文件")
@SneakyThrows
public void file(CommandSender sender, String file) {
result(sender, engine.eval(new FileReader(new File(getDataFolder(), file))));
}
private void result(CommandSender sender, Object result) {
if (result == null) {
Log.sender(sender, "§a运行成功! §c没有返回结果!");
} else {
Log.sender(sender, "§a运行成功! §b数据类型: §r%s §d结果: §r%s", result.getClass().getName(), result);
}
}
@ -66,58 +78,13 @@ public class MiaoScript extends JavaPlugin {
}
}
@NotProguard
public static class Base {
public Class getClass(String name) throws ClassNotFoundException {
return Class.forName(name);
}
public Class getLog() {
return Log.class;
}
public String read(String path) throws IOException {
Log.d("读取文件 %s ...", path);
return new String(Files.readAllBytes(new File(path).toPath()), "UTF-8");
}
public void save(String path, String content) throws IOException {
Log.d("保存文件 %s ...", path);
File file = new File(path);
file.getParentFile().mkdirs();
Files.write(file.toPath(), content.getBytes("UTF-8"));
}
public void delete(String path) throws IOException {
delete(new File(path).toPath());
}
public void delete(Path path) throws IOException {
val file = path.toFile();
if (!file.exists()) { return; }
Log.d("删除文件 %s ...", path);
if (file.isDirectory()) {
for (Path f : Files.list(file.toPath()).collect(Collectors.toList())) {
delete(f);
}
}
Files.delete(path);
}
public Class getActionBar() {
return C.ActionBar.class;
}
public Class getTitle() {
return C.Title.class;
}
public Class getPlayer() {
return C.Player.class;
}
public Class getTools() {
return MinecraftTools.class;
@Override
public void onDisable() {
try {
engine.invokeFunction("disable");
} catch (ScriptException | NoSuchMethodException e) {
Log.w("脚本引擎关闭失败! %s:%s", e.getClass().getName(), e.getMessage());
Log.d(e);
}
}
}

View File

@ -1,6 +1,8 @@
package pw.yumc.MiaoScript;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
@ -10,7 +12,7 @@ import jdk.nashorn.api.scripting.ScriptObjectMirror;
* @author
* Created on 2017/9/30 21:32.
*/
public class ScriptEvent extends BaseEvent implements Cancellable {
public class ScriptEvent extends Event implements Cancellable {
private ScriptObjectMirror mirror;
private boolean cancelled = false;
@ -35,4 +37,15 @@ public class ScriptEvent extends BaseEvent implements Cancellable {
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
private static HandlerList handlerList = new HandlerList();
public static HandlerList getHandlerList() {
return handlerList;
}
@Override
public HandlerList getHandlers() {
return handlerList;
}
}

View File

@ -8,6 +8,7 @@ function init(root, plugin) {
initDir();
loadCore();
loadRequire();
loadLib4Bukkit();
loadPlugins(plugin);
}
@ -30,6 +31,7 @@ function loadCore() {
// 加载基础模块
load(core_dir + '/ext.js');
load(core_dir + '/static.js');
load(core_dir + '/console.js');
}
/**
@ -40,6 +42,23 @@ function loadRequire() {
global.require = load(core_dir + '/require.js')(root, core_dir, miao_module_dir);
}
function loadLib4Bukkit() {
require('modules/event');
var task = require('modules/task');
global.setTimeout = function (func, time) {
return task.later(func, time)
};
global.clearTimeout = function (task) {
task.cancel();
};
global.setInterval = function (func, time) {
return task.timer(func, time)
};
global.clearInterval = function (task) {
task.cancel();
};
}
/**
* 加载JS插件
*/

View File

@ -20,6 +20,7 @@
if (_canonical(name)) {
name = _canonical(name);
}
// 如果不是 .js 结尾就加上
if (!name.match(/.*\.js/)) {
name += ".js";
}
@ -77,12 +78,12 @@
/**
* 加载模块
* @param name 模块名称
* @param parent 父目录
* @param path 路径
* @returns {*}
* @private
*/
function _require(name, parent) {
var file = findModule(name, parent);
function _require(name, path) {
var file = findModule(name, path);
// 重定向文件名称
name = file.name.split(".")[0];
var id = _canonical(file);
@ -91,6 +92,7 @@
return module;
}
log.d('加载模块 %s 位于 %s', name, id);
// noinspection JSUnresolvedVariable
module = {
loaded: false,
id: id,
@ -110,7 +112,7 @@
log.d(ex);
}
cacheModules[id] = module;
return cacheModules[id];
return module;
}
/**

View File

@ -0,0 +1,5 @@
'use strict';
/**
* Bukkit 命令相关类
*/
/*global Java, base, module, exports, require, __FILE__*/

View File

@ -10,13 +10,13 @@ var Modifier = Java.type("java.lang.reflect.Modifier");
var BukkitEvent = Java.type("org.bukkit.event.Event");
var EventPriority = Java.type("org.bukkit.event.EventPriority");
var EventExecutor = Java.type("org.bukkit.plugin.EventExecutor");
var IllegalStateException = Java.type("java.lang.IllegalStateException");
var mapEvent = [];
var plugin = require('plugin').$;
/**
* 映射事件名称 org.bukkit.event.player.PlayerLoginEvent => playerloginevent
* 扫描包 org.bukkit.event 下的所有事件
* 映射简写名称 org.bukkit.event.player.PlayerLoginEvent => playerloginevent
*/
function mapEventName() {
var eventPackageDir = "org/bukkit/event";
@ -32,10 +32,12 @@ function mapEventName() {
while (entries.hasMoreElements()) {
var entry = entries.nextElement();
var name = entry.name;
// 以 org/bukkit/event 开头 并且以 .class 结尾
if (name.startsWith(eventPackageDir) && name.endsWith(".class")) {
var i = name.replaceAll('/', '.');
try {
var clz = base.getClass(i.substring(0, i.length - 6));
// 继承于 org.bukkit.event.Event 访问符为Public
if (isVaildEvent(clz)) {
// noinspection JSUnresolvedVariable
var simpleName = clz.simpleName.toLowerCase();
@ -51,9 +53,18 @@ function mapEventName() {
}
}
/**
* 判断是否为一个有效的事件类
* @param clz
* @returns {*|boolean}
*/
function isVaildEvent(clz) {
// noinspection JSUnresolvedVariable
return BukkitEvent.class.isAssignableFrom(clz) && Modifier.isPublic(clz.getModifiers()) && !Modifier.isAbstract(clz.getModifiers());
// noinspection JSUnresolvedVariable 继承于 org.bukkit.event.Event
return BukkitEvent.class.isAssignableFrom(clz) &&
// 访问符为Public
Modifier.isPublic(clz.getModifiers()) &&
// 不是抽象类
!Modifier.isAbstract(clz.getModifiers());
}
/**
@ -70,8 +81,8 @@ function listen(event, exec, priority, ignoreCancel) {
eventCls = base.getClass(eventCls);
} catch (ex) {
log.w("事件 %s 未找到!");
return;
}
return;
}
if (priority === undefined) {
priority = 'NORMAL'
@ -79,6 +90,7 @@ function listen(event, exec, priority, ignoreCancel) {
if (ignoreCancel === undefined) {
ignoreCancel = false;
}
var listener = new Listener({});
// noinspection JSUnusedGlobalSymbols
/**
* @param event Event type to register
@ -90,30 +102,41 @@ function listen(event, exec, priority, ignoreCancel) {
*/
Bukkit.getPluginManager().registerEvent(
eventCls,
new Listener({}),
listener,
EventPriority[priority],
new Java.extend(EventExecutor, {
new EventExecutor({
execute: function (listener, event) {
exec(event);
}
}),
plugin,
require('plugin').$,
ignoreCancel);
// noinspection JSUnresolvedVariable
log.d('注册事件 %s 方法 %s', eventCls.simpleName, exec.name === '' ? '匿名方法' : exec.name);
return {
event: eventCls,
listener: listener
}
}
// 映射事件名称
mapEventName();
exports.on = listen;
/**
* 取消事件监听
* @param listener 监听结果
*/
exports.off = function (listener) {
function unlisten(listener) {
if (!listener.event || !listener.listener) {
throw new IllegalStateException("非法的监听器对象 无法取消事件!");
}
listener.event.getMethod("getHandlerList").invoke(null).unregister(listener.listener);
// noinspection JSUnresolvedVariable
listener.event.handlerList.unregister(listener.listener);
log.d('注销事件 %s', eventCls.simpleName);
}
// 映射事件名称
mapEventName();
log.i('Bukkit 事件映射完毕 共计 %s 个事件!', mapEvent.length);
module.exports = {
on: listen,
off: unlisten
};

View File

@ -15,7 +15,7 @@ if (bukkit.plugin.load("PlaceholderAPI")) {
}
}
}
exports.$ = function (player, str) {
exports.$ = function () {
if (arguments.length > 1) {
return PlaceholderAPI.setPlaceholders(arguments[0], arguments[1]);
} else {

View File

@ -3,7 +3,7 @@
* MiaoScript脚本插件加载类
*/
/*global Java, base, module, exports, require, __FILE__*/
var zip = require("core/zip");
// var zip = require("core/zip");
var fs = require('core/fs');
/**
@ -56,37 +56,74 @@ function loadJsPlugin(files) {
return file.name.endsWith(".js")
}).forEach(function (file) {
var p = require(file);
log.d("插件编译结果: %s", JSON.stringify(p));
if (!p.description || !p.description.name) {
log.w("文件 %s 不存在 description 描述信息 无法加载插件!");
log.w("文件 %s 不存在 description 描述信息 无法加载插件!", file);
} else {
exports.plugins.push(p);
plugins.push(p);
plugins[p.description.name] = p;
log.i('插件 %s 版本 %s 加载成功!', p.description.name, p.description.version);
}
})
}
function runAndCatch(name, exec) {
if (exec) {
try {
exec();
} catch (ex) {
log.w('插件 %s 执行 %s 发生错误: %s', name, exec.name, ex.message);
ex.printStackTrace();
}
}
}
function checkAndGet(name) {
if (!exports.plugins[name]) {
throw new Error("插件 " + name + "不存在!");
}
return exports.plugins[name];
}
var plugins = [];
exports.$ = undefined;
exports.plugins = [];
exports.plugins = plugins;
exports.init = function (plugin, path) {
if (plugin !== null) {
// 如果过plugin不等于null 则代表是正式环境
exports.$ = plugin;
log.i("Init MiaoScript Engine Version: %s", plugin.description.version);
require('./event');
log.i("初始化 MiaoScript 插件系统 版本: %s", plugin.description.version);
}
loadPlugins(path);
};
exports.load = function () {
exports.plugins.forEach(function (p) {
p.load();
})
if (arguments.length === 0) {
plugins.forEach(function (p) {
runAndCatch(p.description.name, p.load);
})
} else {
var p = checkAndGet(arguments[0]);
runAndCatch(p.description.name, p.load);
}
};
exports.enable = function () {
exports.plugins.forEach(function (p) {
p.enable();
})
if (arguments.length === 0) {
plugins.forEach(function (p) {
runAndCatch(p.description.name, p.enable);
})
} else {
var p = checkAndGet(arguments[0]);
runAndCatch(p.description.name, p.enable);
}
};
exports.disable = function () {
exports.plugins.forEach(function (p) {
p.disable();
})
if (arguments.length === 0) {
plugins.forEach(function (p) {
runAndCatch(p.description.name, p.disable);
})
} else {
var p = checkAndGet(arguments[0]);
runAndCatch(p.description.name, p.disable);
}
};

View File

@ -0,0 +1,71 @@
'use strict';
/*global Java, base, module, exports, require, __FILE__*/
/**
* 任务计划
* Created by 蒋天蓓 on 2017/2/9 0009.
*/
var plugin = require('modules/plugin').$;
var BukkitRunnable = Java.type("org.bukkit.scheduler.BukkitRunnable");
/**
* 创建任务对象
* @param func 任务
*/
exports.create = function (func) {
return new BukkitRunnable(func);
};
/**
* 运行任务
* @param func 任务
*/
exports.run = function (func) {
return exports.create(func).runTask(plugin);
};
/**
* 延时运行任务
* @param func 任务
* @param time 延时时间
*/
exports.later = function (func, time) {
return exports.create(func).runTaskLater(plugin, time);
};
/**
* 运行循环任务
* @constructor (任务,执行间隔).
* @constructor (任务,首次延时,执行间隔)
*/
exports.timer = function () {
switch (arguments.length) {
case 2:
return exports.create(arguments[0]).runTaskTimer(plugin, 0, arguments[1]);
case 3:
return exports.create(arguments[0]).runTaskTimer(plugin, arguments[1], arguments[2]);
}
};
/**
* 运行异步任务
* @param func function 任务
*/
exports.async = function (func) {
return exports.create(func).runTaskAsynchronously(plugin);
};
/**
* 延时运行异步任务
* @param func 任务
* @param time 延时时间
*/
exports.laterAsync = function (func, time) {
return exports.create(func).runTaskLaterAsynchronously(plugin, time);
};
/**
* 运行异步循环任务
* @constructor (任务,执行间隔).
* @constructor (任务,首次延时,执行间隔)
*/
exports.timerAsync = function () {
switch (arguments.length) {
case 2:
return exports.create(arguments[0]).runTaskTimerAsynchronously(plugin, 0, arguments[1]);
case 3:
return exports.create(arguments[0]).runTaskTimerAsynchronously(plugin, arguments[1], arguments[2]);
}
};

View File

@ -11,6 +11,9 @@ commands:
description: ${project.artifactId} - ${project.description}
aliases:
- ms
- mjs
- script
- mscript
usage: §b使用/${project.artifactId} help 查看帮助!
permission: ${project.artifactId}.reload
permission-message: §c你没有 <permission> 的权限来执行此命令!

View File

@ -2,11 +2,12 @@
/**
* Hello Wrold 测试插件
*/
/*global Java, base, module, exports, require*/
var papi = require("modules/ext/papi");
var event = require('modules/event');
var join;
/*global Java, base, module, exports, require*/
var description = {
name: 'HelloWorld',
version: '1.0'
@ -18,9 +19,13 @@ function load() {
function enable() {
log.i('启用 Hello Wrold 测试插件!');
join = event.on('playerloginevent', function (event) {
join = event.on('playerloginevent', function join(event) {
// noinspection JSUnresolvedVariable
event.player.sendMessage(papi.$(event.player, "§a欢迎来到 §bMiaoScript §a的世界! 当前在线: %server_onlone%"));
log.d('玩家 %s 触发事件 %s', event.player.name, event.name);
setTimeout(function () {
// noinspection JSUnresolvedVariable
event.player.sendMessage(papi.$(event.player, "§a欢迎来到 §bMiaoScript §a的世界! 当前在线: %server_online%"));
}, 10);
});
}
@ -29,7 +34,7 @@ function disable() {
event.off(join);
}
exports = {
module.exports = {
description: description,
load: load,
enable: enable,

View File

@ -26,7 +26,7 @@ public class MiaoScriptTest {
try {
ScriptEngineManager manager = new ScriptEngineManager();
this.engine = new MiaoScriptEngine(manager);
this.engine.put("base", new MiaoScript.Base());
this.engine.put("base", new Base());
this.engine.eval(new FileReader("src/main/resources/bios.js"));
engine.invokeFunction("boot", null, engine);
} catch (Exception e) {