From ad040bed39020261fd3b5a47cfae62aae65e9575 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Fri, 25 Apr 2025 13:16:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(network):=20=E6=B7=BB=E5=8A=A0=E6=A3=80?= =?UTF-8?q?=E6=B5=8B=E5=AE=A2=E6=88=B7=E7=AB=AF=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bukkit/compatibility/build.gradle.kts | 3 ++ .../viaversion/ViaVersionProtocol.java | 27 ++++++++++ .../plugin/network/BukkitNetworkManager.java | 16 ++++-- .../plugin/network/PacketConsumers.java | 26 ++++++++++ .../plugin/user/BukkitServerPlayer.java | 13 +++++ .../craftengine/bukkit/util/Reflections.java | 19 +++++++ .../core/plugin/network/NetWorkUser.java | 4 ++ .../core/plugin/network/ProtocolVersion.java | 52 +++++++++++++++++++ .../core/util/ProtocolVersionUtils.java | 10 ++++ 9 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/viaversion/ViaVersionProtocol.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/plugin/network/ProtocolVersion.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/util/ProtocolVersionUtils.java diff --git a/bukkit/compatibility/build.gradle.kts b/bukkit/compatibility/build.gradle.kts index 0165818bd..8b95c7872 100644 --- a/bukkit/compatibility/build.gradle.kts +++ b/bukkit/compatibility/build.gradle.kts @@ -9,6 +9,7 @@ repositories { maven("https://repo.momirealms.net/releases/") maven("https://mvn.lumine.io/repository/maven-public/") // model engine maven("https://nexus.phoenixdevt.fr/repository/maven-public/") // mmoitems + maven("https://repo.viaversion.com") // via } dependencies { @@ -34,6 +35,8 @@ dependencies { compileOnly("io.lumine:MythicLib-dist:1.6.2-SNAPSHOT") // LuckPerms compileOnly("net.luckperms:api:5.4") + // viaversion + compileOnly("com.viaversion:viaversion-api:5.3.2") } java { diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/viaversion/ViaVersionProtocol.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/viaversion/ViaVersionProtocol.java new file mode 100644 index 000000000..53ef4f5e5 --- /dev/null +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/viaversion/ViaVersionProtocol.java @@ -0,0 +1,27 @@ +package net.momirealms.craftengine.bukkit.compatibility.viaversion; + +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.ViaAPI; + +import java.util.UUID; + + +public class ViaVersionProtocol { + private final boolean hasPlugin; + private final ViaAPI viaAPI; + + public ViaVersionProtocol(boolean hasPlugin) { + this.hasPlugin = hasPlugin; + this.viaAPI = hasPlugin ? Via.getAPI() : null; + } + + public int getPlayerProtocolVersion(UUID uuid) { + if (!hasPlugin) return -1; + System.out.println(this.viaAPI.getPlayerProtocolVersion(uuid).getVersion()); + return this.viaAPI.getPlayerProtocolVersion(uuid).getVersion(); + } + + public boolean hasPlugin() { + return hasPlugin; + } +} 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 c5160f6db..177e310c6 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 @@ -6,6 +6,7 @@ import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; +import net.momirealms.craftengine.bukkit.compatibility.viaversion.ViaVersionProtocol; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIds1_20; @@ -16,10 +17,8 @@ import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.network.ConnectionState; import net.momirealms.craftengine.core.plugin.network.NetWorkUser; import net.momirealms.craftengine.core.plugin.network.NetworkManager; -import net.momirealms.craftengine.core.util.FriendlyByteBuf; -import net.momirealms.craftengine.core.util.ListMonitor; -import net.momirealms.craftengine.core.util.TriConsumer; -import net.momirealms.craftengine.core.util.VersionHelper; +import net.momirealms.craftengine.core.plugin.network.ProtocolVersion; +import net.momirealms.craftengine.core.util.*; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -57,6 +56,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes private final BiConsumer packetConsumer; private final BiConsumer immediatePacketConsumer; private final BukkitCraftEngine plugin; + private final ViaVersionProtocol viaVersionProtocol; private final Map users = new ConcurrentHashMap<>(); private final Map onlineUsers = new ConcurrentHashMap<>(); @@ -77,6 +77,8 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes instance = this; hasModelEngine = Bukkit.getPluginManager().getPlugin("ModelEngine") != null; this.plugin = plugin; + // hook via + this.viaVersionProtocol = new ViaVersionProtocol(Bukkit.getPluginManager().getPlugin("ViaVersion") != null); // set up packet id this.packetIds = setupPacketIds(); // register packet handlers @@ -147,6 +149,8 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerNMSPacketConsumer(PacketConsumers.EDIT_BOOK, Reflections.clazz$ServerboundEditBookPacket); registerNMSPacketConsumer(PacketConsumers.CUSTOM_PAYLOAD, Reflections.clazz$ServerboundCustomPayloadPacket); registerNMSPacketConsumer(PacketConsumers.RESOURCE_PACK_PUSH, Reflections.clazz$ClientboundResourcePackPushPacket); + registerNMSPacketConsumer(PacketConsumers.HANDSHAKE_C2S, Reflections.clazz$ClientIntentionPacket); + registerNMSPacketConsumer(PacketConsumers.LOGIN_ACKNOWLEDGED, Reflections.clazz$ServerboundLoginAcknowledgedPacket); registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket()); registerByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket()); registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_21_3() ? PacketConsumers.LEVEL_PARTICLE_1_21_3 : (VersionHelper.isVersionNewerThan1_20_5() ? PacketConsumers.LEVEL_PARTICLE_1_20_5 : PacketConsumers.LEVEL_PARTICLE_1_20), this.packetIds.clientboundLevelParticlesPacket()); @@ -620,4 +624,8 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes } return output; } + + public ViaVersionProtocol viaVersionProtocol() { + return this.viaVersionProtocol; + } } 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 719667520..6d9c235f1 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 @@ -10,6 +10,7 @@ import net.momirealms.craftengine.bukkit.api.event.FurnitureBreakEvent; import net.momirealms.craftengine.bukkit.api.event.FurnitureInteractEvent; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.compatibility.modelengine.ModelEngineUtils; +import net.momirealms.craftengine.bukkit.compatibility.viaversion.ViaVersionProtocol; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture; import net.momirealms.craftengine.bukkit.item.behavior.FurnitureItemBehavior; @@ -1248,6 +1249,10 @@ public class PacketConsumers { player.setConnectionState(ConnectionState.PLAY); Object dimensionKey; if (!VersionHelper.isVersionNewerThan1_20_2()) { + ViaVersionProtocol viaVersionProtocol = BukkitNetworkManager.instance().viaVersionProtocol(); + if (viaVersionProtocol.hasPlugin()) { + user.setProtocolVersion(viaVersionProtocol.getPlayerProtocolVersion(player.uuid())); + } dimensionKey = Reflections.field$ClientboundLoginPacket$dimension.get(packet); } else { Object commonInfo = Reflections.field$ClientboundLoginPacket$commonPlayerSpawnInfo.get(packet); @@ -2178,4 +2183,25 @@ public class PacketConsumers { CraftEngine.instance().logger().warn("Failed to handle ClientboundResourcePackPushPacket", e); } }; + + public static final TriConsumer HANDSHAKE_C2S = (user, event, packet) -> { + try { + if (BukkitNetworkManager.instance().viaVersionProtocol().hasPlugin()) return; + int protocolVersion = Reflections.field$ClientIntentionPacket$protocolVersion.getInt(packet); + user.setProtocolVersion(protocolVersion); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientIntentionPacket", e); + } + }; + + public static final TriConsumer LOGIN_ACKNOWLEDGED = (user, event, packet) -> { + try { + ViaVersionProtocol viaVersionProtocol = BukkitNetworkManager.instance().viaVersionProtocol(); + if (viaVersionProtocol.hasPlugin()) { + user.setProtocolVersion(viaVersionProtocol.getPlayerProtocolVersion(user.uuid())); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ServerboundLoginAcknowledgedPacket", e); + } + }; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java index bd873f8e8..6028093da 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java @@ -18,6 +18,7 @@ import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.network.ConnectionState; +import net.momirealms.craftengine.core.plugin.network.ProtocolVersion; import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; @@ -39,6 +40,8 @@ import java.util.concurrent.ConcurrentHashMap; public class BukkitServerPlayer extends Player { private final BukkitCraftEngine plugin; + // handshake + private ProtocolVersion protocolVersion = ProtocolVersion.UNKNOWN; // connection state private final Channel channel; private String name; @@ -758,6 +761,16 @@ public class BukkitServerPlayer extends Player { } } + @Override + public ProtocolVersion protocolVersion() { + return this.protocolVersion; + } + + @Override + public void setProtocolVersion(int protocolVersion) { + this.protocolVersion = ProtocolVersion.getById(protocolVersion); + } + @Override public void clearView() { this.entityTypeView.clear(); 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 cba4df44f..b0e8836bd 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 @@ -6521,4 +6521,23 @@ public class Reflections { "core.component.DataComponentType" ) ); + + public static final Class clazz$ClientIntentionPacket = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("network.protocol.handshake.ClientIntentionPacket"), + BukkitReflectionUtils.assembleMCClass("network.protocol.handshake.PacketHandshakingInSetProtocol") + ) + ); + + public static final Field field$ClientIntentionPacket$protocolVersion = requireNonNull( + ReflectionUtils.getDeclaredField( + clazz$ClientIntentionPacket, int.class, VersionHelper.isVersionNewerThan1_20_2() ? 0 : 1 + ) + ); + + // 1.20.2+ + public static final Class clazz$ServerboundLoginAcknowledgedPacket = + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("network.protocol.login.ServerboundLoginAcknowledgedPacket") + ); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java index f2a8b8d2d..3c84bf63c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/NetWorkUser.java @@ -51,4 +51,8 @@ public interface NetWorkUser { void setClientModState(boolean enable); void addResourcePackUUID(UUID uuid); + + ProtocolVersion protocolVersion(); + + void setProtocolVersion(int protocolVersion); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/network/ProtocolVersion.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/ProtocolVersion.java new file mode 100644 index 000000000..c692c6da6 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/network/ProtocolVersion.java @@ -0,0 +1,52 @@ +package net.momirealms.craftengine.core.plugin.network; + +public enum ProtocolVersion { + UNKNOWN(-1, "Unknown"), + V1_20(763, "1.20"), + V1_20_1(763, "1.20.1"), + V1_20_2(764, "1.20.2"), + V1_20_3(765, "1.20.3"), + V1_20_4(765, "1.20.4"), + V1_20_5(766, "1.20.5"), + V1_20_6(766, "1.20.6"), + V1_21(767, "1.21"), + V1_21_1(767, "1.21.1"), + V1_21_2(768, "1.21.2"), + V1_21_3(768, "1.21.3"), + V1_21_4(769, "1.21.4"), + V1_21_5(770, "1.21.5"); + + private final int id; + private final String name; + + ProtocolVersion(int id, String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public static ProtocolVersion getByName(String name) { + for (ProtocolVersion version : values()) { + if (version.getName().equals(name)) { + return version; + } + } + return UNKNOWN; + } + + public static ProtocolVersion getById(int id) { + for (ProtocolVersion version : values()) { + if (version.getId() == id) { + return version; + } + } + return UNKNOWN; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/ProtocolVersionUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/ProtocolVersionUtils.java new file mode 100644 index 000000000..8372e1117 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/util/ProtocolVersionUtils.java @@ -0,0 +1,10 @@ +package net.momirealms.craftengine.core.util; + +import net.momirealms.craftengine.core.plugin.network.ProtocolVersion; + +public class ProtocolVersionUtils { + + public static boolean isVersionNewerThan(ProtocolVersion version, ProtocolVersion targetVersion) { + return version.getId() >= targetVersion.getId(); + } +}