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 0e5dfb657..01d66a69d 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 @@ -150,7 +150,7 @@ public final class BukkitBlockManager extends AbstractBlockManager { } @Override - protected void resendTags() { + protected void updateTags() { // if there's no change if (this.clientBoundTags.equals(this.previousClientBoundTags)) return; List list = new ArrayList<>(); @@ -158,10 +158,6 @@ public final class BukkitBlockManager extends AbstractBlockManager { list.add(new TagUtils.TagEntry(entry.getKey(), entry.getValue())); } this.cachedUpdateTags = list; - Object packet = TagUtils.createUpdateTagsPacket(Map.of(MRegistries.BLOCK, list)); - for (BukkitServerPlayer player : this.plugin.networkManager().onlineUsers()) { - player.sendPacket(packet, false); - } } @Nullable 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 2ce8c026c..1ff589e57 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 @@ -241,6 +241,19 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes this.c2sGamePacketListeners[id] = new ByteBufferPacketListenerHolder(name, listener); } + @Override + public void delayedLoad() { + this.resendTags(); + } + + @SuppressWarnings("unchecked") + public void resendTags() { + Object packet = TagUtils.createUpdateTagsPacket(Map.of(MRegistries.BLOCK, BukkitBlockManager.instance().cachedUpdateTags()), FastNMS.INSTANCE.method$TagNetworkSerialization$serializeTagsToNetwork()); + for (BukkitServerPlayer player : onlineUsers()) { + player.sendPacket(packet, false); + } + } + public void addFakePlayer(Player player) { FakeBukkitServerPlayer fakePlayer = new FakeBukkitServerPlayer(this.plugin); fakePlayer.setPlayer(player); @@ -1862,13 +1875,10 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes public void onPacketSend(NetWorkUser user, NMSPacketEvent event, Object packet) { List cachedUpdateTags = BukkitBlockManager.instance().cachedUpdateTags(); if (cachedUpdateTags.isEmpty()) return; - Map tags; - try { - tags = (Map) NetworkReflections.field$ClientboundUpdateTagsPacket$tags.get(packet); - } catch (Throwable e) { - CraftEngine.instance().logger().warn("Failed to get tags from ClientboundUpdateTagsPacket", e); - return; - } + Map tags = FastNMS.INSTANCE.field$ClientboundUpdateTagsPacket$tags(packet); + // 已经替换过了 + if (tags instanceof MarkedHashMap) return; + // 需要虚假的block if (tags.get(MRegistries.BLOCK) == null) return; event.replacePacket(TagUtils.createUpdateTagsPacket(Map.of(MRegistries.BLOCK, cachedUpdateTags), tags)); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/TagUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/TagUtils.java index 51e2887d6..9f82073e8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/TagUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/TagUtils.java @@ -5,6 +5,7 @@ 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.util.FriendlyByteBuf; +import net.momirealms.craftengine.core.util.MarkedHashMap; import java.util.ArrayList; import java.util.HashMap; @@ -15,6 +16,9 @@ public final class TagUtils { private TagUtils() {} + public record TagEntry(int id, List tags) { + } + /** * 构建模拟标签更新数据包(用于向客户端添加虚拟标签) * @@ -39,57 +43,8 @@ public final class TagUtils { * * @return 可发送给客户端的 ClientboundUpdateTagsPacket 数据包对象 */ - @SuppressWarnings("unchecked") - public static Object createUpdateTagsPacket(Map> tags) { - Map registriesNetworkPayload = (Map) FastNMS.INSTANCE.method$TagNetworkSerialization$serializeTagsToNetwork(); - Map modified = new HashMap<>(); - for (Map.Entry payload : registriesNetworkPayload.entrySet()) { - List overrides = tags.get(payload.getKey()); - if (overrides == null || overrides.isEmpty()) { - modified.put(payload.getKey(), payload.getValue()); - continue; - } - FriendlyByteBuf deserializeBuf = new FriendlyByteBuf(Unpooled.buffer()); - FastNMS.INSTANCE.method$TagNetworkSerialization$NetworkPayload$write(payload.getValue(), deserializeBuf); - Map originalTags = deserializeBuf.readMap( - FriendlyByteBuf::readUtf, - FriendlyByteBuf::readIntIdList - ); - Map> reversedTags = new HashMap<>(); - for (Map.Entry tagEntry : originalTags.entrySet()) { - for (int id : tagEntry.getValue()) { - reversedTags.computeIfAbsent(id, k -> new ArrayList<>()).add(tagEntry.getKey()); - } - } - for (TagEntry tagEntry : overrides) { - reversedTags.remove(tagEntry.id); - for (String tag : tagEntry.tags) { - reversedTags.computeIfAbsent(tagEntry.id, k -> new ArrayList<>()).add(tag); - } - } - Map processedTags = new HashMap<>(); - for (Map.Entry> tagEntry : reversedTags.entrySet()) { - for (String tag : tagEntry.getValue()) { - processedTags.computeIfAbsent(tag, k -> new IntArrayList()).addLast(tagEntry.getKey()); - } - } - FriendlyByteBuf serializeBuf = new FriendlyByteBuf(Unpooled.buffer()); - serializeBuf.writeMap(processedTags, - FriendlyByteBuf::writeUtf, - FriendlyByteBuf::writeIntIdList - ); - Object mergedPayload = FastNMS.INSTANCE.method$TagNetworkSerialization$NetworkPayload$read(serializeBuf); - modified.put(payload.getKey(), mergedPayload); - } - return FastNMS.INSTANCE.constructor$ClientboundUpdateTagsPacket(modified); - } - - public record TagEntry(int id, List tags) { - } - - public static Object createUpdateTagsPacket(Map> tags, Map existingTags) { - Map modified = new HashMap<>(); + Map modified = new MarkedHashMap<>(); for (Map.Entry payload : existingTags.entrySet()) { List overrides = tags.get(payload.getKey()); if (overrides == null || overrides.isEmpty()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java b/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java index fffa626dd..59941bb1f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java @@ -143,7 +143,7 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem @Override public void delayedLoad() { this.initSuggestions(); - this.resendTags(); + this.updateTags(); this.processSounds(); this.clearCache(); } @@ -232,7 +232,7 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem public abstract BlockBehavior createBlockBehavior(CustomBlock customBlock, List> behaviorConfig); - protected abstract void resendTags(); + protected abstract void updateTags(); protected abstract boolean isVanillaBlock(Key id); diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java index c72a2f0b2..918c4dcb5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java @@ -184,6 +184,8 @@ public abstract class CraftEngine implements Plugin { delayedLoadTasks.add(CompletableFuture.runAsync(() -> this.recipeManager.delayedLoad(), this.scheduler.async())); } CompletableFutures.allOf(delayedLoadTasks).join(); + // 重新发送tags,需要等待tags更新完成 + this.networkManager.delayedLoad(); long time2 = System.currentTimeMillis(); asyncTime = time2 - time1; } finally { diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/MarkedHashMap.java b/core/src/main/java/net/momirealms/craftengine/core/util/MarkedHashMap.java new file mode 100644 index 000000000..5acda9dda --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/util/MarkedHashMap.java @@ -0,0 +1,6 @@ +package net.momirealms.craftengine.core.util; + +import java.util.HashMap; + +public class MarkedHashMap extends HashMap { +} diff --git a/gradle.properties b/gradle.properties index 6c85cac44..f70a1caa7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -49,7 +49,7 @@ byte_buddy_version=1.17.8 ahocorasick_version=0.6.3 snake_yaml_version=2.5 anti_grief_version=1.0.4 -nms_helper_version=1.0.126 +nms_helper_version=1.0.127 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.34.5