TabooLib v4.27
+ 修复 TFunction 注解会因为 onEnable/onDisable 方法不存在而报错的问题。 + 优化 TabooLibServer 模块,现在可以在服务器内启动终端,不需要另外运行插件。 + 优化 PacketParser 模块,现在会自动注册含有 @PacketType 注解的类,和 @TListener 一样方便。 + 增加 @PacketValue 注解,使用该直接的成员变量会被自动序列化。 “最近开发的机器人用到了通讯网,所以本次更新对该模块进行了反复测试和优化”
This commit is contained in:
parent
5b5a96464f
commit
de98b51c57
2
pom.xml
2
pom.xml
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>me.skymc</groupId>
|
||||
<artifactId>TabooLib</artifactId>
|
||||
<version>4.26</version>
|
||||
<version>4.27</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<Map.Entry<Integer, ClientConnection>> getConnection(int port) {
|
||||
return client.entrySet().stream().filter(entry -> entry.getKey().equals(port)).findFirst();
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -13,16 +13,6 @@ DATAURL:
|
||||
# 物品数据(来自 ItemSave 插件)
|
||||
ITEMDIR: 'plugins/Skript/scripts/config/item.yml'
|
||||
|
||||
# 是否启用调试模式
|
||||
# 启用后将收到来自其他插件的调试信息
|
||||
DEBUG: false
|
||||
|
||||
# 网络连接测试地址
|
||||
TEST-URL: 'aliyun.com'
|
||||
|
||||
# 下载依赖时启用的线程数
|
||||
DOWNLOAD-POOL-SIZE: 4
|
||||
|
||||
# 语言文件相关设置
|
||||
LOCALE:
|
||||
# 加载语言文件的顺序
|
||||
@ -34,6 +24,20 @@ LOCALE:
|
||||
# 如果需要开启仍然可以在语言文件中加入 papi: true
|
||||
USE_PAPI: false
|
||||
|
||||
# 是否启用调试模式
|
||||
# 启用后将收到来自其他插件的调试信息
|
||||
DEBUG: false
|
||||
|
||||
# 是否在当前服务器启用交流网终端
|
||||
# 启用后将会收到大量调试信息, 不建议使用
|
||||
SERVER: false
|
||||
|
||||
# 网络连接测试地址
|
||||
TEST-URL: 'aliyun.com'
|
||||
|
||||
# 下载依赖时启用的线程数
|
||||
DOWNLOAD-POOL-SIZE: 4
|
||||
|
||||
# 玩家列表(TAB-API)是否根据前缀排序
|
||||
TABLIST-SORT: true
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user