From 0ebeef9481a08a1cd774f34c095c98729b08a051 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Sun, 11 May 2025 06:01:15 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix(network):=20=E8=A7=A3=E5=86=B3set?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E5=8C=85=E6=8A=A5=E9=94=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/plugin/network/PacketConsumers.java | 1 + 1 file changed, 1 insertion(+) 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 dd0c37492..a4847d28d 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 @@ -1998,6 +1998,7 @@ public class PacketConsumers { EntityPacketHandler handler = user.entityPacketHandlers().get(id); if (handler != null) { handler.handleSetEntityData(user, event); + return; } if (Config.interceptEntityName()) { boolean isChanged = false; From f0340f3707706c75c301a2e68e498b452c2888a5 Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Sun, 11 May 2025 09:15:27 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(bukkit):=20=E6=B7=BB=E5=8A=A0=E6=96=B9?= =?UTF-8?q?=E5=9D=97=E6=A0=87=E7=AD=BE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/command/feature/TestCommand.java | 35 ++++---- .../craftengine/bukkit/util/BlockTags.java | 83 +++++++++++++++++++ gradle.properties | 2 +- 3 files changed, 104 insertions(+), 16 deletions(-) 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 e31773b82..98db57b67 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 @@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.plugin.command.feature; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; +import net.momirealms.craftengine.bukkit.util.BlockTags; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; @@ -13,47 +14,51 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.checkerframework.checker.nullness.qual.NonNull; import org.incendo.cloud.Command; +import org.incendo.cloud.bukkit.data.BlockPredicate; +import org.incendo.cloud.bukkit.parser.BlockPredicateParser; import org.incendo.cloud.bukkit.parser.NamespacedKeyParser; import org.incendo.cloud.context.CommandContext; import org.incendo.cloud.context.CommandInput; +import org.incendo.cloud.parser.standard.BooleanParser; import org.incendo.cloud.parser.standard.ByteParser; import org.incendo.cloud.parser.standard.StringParser; import org.incendo.cloud.suggestion.Suggestion; import org.incendo.cloud.suggestion.SuggestionProvider; -import java.util.Optional; +import java.util.*; import java.util.concurrent.CompletableFuture; public class TestCommand extends BukkitCommandFeature { + public static final Collection TARGET_BLOCK_SUGGESTIONS = new HashSet<>(); + + static { + for (Material material : Material.values()) { + TARGET_BLOCK_SUGGESTIONS.add(Suggestion.suggestion(material.getKey().toString())); + } + } public TestCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) { super(commandManager, plugin); } @Override - @SuppressWarnings("deprecation") public Command.Builder assembleCommand(org.incendo.cloud.CommandManager manager, Command.Builder builder) { return builder .senderType(Player.class) - .required("id", NamespacedKeyParser.namespacedKeyComponent().suggestionProvider(new SuggestionProvider<>() { + .required("reset", BooleanParser.booleanParser()) + .required("setTag", NamespacedKeyParser.namespacedKeyParser()) + .required("targetBlock", StringParser.stringComponent(StringParser.StringMode.GREEDY_FLAG_YIELDING).suggestionProvider(new SuggestionProvider<>() { @Override public @NonNull CompletableFuture> suggestionsFuture(@NonNull CommandContext context, @NonNull CommandInput input) { - return CompletableFuture.completedFuture(plugin().itemManager().cachedSuggestions()); + return CompletableFuture.completedFuture(TARGET_BLOCK_SUGGESTIONS); } })) - .required("displayType", ByteParser.byteParser((byte) 0, (byte) 8)) - .required("translation", StringParser.stringParser()) - .required("rotation", StringParser.stringParser()) .handler(context -> { Player player = context.sender(); - NamespacedKey namespacedKey = context.get("id"); - ItemStack item = new ItemStack(Material.TRIDENT); - item.editMeta((meta) -> { - Item ceItem = BukkitItemManager.instance().createWrappedItem(Key.of(namespacedKey.asString()), null); - Optional customModelData = ceItem.customModelData(); - customModelData.ifPresent(meta::setCustomModelData); - }); - player.getInventory().addItem(item); + player.sendMessage("开始测试"); + NamespacedKey key = context.get("setTag"); + BlockTags.test(plugin().adapt(player), context.get("reset"), context.get("targetBlock"), key.asString()); + player.sendMessage("结束测试"); }); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockTags.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockTags.java index e7f746d29..ef7eb4cd0 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockTags.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/BlockTags.java @@ -1,9 +1,16 @@ package net.momirealms.craftengine.bukkit.util; +import io.netty.buffer.Unpooled; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import net.momirealms.craftengine.bukkit.nms.FastNMS; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.util.FriendlyByteBuf; import net.momirealms.craftengine.core.util.Key; import java.util.HashMap; import java.util.Map; +import java.util.Optional; public class BlockTags { private static final Map CACHE = new HashMap<>(); @@ -24,4 +31,80 @@ public class BlockTags { return value; } } + + /** + * 用于测试下面的 buildFakeUpdateTagsPacket 方法 + * + * @param player CraftEngine玩家对象 + * @param reset 是否重置标签 + * @param targetBlock 测试添加标签的目标方块 + * @param setTag 测试添加的标签 + */ + public static void test(Player player, boolean reset, String targetBlock, String setTag) { + Map> addTags = new HashMap<>(); + if (!reset) { + Object registries = Reflections.instance$BuiltInRegistries$BLOCK; + Object key = FastNMS.INSTANCE.method$Registry$key(registries); + Map blockTags = new HashMap<>(); + IntList blockId = new IntArrayList(); + Object blockKey = KeyUtils.toResourceLocation(Key.of(targetBlock)); + Object block = FastNMS.INSTANCE.method$Registry$get(registries, blockKey); + Optional optionalBlockId = FastNMS.INSTANCE.method$BuiltInRegistries$getId(registries, block); + optionalBlockId.ifPresent(integer -> blockId.add(integer.intValue())); + blockTags.put(setTag, blockId); + addTags.put(key, blockTags); + } + Object packet = buildFakeUpdateTagsPacket(addTags); + player.sendPacket(packet, true); + } + + /** + * 构建模拟标签更新数据包(用于向客户端添加虚拟标签) + * + * @param addTags 需要添加的标签数据,结构为嵌套映射: + *
{@code
+     *               Map结构示例:
+     *               {
+     *                 注册表键1 (如BuiltInRegistries.ITEM.key) -> {
+     *                   "命名空间:值1" -> IntList.of(1, 2, 3),  // 该命名空间下生效的物品ID列表
+     *                   "命名空间:值2" -> IntList.of(5, 7)
+     *                 },
+     *                 注册表键2 (如BuiltInRegistries.BLOCK.key) -> {
+     *                   "minecraft:beacon_base_blocks" -> IntList.of(1024, 2048)
+     *                 },
+     *                 ....
+     *               }
+     *               }
+ * 其中:
+ * - 外层键:注册表对象(如物品/方块注册表)
+ * - 中间层键:标签的命名空间:值(字符串)
+ * - 值:包含注册表内项目数字ID的IntList + * + * @return 可发送给客户端的 ClientboundUpdateTagsPacket 数据包对象 + */ + @SuppressWarnings("unchecked") + public static Object buildFakeUpdateTagsPacket(Map> addTags) { + Map registriesNetworkPayload = (Map) FastNMS.INSTANCE.method$TagNetworkSerialization$serializeTagsToNetwork(); + for (Map.Entry> entry : addTags.entrySet()) { + Object registryKey = entry.getKey(); + Map tagsToAdd = entry.getValue(); + Object existingPayload = registriesNetworkPayload.get(registryKey); + if (existingPayload == null) continue; + FriendlyByteBuf deserializeBuf = new FriendlyByteBuf(Unpooled.buffer()); + FastNMS.INSTANCE.method$TagNetworkSerialization$NetworkPayload$write(existingPayload, deserializeBuf); + Map combinedTags = deserializeBuf.readMap( + FriendlyByteBuf::readUtf, + FriendlyByteBuf::readIntIdList + ); + combinedTags.putAll(tagsToAdd); + FriendlyByteBuf serializeBuf = new FriendlyByteBuf(Unpooled.buffer()); + serializeBuf.writeMap(combinedTags, + FriendlyByteBuf::writeUtf, + FriendlyByteBuf::writeIntIdList + ); + Object mergedPayload = FastNMS.INSTANCE.method$TagNetworkSerialization$NetworkPayload$read(serializeBuf); + registriesNetworkPayload.put(registryKey, mergedPayload); + } + return FastNMS.INSTANCE.constructor$ClientboundUpdateTagsPacket(registriesNetworkPayload); + } } diff --git a/gradle.properties b/gradle.properties index af4fa0f0e..22e20eb06 100644 --- a/gradle.properties +++ b/gradle.properties @@ -50,7 +50,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.15 -nms_helper_version=0.65.19 +nms_helper_version=0.65.20 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23