From 2b8f103d4b5031e5e4afe1bf8ea355354edb026c Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Wed, 28 May 2025 02:47:55 +0800 Subject: [PATCH] =?UTF-8?q?feat(network):=20=E5=AE=8C=E5=96=84=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E7=AB=AF=E4=BE=A7=E7=89=A9=E5=93=81=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/network/BukkitNetworkManager.java | 25 +++++++++++++------ .../plugin/network/PacketConsumers.java | 5 ++-- .../plugin/network/id/PacketIdFinder.java | 20 +++++++++++++++ .../craftengine/bukkit/util/Reflections.java | 2 +- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java index 1bb9a7944..b874b9d27 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java @@ -9,6 +9,7 @@ import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; +import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIdFinder; import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIds1_20; import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIds1_20_5; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; @@ -40,9 +41,8 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes private static BukkitNetworkManager instance; private static final Map, TriConsumer> NMS_PACKET_HANDLERS = new HashMap<>(); // only for game stage for the moment - // todo 优化成 数组 - private static final Map> S2C_BYTE_BUFFER_PACKET_HANDLERS = new HashMap<>(); - private static final Map> C2S_BYTE_BUFFER_PACKET_HANDLERS = new HashMap<>(); + private static BiConsumer[] S2C_BYTE_BUFFER_PACKET_HANDLERS; + private static BiConsumer[] C2S_BYTE_BUFFER_PACKET_HANDLERS; private static void registerNMSPacketConsumer(final TriConsumer function, @Nullable Class packet) { if (packet == null) return; @@ -51,12 +51,18 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes private static void registerS2CByteBufPacketConsumer(final BiConsumer function, int id) { if (id == -1) return; - S2C_BYTE_BUFFER_PACKET_HANDLERS.put(id, function); + if (id < 0 || id >= S2C_BYTE_BUFFER_PACKET_HANDLERS.length) { + throw new IllegalArgumentException("Invalid packet id: " + id); + } + S2C_BYTE_BUFFER_PACKET_HANDLERS[id] = function; } private static void registerC2SByteBufPacketConsumer(final BiConsumer function, int id) { if (id == -1) return; - C2S_BYTE_BUFFER_PACKET_HANDLERS.put(id, function); + if (id < 0 || id >= C2S_BYTE_BUFFER_PACKET_HANDLERS.length) { + throw new IllegalArgumentException("Invalid packet id: " + id); + } + C2S_BYTE_BUFFER_PACKET_HANDLERS[id] = function; } private final BiConsumer> packetsConsumer; @@ -81,8 +87,13 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes private static boolean hasModelEngine; private static boolean hasViaVersion; + @SuppressWarnings("unchecked") public BukkitNetworkManager(BukkitCraftEngine plugin) { instance = this; + S2C_BYTE_BUFFER_PACKET_HANDLERS = new BiConsumer[PacketIdFinder.maxS2CPacketId() + 1]; + C2S_BYTE_BUFFER_PACKET_HANDLERS = new BiConsumer[PacketIdFinder.maxC2SPacketId() + 1]; + Arrays.fill(S2C_BYTE_BUFFER_PACKET_HANDLERS, (BiConsumer) (user, event) -> {}); + Arrays.fill(C2S_BYTE_BUFFER_PACKET_HANDLERS, (BiConsumer) (user, event) -> {}); hasModelEngine = Bukkit.getPluginManager().getPlugin("ModelEngine") != null; hasViaVersion = Bukkit.getPluginManager().getPlugin("ViaVersion") != null; this.plugin = plugin; @@ -647,13 +658,13 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes protected void handleS2CByteBufPacket(NetWorkUser user, ByteBufPacketEvent event) { int packetID = event.packetID(); - Optional.ofNullable(S2C_BYTE_BUFFER_PACKET_HANDLERS.get(packetID)) + Optional.ofNullable(S2C_BYTE_BUFFER_PACKET_HANDLERS[packetID]) .ifPresent(function -> function.accept(user, event)); } protected void handleC2SByteBufPacket(NetWorkUser user, ByteBufPacketEvent event) { int packetID = event.packetID(); - Optional.ofNullable(C2S_BYTE_BUFFER_PACKET_HANDLERS.get(packetID)) + Optional.ofNullable(C2S_BYTE_BUFFER_PACKET_HANDLERS[packetID]) .ifPresent(function -> function.accept(user, event)); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 7171b67f2..1f13e2383 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -2140,11 +2140,12 @@ public class PacketConsumers { buf.writeByte(buttonNum); buf.writeVarInt(clickType); buf.writeVarInt(changedSlots.size()); + Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); changedSlots.forEach((k, v) -> { buf.writeShort(k); - FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(buf, v); + FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, v); }); - FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(buf, carriedItem); + FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, carriedItem); } } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ServerboundContainerClickPacket", e); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIdFinder.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIdFinder.java index cff1f93b8..c399ea948 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIdFinder.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIdFinder.java @@ -6,12 +6,15 @@ import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.VersionHelper; +import java.util.Collections; import java.util.HashMap; import java.util.Map; public class PacketIdFinder { private static final Map> gamePacketIdsByName = new HashMap<>(); private static final Map, Integer>> gamePacketIdsByClazz = new HashMap<>(); + private static final int maxC2SPacketId; + private static final int maxS2CPacketId; static { try { @@ -34,6 +37,23 @@ public class PacketIdFinder { } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to get packets", e); } + maxS2CPacketId = calculateMaxId("clientbound"); + maxC2SPacketId = calculateMaxId("serverbound"); + } + private static int calculateMaxId(String direction) { + if (VersionHelper.isOrAbove1_20_5()) { + return gamePacketIdsByName.getOrDefault(direction, Collections.emptyMap()).size(); + } else { + return gamePacketIdsByClazz.getOrDefault(direction, Collections.emptyMap()).size(); + } + } + + public static int maxC2SPacketId() { + return maxC2SPacketId; + } + + public static int maxS2CPacketId() { + return maxS2CPacketId; } public static int clientboundByName(String packetName) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index fba7a0f92..d07de7afe 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -41,7 +41,7 @@ import java.util.function.Consumer; import static java.util.Objects.requireNonNull; -@SuppressWarnings("unused") +@SuppressWarnings({"unused", "unchecked"}) public class Reflections { public static void init() {