package top.sunsetlab.utils; import com.google.gson.Gson; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import top.sunsetlab.PluginMain; import top.sunsetlab.actions.ActionParam; import top.sunsetlab.actions.IActionBase; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; class ActionData { String id; String classname; boolean sync; } /** * Json定义的动作 */ public class JsonAction { private final ActionData data; /** * 构造器 * @param location 资源文件(json)的位置 */ public JsonAction(String location) { InputStream is = JsonAction.class.getResourceAsStream("/" + location); if (is == null) { throw new RuntimeException(location + " not found"); } BufferedReader br = new BufferedReader(new InputStreamReader(is)); Gson gson = new Gson(); data = gson.fromJson(br, ActionData.class); } /** * 调用动作 * @param location 调用位置 * @param caller 执行者 * @return 动作是否成功运行,sync动作始终为true */ public boolean run(Location location, Player caller, ActionParam param) { try { // 通过反射加载动作类 Class clazz = Class.forName(data.classname); if (!IActionBase.class.isAssignableFrom(clazz)) { throw new RuntimeException(data.classname + " is not a Action"); } // 获取构造器 Constructor constructor = clazz.getConstructor(); IActionBase action = (IActionBase) constructor.newInstance(); ActionParam p = param == null ? new ActionParam(new HashMap<>()): param; if (data.sync) { // 在Minecraft线程内执行,一般用于世界交互 Bukkit.getScheduler().runTask(PluginMain.plugin, () -> { action.call(location, caller, p); }); return true; }else { // 异步执行 return action.call(location, caller, p); } }catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new RuntimeException( "Something went wrong while trying to run action " + data.id + ":", e); } } /** * 获取动作id * @return 动作id */ public String getId() { return data.id; } }