diff --git a/pom.xml b/pom.xml index 67dc6fb..c45afe4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.skymc TabooLib - 4.26 + 4.27 UTF-8 diff --git a/src/main/java/me/skymc/taboolib/Main.java b/src/main/java/me/skymc/taboolib/Main.java index 7e36788..7913663 100644 --- a/src/main/java/me/skymc/taboolib/Main.java +++ b/src/main/java/me/skymc/taboolib/Main.java @@ -23,6 +23,7 @@ import me.skymc.taboolib.permission.PermissionUtils; import me.skymc.taboolib.playerdata.DataUtils; import me.skymc.taboolib.skript.SkriptHandler; import me.skymc.taboolib.socket.TabooLibClient; +import me.skymc.taboolib.socket.TabooLibServer; import me.skymc.taboolib.string.language2.Language2; import me.skymc.taboolib.support.SupportPlaceholder; import me.skymc.taboolib.timecycle.TimeCycleManager; @@ -163,6 +164,10 @@ public class Main extends JavaPlugin { } } catch (IOException ignored) { } + // 本地通讯网络终端 + if (getConfig().getBoolean("SERVER")) { + TabooLibServer.main(new String[0]); + } // 本地通讯网络 TabooLibClient.init(); } diff --git a/src/main/java/me/skymc/taboolib/common/function/TFunctionLoader.java b/src/main/java/me/skymc/taboolib/common/function/TFunctionLoader.java index 9ef819f..038e3f2 100644 --- a/src/main/java/me/skymc/taboolib/common/function/TFunctionLoader.java +++ b/src/main/java/me/skymc/taboolib/common/function/TFunctionLoader.java @@ -40,14 +40,10 @@ public class TFunctionLoader implements Listener { TFunction function = (TFunction) pluginClass.getAnnotation(TFunction.class); try { Method method = pluginClass.getDeclaredMethod(function.enable()); - if (method == null) { - continue; - } method.setAccessible(true); method.invoke(pluginClass.newInstance()); pluginFunction.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(pluginClass); - } catch (Exception e) { - e.printStackTrace(); + } catch (Exception ignored) { } } } @@ -65,13 +61,9 @@ public class TFunctionLoader implements Listener { TFunction function = (TFunction) pluginClass.getAnnotation(TFunction.class); try { Method method = pluginClass.getDeclaredMethod(function.disable()); - if (method == null) { - continue; - } method.setAccessible(true); method.invoke(pluginClass.newInstance()); - } catch (Exception e) { - e.printStackTrace(); + } catch (Exception ignored) { } } } diff --git a/src/main/java/me/skymc/taboolib/socket/TabooLibServer.java b/src/main/java/me/skymc/taboolib/socket/TabooLibServer.java index 42dd99b..24f7fa7 100644 --- a/src/main/java/me/skymc/taboolib/socket/TabooLibServer.java +++ b/src/main/java/me/skymc/taboolib/socket/TabooLibServer.java @@ -1,11 +1,13 @@ package me.skymc.taboolib.socket; +·import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.other.NumberUtils; import me.skymc.taboolib.socket.packet.Packet; import me.skymc.taboolib.socket.packet.PacketSerializer; import me.skymc.taboolib.socket.packet.impl.PacketHeartbeat; import me.skymc.taboolib.socket.packet.impl.PacketQuit; import me.skymc.taboolib.socket.server.ClientConnection; +import org.bukkit.Bukkit; import java.io.IOException; import java.net.ServerSocket; @@ -58,17 +60,22 @@ public class TabooLibServer { client.entrySet().stream().filter(connection -> !connection.getValue().isAlive()).map(connection -> new PacketQuit(connection.getKey(), "Lost connection")).forEach(TabooLibServer::sendPacket); }, 0, 1, TimeUnit.SECONDS); - while (true) { - try { - Socket socket = server.accept(); - ClientConnection connection = new ClientConnection(socket); - client.put(socket.getPort(), connection); - executorService.execute(connection); - println("Client accepted: " + socket.getPort() + " online: " + client.size()); - } catch (Exception e) { - println("Client accept failed: " + e.toString()); + /* + 异步接收连接请求 + */ + Executors.newSingleThreadScheduledExecutor().execute(() -> { + while (true) { + try { + Socket socket = server.accept(); + ClientConnection connection = new ClientConnection(socket); + client.put(socket.getPort(), connection); + executorService.execute(connection); + println("Client accepted: " + socket.getPort() + " online: " + client.size()); + } catch (Exception e) { + println("Client accept failed: " + e.toString()); + } } - } + }); } public static void sendPacket(Packet packet) { @@ -89,10 +96,9 @@ public class TabooLibServer { } public static void println(Object obj) { - System.out.println("[" + infoFormat.format(System.currentTimeMillis()) + " INFO]: " + obj); + System.out.println(TabooLib.isSpigot() ? obj : "[" + infoFormat.format(System.currentTimeMillis()) + " INFO]: " + obj); } - public static Optional> getConnection(int port) { return client.entrySet().stream().filter(entry -> entry.getKey().equals(port)).findFirst(); } diff --git a/src/main/java/me/skymc/taboolib/socket/packet/PacketParser.java b/src/main/java/me/skymc/taboolib/socket/packet/PacketParser.java index 0f733fd..c77cd31 100644 --- a/src/main/java/me/skymc/taboolib/socket/packet/PacketParser.java +++ b/src/main/java/me/skymc/taboolib/socket/packet/PacketParser.java @@ -4,6 +4,7 @@ import com.google.gson.JsonObject; import me.skymc.taboolib.fileutils.FileUtils; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -31,6 +32,43 @@ public class PacketParser { try { Packet packetObject = (Packet) packetFind.get().getConstructor(Integer.TYPE).newInstance(json.get("port").getAsInt()); packetObject.unSerialize(json); + Arrays.stream(packetObject.getClass().getDeclaredFields()).filter(field -> field.isAnnotationPresent(PacketValue.class)).forEach(field -> { + field.setAccessible(true); + try { + switch (field.getType().getSimpleName().toLowerCase()) { + case "double": + field.set(packetObject, json.get(field.getName()).getAsDouble()); + break; + case "long": + field.set(packetObject, json.get(field.getName()).getAsLong()); + break; + case "short": + field.set(packetObject, json.get(field.getName()).getAsShort()); + break; + case "boolean": + field.set(packetObject, json.get(field.getName()).getAsBoolean()); + break; + case "string": + field.set(packetObject, json.get(field.getName()).getAsString()); + break; + case "number": + field.set(packetObject, json.get(field.getName()).getAsNumber()); + break; + case "int": + case "integer": + field.set(packetObject, json.get(field.getName()).getAsInt()); + break; + case "char": + case "character": + field.set(packetObject, json.get(field.getName()).getAsCharacter()); + break; + default: + System.out.println("UnSerialize: Invalid packet value: " + field.getName()); + } + } catch (Exception e) { + e.printStackTrace(); + } + }); return packetObject; } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/me/skymc/taboolib/socket/packet/PacketSerializer.java b/src/main/java/me/skymc/taboolib/socket/packet/PacketSerializer.java index 2ec3b94..ddd5aeb 100644 --- a/src/main/java/me/skymc/taboolib/socket/packet/PacketSerializer.java +++ b/src/main/java/me/skymc/taboolib/socket/packet/PacketSerializer.java @@ -3,22 +3,88 @@ package me.skymc.taboolib.socket.packet; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.TabooLibLoader; +import me.skymc.taboolib.listener.TListener; import me.skymc.taboolib.socket.packet.impl.PacketEmpty; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.event.server.PluginEnableEvent; +import org.bukkit.plugin.Plugin; + +import java.lang.reflect.Field; +import java.util.Arrays; /** * @Author sky * @Since 2018-08-22 23:32 */ -public class PacketSerializer { +@TListener +public class PacketSerializer implements Listener { private static PacketParser parser = new PacketParser(); + public PacketSerializer() { + loadPacket(); + } + + @EventHandler + public void onEnable(PluginEnableEvent e) { + loadPacket(e.getPlugin()); + } + + @EventHandler + public void onDisable(PluginDisableEvent e) { + unloadPacket(e.getPlugin()); + } + + public static void loadPacket() { + Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(PacketSerializer::loadPacket); + } + + public static void loadPacket(Plugin plugin) { + if (TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin)) { + TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> classes.stream().filter(pluginClass -> pluginClass.isAnnotationPresent(PacketType.class)).forEach(pluginClass -> parser.getPackets().add(pluginClass))); + } + } + + public static void unloadPacket() { + Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(PacketSerializer::unloadPacket); + } + + public static void unloadPacket(Plugin plugin) { + if (TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin)) { + TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> classes.stream().filter(pluginClass -> pluginClass.isAnnotationPresent(PacketType.class)).forEach(pluginClass -> parser.getPackets().remove(pluginClass))); + } + } + public static String serialize(Packet packet) { JsonObject json = new JsonObject(); + packet.serialize(json); json.addProperty("uid", packet.getUid()); json.addProperty("port", packet.getPort()); json.addProperty("packet", packet.getClass().getAnnotation(PacketType.class).name()); - packet.serialize(json); + Arrays.stream(packet.getClass().getDeclaredFields()).filter(field -> field.isAnnotationPresent(PacketValue.class)).forEach(field -> { + field.setAccessible(true); + try { + Object obj = field.get(packet); + if (obj instanceof Number) { + json.addProperty(field.getName(), (Number) obj); + } else if (obj instanceof Boolean) { + json.addProperty(field.getName(), (Boolean) obj); + } else if (obj instanceof String) { + json.addProperty(field.getName(), (String) obj); + } else if (obj instanceof Character) { + json.addProperty(field.getName(), (Character) obj); + } else { + System.out.println("Serialize: Invalid packet value: " + field.getName()); + } + } catch (Exception e) { + e.printStackTrace(); + } + }); return json.toString(); } diff --git a/src/main/java/me/skymc/taboolib/socket/packet/PacketValue.java b/src/main/java/me/skymc/taboolib/socket/packet/PacketValue.java new file mode 100644 index 0000000..c3166ea --- /dev/null +++ b/src/main/java/me/skymc/taboolib/socket/packet/PacketValue.java @@ -0,0 +1,25 @@ +package me.skymc.taboolib.socket.packet; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 使用该注解的成员变量 + * 将会被自动序列化 + * + * 仅限以下类型: + * - Number + * - String + * - Boolean + * - Character + * + * @Author sky + * @Since 2018-08-22 23:09 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface PacketValue { + +} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketCommand.java b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketCommand.java index 12ecab9..ac1bcb4 100644 --- a/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketCommand.java +++ b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketCommand.java @@ -1,10 +1,9 @@ package me.skymc.taboolib.socket.packet.impl; -import com.google.gson.JsonObject; -import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.socket.TabooLibServer; import me.skymc.taboolib.socket.packet.Packet; import me.skymc.taboolib.socket.packet.PacketType; +import me.skymc.taboolib.socket.packet.PacketValue; import org.bukkit.Bukkit; /** @@ -14,6 +13,7 @@ import org.bukkit.Bukkit; @PacketType(name = "command") public class PacketCommand extends Packet { + @PacketValue private String command; public PacketCommand(int port) { @@ -34,18 +34,4 @@ public class PacketCommand extends Packet { TabooLibServer.sendPacket(new PacketMessage(0, "Invalid arguments.")); } } - - @Override - public void readOnClient() { - } - - @Override - public void serialize(JsonObject json) { - json.addProperty("command", this.command); - } - - @Override - public void unSerialize(JsonObject json) { - this.command = json.get("command").getAsString(); - } } diff --git a/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketMessage.java b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketMessage.java index 9721d46..9cc9698 100644 --- a/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketMessage.java +++ b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketMessage.java @@ -5,6 +5,7 @@ import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.socket.TabooLibServer; import me.skymc.taboolib.socket.packet.Packet; import me.skymc.taboolib.socket.packet.PacketType; +import me.skymc.taboolib.socket.packet.PacketValue; import org.bukkit.Bukkit; /** @@ -14,6 +15,7 @@ import org.bukkit.Bukkit; @PacketType(name = "message") public class PacketMessage extends Packet { + @PacketValue private String message; public PacketMessage(int port) { @@ -39,14 +41,4 @@ public class PacketMessage extends Packet { public void readOnClient() { TLocale.sendToConsole("COMMUNICATION.PACKET-MESSAGE", String.valueOf(getPort()), message); } - - @Override - public void serialize(JsonObject json) { - json.addProperty("message", message); - } - - @Override - public void unSerialize(JsonObject json) { - message = json.get("message").getAsString(); - } } diff --git a/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketQuit.java b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketQuit.java index cdb740c..fcb46fd 100644 --- a/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketQuit.java +++ b/src/main/java/me/skymc/taboolib/socket/packet/impl/PacketQuit.java @@ -1,10 +1,10 @@ package me.skymc.taboolib.socket.packet.impl; -import com.google.gson.JsonObject; import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.socket.TabooLibServer; import me.skymc.taboolib.socket.packet.Packet; import me.skymc.taboolib.socket.packet.PacketType; +import me.skymc.taboolib.socket.packet.PacketValue; /** * @Author sky @@ -13,6 +13,7 @@ import me.skymc.taboolib.socket.packet.PacketType; @PacketType(name = "quit") public class PacketQuit extends Packet { + @PacketValue private String message; public PacketQuit(int port) { @@ -43,14 +44,4 @@ public class PacketQuit extends Packet { public void readOnClient() { TLocale.sendToConsole("COMMUNICATION.CLIENT-QUITED", String.valueOf(getPort())); } - - @Override - public void serialize(JsonObject json) { - json.addProperty("message", message); - } - - @Override - public void unSerialize(JsonObject json) { - message = json.get("message").getAsString(); - } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index ae069c3..3fad166 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -13,16 +13,6 @@ DATAURL: # 物品数据(来自 ItemSave 插件) ITEMDIR: 'plugins/Skript/scripts/config/item.yml' -# 是否启用调试模式 -# 启用后将收到来自其他插件的调试信息 -DEBUG: false - -# 网络连接测试地址 -TEST-URL: 'aliyun.com' - -# 下载依赖时启用的线程数 -DOWNLOAD-POOL-SIZE: 4 - # 语言文件相关设置 LOCALE: # 加载语言文件的顺序 @@ -33,6 +23,20 @@ LOCALE: # 关闭可提升性能 # 如果需要开启仍然可以在语言文件中加入 papi: true USE_PAPI: false + +# 是否启用调试模式 +# 启用后将收到来自其他插件的调试信息 +DEBUG: false + +# 是否在当前服务器启用交流网终端 +# 启用后将会收到大量调试信息, 不建议使用 +SERVER: false + +# 网络连接测试地址 +TEST-URL: 'aliyun.com' + +# 下载依赖时启用的线程数 +DOWNLOAD-POOL-SIZE: 4 # 玩家列表(TAB-API)是否根据前缀排序 TABLIST-SORT: true