From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Sat, 13 Jul 2024 21:23:12 +0800 Subject: [PATCH] Optimize LeavesProtocolManager init protocol In original LeavesProtocolManager, it will init for all protocol support modules even they are disabled. And the "protocol support event" will be fired in every tick and when player joined to do the module enable check It is no necessary to check whether enable every tick..., so I changed the init part, it will only load enabled modules and will do init again when server reload or config reload diff --git a/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java index eb51acf0351769af0910ebb2d4a5abf542cbfb90..1e5d14690d92c7f9eccecd1cd0f3ecc6c90fc258 100644 --- a/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java +++ b/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java @@ -33,6 +33,10 @@ public class AppleSkinProtocol { private static final Map> subscribedChannels = new HashMap<>(); + public static boolean shouldEnable() { + return org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol; + } + @Contract("_ -> new") public static @NotNull ResourceLocation id(String path) { return new ResourceLocation(PROTOCOL_ID, path); @@ -40,17 +44,13 @@ public class AppleSkinProtocol { @ProtocolHandler.PlayerJoin public static void onPlayerLoggedIn(@NotNull ServerPlayer player) { - if (org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol) { - resetPlayerData(player); - } + resetPlayerData(player); } @ProtocolHandler.PlayerLeave public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { - if (org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol) { subscribedChannels.remove(player); resetPlayerData(player); - } } @ProtocolHandler.MinecraftRegister(ignoreId = true) @@ -62,7 +62,6 @@ public class AppleSkinProtocol { @ProtocolHandler.Ticker public static void tick() { - if (org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol) { if (MinecraftServer.getServer().getTickCount() % org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinSyncTickInterval != 0) { return; } @@ -102,7 +101,6 @@ public class AppleSkinProtocol { } } } - } } @ProtocolHandler.ReloadServer diff --git a/src/main/java/org/leavesmc/leaves/protocol/AsteorBarProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/AsteorBarProtocol.java index e6f3a52c3b6a23d8a8f7c4ae7828efa5dd51523e..1f22ebe756bd19afca3b7f826ff12cd6735da59f 100644 --- a/src/main/java/org/leavesmc/leaves/protocol/AsteorBarProtocol.java +++ b/src/main/java/org/leavesmc/leaves/protocol/AsteorBarProtocol.java @@ -30,6 +30,10 @@ public class AsteorBarProtocol { private static final Set players = new HashSet<>(); + public static boolean shouldEnable() { + return org.dreeam.leaf.config.modules.network.ProtocolSupport.asteorBarProtocol; + } + @Contract("_ -> new") public static @NotNull ResourceLocation id(String path) { return ResourceLocation.fromNamespaceAndPath(PROTOCOL_ID, path); @@ -37,29 +41,22 @@ public class AsteorBarProtocol { @ProtocolHandler.PlayerJoin public static void onPlayerLoggedIn(@NotNull ServerPlayer player) { - if (org.dreeam.leaf.config.modules.network.ProtocolSupport.asteorBarProtocol) { - resetPlayerData(player); - } + resetPlayerData(player); } @ProtocolHandler.PlayerLeave public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { - if (org.dreeam.leaf.config.modules.network.ProtocolSupport.asteorBarProtocol) { - players.remove(player); - resetPlayerData(player); - } + players.remove(player); + resetPlayerData(player); } @ProtocolHandler.MinecraftRegister(ignoreId = true) public static void onPlayerSubscribed(@NotNull ServerPlayer player) { - if (org.dreeam.leaf.config.modules.network.ProtocolSupport.asteorBarProtocol) { - players.add(player); - } + players.add(player); } @ProtocolHandler.Ticker public static void tick() { - if (org.dreeam.leaf.config.modules.network.ProtocolSupport.asteorBarProtocol) { for (ServerPlayer player : players) { FoodData data = player.getFoodData(); @@ -83,7 +80,6 @@ public class AsteorBarProtocol { previousExhaustionLevels.put(player.getUUID(), exhaustion); } } - } } @ProtocolHandler.ReloadServer diff --git a/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java index dd652437c0e999f0b523b69bca8f5803611ead6c..364922e9756193130608c51e052ddc9679854ced 100644 --- a/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java +++ b/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java @@ -31,6 +31,10 @@ public class ChatImageProtocol { public static int MAX_STRING = 532767; private static final Gson gson = new Gson(); + public static boolean shouldEnable() { + return org.dreeam.leaf.config.modules.network.ProtocolSupport.chatImageProtocol; + } + public record FileInfoChannelPacket( String message) implements LeavesCustomPayload { private static final ResourceLocation FILE_INFO = ChatImageProtocol.id("file_info"); diff --git a/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java index 9e35dfaf8bb5511b4cd0a71175d7ecb6d835042f..5ef19098512ae8a070dea270a68c27695c34624b 100644 --- a/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java +++ b/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java @@ -16,6 +16,10 @@ public class XaeroMapProtocol { private static final ResourceLocation MINIMAP_KEY = idMini("main"); private static final ResourceLocation WORLDMAP_KEY = idWorld("main"); + public static boolean shouldEnable() { + return org.dreeam.leaf.config.modules.network.ProtocolSupport.xaeroMapProtocol; + } + @Contract("_ -> new") public static @NotNull ResourceLocation idMini(String path) { return new ResourceLocation(PROTOCOL_ID_MINI, path); @@ -27,7 +31,7 @@ public class XaeroMapProtocol { } public static void onSendWorldInfo(@NotNull ServerPlayer player) { - if (org.dreeam.leaf.config.modules.network.ProtocolSupport.xaeroMapProtocol) { + if (shouldEnable()) { ProtocolUtils.sendPayloadPacket(player, MINIMAP_KEY, buf -> { buf.writeByte(0); buf.writeInt(org.dreeam.leaf.config.modules.network.ProtocolSupport.xaeroMapServerID); diff --git a/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java b/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java index 87b1502c1b980d33cae205ae35d336f7450e5e94..89cc2bc49c9a8d6ae5dd3ff10ac96e4282d9a727 100644 --- a/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java +++ b/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java @@ -10,30 +10,21 @@ import org.bukkit.event.player.PlayerKickEvent; import org.jetbrains.annotations.NotNull; import org.leavesmc.leaves.LeavesLogger; -import java.io.File; -import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Executable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.net.JarURLConnection; -import java.net.URL; -import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; public class LeavesProtocolManager { @@ -51,8 +42,16 @@ public class LeavesProtocolManager { private static final List RELOAD_SERVER = new ArrayList<>(); private static final Map> MINECRAFT_REGISTER = new HashMap<>(); + public static void reload() { + handleServerReload(); + cleanProtocols(); // Do cleanup + init(); + } + public static void init() { - for (Class clazz : getClasses("org.leavesmc.leaves.protocol")) { + boolean shouldEnable; + + for (Class clazz : org.dreeam.leaf.config.LeafConfig.getClasses("org.leavesmc.leaves.protocol")) { final LeavesProtocol protocol = clazz.getAnnotation(LeavesProtocol.class); if (protocol != null) { Set methods; @@ -62,7 +61,12 @@ public class LeavesProtocolManager { methods = new HashSet<>(publicMethods.length + privateMethods.length, 1.0f); Collections.addAll(methods, publicMethods); Collections.addAll(methods, privateMethods); - } catch (NoClassDefFoundError error) { + + Object instance = clazz.getConstructor().newInstance(); + Method method = clazz.getMethod("shouldEnable"); + shouldEnable = (boolean) method.invoke(instance); + } catch (NoClassDefFoundError | InvocationTargetException | InstantiationException | + IllegalAccessException | NoSuchMethodException error) { LOGGER.severe("Failed to load class " + clazz.getName() + " due to missing dependencies, " + error.getCause() + ": " + error.getMessage()); return; } @@ -75,6 +79,16 @@ public class LeavesProtocolManager { method.setAccessible(true); + final ProtocolHandler.ReloadServer reloadServer = method.getAnnotation(ProtocolHandler.ReloadServer.class); + if (reloadServer != null) { + RELOAD_SERVER.add(method); + continue; + } + + if (!shouldEnable) { + continue; + } + final ProtocolHandler.Init init = method.getAnnotation(ProtocolHandler.Init.class); if (init != null) { try { @@ -140,12 +154,6 @@ public class LeavesProtocolManager { continue; } - final ProtocolHandler.ReloadServer reloadServer = method.getAnnotation(ProtocolHandler.ReloadServer.class); - if (reloadServer != null) { - RELOAD_SERVER.add(method); - continue; - } - final ProtocolHandler.MinecraftRegister minecraftRegister = method.getAnnotation(ProtocolHandler.MinecraftRegister.class); if (minecraftRegister != null) { if (!MINECRAFT_REGISTER.containsKey(protocol)) { @@ -174,6 +182,17 @@ public class LeavesProtocolManager { ALL_KNOWN_ID = ImmutableSet.copyOf(ALL_KNOWN_ID); } + private static void cleanProtocols() { + KNOWN_TYPES.clear(); + KNOW_RECEIVERS.clear(); + //ALL_KNOWN_ID.clear(); // No need + TICKERS.clear(); + PLAYER_JOIN.clear(); + PLAYER_LEAVE.clear(); + //RELOAD_SERVER.clear(); // No need + MINECRAFT_REGISTER.clear(); + } + public static LeavesCustomPayload decode(ResourceLocation id, FriendlyByteBuf buf) { for (LeavesProtocol protocol : KNOWN_TYPES.keySet()) { if (!ArrayUtils.contains(protocol.namespace(), id.getNamespace())) { @@ -296,81 +315,6 @@ public class LeavesProtocolManager { } } - public static Set> getClasses(String pack) { - Set> classes = new LinkedHashSet<>(); - String packageDirName = pack.replace('.', '/'); - Enumeration dirs; - try { - dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName); - while (dirs.hasMoreElements()) { - URL url = dirs.nextElement(); - String protocol = url.getProtocol(); - if ("file".equals(protocol)) { - String filePath = URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8); - findClassesInPackageByFile(pack, filePath, classes); - } else if ("jar".equals(protocol)) { - JarFile jar; - try { - jar = ((JarURLConnection) url.openConnection()).getJarFile(); - Enumeration entries = jar.entries(); - findClassesInPackageByJar(pack, entries, packageDirName, classes); - } catch (IOException exception) { - LOGGER.warning("Failed to load jar file, " + exception.getCause() + ": " + exception.getMessage()); - } - } - } - } catch (IOException exception) { - LOGGER.warning("Failed to load classes, " + exception.getCause() + ": " + exception.getMessage()); - } - return classes; - } - - private static void findClassesInPackageByFile(String packageName, String packagePath, Set> classes) { - File dir = new File(packagePath); - if (!dir.exists() || !dir.isDirectory()) { - return; - } - File[] dirfiles = dir.listFiles((file) -> file.isDirectory() || file.getName().endsWith(".class")); - if (dirfiles != null) { - for (File file : dirfiles) { - if (file.isDirectory()) { - findClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), classes); - } else { - String className = file.getName().substring(0, file.getName().length() - 6); - try { - classes.add(Class.forName(packageName + '.' + className)); - } catch (ClassNotFoundException exception) { - LOGGER.warning("Failed to load class " + className + ", " + exception.getCause() + ": " + exception.getMessage()); - } - } - } - } - } - - private static void findClassesInPackageByJar(String packageName, Enumeration entries, String packageDirName, Set> classes) { - while (entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); - String name = entry.getName(); - if (name.charAt(0) == '/') { - name = name.substring(1); - } - if (name.startsWith(packageDirName)) { - int idx = name.lastIndexOf('/'); - if (idx != -1) { - packageName = name.substring(0, idx).replace('/', '.'); - } - if (name.endsWith(".class") && !entry.isDirectory()) { - String className = name.substring(packageName.length() + 1, name.length() - 6); - try { - classes.add(Class.forName(packageName + '.' + className)); - } catch (ClassNotFoundException exception) { - LOGGER.warning("Failed to load class " + className + ", " + exception.getCause() + ": " + exception.getMessage()); - } - } - } - } - } - public record ErrorPayload(ResourceLocation id, String[] protocolID, String[] packetID) implements LeavesCustomPayload { @Override public void write(@NotNull FriendlyByteBuf buf) { diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java index 3f21db1707c961242090f2edd54b72f233c59d79..a7d9bd324f8a83e0424194711af66f691172b3f6 100644 --- a/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java @@ -89,6 +89,10 @@ public class JadeProtocol { public static final PairHierarchyLookup> blockDataProviders = new PairHierarchyLookup<>(new HierarchyLookup<>(Block.class), new HierarchyLookup<>(BlockEntity.class)); public static final WrappedHierarchyLookup> itemStorageProviders = WrappedHierarchyLookup.forAccessor(); + public static boolean shouldEnable() { + return org.dreeam.leaf.config.modules.network.ProtocolSupport.jadeProtocol; + } + @Contract("_ -> new") public static @NotNull ResourceLocation id(String path) { return new ResourceLocation(PROTOCOL_ID, path); @@ -161,19 +165,11 @@ public class JadeProtocol { @ProtocolHandler.PlayerJoin public static void onPlayerJoin(ServerPlayer player) { - if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.jadeProtocol) { - return; - } - sendPingPacket(player); } @ProtocolHandler.PayloadReceiver(payload = RequestEntityPayload.class, payloadId = "request_entity") public static void requestEntityData(ServerPlayer player, RequestEntityPayload payload) { - if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.jadeProtocol) { - return; - } - MinecraftServer.getServer().execute(() -> { EntityAccessor accessor = payload.data().unpack(player); if (accessor == null) { @@ -210,10 +206,6 @@ public class JadeProtocol { @ProtocolHandler.PayloadReceiver(payload = RequestBlockPayload.class, payloadId = "request_block") public static void requestBlockData(ServerPlayer player, RequestBlockPayload payload) { - if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.jadeProtocol) { - return; - } - MinecraftServer server = MinecraftServer.getServer(); server.execute(() -> { BlockAccessor accessor = payload.data().unpack(player); diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java index 0704ac7825c69e69097b3e7c77763044f9fa9e1e..c039765237d56def91a1e630a0510062305fd585 100644 --- a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java @@ -48,6 +48,10 @@ public class CommunicationManager { public CommunicationManager() { } + public static boolean shouldEnable() { + return org.dreeam.leaf.config.modules.network.ProtocolSupport.syncmaticaProtocol; + } + public static GameProfile getGameProfile(final ExchangeTarget exchangeTarget) { return playerMap.get(exchangeTarget).getGameProfile(); } @@ -66,9 +70,6 @@ public class CommunicationManager { @ProtocolHandler.PlayerJoin public static void onPlayerJoin(ServerPlayer player) { - if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.syncmaticaProtocol) { - return; - } final ExchangeTarget newPlayer = player.connection.exchangeTarget; final VersionHandshakeServer hi = new VersionHandshakeServer(newPlayer); playerMap.put(newPlayer, player); @@ -79,9 +80,6 @@ public class CommunicationManager { @ProtocolHandler.PlayerLeave public static void onPlayerLeave(ServerPlayer player) { - if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.syncmaticaProtocol) { - return; - } final ExchangeTarget oldPlayer = player.connection.exchangeTarget; final Collection potentialMessageTarget = oldPlayer.getExchanges(); if (potentialMessageTarget != null) { @@ -96,9 +94,6 @@ public class CommunicationManager { @ProtocolHandler.PayloadReceiver(payload = SyncmaticaPayload.class, payloadId = "main") public static void onPacketGet(ServerPlayer player, SyncmaticaPayload payload) { - if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.syncmaticaProtocol) { - return; - } onPacket(player.connection.exchangeTarget, payload.packetType(), payload.data()); }