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 b1c8bc67f..bcb2ff7c4 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 @@ -46,6 +46,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes } private static void registerByteBufPacketConsumer(final BiConsumer function, int id) { + if (id == -1) return; BYTE_BUFFER_PACKET_HANDLERS.put(id, function); } @@ -156,6 +157,10 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerByteBufPacketConsumer(PacketConsumers.LEVEL_PARTICLE, this.packetIds.clientboundLevelParticlesPacket()); registerByteBufPacketConsumer(PacketConsumers.LEVEL_EVENT, this.packetIds.clientboundLevelEventPacket()); registerByteBufPacketConsumer(PacketConsumers.OPEN_SCREEN, this.packetIds.clientboundOpenScreenPacket()); + // registerByteBufPacketConsumer(PacketConsumers.REMOVE_ENTITY, this.packetIds.clientboundRemoveEntitiesPacket()); + registerByteBufPacketConsumer(PacketConsumers.ADD_ENTITY_BYTEBUFFER, this.packetIds.clientboundAddEntityPacket()); + // registerByteBufPacketConsumer(PacketConsumers.SOUND, this.packetIds.clientboundSoundPacket()); + // registerByteBufPacketConsumer(PacketConsumers.SET_ENTITY_DATA, this.packetIds.clientboundSetEntityDataPacket()); } public static BukkitNetworkManager instance() { 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 582ce1793..7acfeea64 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 @@ -244,10 +244,10 @@ public class PacketConsumers { public static final BiConsumer OPEN_SCREEN = (user, event) -> { try { + FriendlyByteBuf buf = event.getBuffer(); + int containerId = buf.readVarInt(); + int type = buf.readVarInt(); if (VersionHelper.isVersionNewerThan1_20_3()) { - FriendlyByteBuf buf = event.getBuffer(); - int containerId = buf.readVarInt(); - int type = buf.readVarInt(); Tag nbt = buf.readNbt(false); if (nbt == null) return; Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); @@ -262,9 +262,6 @@ public class PacketConsumers { buf.writeVarInt(type); buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false); } else { - FriendlyByteBuf buf = event.getBuffer(); - int containerId = buf.readVarInt(); - int type = buf.readVarInt(); String json = buf.readUtf(); Map tokens = CraftEngine.instance().imageManager().matchTags(json); if (tokens.isEmpty()) return; @@ -656,18 +653,55 @@ public class PacketConsumers { Reflections.field$ServerPlayer$connection.get(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)), FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack)); } - // TODO USE bytebuffer + public static final BiConsumer ADD_ENTITY_BYTEBUFFER = (user, event) -> { + try { + FriendlyByteBuf buf = event.getBuffer(); + int id = buf.readVarInt(); + UUID uuid = buf.readUUID(); + int type = buf.readVarInt(); + double x = buf.readDouble(); + double y = buf.readDouble(); + double z = buf.readDouble(); + byte xRot = buf.readByte(); + byte yRot = buf.readByte(); + byte yHeadRot = buf.readByte(); + int data = buf.readVarInt(); + int xa = buf.readShort(); + int ya = buf.readShort(); + int za = buf.readShort(); + // Falling blocks + if (type == Reflections.instance$EntityType$FALLING_BLOCK$registryId) { + int remapped = remap(data); + if (remapped != data) { + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeVarInt(id); + buf.writeUUID(uuid); + buf.writeVarInt(type); + buf.writeDouble(x); + buf.writeDouble(y); + buf.writeDouble(z); + buf.writeByte(xRot); + buf.writeByte(yRot); + buf.writeByte(yHeadRot); + buf.writeVarInt(remapped); + buf.writeShort(xa); + buf.writeShort(ya); + buf.writeShort(za); + } + } else if (type == Reflections.instance$EntityType$BLOCK_DISPLAY$registryId) { + user.entityView().put(id, Reflections.instance$EntityType$BLOCK_DISPLAY); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundAddEntityPacket", e); + } + }; + public static final TriConsumer ADD_ENTITY = (user, event, packet) -> { try { Object entityType = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$type(packet); - // Falling blocks - if (entityType == Reflections.instance$EntityType$FALLING_BLOCK) { - int data = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$data(packet); - int remapped = remap(data); - if (remapped != data) { - Reflections.field$ClientboundAddEntityPacket$data.set(packet, remapped); - } - } else if (entityType == Reflections.instance$EntityType$ITEM_DISPLAY) { + if (entityType == Reflections.instance$EntityType$ITEM_DISPLAY) { // Furniture int entityId = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$entityId(packet); LoadedFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(entityId); @@ -685,9 +719,6 @@ public class PacketConsumers { if (furniture != null) { event.setCancelled(true); } - } else if (entityType == Reflections.instance$EntityType$BLOCK_DISPLAY) { - int entityId = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$entityId(packet); - user.entityView().put(entityId, entityType); } } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ClientboundAddEntityPacket", e); @@ -695,10 +726,9 @@ public class PacketConsumers { }; // 1.21.3+ - // TODO USE bytebuffer public static final TriConsumer SYNC_ENTITY_POSITION = (user, event, packet) -> { try { - int entityId = (int) Reflections.field$ClientboundEntityPositionSyncPacket$id.get(packet); + int entityId = FastNMS.INSTANCE.method$ClientboundEntityPositionSyncPacket$id(packet); if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) { event.setCancelled(true); } @@ -707,7 +737,6 @@ public class PacketConsumers { } }; - // TODO USE bytebuffer public static final TriConsumer MOVE_ENTITY = (user, event, packet) -> { try { int entityId = BukkitInjector.internalFieldAccessor().field$ClientboundMoveEntityPacket$entityId(packet); @@ -1002,6 +1031,7 @@ public class PacketConsumers { ); user.nettyChannel().writeAndFlush(kickPacket); user.nettyChannel().disconnect(); + return; } user.setClientModState(true); } @@ -1010,38 +1040,84 @@ public class PacketConsumers { } }; - // TODO 使用bytebuffer -// public static final TriConsumer SET_ENTITY_DATA = (user, event, packet) -> { -// try { -// int id = FastNMS.INSTANCE.field$ClientboundSetEntityDataPacket$id(packet); -// Object entityType = user.entityView().get(id); -// if (entityType == Reflections.instance$EntityType$BLOCK_DISPLAY) { -// List packedItems = FastNMS.INSTANCE.field$ClientboundSetEntityDataPacket$packedItems(packet); -// for (int i = 0; i < packedItems.size(); i++) { -// Object packedItem = packedItems.get(i); -// int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem); -// if (entityDataId != EntityDataUtils.BLOCK_STATE_DATA_ID) { -// continue; -// } -// Object blockState = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem); -// int stateId = BlockStateUtils.blockStateToId(blockState); -// int newStateId; -// if (!user.clientModEnabled()) { -// newStateId = remap(stateId); -// } else { -// newStateId = remapMOD(stateId); -// } -// Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem); -// packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue( -// entityDataId, serializer, BlockStateUtils.idToBlockState(newStateId) -// )); -// break; -// } -// } -// } catch (Exception e) { -// CraftEngine.instance().logger().warn("Failed to handle ClientboundSetEntityDataPacket", e); -// } -// }; + + // TODO 需要修复 + // @SuppressWarnings("unchecked") + // public static final BiConsumer SET_ENTITY_DATA = (user, event) -> { + // try { + // FriendlyByteBuf buf = event.getBuffer(); + // int id = buf.readVarInt(); + // Object entityType = user.entityView().get(id); + // if (entityType == Reflections.instance$EntityType$BLOCK_DISPLAY) { + // Object registryFriendlyByteBuf = FastNMS.INSTANCE.constructor$RegistryFriendlyByteBuf(buf, Reflections.instance$registryAccess); + // boolean isChanged = false; + // List packedItems = (List) Reflections.method$ClientboundSetEntityDataPacket$unpack.invoke(null, registryFriendlyByteBuf); + // for (int i = 0; i < packedItems.size(); i++) { + // Object packedItem = packedItems.get(i); + // int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem); + // if (entityDataId != EntityDataUtils.BLOCK_STATE_DATA_ID) { + // continue; + // } + // Object blockState = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem); + // int stateId = BlockStateUtils.blockStateToId(blockState); + // int newStateId; + // if (!user.clientModEnabled()) { + // newStateId = remap(stateId); + // } else { + // newStateId = remapMOD(stateId); + // } + // Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem); + // packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue( + // entityDataId, serializer, BlockStateUtils.idToBlockState(newStateId) + // )); + // isChanged = true; + // break; + // } + // if (isChanged) { + // System.out.println("Changed"); + // event.setChanged(true); + // buf.clear(); + // buf.writeVarInt(event.packetID()); + // Reflections.method$ClientboundSetEntityDataPacket$pack.invoke(null, packedItems, registryFriendlyByteBuf); + // } + // } + // } catch (Exception e) { + // CraftEngine.instance().logger().warn("Failed to handle ClientboundSetEntityDataPacket", e); + // } + // }; + + // 之前的旧东西经供参考需要改成使用bytebuffer的 + // public static final TriConsumer SET_ENTITY_DATA = (user, event, packet) -> { + // try { + // int id = FastNMS.INSTANCE.field$ClientboundSetEntityDataPacket$id(packet); + // Object entityType = user.entityView().get(id); + // if (entityType == Reflections.instance$EntityType$BLOCK_DISPLAY) { + // List packedItems = FastNMS.INSTANCE.field$ClientboundSetEntityDataPacket$packedItems(packet); + // for (int i = 0; i < packedItems.size(); i++) { + // Object packedItem = packedItems.get(i); + // int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem); + // if (entityDataId != EntityDataUtils.BLOCK_STATE_DATA_ID) { + // continue; + // } + // Object blockState = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem); + // int stateId = BlockStateUtils.blockStateToId(blockState); + // int newStateId; + // if (!user.clientModEnabled()) { + // newStateId = remap(stateId); + // } else { + // newStateId = remapMOD(stateId); + // } + // Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem); + // packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue( + // entityDataId, serializer, BlockStateUtils.idToBlockState(newStateId) + // )); + // break; + // } + // } + // } catch (Exception e) { + // CraftEngine.instance().logger().warn("Failed to handle ClientboundSetEntityDataPacket", e); + // } + // }; // public static final TriConsumer OPEN_SCREEN = (user, event, packet) -> { // try { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketIds.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketIds.java index ca7338f6b..bc89467c1 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketIds.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketIds.java @@ -13,4 +13,10 @@ public interface PacketIds { int clientboundAddEntityPacket(); int clientboundOpenScreenPacket(); + + int clientboundSoundPacket(); + + int clientboundRemoveEntitiesPacket(); + + int clientboundSetEntityDataPacket(); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIdFinder.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIdFinder.java index d7db35e57..eea73d2ec 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIdFinder.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIdFinder.java @@ -28,6 +28,6 @@ public class PacketIdFinder { } public static int clientboundByName(String packetName) { - return gamePacketIds.get("clientbound").get(packetName); + return gamePacketIds.get("clientbound").getOrDefault(packetName, -1); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20.java index e833e4d8c..418af0473 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20.java @@ -33,4 +33,19 @@ public class PacketIds1_20 implements PacketIds { public int clientboundOpenScreenPacket() { return 48; } + + @Override + public int clientboundSoundPacket() { + return 98; + } + + @Override + public int clientboundRemoveEntitiesPacket() { + return 62; + } + + @Override + public int clientboundSetEntityDataPacket() { + return 82; + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20_2.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20_2.java index c4d740242..a79c2a0ea 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20_2.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20_2.java @@ -33,4 +33,19 @@ public class PacketIds1_20_2 implements PacketIds { public int clientboundOpenScreenPacket() { return 49; } + + @Override + public int clientboundSoundPacket() { + return 100; + } + + @Override + public int clientboundRemoveEntitiesPacket() { + return 64; + } + + @Override + public int clientboundSetEntityDataPacket() { + return 84; + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20_3.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20_3.java index c18291673..dcae35e59 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20_3.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20_3.java @@ -33,4 +33,19 @@ public class PacketIds1_20_3 implements PacketIds { public int clientboundOpenScreenPacket() { return 49; } + + @Override + public int clientboundSoundPacket() { + return 102; + } + + @Override + public int clientboundRemoveEntitiesPacket() { + return 64; + } + + @Override + public int clientboundSetEntityDataPacket() { + return 86; + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20_5.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20_5.java index 70e909fd6..d6da5f830 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20_5.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_20_5.java @@ -33,4 +33,19 @@ public class PacketIds1_20_5 implements PacketIds { public int clientboundOpenScreenPacket() { return 51; } + + @Override + public int clientboundSoundPacket() { + return 104; + } + + @Override + public int clientboundRemoveEntitiesPacket() { + return 66; + } + + @Override + public int clientboundSetEntityDataPacket() { + return 88; + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_21.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_21.java index 8d1417f2a..944d99a1a 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_21.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/impl/PacketIds1_21.java @@ -33,4 +33,19 @@ public class PacketIds1_21 implements PacketIds { public int clientboundOpenScreenPacket() { return PacketIdFinder.clientboundByName("minecraft:open_screen"); } + + @Override + public int clientboundSoundPacket() { + return PacketIdFinder.clientboundByName("minecraft:sound"); + } + + @Override + public int clientboundRemoveEntitiesPacket() { + return PacketIdFinder.clientboundByName("minecraft:remove_entities"); + } + + @Override + public int clientboundSetEntityDataPacket() { + return PacketIdFinder.clientboundByName("minecraft:set_entity_data"); + } } 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 46cdb16c4..282888557 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 @@ -6264,4 +6264,33 @@ public class Reflections { public static final Field field$ClientInformation$particleStatus = Optional.ofNullable(clazz$ClientInformation) .map(it -> ReflectionUtils.getDeclaredField(it, 8)) .orElse(null); + + public static final Method method$Registry$getId = requireNonNull( + ReflectionUtils.getMethod(clazz$Registry, int.class, Object.class) + ); + + public static final int instance$EntityType$BLOCK_DISPLAY$registryId; + public static final int instance$EntityType$FALLING_BLOCK$registryId; + + static { + try { + instance$EntityType$BLOCK_DISPLAY$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$BLOCK_DISPLAY); + instance$EntityType$FALLING_BLOCK$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$FALLING_BLOCK); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + // 先注释后面再说 + // public static final Method method$ClientboundSetEntityDataPacket$pack = requireNonNull( + // ReflectionUtils.getDeclaredMethod( + // clazz$ClientboundSetEntityDataPacket, void.class, List.class, clazz$RegistryFriendlyByteBuf + // ) + // ); + // + // public static final Method method$ClientboundSetEntityDataPacket$unpack = requireNonNull( + // ReflectionUtils.getDeclaredMethod( + // clazz$ClientboundSetEntityDataPacket, List.class, clazz$RegistryFriendlyByteBuf + // ) + // ); } diff --git a/gradle.properties b/gradle.properties index a80c87bb7..700cc6878 100644 --- a/gradle.properties +++ b/gradle.properties @@ -51,7 +51,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.13 -nms_helper_version=0.43 +nms_helper_version=0.44 # Ignite Dependencies mixinextras_version=0.4.1 mixin_version=0.15.2+mixin.0.8.7