diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/item/MMOItemsProvider.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/item/MMOItemsProvider.java index a22ade2d0..c466f82ca 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/item/MMOItemsProvider.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/item/MMOItemsProvider.java @@ -14,6 +14,7 @@ import java.util.Locale; import static java.util.Objects.requireNonNull; public class MMOItemsProvider implements ExternalItemProvider { + @Override public String plugin() { return "MMOItems"; diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index 79c9af030..78ff3ec52 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -163,6 +163,7 @@ image: team: true scoreboard: true entity-name: false + armor-stand: true text-display: true emoji: {} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index 239bc3e61..88c6c4617 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -63,18 +63,20 @@ public class BlockEventListener implements Listener { if (Config.enableSoundSystem()) { Block block = event.getBlock(); Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData()); - Object ownerBlock = BlockStateUtils.getBlockOwner(blockState); - if (this.manager.isBlockSoundRemoved(ownerBlock)) { - if (player.getInventory().getItemInMainHand().getType() != Material.DEBUG_STICK) { - try { - Object soundType = Reflections.field$BlockBehaviour$soundType.get(ownerBlock); - Object placeSound = Reflections.field$SoundType$placeSound.get(soundType); - player.playSound(block.getLocation(), Reflections.field$SoundEvent$location.get(placeSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f); - } catch (ReflectiveOperationException e) { - this.plugin.logger().warn("Failed to get sound type", e); + if (blockState != Reflections.instance$Blocks$AIR$defaultState) { + Object ownerBlock = BlockStateUtils.getBlockOwner(blockState); + if (this.manager.isBlockSoundRemoved(ownerBlock)) { + if (player.getInventory().getItemInMainHand().getType() != Material.DEBUG_STICK) { + try { + Object soundType = Reflections.field$BlockBehaviour$soundType.get(ownerBlock); + Object placeSound = Reflections.field$SoundType$placeSound.get(soundType); + player.playSound(block.getLocation(), Reflections.field$SoundEvent$location.get(placeSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f); + } catch (ReflectiveOperationException e) { + this.plugin.logger().warn("Failed to get sound type", e); + } } + return; } - return; } } // resend sound if the clicked block is interactable on client side 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 bf9365b43..730920314 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 @@ -311,7 +311,10 @@ public class BukkitBlockManager extends AbstractBlockManager { for (Object block : (Iterable) Reflections.instance$BuiltInRegistries$BLOCK) { Object soundType = Reflections.field$BlockBehaviour$soundType.get(block); if (affectedSounds.contains(soundType)) { - affectedBlocks.add(block); + Object state = getOnlyBlockState(block); + if (BlockStateUtils.isVanillaBlock(state)) { + affectedBlocks.add(block); + } } } 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 e43ab1555..4816cd91f 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 @@ -139,14 +139,13 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerNMSPacketConsumer(PacketConsumers.SYNC_ENTITY_POSITION, Reflections.clazz$ClientboundEntityPositionSyncPacket); registerNMSPacketConsumer(PacketConsumers.MOVE_ENTITY, Reflections.clazz$ClientboundMoveEntityPacket$Pos); registerNMSPacketConsumer(PacketConsumers.PICK_ITEM_FROM_ENTITY, Reflections.clazz$ServerboundPickItemFromEntityPacket); - registerNMSPacketConsumer(PacketConsumers.SOUND, Reflections.clazz$ClientboundSoundPacket); registerNMSPacketConsumer(PacketConsumers.RENAME_ITEM, Reflections.clazz$ServerboundRenameItemPacket); registerNMSPacketConsumer(PacketConsumers.SIGN_UPDATE, Reflections.clazz$ServerboundSignUpdatePacket); registerNMSPacketConsumer(PacketConsumers.EDIT_BOOK, Reflections.clazz$ServerboundEditBookPacket); registerNMSPacketConsumer(PacketConsumers.CUSTOM_PAYLOAD, Reflections.clazz$ServerboundCustomPayloadPacket); registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket()); registerByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket()); - registerByteBufPacketConsumer(PacketConsumers.LEVEL_PARTICLE, this.packetIds.clientboundLevelParticlesPacket()); + 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()); registerByteBufPacketConsumer(PacketConsumers.LEVEL_EVENT, this.packetIds.clientboundLevelEventPacket()); 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()); @@ -159,6 +158,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerByteBufPacketConsumer(VersionHelper.isVersionNewerThan1_20_3() ? PacketConsumers.SET_OBJECTIVE_1_20_3 : PacketConsumers.SET_OBJECTIVE_1_20, this.packetIds.clientboundSetObjectivePacket()); 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()); } 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 a40076531..2fce786b1 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 @@ -39,7 +39,6 @@ import org.bukkit.inventory.PlayerInventory; import org.bukkit.util.RayTraceResult; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.function.BiConsumer; @@ -241,25 +240,6 @@ public class PacketConsumers { } }; - public static final TriConsumer SOUND = (user, event, packet) -> { - try { - Object soundEvent = FastNMS.INSTANCE.field$ClientboundSoundPacket$soundEvent(packet); - Key soundId = Key.of(FastNMS.INSTANCE.field$SoundEvent$location(soundEvent).toString()); - Key mapped = BukkitBlockManager.instance().replaceSoundIfExist(soundId); - if (mapped != null) { - event.setCancelled(true); - Object newId = FastNMS.INSTANCE.method$ResourceLocation$fromNamespaceAndPath(mapped.namespace(), mapped.value()); - Object newSoundEvent = VersionHelper.isVersionNewerThan1_21_2() ? - Reflections.constructor$SoundEvent.newInstance(newId, Reflections.field$SoundEvent$fixedRange.get(soundEvent)) : - Reflections.constructor$SoundEvent.newInstance(newId, Reflections.field$SoundEvent$range.get(soundEvent), Reflections.field$SoundEvent$newSystem.get(soundEvent)); - Object newSoundPacket = FastNMS.INSTANCE.fastConstructor$ClientboundSoundPacket(newSoundEvent, packet); - user.sendPacket(newSoundPacket, true); - } - } catch (Exception e) { - CraftEngine.instance().logger().warn("Failed to handle ClientboundSoundPacket", e); - } - }; - public static final BiConsumer TEAM_1_20_3 = (user, event) -> { if (!Config.interceptTeam()) return; try { @@ -280,9 +260,9 @@ public class PacketConsumers { Tag suffix = buf.readNbt(false); if (suffix == null) return; - Map tokens1 = CraftEngine.instance().imageManager().matchTags(displayName.getAsString()); - Map tokens2 = CraftEngine.instance().imageManager().matchTags(prefix.getAsString()); - Map tokens3 = CraftEngine.instance().imageManager().matchTags(suffix.getAsString()); + Map tokens1 = CraftEngine.instance().imageManager().matchTags(displayName.getAsString()); + Map tokens2 = CraftEngine.instance().imageManager().matchTags(prefix.getAsString()); + Map tokens3 = CraftEngine.instance().imageManager().matchTags(suffix.getAsString()); if (tokens1.isEmpty() && tokens2.isEmpty() && tokens3.isEmpty()) return; event.setChanged(true); @@ -300,8 +280,8 @@ public class PacketConsumers { if (!tokens1.isEmpty()) { Component component = AdventureHelper.tagToComponent(displayName); - for (Map.Entry token : tokens1.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens1.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.writeNbt(AdventureHelper.componentToTag(component), false); } else { @@ -315,8 +295,8 @@ public class PacketConsumers { if (!tokens2.isEmpty()) { Component component = AdventureHelper.tagToComponent(prefix); - for (Map.Entry token : tokens2.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens2.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.writeNbt(AdventureHelper.componentToTag(component), false); } else { @@ -325,8 +305,8 @@ public class PacketConsumers { if (!tokens3.isEmpty()) { Component component = AdventureHelper.tagToComponent(suffix); - for (Map.Entry token : tokens3.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens3.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.writeNbt(AdventureHelper.componentToTag(component), false); } else { @@ -358,9 +338,9 @@ public class PacketConsumers { String prefix = buf.readUtf(); String suffix = buf.readUtf(); - Map tokens1 = CraftEngine.instance().imageManager().matchTags(displayName); - Map tokens2 = CraftEngine.instance().imageManager().matchTags(prefix); - Map tokens3 = CraftEngine.instance().imageManager().matchTags(suffix); + Map tokens1 = CraftEngine.instance().imageManager().matchTags(displayName); + Map tokens2 = CraftEngine.instance().imageManager().matchTags(prefix); + Map tokens3 = CraftEngine.instance().imageManager().matchTags(suffix); if (tokens1.isEmpty() && tokens2.isEmpty() && tokens3.isEmpty()) return; event.setChanged(true); @@ -378,8 +358,8 @@ public class PacketConsumers { if (!tokens1.isEmpty()) { Component component = AdventureHelper.jsonToComponent(displayName); - for (Map.Entry token : tokens1.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens1.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.writeUtf(AdventureHelper.componentToJson(component)); } else { @@ -393,8 +373,8 @@ public class PacketConsumers { if (!tokens2.isEmpty()) { Component component = AdventureHelper.jsonToComponent(prefix); - for (Map.Entry token : tokens2.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens2.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.writeUtf(AdventureHelper.componentToJson(component)); } else { @@ -403,8 +383,8 @@ public class PacketConsumers { if (!tokens3.isEmpty()) { Component component = AdventureHelper.jsonToComponent(suffix); - for (Map.Entry token : tokens3.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens3.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.writeUtf(AdventureHelper.componentToJson(component)); } else { @@ -427,11 +407,11 @@ public class PacketConsumers { int actionType = buf.readVarInt(); if (actionType == 0) { String json = buf.readUtf(); - Map tokens = CraftEngine.instance().imageManager().matchTags(json); + Map tokens = CraftEngine.instance().imageManager().matchTags(json); if (tokens.isEmpty()) return; 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()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } float health = buf.readFloat(); int color = buf.readVarInt(); @@ -449,12 +429,12 @@ public class PacketConsumers { buf.writeByte(flag); } else if (actionType == 3) { String json = buf.readUtf(); - Map tokens = CraftEngine.instance().imageManager().matchTags(json); + 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()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -476,11 +456,11 @@ public class PacketConsumers { if (actionType == 0) { Tag nbt = buf.readNbt(false); if (nbt == null) return; - Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); if (tokens.isEmpty()) return; Component component = AdventureHelper.tagToComponent(nbt); - for (Map.Entry token : tokens.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } float health = buf.readFloat(); int color = buf.readVarInt(); @@ -499,12 +479,12 @@ public class PacketConsumers { } else if (actionType == 3) { Tag nbt = buf.readNbt(false); if (nbt == null) return; - Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); if (tokens.isEmpty()) return; event.setChanged(true); Component component = AdventureHelper.tagToComponent(nbt); - for (Map.Entry token : tokens.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -526,12 +506,12 @@ public class PacketConsumers { if (mode != 0 && mode != 2) return; String displayName = buf.readUtf(); int renderType = buf.readVarInt(); - Map tokens = CraftEngine.instance().imageManager().matchTags(displayName); + Map tokens = CraftEngine.instance().imageManager().matchTags(displayName); if (tokens.isEmpty()) return; event.setChanged(true); Component component = AdventureHelper.jsonToComponent(displayName); - for (Map.Entry token : tokens.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -558,12 +538,12 @@ public class PacketConsumers { if (optionalNumberFormat) { int format = buf.readVarInt(); if (format == 0) { - Map tokens = CraftEngine.instance().imageManager().matchTags(displayName.getAsString()); + Map tokens = CraftEngine.instance().imageManager().matchTags(displayName.getAsString()); if (tokens.isEmpty()) return; event.setChanged(true); Component component = AdventureHelper.tagToComponent(displayName); - for (Map.Entry token : tokens.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -574,13 +554,13 @@ public class PacketConsumers { buf.writeBoolean(true); buf.writeVarInt(0); } else if (format == 1) { - Map tokens = CraftEngine.instance().imageManager().matchTags(displayName.getAsString()); + Map tokens = CraftEngine.instance().imageManager().matchTags(displayName.getAsString()); if (tokens.isEmpty()) return; Tag style = buf.readNbt(false); event.setChanged(true); Component component = AdventureHelper.tagToComponent(displayName); - for (Map.Entry token : tokens.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -594,8 +574,8 @@ public class PacketConsumers { } else if (format == 2) { Tag fixed = buf.readNbt(false); if (fixed == null) return; - Map tokens1 = CraftEngine.instance().imageManager().matchTags(displayName.getAsString()); - Map tokens2 = CraftEngine.instance().imageManager().matchTags(fixed.getAsString()); + Map tokens1 = CraftEngine.instance().imageManager().matchTags(displayName.getAsString()); + Map tokens2 = CraftEngine.instance().imageManager().matchTags(fixed.getAsString()); if (tokens1.isEmpty() && tokens2.isEmpty()) return; event.setChanged(true); buf.clear(); @@ -604,8 +584,8 @@ public class PacketConsumers { buf.writeByte(mode); if (!tokens1.isEmpty()) { Component component = AdventureHelper.tagToComponent(displayName); - for (Map.Entry token : tokens1.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens1.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.writeNbt(AdventureHelper.componentToTag(component), false); } else { @@ -616,8 +596,8 @@ public class PacketConsumers { buf.writeVarInt(2); if (!tokens2.isEmpty()) { Component component = AdventureHelper.tagToComponent(fixed); - for (Map.Entry token : tokens2.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens2.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.writeNbt(AdventureHelper.componentToTag(component), false); } else { @@ -625,12 +605,12 @@ public class PacketConsumers { } } } else { - Map tokens = CraftEngine.instance().imageManager().matchTags(displayName.getAsString()); + Map tokens = CraftEngine.instance().imageManager().matchTags(displayName.getAsString()); if (tokens.isEmpty()) return; event.setChanged(true); Component component = AdventureHelper.tagToComponent(displayName); - for (Map.Entry token : tokens.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -650,13 +630,13 @@ public class PacketConsumers { try { FriendlyByteBuf buf = event.getBuffer(); String jsonOrPlainString = buf.readUtf(); - Map tokens = CraftEngine.instance().imageManager().matchTags(jsonOrPlainString); + Map tokens = CraftEngine.instance().imageManager().matchTags(jsonOrPlainString); if (tokens.isEmpty()) return; boolean overlay = buf.readBoolean(); event.setChanged(true); Component component = AdventureHelper.jsonToComponent(jsonOrPlainString); - for (Map.Entry token : tokens.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -673,13 +653,13 @@ public class PacketConsumers { FriendlyByteBuf buf = event.getBuffer(); Tag nbt = buf.readNbt(false); if (nbt == null) return; - Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); if (tokens.isEmpty()) return; boolean overlay = buf.readBoolean(); event.setChanged(true); Component component = AdventureHelper.tagToComponent(nbt); - for (Map.Entry token : tokens.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -695,12 +675,12 @@ public class PacketConsumers { try { FriendlyByteBuf buf = event.getBuffer(); String json = buf.readUtf(); - Map tokens = CraftEngine.instance().imageManager().matchTags(json); + 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()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -716,12 +696,12 @@ public class PacketConsumers { FriendlyByteBuf buf = event.getBuffer(); Tag nbt = buf.readNbt(false); if (nbt == null) return; - Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); if (tokens.isEmpty()) return; event.setChanged(true); Component component = AdventureHelper.tagToComponent(nbt); - for (Map.Entry token : tokens.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -736,12 +716,12 @@ public class PacketConsumers { try { FriendlyByteBuf buf = event.getBuffer(); String json = buf.readUtf(); - Map tokens = CraftEngine.instance().imageManager().matchTags(json); + 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()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -757,12 +737,12 @@ public class PacketConsumers { FriendlyByteBuf buf = event.getBuffer(); Tag nbt = buf.readNbt(false); if (nbt == null) return; - Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); if (tokens.isEmpty()) return; event.setChanged(true); Component component = AdventureHelper.tagToComponent(nbt); - for (Map.Entry token : tokens.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -777,12 +757,12 @@ public class PacketConsumers { try { FriendlyByteBuf buf = event.getBuffer(); String json = buf.readUtf(); - Map tokens = CraftEngine.instance().imageManager().matchTags(json); + 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()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -798,12 +778,12 @@ public class PacketConsumers { FriendlyByteBuf buf = event.getBuffer(); Tag nbt = buf.readNbt(false); if (nbt == null) return; - Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); if (tokens.isEmpty()) return; event.setChanged(true); Component component = AdventureHelper.tagToComponent(nbt); - for (Map.Entry token : tokens.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -819,16 +799,16 @@ public class PacketConsumers { 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); + 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()))); + for (Map.Entry token : tokens1.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.writeUtf(AdventureHelper.componentToJson(component)); } else { @@ -836,8 +816,8 @@ public class PacketConsumers { } 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()))); + for (Map.Entry token : tokens2.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.writeUtf(AdventureHelper.componentToJson(component)); } else { @@ -856,16 +836,16 @@ public class PacketConsumers { 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()); + 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 = AdventureHelper.tagToComponent(nbt1); - for (Map.Entry token : tokens1.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens1.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.writeNbt(AdventureHelper.componentToTag(component), false); } else { @@ -873,8 +853,8 @@ public class PacketConsumers { } if (!tokens2.isEmpty()) { Component component = AdventureHelper.tagToComponent(nbt2); - for (Map.Entry token : tokens2.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens2.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.writeNbt(AdventureHelper.componentToTag(component), false); } else { @@ -892,12 +872,12 @@ public class PacketConsumers { int containerId = buf.readVarInt(); int type = buf.readVarInt(); String json = buf.readUtf(); - Map tokens = CraftEngine.instance().imageManager().matchTags(json); + 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()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -917,11 +897,11 @@ public class PacketConsumers { int type = buf.readVarInt(); Tag nbt = buf.readNbt(false); if (nbt == null) return; - Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); + Map tokens = CraftEngine.instance().imageManager().matchTags(nbt.getAsString()); if (tokens.isEmpty()) return; Component component = AdventureHelper.tagToComponent(nbt); - for (Map.Entry token : tokens.entrySet()) { - component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(AdventureHelper.miniMessage().deserialize(token.getValue()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } buf.clear(); buf.writeVarInt(event.packetID()); @@ -933,31 +913,122 @@ public class PacketConsumers { } }; - public static final BiConsumer LEVEL_PARTICLE = (user, event) -> { + public static final BiConsumer LEVEL_PARTICLE_1_21_3 = (user, event) -> { try { FriendlyByteBuf buf = event.getBuffer(); - Object mcByteBuf; - Method writeMethod; - if (VersionHelper.isVersionNewerThan1_20_5()) { - mcByteBuf = Reflections.constructor$RegistryFriendlyByteBuf.newInstance(buf, Reflections.instance$registryAccess); - writeMethod = Reflections.method$ClientboundLevelParticlesPacket$write; - } else { - mcByteBuf = Reflections.constructor$FriendlyByteBuf.newInstance(event.getBuffer().source()); - writeMethod = Reflections.method$Packet$write; - } - Object packet = Reflections.constructor$ClientboundLevelParticlesPacket.newInstance(mcByteBuf); - Object option = FastNMS.INSTANCE.field$ClientboundLevelParticlesPacket$particle(packet); + boolean overrideLimiter = buf.readBoolean(); + boolean alwaysShow = buf.readBoolean(); + double x = buf.readDouble(); + double y = buf.readDouble(); + double z = buf.readDouble(); + float xDist = buf.readFloat(); + float yDist = buf.readFloat(); + float zDist = buf.readFloat(); + float maxSpeed = buf.readFloat(); + int count = buf.readInt(); + Object option = FastNMS.INSTANCE.method$ParticleTypes$STREAM_CODEC$decode(buf); if (option == null) return; if (!Reflections.clazz$BlockParticleOption.isInstance(option)) return; Object blockState = FastNMS.INSTANCE.field$BlockParticleOption$blockState(option); int id = BlockStateUtils.blockStateToId(blockState); int remapped = remap(id); if (remapped == id) return; - Reflections.field$BlockParticleOption$blockState.set(option, BlockStateUtils.idToBlockState(remapped)); + Object type = FastNMS.INSTANCE.method$BlockParticleOption$getType(option); + Object remappedOption = FastNMS.INSTANCE.constructor$BlockParticleOption(type, BlockStateUtils.idToBlockState(remapped)); event.setChanged(true); buf.clear(); buf.writeVarInt(event.packetID()); - writeMethod.invoke(packet, mcByteBuf); + buf.writeBoolean(overrideLimiter); + buf.writeBoolean(alwaysShow); + buf.writeDouble(x); + buf.writeDouble(y); + buf.writeDouble(z); + buf.writeFloat(xDist); + buf.writeFloat(yDist); + buf.writeFloat(zDist); + buf.writeFloat(maxSpeed); + buf.writeInt(count); + FastNMS.INSTANCE.method$ParticleTypes$STREAM_CODEC$encode(buf, remappedOption); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundLevelParticlesPacket", e); + } + }; + + public static final BiConsumer LEVEL_PARTICLE_1_20_5 = (user, event) -> { + try { + FriendlyByteBuf buf = event.getBuffer(); + boolean overrideLimiter = buf.readBoolean(); + double x = buf.readDouble(); + double y = buf.readDouble(); + double z = buf.readDouble(); + float xDist = buf.readFloat(); + float yDist = buf.readFloat(); + float zDist = buf.readFloat(); + float maxSpeed = buf.readFloat(); + int count = buf.readInt(); + Object option = FastNMS.INSTANCE.method$ParticleTypes$STREAM_CODEC$decode(buf); + if (option == null) return; + if (!Reflections.clazz$BlockParticleOption.isInstance(option)) return; + Object blockState = FastNMS.INSTANCE.field$BlockParticleOption$blockState(option); + int id = BlockStateUtils.blockStateToId(blockState); + int remapped = remap(id); + if (remapped == id) return; + Object type = FastNMS.INSTANCE.method$BlockParticleOption$getType(option); + Object remappedOption = FastNMS.INSTANCE.constructor$BlockParticleOption(type, BlockStateUtils.idToBlockState(remapped)); + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeBoolean(overrideLimiter); + buf.writeDouble(x); + buf.writeDouble(y); + buf.writeDouble(z); + buf.writeFloat(xDist); + buf.writeFloat(yDist); + buf.writeFloat(zDist); + buf.writeFloat(maxSpeed); + buf.writeInt(count); + FastNMS.INSTANCE.method$ParticleTypes$STREAM_CODEC$encode(buf, remappedOption); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundLevelParticlesPacket", e); + } + }; + + public static final BiConsumer LEVEL_PARTICLE_1_20 = (user, event) -> { + try { + FriendlyByteBuf buf = event.getBuffer(); + Object particleType = FastNMS.INSTANCE.method$FriendlyByteBuf$readById(buf, Reflections.instance$BuiltInRegistries$PARTICLE_TYPE); + boolean overrideLimiter = buf.readBoolean(); + double x = buf.readDouble(); + double y = buf.readDouble(); + double z = buf.readDouble(); + float xDist = buf.readFloat(); + float yDist = buf.readFloat(); + float zDist = buf.readFloat(); + float maxSpeed = buf.readFloat(); + int count = buf.readInt(); + Object option = FastNMS.INSTANCE.method$ClientboundLevelParticlesPacket$readParticle(buf, particleType); + if (option == null) return; + if (!Reflections.clazz$BlockParticleOption.isInstance(option)) return; + Object blockState = FastNMS.INSTANCE.field$BlockParticleOption$blockState(option); + int id = BlockStateUtils.blockStateToId(blockState); + int remapped = remap(id); + if (remapped == id) return; + Object type = FastNMS.INSTANCE.method$BlockParticleOption$getType(option); + Object remappedOption = FastNMS.INSTANCE.constructor$BlockParticleOption(type, BlockStateUtils.idToBlockState(remapped)); + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + FastNMS.INSTANCE.method$FriendlyByteBuf$writeId(buf, remappedOption, Reflections.instance$BuiltInRegistries$PARTICLE_TYPE); + buf.writeBoolean(overrideLimiter); + buf.writeDouble(x); + buf.writeDouble(y); + buf.writeDouble(z); + buf.writeFloat(xDist); + buf.writeFloat(yDist); + buf.writeFloat(zDist); + buf.writeFloat(maxSpeed); + buf.writeInt(count); + FastNMS.INSTANCE.method$ParticleOptions$writeToNetwork(remappedOption, buf); } catch (Exception e) { CraftEngine.instance().logger().warn("Failed to handle ClientboundLevelParticlesPacket", e); } @@ -1492,6 +1563,81 @@ public class PacketConsumers { } }; + public static final BiConsumer SOUND = (user, event) -> { + try { + FriendlyByteBuf buf = event.getBuffer(); + int id = buf.readVarInt(); + if (id == 0) { + Key soundId = buf.readKey(); + Float range = null; + if (buf.readBoolean()) { + range = buf.readFloat(); + } + int source = buf.readVarInt(); + int x = buf.readInt(); + int y = buf.readInt(); + int z = buf.readInt(); + float volume = buf.readFloat(); + float pitch = buf.readFloat(); + long seed = buf.readLong(); + Key mapped = BukkitBlockManager.instance().replaceSoundIfExist(soundId); + if (mapped != null) { + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeVarInt(0); + buf.writeKey(mapped); + if (range != null) { + buf.writeBoolean(true); + buf.writeFloat(range); + } else { + buf.writeBoolean(false); + } + buf.writeVarInt(source); + buf.writeInt(x); + buf.writeInt(y); + buf.writeInt(z); + buf.writeFloat(volume); + buf.writeFloat(pitch); + buf.writeLong(seed); + } + } else { + Optional optionalSound = FastNMS.INSTANCE.method$BuiltInRegistries$byId(Reflections.instance$BuiltInRegistries$SOUND_EVENT, id - 1); + if (optionalSound.isEmpty()) return; + Object soundEvent = optionalSound.get(); + Key soundId = Key.of(FastNMS.INSTANCE.method$SoundEvent$location(soundEvent)); + int source = buf.readVarInt(); + int x = buf.readInt(); + int y = buf.readInt(); + int z = buf.readInt(); + float volume = buf.readFloat(); + float pitch = buf.readFloat(); + long seed = buf.readLong(); + Key mapped = BukkitBlockManager.instance().replaceSoundIfExist(soundId); + if (mapped != null) { + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeVarInt(0); + Object newId = KeyUtils.toResourceLocation(mapped); + Object newSoundEvent = VersionHelper.isVersionNewerThan1_21_2() ? + Reflections.constructor$SoundEvent.newInstance(newId, Reflections.field$SoundEvent$fixedRange.get(soundEvent)) : + Reflections.constructor$SoundEvent.newInstance(newId, Reflections.field$SoundEvent$range.get(soundEvent), Reflections.field$SoundEvent$newSystem.get(soundEvent)); + FastNMS.INSTANCE.method$SoundEvent$directEncode(buf, newSoundEvent); + buf.writeVarInt(source); + buf.writeInt(x); + buf.writeInt(y); + buf.writeInt(z); + buf.writeFloat(volume); + buf.writeFloat(pitch); + buf.writeLong(seed); + } + } + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundSoundPacket", e); + } + }; + // we handle it on packet level to prevent it from being captured by plugins public static final TriConsumer RENAME_ITEM = (user, event, packet) -> { try { @@ -1715,11 +1861,11 @@ public class PacketConsumers { if (optionalTextComponent.isPresent()) { Object textComponent = optionalTextComponent.get(); String json = ComponentUtils.minecraftToJson(textComponent); - Map tokens = CraftEngine.instance().imageManager().matchTags(json); + Map tokens = CraftEngine.instance().imageManager().matchTags(json); if (!tokens.isEmpty()) { 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()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem); packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue( @@ -1737,10 +1883,10 @@ public class PacketConsumers { buf.writeVarInt(id); FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf); } - } else if (Config.interceptEntityName()) { - boolean isChanged = false; - List packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf); - if (entityType == Reflections.instance$EntityType$TEXT_DISPLAY) { + } else if (entityType == Reflections.instance$EntityType$TEXT_DISPLAY) { + if (Config.interceptTextDisplay()) { + boolean isChanged = false; + List packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf); for (int i = 0; i < packedItems.size(); i++) { Object packedItem = packedItems.get(i); int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem); @@ -1748,11 +1894,11 @@ public class PacketConsumers { Object textComponent = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem); if (textComponent == Reflections.instance$Component$empty) break; String json = ComponentUtils.minecraftToJson(textComponent); - Map tokens = CraftEngine.instance().imageManager().matchTags(json); + Map tokens = CraftEngine.instance().imageManager().matchTags(json); if (!tokens.isEmpty()) { 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()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem); packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(entityDataId, serializer, ComponentUtils.adventureToMinecraft(component))); @@ -1761,7 +1907,18 @@ public class PacketConsumers { } } } - } else { + if (isChanged) { + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeVarInt(id); + FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf); + } + } + } else if (entityType == Reflections.instance$EntityType$ARMOR_STAND) { + if (Config.interceptArmorStand()) { + boolean isChanged = false; + List packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf); for (int i = 0; i < packedItems.size(); i++) { Object packedItem = packedItems.get(i); int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem); @@ -1770,11 +1927,11 @@ public class PacketConsumers { if (optionalTextComponent.isPresent()) { Object textComponent = optionalTextComponent.get(); String json = ComponentUtils.minecraftToJson(textComponent); - Map tokens = CraftEngine.instance().imageManager().matchTags(json); + Map tokens = CraftEngine.instance().imageManager().matchTags(json); if (!tokens.isEmpty()) { 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()))); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); } Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem); packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(entityDataId, serializer, Optional.of(ComponentUtils.adventureToMinecraft(component)))); @@ -1784,6 +1941,38 @@ public class PacketConsumers { } } } + if (isChanged) { + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeVarInt(id); + FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$pack(packedItems, buf); + } + } + } else if (Config.interceptEntityName()) { + boolean isChanged = false; + List packedItems = FastNMS.INSTANCE.method$ClientboundSetEntityDataPacket$unpack(buf); + 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.CUSTOM_NAME_DATA_ID) { + Optional optionalTextComponent = (Optional) FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem); + if (optionalTextComponent.isPresent()) { + Object textComponent = optionalTextComponent.get(); + String json = ComponentUtils.minecraftToJson(textComponent); + Map tokens = CraftEngine.instance().imageManager().matchTags(json); + if (!tokens.isEmpty()) { + Component component = AdventureHelper.jsonToComponent(json); + for (Map.Entry token : tokens.entrySet()) { + component = component.replaceText(b -> b.matchLiteral(token.getKey()).replacement(token.getValue())); + } + Object serializer = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$serializer(packedItem); + packedItems.set(i, FastNMS.INSTANCE.constructor$SynchedEntityData$DataValue(entityDataId, serializer, Optional.of(ComponentUtils.adventureToMinecraft(component)))); + isChanged = true; + break; + } + } + } } if (isChanged) { event.setChanged(true); 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 679af61e3..060d79728 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 @@ -35,4 +35,6 @@ public interface PacketIds { int clientboundSetPlayerTeamPacket(); int clientboundSetObjectivePacket(); + + int clientboundLevelChunkWithLightPacket(); } 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 de1ba2be7..bbf6bfbaf 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 @@ -89,4 +89,9 @@ public class PacketIds1_20 implements PacketIds { public int clientboundSetObjectivePacket() { return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundSetObjectivePacket); } + + @Override + public int clientboundLevelChunkWithLightPacket() { + return PacketIdFinder.clientboundByClazz(Reflections.clazz$ClientboundLevelChunkWithLightPacket); + } } 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 1574df2ee..8acbd3d52 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 @@ -88,4 +88,9 @@ public class PacketIds1_20_5 implements PacketIds { public int clientboundSetObjectivePacket() { return PacketIdFinder.clientboundByName("minecraft:set_objective"); } + + @Override + public int clientboundLevelChunkWithLightPacket() { + return PacketIdFinder.clientboundByName("minecraft:level_chunk_with_light"); + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/sound/BukkitSoundManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/sound/BukkitSoundManager.java index 2c1d4aacd..1f9203366 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/sound/BukkitSoundManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/sound/BukkitSoundManager.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.bukkit.sound; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.util.ComponentUtils; import net.momirealms.craftengine.bukkit.util.KeyUtils; import net.momirealms.craftengine.bukkit.util.Reflections; @@ -17,6 +18,7 @@ public class BukkitSoundManager extends AbstractSoundManager { public BukkitSoundManager(CraftEngine plugin) { super(plugin); + VANILLA_SOUND_EVENTS.addAll(FastNMS.INSTANCE.getAllVanillaSounds().stream().map(it -> Key.of(it.getNamespace(), it.getKey())).toList()); } @Override 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 13dea6c76..7c67dbc05 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 @@ -3706,6 +3706,7 @@ public class Reflections { public static final Object instance$EntityType$TEXT_DISPLAY; public static final Object instance$EntityType$ITEM_DISPLAY; public static final Object instance$EntityType$BLOCK_DISPLAY; + public static final Object instance$EntityType$ARMOR_STAND; public static final Object instance$EntityType$FALLING_BLOCK; public static final Object instance$EntityType$INTERACTION; public static final Object instance$EntityType$SHULKER; @@ -3724,6 +3725,8 @@ public class Reflections { instance$EntityType$INTERACTION = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, interaction); Object shulker = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "shulker"); instance$EntityType$SHULKER = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, shulker); + Object armorStand = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "armor_stand"); + instance$EntityType$ARMOR_STAND = Reflections.method$Registry$get.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, armorStand); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/BlockSounds.java b/core/src/main/java/net/momirealms/craftengine/core/block/BlockSounds.java index 180708712..04ffd23a1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/BlockSounds.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/BlockSounds.java @@ -39,7 +39,7 @@ public class BlockSounds { return new BlockSounds( SoundData.create(map.getOrDefault("break", "minecraft:intentionally_empty"), 1f, 0.8f), SoundData.create(map.getOrDefault("step", "minecraft:intentionally_empty"), 0.15f, 1f), - SoundData.create(map.getOrDefault("place", "minecraft:intentionally_empty"), 0f, 0.8f), // todo 0? + SoundData.create(map.getOrDefault("place", "minecraft:intentionally_empty"), 1f, 0.8f), SoundData.create(map.getOrDefault("hit", "minecraft:intentionally_empty"), 0.5f, 0.5f), SoundData.create(map.getOrDefault("fall", "minecraft:intentionally_empty"), 0.5f, 0.75f), SoundData.create(map.getOrDefault("land", "minecraft:intentionally_empty"), 0.3f, 1f), diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java index 11ae91ea3..77d1e3c6c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java @@ -1,15 +1,13 @@ package net.momirealms.craftengine.core.font; +import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.pack.LoadingSequence; import net.momirealms.craftengine.core.pack.Pack; import net.momirealms.craftengine.core.pack.ResourceLocation; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; import net.momirealms.craftengine.core.plugin.locale.TranslationManager; -import net.momirealms.craftengine.core.util.CharacterUtils; -import net.momirealms.craftengine.core.util.FormatUtils; -import net.momirealms.craftengine.core.util.Key; -import net.momirealms.craftengine.core.util.MiscUtils; +import net.momirealms.craftengine.core.util.*; import org.ahocorasick.trie.Token; import org.ahocorasick.trie.Trie; @@ -31,7 +29,7 @@ public abstract class AbstractFontManager implements FontManager { private OffsetFont offsetFont; private Trie trie; - private Map tagMapper; + private Map tagMapper; public AbstractFontManager(CraftEngine plugin) { this.plugin = plugin; @@ -54,11 +52,11 @@ public abstract class AbstractFontManager implements FontManager { } @Override - public Map matchTags(String json) { + public Map matchTags(String json) { if (this.trie == null) { return Collections.emptyMap(); } - Map tags = new HashMap<>(); + Map tags = new HashMap<>(); for (Token token : this.trie.tokenize(json)) { if (token.isMatch()) { tags.put(token.getFragment(), this.tagMapper.get(token.getFragment())); @@ -82,15 +80,18 @@ public abstract class AbstractFontManager implements FontManager { this.tagMapper = new HashMap<>(); for (BitmapImage image : this.images.values()) { String id = image.id().toString(); - this.tagMapper.put(addImageTag(id), image.miniMessage(0, 0)); + this.tagMapper.put(imageTag(id), AdventureHelper.miniMessage().deserialize(image.miniMessage(0, 0))); + this.tagMapper.put("\\" + imageTag(id), Component.text(imageTag(id))); for (int i = 0; i < image.rows(); i++) { for (int j = 0; j < image.columns(); j++) { - this.tagMapper.put(addImageTag(id + ":" + i + ":" + j), image.miniMessage(i, j)); + this.tagMapper.put(imageTag(id + ":" + i + ":" + j), AdventureHelper.miniMessage().deserialize(image.miniMessage(i, j))); + this.tagMapper.put(imageTag("\\" + id + ":" + i + ":" + j), Component.text(imageTag(id + ":" + i + ":" + j))); } } } for (int i = -256; i <= 256; i++) { - this.tagMapper.put("", this.offsetFont.createOffset(i, FormatUtils::miniMessageFont)); + this.tagMapper.put("", AdventureHelper.miniMessage().deserialize(this.offsetFont.createOffset(i, FormatUtils::miniMessageFont))); + this.tagMapper.put("\\", Component.text("")); } this.trie = Trie.builder() .ignoreOverlaps() @@ -98,7 +99,7 @@ public abstract class AbstractFontManager implements FontManager { .build(); } - private static String addImageTag(String text) { + private static String imageTag(String text) { return ""; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java b/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java index a6af44fcb..143bd2858 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/FontManager.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.font; +import net.kyori.adventure.text.Component; import net.momirealms.craftengine.core.plugin.Manageable; import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser; import net.momirealms.craftengine.core.util.CharacterUtils; @@ -64,5 +65,5 @@ public interface FontManager extends Manageable { return createOffsets(offset, (raw, font) -> raw); } - Map matchTags(String json); + Map matchTags(String json); } 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 83f78491d..fd197c315 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 @@ -132,6 +132,7 @@ public class Config { protected boolean image$intercept_packets$scoreboard; protected boolean image$intercept_packets$entity_name; protected boolean image$intercept_packets$text_display; + protected boolean image$intercept_packets$armor_stand; public Config(CraftEngine plugin) { this.plugin = plugin; @@ -296,8 +297,9 @@ public class Config { image$intercept_packets$container = config.getBoolean("image.intercept-packets.container", true); image$intercept_packets$team = config.getBoolean("image.intercept-packets.team", true); image$intercept_packets$scoreboard = config.getBoolean("image.intercept-packets.scoreboard", true); - image$intercept_packets$entity_name = config.getBoolean("image.intercept-packets.entity-name", true); + image$intercept_packets$entity_name = config.getBoolean("image.intercept-packets.entity-name", false); image$intercept_packets$text_display = config.getBoolean("image.intercept-packets.text-display", true); + image$intercept_packets$armor_stand = config.getBoolean("image.intercept-packets.armor-stand", true); Class modClazz = ReflectionUtils.getClazz(CraftEngine.MOD_CLASS); if (modClazz != null) { @@ -638,6 +640,10 @@ public class Config { return instance.image$intercept_packets$text_display; } + public static boolean interceptArmorStand() { + return instance.image$intercept_packets$armor_stand; + } + public YamlDocument loadOrCreateYamlData(String fileName) { File file = new File(this.plugin.dataFolderFile(), fileName); if (!file.exists()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java index 06d916542..11ca0db20 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java @@ -222,6 +222,8 @@ public class TemplateManagerImpl implements TemplateManager { for (Map.Entry argumentEntry : rawChildArguments.entrySet()) { // 获取最终的string形式参数 String placeholder = LEFT_BRACKET + argumentEntry.getKey() + RIGHT_BRACKET; + // 父亲参数最大 + if (result.containsKey(placeholder)) continue; Object rawArgument = argumentEntry.getValue(); if (rawArgument instanceof Map mapArgument) { // 此参数是一个map,那么对map应用模板,然后再根据map是否含有type等参数,判别其是否为带名特殊参数 diff --git a/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java b/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java index 030853ab4..939968c01 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/sound/AbstractSoundManager.java @@ -15,6 +15,7 @@ import java.nio.file.Path; import java.util.*; public abstract class AbstractSoundManager implements SoundManager { + protected static final Set VANILLA_SOUND_EVENTS = new HashSet<>(); protected final CraftEngine plugin; protected final Map byId = new HashMap<>(); protected final Map> byNamespace = new HashMap<>(); @@ -28,6 +29,11 @@ public abstract class AbstractSoundManager implements SoundManager { this.songParser = new SongParser(); } + @Override + public boolean isVanillaSoundEvent(Key key) { + return VANILLA_SOUND_EVENTS.contains(key); + } + @Override public ConfigSectionParser[] parsers() { return new ConfigSectionParser[] { this.soundParser, this.songParser }; diff --git a/core/src/main/java/net/momirealms/craftengine/core/sound/SoundManager.java b/core/src/main/java/net/momirealms/craftengine/core/sound/SoundManager.java index 367785592..54450acd5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/sound/SoundManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/sound/SoundManager.java @@ -8,6 +8,8 @@ import java.util.Map; public interface SoundManager extends Manageable { + boolean isVanillaSoundEvent(Key key); + ConfigSectionParser[] parsers(); Map sounds(); diff --git a/gradle.properties b/gradle.properties index acd95d191..47baf8538 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.46 +project_version=0.0.46.2 config_version=23 lang_version=4 project_group=net.momirealms @@ -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.6.1 +sparrow_nbt_version=0.6.2 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.47 +nms_helper_version=0.52 # Ignite Dependencies mixinextras_version=0.4.1 mixin_version=0.15.2+mixin.0.8.7