diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java index 4bbd48d83..03b8034aa 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java @@ -261,7 +261,7 @@ public class BukkitBlockManager extends AbstractBlockManager { finalMapping.put(custom, stoneId); } finalMapping.putAll(this.tempBlockAppearanceConvertor); - PacketConsumers.init(finalMapping, RegistryUtils.currentBlockRegistrySize()); + PacketConsumers.initBlocks(finalMapping, RegistryUtils.currentBlockRegistrySize()); } private void initVanillaRegistry() { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java index ab90e1751..c6d40697d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java @@ -6,18 +6,15 @@ import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.AdventureHelper; -import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.ListTag; -import net.momirealms.sparrow.nbt.StringTag; import net.momirealms.sparrow.nbt.Tag; import org.bukkit.inventory.ItemStack; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.Optional; +@SuppressWarnings("DuplicatedCode") public class ModernNetworkItemHandler implements NetworkItemHandler { private final BukkitItemManager itemManager; @@ -51,17 +48,64 @@ public class ModernNetworkItemHandler implements NetworkItemHandler { return new OtherItem(wrapped).process(); } else { CustomItem customItem = optionalCustomItem.get(); - if (!customItem.hasClientBoundDataModifier()) return Optional.empty(); - CompoundTag customData = Optional.ofNullable(wrapped.getNBTComponent(ComponentTypes.CUSTOM_DATA)).map(CompoundTag.class::cast).orElse(new CompoundTag()); - CompoundTag tag = new CompoundTag(); - for (ItemDataModifier modifier : customItem.clientBoundDataModifiers()) { - modifier.prepareNetworkItem(wrapped, context, tag); - modifier.apply(wrapped, context); + if (!customItem.hasClientBoundDataModifier()) { + if (!Config.interceptItem()) return Optional.empty(); + return new OtherItem(wrapped).process(); + } else { + CompoundTag customData = Optional.ofNullable(wrapped.getNBTComponent(ComponentTypes.CUSTOM_DATA)).map(CompoundTag.class::cast).orElse(new CompoundTag()); + CompoundTag tag = new CompoundTag(); + for (ItemDataModifier modifier : customItem.clientBoundDataModifiers()) { + modifier.prepareNetworkItem(wrapped, context, tag); + modifier.apply(wrapped, context); + } + if (Config.interceptItem()) { + if (!tag.containsKey(ComponentIds.ITEM_NAME)) { + Tag nameTag = wrapped.getNBTComponent(ComponentTypes.ITEM_NAME); + if (nameTag != null) { + String tagStr = nameTag.getAsString(); + Map tokens = CraftEngine.instance().fontManager().matchTags(tagStr); + if (!tokens.isEmpty()) { + wrapped.setNBTComponent(ComponentKeys.ITEM_NAME, AdventureHelper.componentToNbt(AdventureHelper.replaceText(AdventureHelper.nbtToComponent(nameTag), tokens))); + tag.put(ComponentIds.ITEM_NAME, NetworkItemHandler.pack(Operation.ADD, nameTag)); + } + } + } + if (!tag.containsKey(ComponentIds.CUSTOM_NAME)) { + Tag nameTag = wrapped.getNBTComponent(ComponentTypes.CUSTOM_NAME); + if (nameTag != null) { + String tagStr = nameTag.getAsString(); + Map tokens = CraftEngine.instance().fontManager().matchTags(tagStr); + if (!tokens.isEmpty()) { + wrapped.setNBTComponent(ComponentKeys.CUSTOM_NAME, AdventureHelper.componentToNbt(AdventureHelper.replaceText(AdventureHelper.nbtToComponent(nameTag), tokens))); + tag.put(ComponentIds.CUSTOM_NAME, NetworkItemHandler.pack(Operation.ADD, nameTag)); + } + } + } + if (!tag.containsKey(ComponentIds.LORE)) { + Tag loreTag = wrapped.getNBTComponent(ComponentTypes.LORE); + if (loreTag instanceof ListTag listTag) { + ListTag newLore = new ListTag(); + boolean changed = false; + String tagStr = listTag.getAsString(); + Map tokens = CraftEngine.instance().fontManager().matchTags(tagStr); + if (tokens.isEmpty()) { + newLore.add(tag); + } else { + newLore.add(AdventureHelper.componentToNbt(AdventureHelper.replaceText(AdventureHelper.nbtToComponent(tag), tokens))); + changed = true; + } + if (changed) { + wrapped.setNBTComponent(ComponentKeys.LORE, newLore); + tag.put(ComponentIds.LORE, NetworkItemHandler.pack(Operation.ADD, listTag)); + } + } + } + } + if (tag.isEmpty()) return Optional.empty(); + customData.put(NETWORK_ITEM_TAG, tag); + wrapped.setNBTComponent(ComponentTypes.CUSTOM_DATA, customData); + return Optional.of(wrapped); } - if (tag.isEmpty()) return Optional.empty(); - customData.put(NETWORK_ITEM_TAG, tag); - wrapped.setNBTComponent(ComponentTypes.CUSTOM_DATA, customData); - return Optional.of(wrapped); } } @@ -75,15 +119,9 @@ public class ModernNetworkItemHandler implements NetworkItemHandler { } public Optional> process() { - if (VersionHelper.isOrAbove1_21_5()) { - processModernLore(); - processModernCustomName(); - processModernItemName(); - } else { - processLore(); - processCustomName(); - processItemName(); - } + processModernLore(); + processModernCustomName(); + processModernItemName(); if (this.globalChanged) { CompoundTag customData = Optional.ofNullable(this.item.getNBTComponent(ComponentTypes.CUSTOM_DATA)).map(CompoundTag.class::cast).orElse(new CompoundTag()); customData.put(NETWORK_ITEM_TAG, getOrCreateTag()); @@ -94,46 +132,6 @@ public class ModernNetworkItemHandler implements NetworkItemHandler { } } - private void processLore() { - Optional> optionalLore = this.item.loreJson(); - if (optionalLore.isPresent()) { - boolean changed = false; - List lore = optionalLore.get(); - List newLore = new ArrayList<>(lore.size()); - for (String line : lore) { - Map tokens = CraftEngine.instance().fontManager().matchTags(line); - if (tokens.isEmpty()) { - newLore.add(line); - } else { - newLore.add(AdventureHelper.componentToJson(AdventureHelper.replaceText(AdventureHelper.jsonToComponent(line), tokens))); - changed = true; - } - } - if (changed) { - this.globalChanged = true; - this.item.loreJson(newLore); - ListTag listTag = new ListTag(); - for (String line : lore) { - listTag.add(new StringTag(line)); - } - getOrCreateTag().put(ComponentKeys.LORE.asString(), NetworkItemHandler.pack(Operation.ADD, listTag)); - } - } - } - - private void processItemName() { - Optional optionalItemName = this.item.itemNameJson(); - if (optionalItemName.isPresent()) { - String line = optionalItemName.get(); - Map tokens = CraftEngine.instance().fontManager().matchTags(line); - if (!tokens.isEmpty()) { - this.item.itemNameJson(AdventureHelper.componentToJson(AdventureHelper.replaceText(AdventureHelper.jsonToComponent(line), tokens))); - this.globalChanged = true; - getOrCreateTag().put(ComponentKeys.ITEM_NAME.asString(), NetworkItemHandler.pack(Operation.ADD, new StringTag(line))); - } - } - } - private void processModernItemName() { Tag nameTag = this.item.getNBTComponent(ComponentTypes.ITEM_NAME); if (nameTag == null) return; @@ -146,19 +144,6 @@ public class ModernNetworkItemHandler implements NetworkItemHandler { } } - private void processCustomName() { - Optional optionalCustomName = this.item.customNameJson(); - if (optionalCustomName.isPresent()) { - String line = optionalCustomName.get(); - Map tokens = CraftEngine.instance().fontManager().matchTags(line); - if (!tokens.isEmpty()) { - this.item.customNameJson(AdventureHelper.componentToJson(AdventureHelper.replaceText(AdventureHelper.jsonToComponent(line), tokens))); - this.globalChanged = true; - getOrCreateTag().put(ComponentKeys.CUSTOM_NAME.asString(), NetworkItemHandler.pack(Operation.ADD, new StringTag(line))); - } - } - } - private void processModernCustomName() { Tag nameTag = this.item.getNBTComponent(ComponentTypes.CUSTOM_NAME); if (nameTag == null) return; @@ -173,7 +158,6 @@ public class ModernNetworkItemHandler implements NetworkItemHandler { private void processModernLore() { Tag loreTag = this.item.getNBTComponent(ComponentTypes.LORE); - if (loreTag == null) return; boolean changed = false; if (!(loreTag instanceof ListTag listTag)) { return; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java index ec9009aa4..45d3ceb87 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/BukkitItemFactory.java @@ -2,7 +2,6 @@ package net.momirealms.craftengine.bukkit.item.factory; import com.google.gson.JsonElement; import com.saicone.rtag.item.ItemTagStream; -import net.momirealms.craftengine.bukkit.item.LegacyItemWrapper; import net.momirealms.craftengine.bukkit.util.ItemTags; import net.momirealms.craftengine.bukkit.util.Reflections; import net.momirealms.craftengine.core.item.EquipmentData; diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java index ab28f1adf..0fb4724e7 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java @@ -19,11 +19,13 @@ import net.momirealms.craftengine.bukkit.plugin.command.BukkitSenderFactory; import net.momirealms.craftengine.bukkit.plugin.gui.BukkitGuiManager; import net.momirealms.craftengine.bukkit.plugin.injector.BukkitInjector; import net.momirealms.craftengine.bukkit.plugin.network.BukkitNetworkManager; +import net.momirealms.craftengine.bukkit.plugin.network.PacketConsumers; import net.momirealms.craftengine.bukkit.plugin.scheduler.BukkitSchedulerAdapter; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.bukkit.sound.BukkitSoundManager; import net.momirealms.craftengine.bukkit.util.EventUtils; import net.momirealms.craftengine.bukkit.util.Reflections; +import net.momirealms.craftengine.bukkit.util.RegistryUtils; import net.momirealms.craftengine.bukkit.world.BukkitWorldManager; import net.momirealms.craftengine.core.item.ItemManager; import net.momirealms.craftengine.core.plugin.CraftEngine; @@ -155,6 +157,7 @@ public class BukkitCraftEngine extends CraftEngine { BukkitBlockBehaviors.init(); BukkitItemBehaviors.init(); BukkitHitBoxTypes.init(); + PacketConsumers.initEntities(RegistryUtils.currentEntityTypeRegistrySize()); super.packManager = new BukkitPackManager(this); super.senderFactory = new BukkitSenderFactory(this); super.itemManager = new BukkitItemManager(this); 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 1f13e2383..399ad9d47 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 @@ -73,12 +73,57 @@ import java.util.*; import java.util.function.BiConsumer; public class PacketConsumers { + private static AddEntityHandler[] ADD_ENTITY_HANDLERS; private static int[] mappings; private static int[] mappingsMOD; private static IntIdentityList BLOCK_LIST; private static IntIdentityList BIOME_LIST; - public static void init(Map map, int registrySize) { + public static void initEntities(int registrySize) { + ADD_ENTITY_HANDLERS = new AddEntityHandler[registrySize]; + Arrays.fill(ADD_ENTITY_HANDLERS, AddEntityHandler.DO_NOTHING); + ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$FALLING_BLOCK$registryId] = (user, event) -> { + 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(); + // Falling blocks + int remapped = remap(data); + if (remapped != data) { + int xa = buf.readShort(); + int ya = buf.readShort(); + int za = buf.readShort(); + 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); + } + }; + ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$BLOCK_DISPLAY$registryId] = simpleAddEntityHandler(BlockDisplayPacketHandler.INSTANCE); + ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$TEXT_DISPLAY$registryId] = simpleAddEntityHandler(TextDisplayPacketHandler.INSTANCE); + ADD_ENTITY_HANDLERS[Reflections.instance$EntityType$ARMOR_STAND$registryId] = simpleAddEntityHandler(ArmorStandPacketHandler.INSTANCE); + } + + public static void initBlocks(Map map, int registrySize) { mappings = new int[registrySize]; for (int i = 0; i < registrySize; i++) { mappings[i] = i; @@ -1345,47 +1390,10 @@ public class PacketConsumers { public static final BiConsumer ADD_ENTITY_BYTEBUFFER = (user, event) -> { try { FriendlyByteBuf buf = event.getBuffer(); - int id = buf.readVarInt(); - UUID uuid = buf.readUUID(); + buf.readVarInt(); + 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.entityPacketHandlers().put(id, BlockDisplayPacketHandler.INSTANCE); - } else if (type == Reflections.instance$EntityType$TEXT_DISPLAY$registryId) { - user.entityPacketHandlers().put(id, TextDisplayPacketHandler.INSTANCE); - } else if (type == Reflections.instance$EntityType$ARMOR_STAND$registryId) { - user.entityPacketHandlers().put(id, ArmorStandPacketHandler.INSTANCE); - } + ADD_ENTITY_HANDLERS[type].accept(user, event); } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ClientboundAddEntityPacket", e); } @@ -2262,4 +2270,21 @@ public class PacketConsumers { CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e); } }; + + @FunctionalInterface + public interface AddEntityHandler extends BiConsumer { + AddEntityHandler DO_NOTHING = doNothing(); + + static AddEntityHandler doNothing() { + return (user, byteBufPacketEvent) -> { + }; + } + } + + private static AddEntityHandler simpleAddEntityHandler(EntityPacketHandler handler) { + return (user, event) -> { + FriendlyByteBuf buf = event.getBuffer(); + user.entityPacketHandlers().put(buf.readVarInt(), handler); + }; + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/RegistryUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/RegistryUtils.java index 52390c0bf..063ce0797 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/RegistryUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/RegistryUtils.java @@ -20,4 +20,13 @@ public class RegistryUtils { throw new RuntimeException(e); } } + + public static int currentEntityTypeRegistrySize() { + try { + Object idMap = Reflections.method$Registry$asHolderIdMap.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE); + return (int) Reflections.method$IdMap$size.invoke(idMap); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ComponentIds.java b/core/src/main/java/net/momirealms/craftengine/core/item/ComponentIds.java new file mode 100644 index 000000000..629439c97 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ComponentIds.java @@ -0,0 +1,9 @@ +package net.momirealms.craftengine.core.item; + +public final class ComponentIds { + private ComponentIds() {} + + public static final String ITEM_NAME = "minecraft:item_name"; + public static final String CUSTOM_NAME = "minecraft:custom_name"; + public static final String LORE = "minecraft:lore"; +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ComponentKeys.java b/core/src/main/java/net/momirealms/craftengine/core/item/ComponentKeys.java index bc64868d0..813ac6486 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ComponentKeys.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ComponentKeys.java @@ -2,7 +2,9 @@ package net.momirealms.craftengine.core.item; import net.momirealms.craftengine.core.util.Key; -public class ComponentKeys { +public final class ComponentKeys { + private ComponentKeys() {} + public static final Key CUSTOM_MODEL_DATA = Key.of("minecraft", "custom_model_data"); public static final Key CUSTOM_NAME = Key.of("minecraft", "custom_name"); public static final Key ITEM_NAME = Key.of("minecraft", "item_name");