TabooLib v4.27
+ 修复 TFunction 注解会因为 onEnable/onDisable 方法不存在而报错的问题。 + 优化 TabooLibServer 模块,现在可以在服务器内启动终端,不需要另外运行插件。 + 优化 PacketParser 模块,现在会自动注册含有 @PacketType 注解的类,和 @TListener 一样方便。 + 增加 @PacketValue 注解,使用该直接的成员变量会被自动序列化。 “最近开发的机器人用到了通讯网,所以本次更新对该模块进行了反复测试和优化”
This commit is contained in:
		
							
								
								
									
										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,6 +60,10 @@ 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);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
            异步接收连接请求
 | 
			
		||||
         */
 | 
			
		||||
        Executors.newSingleThreadScheduledExecutor().execute(() -> {
 | 
			
		||||
            while (true) {
 | 
			
		||||
                try {
 | 
			
		||||
                    Socket socket = server.accept();
 | 
			
		||||
@@ -69,6 +75,7 @@ public class TabooLibServer {
 | 
			
		||||
                    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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user