diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index c7a90b6a0..add64ec6f 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -152,6 +152,19 @@ image: chat: true command: true sign: true + # By intercepting packets, you are allowed to use in other plugins + intercept-packets: + system-chat: true + tab-list: true + actionbar: true + title: true + bossbar: true + container: true + # TODO: toast: true + # TODO: name: true + # TODO: team: true + +emoji: {} recipe: # Enable the plugin's recipe system diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java index 0c970796b..9fd2c4f8f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/entity/furniture/BukkitFurnitureManager.java @@ -323,8 +323,9 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager { if (FastNMS.INSTANCE.method$CraftEntity$getHandle(shulker) instanceof CollisionEntity) { return; } + // not a collision entity Byte flag = shulker.getPersistentDataContainer().get(FURNITURE_COLLISION, PersistentDataType.BYTE); - if (flag != null && flag == 1) { + if (flag == null || flag != 1) { return; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java index f7aa65dbe..0b7a822c2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/TestCommand.java @@ -1,7 +1,6 @@ package net.momirealms.craftengine.bukkit.plugin.command.feature; -import net.momirealms.craftengine.bukkit.nms.CollisionEntity; -import net.momirealms.craftengine.bukkit.nms.FastNMS; +import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; @@ -9,6 +8,8 @@ import org.bukkit.Location; import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.entity.Shulker; +import org.bukkit.persistence.PersistentDataType; import org.incendo.cloud.Command; import java.util.Collection; @@ -29,7 +30,7 @@ public class TestCommand extends BukkitCommandFeature { try { Collection entities = player.getLocation().getNearbyEntities(2,2,2); for (Entity entity : entities) { - if (FastNMS.INSTANCE.method$CraftEntity$getHandle(entity) instanceof CollisionEntity) { + if (entity instanceof Shulker) { } } } catch (Exception e) { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java index def463fba..641947e72 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java @@ -3,16 +3,24 @@ package net.momirealms.craftengine.bukkit.plugin.injector; import com.mojang.datafixers.util.Pair; import net.bytebuddy.ByteBuddy; import net.bytebuddy.ClassFileVersion; +import net.bytebuddy.description.field.FieldDescription; import net.bytebuddy.description.modifier.Visibility; +import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.DynamicType; +import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy; import net.bytebuddy.implementation.FieldAccessor; import net.bytebuddy.implementation.FixedValue; +import net.bytebuddy.implementation.Implementation; import net.bytebuddy.implementation.MethodDelegation; import net.bytebuddy.implementation.bind.annotation.AllArguments; import net.bytebuddy.implementation.bind.annotation.RuntimeType; import net.bytebuddy.implementation.bind.annotation.SuperCall; import net.bytebuddy.implementation.bind.annotation.This; +import net.bytebuddy.implementation.bytecode.assign.TypeCasting; +import net.bytebuddy.implementation.bytecode.member.FieldAccess; +import net.bytebuddy.implementation.bytecode.member.MethodReturn; +import net.bytebuddy.implementation.bytecode.member.MethodVariableAccess; import net.bytebuddy.matcher.ElementMatchers; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.block.BukkitBlockShape; @@ -54,6 +62,7 @@ import java.lang.invoke.MethodType; import java.lang.invoke.VarHandle; import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -82,6 +91,8 @@ public class BukkitInjector { private static Class clazz$InjectedCacheChecker; + private static InternalFieldAccessor internalFieldAccessor; + public static void init() { try { // Paletted Container @@ -149,6 +160,36 @@ public class BukkitInjector { .getLoaded(); instance$OptimizedItemDisplayFactory = Objects.requireNonNull(ReflectionUtils.getConstructor(clazz$OptimizedItemDisplayFatory, 0)).newInstance(); + // InternalFieldAccessor Interface + Class internalFieldAccessorInterface = new ByteBuddy() + .makeInterface() + .name("net.momirealms.craftengine.bukkit.plugin.injector.InternalFieldAccessor") + .defineMethod("field$ClientboundMoveEntityPacket$entityId", int.class, Modifier.PUBLIC) + .withParameter(Object.class, "packet") + .withoutCode() + .make() + .load(Reflections.clazz$ClientboundMoveEntityPacket.getClassLoader(), ClassLoadingStrategy.Default.INJECTION) + .getLoaded(); + + // Internal field accessor + FieldDescription moveEntityIdFieldDesc = new FieldDescription.ForLoadedField(Reflections.field$ClientboundMoveEntityPacket$entityId); + Class clazz$InternalFieldAccessor = byteBuddy + .subclass(Object.class) + .name("net.minecraft.network.protocol.game.CraftEngineInternalFieldAccessor") + .implement(internalFieldAccessorInterface) + .method(ElementMatchers.named("field$ClientboundMoveEntityPacket$entityId")) + .intercept(new Implementation.Simple( + MethodVariableAccess.REFERENCE.loadFrom(1), + TypeCasting.to(TypeDescription.ForLoadedType.of(Reflections.clazz$ClientboundMoveEntityPacket)), + FieldAccess.forField(moveEntityIdFieldDesc).read(), + MethodReturn.INTEGER + )) + .make() + .load(Reflections.clazz$ClientboundMoveEntityPacket.getClassLoader(), ClassLoadingStrategy.Default.INJECTION) + .getLoaded(); + internalFieldAccessor = (InternalFieldAccessor) clazz$InternalFieldAccessor.getConstructor().newInstance(); + + // CraftEngine Blocks String packageWithName = BukkitInjector.class.getName(); String generatedClassName = packageWithName.substring(0, packageWithName.lastIndexOf('.')) + ".CraftEngineBlock"; DynamicType.Builder builder = byteBuddy @@ -293,6 +334,10 @@ public class BukkitInjector { } } + public static InternalFieldAccessor internalFieldAccessor() { + return internalFieldAccessor; + } + public static void injectCookingBlockEntity(Object entity) throws ReflectiveOperationException { if (Reflections.clazz$AbstractFurnaceBlockEntity.isInstance(entity)) { Object quickCheck = Reflections.field$AbstractFurnaceBlockEntity$quickCheck.get(entity); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/InternalFieldAccessor.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/InternalFieldAccessor.java new file mode 100644 index 000000000..94c5f6be2 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/InternalFieldAccessor.java @@ -0,0 +1,6 @@ +package net.momirealms.craftengine.bukkit.plugin.injector; + +public interface InternalFieldAccessor { + + int field$ClientboundMoveEntityPacket$entityId(Object packet); +} 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..4fa682f7d 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); } @@ -150,12 +151,21 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerNMSPacketConsumer(PacketConsumers.EDIT_BOOK, Reflections.clazz$ServerboundEditBookPacket); registerNMSPacketConsumer(PacketConsumers.CUSTOM_PAYLOAD, Reflections.clazz$ServerboundCustomPayloadPacket); // registerNMSPacketConsumer(PacketConsumers.SET_ENTITY_DATA, Reflections.clazz$ClientboundSetEntityDataPacket); -// registerNMSPacketConsumer(PacketConsumers.OPEN_SCREEN, Reflections.clazz$ClientboundOpenScreenPacket); registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket()); registerByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket()); registerByteBufPacketConsumer(PacketConsumers.LEVEL_PARTICLE, this.packetIds.clientboundLevelParticlesPacket()); registerByteBufPacketConsumer(PacketConsumers.LEVEL_EVENT, this.packetIds.clientboundLevelEventPacket()); - registerByteBufPacketConsumer(PacketConsumers.OPEN_SCREEN, this.packetIds.clientboundOpenScreenPacket()); + registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.OPEN_SCREEN_1_20_3 : PacketConsumers.OPEN_SCREEN_1_20, this.packetIds.clientboundOpenScreenPacket()); + registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.SET_TITLE_TEXT_1_20_3 : PacketConsumers.SET_TITLE_TEXT_1_20, this.packetIds.clientboundSetTitleTextPacket()); + registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.SET_SUBTITLE_TEXT_1_20_3 : PacketConsumers.SET_SUBTITLE_TEXT_1_20, this.packetIds.clientboundSetSubtitleTextPacket()); + registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.SET_ACTIONBAR_TEXT_1_20_3 : PacketConsumers.SET_ACTIONBAR_TEXT_1_20, this.packetIds.clientboundSetActionBarTextPacket()); + registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.BOSS_EVENT_1_20_3 : PacketConsumers.BOSS_EVENT_1_20, this.packetIds.clientboundBossEventPacket()); + registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.SYSTEM_CHAT_1_20_3 : PacketConsumers.SYSTEM_CHAT_1_20, this.packetIds.clientboundSystemChatPacket()); + registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.TAB_LIST_1_20_3 : PacketConsumers.TAB_LIST_1_20, this.packetIds.clientboundTabListPacket()); + // 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 c99cf53b3..d0c11d59b 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 @@ -14,6 +14,7 @@ import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager import net.momirealms.craftengine.bukkit.entity.furniture.LoadedFurniture; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; +import net.momirealms.craftengine.bukkit.plugin.injector.BukkitInjector; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.bukkit.util.*; import net.momirealms.craftengine.core.block.ImmutableBlockState; @@ -241,29 +242,35 @@ public class PacketConsumers { } }; - public static final BiConsumer OPEN_SCREEN = (user, event) -> { + public static final BiConsumer BOSS_EVENT_1_20 = (user, event) -> { + if (!Config.interceptBossBar()) return; try { - 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()); + FriendlyByteBuf buf = event.getBuffer(); + UUID uuid = buf.readUUID(); + int actionType = buf.readVarInt(); + if (actionType == 0) { + String json = buf.readUtf(); + Map tokens = CraftEngine.instance().imageManager().matchTags(json); if (tokens.isEmpty()) return; - Component component = NBTComponentSerializer.nbt().deserialize(nbt); + Component component = AdventureHelper.jsonToComponent(json); for (Map.Entry token : tokens.entrySet()) { component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); } + float health = buf.readFloat(); + int color = buf.readVarInt(); + int division = buf.readVarInt(); + byte flag = buf.readByte(); + event.setChanged(true); buf.clear(); buf.writeVarInt(event.packetID()); - buf.writeVarInt(containerId); - buf.writeVarInt(type); - buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false); - } else { - FriendlyByteBuf buf = event.getBuffer(); - int containerId = buf.readVarInt(); - int type = buf.readVarInt(); + buf.writeUUID(uuid); + buf.writeVarInt(actionType); + buf.writeUtf(AdventureHelper.componentToJson(component)); + buf.writeFloat(health); + buf.writeVarInt(color); + buf.writeVarInt(division); + buf.writeByte(flag); + } else if (actionType == 3) { String json = buf.readUtf(); Map tokens = CraftEngine.instance().imageManager().matchTags(json); if (tokens.isEmpty()) return; @@ -274,10 +281,348 @@ public class PacketConsumers { } buf.clear(); buf.writeVarInt(event.packetID()); - buf.writeVarInt(containerId); - buf.writeVarInt(type); + buf.writeUUID(uuid); + buf.writeVarInt(actionType); buf.writeUtf(AdventureHelper.componentToJson(component)); } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundBossEventPacket", e); + } + }; + + public static final BiConsumer BOSS_EVENT_1_20_3 = (user, event) -> { + if (!Config.interceptBossBar()) return; + try { + FriendlyByteBuf buf = event.getBuffer(); + UUID uuid = buf.readUUID(); + int actionType = buf.readVarInt(); + if (actionType == 0) { + Tag nbt = buf.readNbt(false); + if (nbt == null) return; + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + if (tokens.isEmpty()) return; + Component component = NBTComponentSerializer.nbt().deserialize(nbt); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + float health = buf.readFloat(); + int color = buf.readVarInt(); + int division = buf.readVarInt(); + byte flag = buf.readByte(); + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeUUID(uuid); + buf.writeVarInt(actionType); + buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false); + buf.writeFloat(health); + buf.writeVarInt(color); + buf.writeVarInt(division); + buf.writeByte(flag); + } else if (actionType == 3) { + Tag nbt = buf.readNbt(false); + if (nbt == null) return; + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + if (tokens.isEmpty()) return; + event.setChanged(true); + Component component = NBTComponentSerializer.nbt().deserialize(nbt); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeUUID(uuid); + buf.writeVarInt(actionType); + buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundBossEventPacket", e); + } + }; + + public static final BiConsumer SYSTEM_CHAT_1_20 = (user, event) -> { + if (!Config.interceptSystemChat()) return; + try { + FriendlyByteBuf buf = event.getBuffer(); + String json = buf.readUtf(); + Map tokens = CraftEngine.instance().imageManager().matchTags(json); + if (tokens.isEmpty()) return; + boolean overlay = buf.readBoolean(); + event.setChanged(true); + Component component = AdventureHelper.jsonToComponent(json); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeUtf(AdventureHelper.componentToJson(component)); + buf.writeBoolean(overlay); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSystemChatPacket", e); + } + }; + + public static final BiConsumer SYSTEM_CHAT_1_20_3 = (user, event) -> { + if (!Config.interceptSystemChat()) return; + try { + FriendlyByteBuf buf = event.getBuffer(); + Tag nbt = buf.readNbt(false); + if (nbt == null) return; + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + if (tokens.isEmpty()) return; + boolean overlay = buf.readBoolean(); + event.setChanged(true); + Component component = NBTComponentSerializer.nbt().deserialize(nbt); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false); + buf.writeBoolean(overlay); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSystemChatPacket", e); + } + }; + + public static final BiConsumer SET_SUBTITLE_TEXT_1_20 = (user, event) -> { + if (!Config.interceptTitle()) return; + try { + FriendlyByteBuf buf = event.getBuffer(); + String json = buf.readUtf(); + Map tokens = CraftEngine.instance().imageManager().matchTags(json); + if (tokens.isEmpty()) return; + event.setChanged(true); + Component component = AdventureHelper.jsonToComponent(json); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeUtf(AdventureHelper.componentToJson(component)); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSetSubtitleTextPacket", e); + } + }; + + public static final BiConsumer SET_SUBTITLE_TEXT_1_20_3 = (user, event) -> { + if (!Config.interceptTitle()) return; + try { + FriendlyByteBuf buf = event.getBuffer(); + Tag nbt = buf.readNbt(false); + if (nbt == null) return; + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + if (tokens.isEmpty()) return; + event.setChanged(true); + Component component = NBTComponentSerializer.nbt().deserialize(nbt); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSetSubtitleTextPacket", e); + } + }; + + public static final BiConsumer SET_TITLE_TEXT_1_20 = (user, event) -> { + if (!Config.interceptTitle()) return; + try { + FriendlyByteBuf buf = event.getBuffer(); + String json = buf.readUtf(); + Map tokens = CraftEngine.instance().imageManager().matchTags(json); + if (tokens.isEmpty()) return; + event.setChanged(true); + Component component = AdventureHelper.jsonToComponent(json); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeUtf(AdventureHelper.componentToJson(component)); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSetTitleTextPacket", e); + } + }; + + public static final BiConsumer SET_TITLE_TEXT_1_20_3 = (user, event) -> { + if (!Config.interceptTitle()) return; + try { + FriendlyByteBuf buf = event.getBuffer(); + Tag nbt = buf.readNbt(false); + if (nbt == null) return; + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + if (tokens.isEmpty()) return; + event.setChanged(true); + Component component = NBTComponentSerializer.nbt().deserialize(nbt); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSetTitleTextPacket", e); + } + }; + + public static final BiConsumer SET_ACTIONBAR_TEXT_1_20 = (user, event) -> { + if (!Config.interceptActionBar()) return; + try { + FriendlyByteBuf buf = event.getBuffer(); + String json = buf.readUtf(); + Map tokens = CraftEngine.instance().imageManager().matchTags(json); + if (tokens.isEmpty()) return; + event.setChanged(true); + Component component = AdventureHelper.jsonToComponent(json); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeUtf(AdventureHelper.componentToJson(component)); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSetActionBarTextPacket", e); + } + }; + + public static final BiConsumer SET_ACTIONBAR_TEXT_1_20_3 = (user, event) -> { + if (!Config.interceptActionBar()) return; + try { + FriendlyByteBuf buf = event.getBuffer(); + Tag nbt = buf.readNbt(false); + if (nbt == null) return; + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + if (tokens.isEmpty()) return; + event.setChanged(true); + Component component = NBTComponentSerializer.nbt().deserialize(nbt); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSetActionBarTextPacket", e); + } + }; + + public static final BiConsumer TAB_LIST_1_20 = (user, event) -> { + if (!Config.interceptTabList()) return; + try { + FriendlyByteBuf buf = event.getBuffer(); + String json1 = buf.readUtf(); + String json2 = buf.readUtf(); + Map tokens1 = CraftEngine.instance().imageManager().matchTags(json1); + Map tokens2 = CraftEngine.instance().imageManager().matchTags(json2); + if (tokens1.isEmpty() && tokens2.isEmpty()) return; + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + if (!tokens1.isEmpty()) { + Component component = AdventureHelper.jsonToComponent(json1); + for (Map.Entry token : tokens1.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.writeUtf(AdventureHelper.componentToJson(component)); + } else { + buf.writeUtf(json1); + } + if (!tokens2.isEmpty()) { + Component component = AdventureHelper.jsonToComponent(json2); + for (Map.Entry token : tokens2.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.writeUtf(AdventureHelper.componentToJson(component)); + } else { + buf.writeUtf(json2); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSet[(Sub)Title/ActionBar]TextPacket", e); + } + }; + + public static final BiConsumer TAB_LIST_1_20_3 = (user, event) -> { + if (!Config.interceptTabList()) return; + try { + FriendlyByteBuf buf = event.getBuffer(); + Tag nbt1 = buf.readNbt(false); + if (nbt1 == null) return; + Tag nbt2 = buf.readNbt(false); + if (nbt2 == null) return; + Map tokens1 = CraftEngine.instance().imageManager().matchTags(nbt1.getAsString()); + Map tokens2 = CraftEngine.instance().imageManager().matchTags(nbt2.getAsString()); + if (tokens1.isEmpty() && tokens2.isEmpty()) return; + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + if (!tokens1.isEmpty()) { + Component component = NBTComponentSerializer.nbt().deserialize(nbt1); + for (Map.Entry token : tokens1.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false); + } else { + buf.writeNbt(nbt1, false); + } + if (!tokens2.isEmpty()) { + Component component = NBTComponentSerializer.nbt().deserialize(nbt2); + for (Map.Entry token : tokens2.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false); + } else { + buf.writeNbt(nbt2, false); + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSet[(Sub)Title/ActionBar]TextPacket", e); + } + }; + + public static final BiConsumer OPEN_SCREEN_1_20 = (user, event) -> { + if (!Config.interceptContainer()) return; + try { + 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; + event.setChanged(true); + Component component = AdventureHelper.jsonToComponent(json); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeVarInt(containerId); + buf.writeVarInt(type); + buf.writeUtf(AdventureHelper.componentToJson(component)); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundOpenScreenPacket", e); + } + }; + + public static final BiConsumer OPEN_SCREEN_1_20_3 = (user, event) -> { + if (!Config.interceptContainer()) return; + try { + 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()); + if (tokens.isEmpty()) return; + Component component = NBTComponentSerializer.nbt().deserialize(nbt); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + } + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeVarInt(containerId); + buf.writeVarInt(type); + buf.writeNbt(NBTComponentSerializer.nbt().serialize(component), false); } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ClientboundOpenScreenPacket", e); } @@ -655,18 +1000,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); @@ -684,9 +1066,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); @@ -694,10 +1073,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); } @@ -706,10 +1084,9 @@ public class PacketConsumers { } }; - // TODO USE bytebuffer public static final TriConsumer MOVE_ENTITY = (user, event, packet) -> { try { - int entityId = (int) Reflections.field$ClientboundMoveEntityPacket$entityId.get(packet); + int entityId = BukkitInjector.internalFieldAccessor().field$ClientboundMoveEntityPacket$entityId(packet); if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) { event.setCancelled(true); } @@ -1001,6 +1378,7 @@ public class PacketConsumers { ); user.nettyChannel().writeAndFlush(kickPacket); user.nettyChannel().disconnect(); + return; } user.setClientModState(true); } @@ -1009,38 +1387,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..cba589e6e 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,22 @@ public interface PacketIds { int clientboundAddEntityPacket(); int clientboundOpenScreenPacket(); + + int clientboundSoundPacket(); + + int clientboundRemoveEntitiesPacket(); + + int clientboundSetEntityDataPacket(); + + int clientboundSetTitleTextPacket(); + + int clientboundSetSubtitleTextPacket(); + + int clientboundSetActionBarTextPacket(); + + int clientboundBossEventPacket(); + + int clientboundSystemChatPacket(); + + int clientboundTabListPacket(); } 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..68b07152f 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,49 @@ 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; + } + + @Override + public int clientboundSetTitleTextPacket() { + return 95; + } + + @Override + public int clientboundSetSubtitleTextPacket() { + return 93; + } + + @Override + public int clientboundSetActionBarTextPacket() { + return 70; + } + + @Override + public int clientboundBossEventPacket() { + return 11; + } + + @Override + public int clientboundSystemChatPacket() { + return 100; + } + + @Override + public int clientboundTabListPacket() { + return 101; + } } 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..9773d7cb5 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,49 @@ 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; + } + + @Override + public int clientboundSetTitleTextPacket() { + return 97; + } + + @Override + public int clientboundSetSubtitleTextPacket() { + return 95; + } + + @Override + public int clientboundSetActionBarTextPacket() { + return 72; + } + + @Override + public int clientboundBossEventPacket() { + return 10; + } + + @Override + public int clientboundSystemChatPacket() { + return 103; + } + + @Override + public int clientboundTabListPacket() { + return 104; + } } 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..c6d0a66ca 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,49 @@ 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; + } + + @Override + public int clientboundSetTitleTextPacket() { + return 99; + } + + @Override + public int clientboundSetSubtitleTextPacket() { + return 97; + } + + @Override + public int clientboundSetActionBarTextPacket() { + return 74; + } + + @Override + public int clientboundBossEventPacket() { + return 10; + } + + @Override + public int clientboundSystemChatPacket() { + return 105; + } + + @Override + public int clientboundTabListPacket() { + return 106; + } } 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..75b6566e3 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,49 @@ 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; + } + + @Override + public int clientboundSetTitleTextPacket() { + return 101; + } + + @Override + public int clientboundSetSubtitleTextPacket() { + return 99; + } + + @Override + public int clientboundSetActionBarTextPacket() { + return 76; + } + + @Override + public int clientboundBossEventPacket() { + return 10; + } + + @Override + public int clientboundSystemChatPacket() { + return 108; + } + + @Override + public int clientboundTabListPacket() { + return 109; + } } 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..5dc7fa843 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,49 @@ 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"); + } + + @Override + public int clientboundSetTitleTextPacket() { + return PacketIdFinder.clientboundByName("minecraft:set_title_text"); + } + + @Override + public int clientboundSetSubtitleTextPacket() { + return PacketIdFinder.clientboundByName("minecraft:set_subtitle_text"); + } + + @Override + public int clientboundSetActionBarTextPacket() { + return PacketIdFinder.clientboundByName("minecraft:set_action_bar_text"); + } + + @Override + public int clientboundBossEventPacket() { + return PacketIdFinder.clientboundByName("minecraft:boss_event"); + } + + @Override + public int clientboundSystemChatPacket() { + return PacketIdFinder.clientboundByName("minecraft:system_chat"); + } + + @Override + public int clientboundTabListPacket() { + return PacketIdFinder.clientboundByName("minecraft:tab_list"); + } } 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/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java index 24b31ff21..5aaffc694 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java @@ -122,6 +122,12 @@ public class Config { protected boolean image$illegal_characters_filter$anvil; protected boolean image$illegal_characters_filter$sign; protected boolean image$illegal_characters_filter$book; + protected boolean image$intercept_packets$system_chat; + protected boolean image$intercept_packets$tab_list; + protected boolean image$intercept_packets$actionbar; + protected boolean image$intercept_packets$title; + protected boolean image$intercept_packets$bossbar; + protected boolean image$intercept_packets$container; public Config(CraftEngine plugin) { this.plugin = plugin; @@ -278,6 +284,12 @@ public class Config { image$illegal_characters_filter$chat = config.getBoolean("image.illegal-characters-filter.chat", true); image$illegal_characters_filter$command = config.getBoolean("image.illegal-characters-filter.command", true); image$illegal_characters_filter$sign = config.getBoolean("image.illegal-characters-filter.sign", true); + image$intercept_packets$system_chat = config.getBoolean("image.intercept-packets.system-chat", true); + image$intercept_packets$tab_list = config.getBoolean("image.intercept-packets.tab-list", true); + image$intercept_packets$actionbar = config.getBoolean("image.intercept-packets.actionbar", true); + image$intercept_packets$title = config.getBoolean("image.intercept-packets.title", true); + image$intercept_packets$bossbar = config.getBoolean("image.intercept-packets.bossbar", true); + image$intercept_packets$container = config.getBoolean("image.intercept-packets.container", true); Class modClazz = ReflectionUtils.getClazz(CraftEngine.MOD_CLASS); if (modClazz != null) { @@ -578,6 +590,30 @@ public class Config { return id; } + public static boolean interceptSystemChat() { + return instance.image$intercept_packets$system_chat; + } + + public static boolean interceptTabList() { + return instance.image$intercept_packets$tab_list; + } + + public static boolean interceptActionBar() { + return instance.image$intercept_packets$actionbar; + } + + public static boolean interceptTitle() { + return instance.image$intercept_packets$title; + } + + public static boolean interceptBossBar() { + return instance.image$intercept_packets$bossbar; + } + + public static boolean interceptContainer() { + return instance.image$intercept_packets$container; + } + public YamlDocument loadOrCreateYamlData(String fileName) { File file = new File(this.plugin.dataFolderFile(), fileName); if (!file.exists()) { diff --git a/gradle.properties b/gradle.properties index a80c87bb7..6db3d7e84 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,8 +2,8 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.45 -config_version=22 +project_version=0.0.46 +config_version=23 lang_version=4 project_group=net.momirealms latest_supported_version=1.21.5 @@ -40,7 +40,7 @@ lz4_version=1.8.0 geantyref_version=1.3.16 zstd_version=1.5.7-2 commons_io_version=2.18.0 -sparrow_nbt_version=0.4.6 +sparrow_nbt_version=0.5 sparrow_util_version=0.37 fastutil_version=8.5.15 netty_version=4.1.119.Final @@ -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.45 # Ignite Dependencies mixinextras_version=0.4.1 mixin_version=0.15.2+mixin.0.8.7