9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-19 15:09:15 +00:00

优化tags更新

This commit is contained in:
XiaoMoMi
2025-11-07 21:14:50 +08:00
parent 2e096558f7
commit e00035adf5
7 changed files with 34 additions and 65 deletions

View File

@@ -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<TagUtils.TagEntry> 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

View File

@@ -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<TagUtils.TagEntry> cachedUpdateTags = BukkitBlockManager.instance().cachedUpdateTags();
if (cachedUpdateTags.isEmpty()) return;
Map<Object, Object> tags;
try {
tags = (Map<Object, Object>) NetworkReflections.field$ClientboundUpdateTagsPacket$tags.get(packet);
} catch (Throwable e) {
CraftEngine.instance().logger().warn("Failed to get tags from ClientboundUpdateTagsPacket", e);
return;
}
Map<Object, Object> tags = FastNMS.INSTANCE.field$ClientboundUpdateTagsPacket$tags(packet);
// 已经替换过了
if (tags instanceof MarkedHashMap<Object, Object>) return;
// 需要虚假的block
if (tags.get(MRegistries.BLOCK) == null) return;
event.replacePacket(TagUtils.createUpdateTagsPacket(Map.of(MRegistries.BLOCK, cachedUpdateTags), tags));
}

View File

@@ -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<String> tags) {
}
/**
* 构建模拟标签更新数据包(用于向客户端添加虚拟标签)
*
@@ -39,57 +43,8 @@ public final class TagUtils {
*
* @return 可发送给客户端的 ClientboundUpdateTagsPacket 数据包对象
*/
@SuppressWarnings("unchecked")
public static Object createUpdateTagsPacket(Map<Object, List<TagEntry>> tags) {
Map<Object, Object> registriesNetworkPayload = (Map<Object, Object>) FastNMS.INSTANCE.method$TagNetworkSerialization$serializeTagsToNetwork();
Map<Object, Object> modified = new HashMap<>();
for (Map.Entry<Object, Object> payload : registriesNetworkPayload.entrySet()) {
List<TagEntry> 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<String, IntList> originalTags = deserializeBuf.readMap(
FriendlyByteBuf::readUtf,
FriendlyByteBuf::readIntIdList
);
Map<Integer, List<String>> reversedTags = new HashMap<>();
for (Map.Entry<String, IntList> 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<String, IntList> processedTags = new HashMap<>();
for (Map.Entry<Integer, List<String>> 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<String> tags) {
}
public static Object createUpdateTagsPacket(Map<Object, List<TagEntry>> tags, Map<Object, Object> existingTags) {
Map<Object, Object> modified = new HashMap<>();
Map<Object, Object> modified = new MarkedHashMap<>();
for (Map.Entry<Object, Object> payload : existingTags.entrySet()) {
List<TagEntry> overrides = tags.get(payload.getKey());
if (overrides == null || overrides.isEmpty()) {

View File

@@ -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<Map<String, Object>> behaviorConfig);
protected abstract void resendTags();
protected abstract void updateTags();
protected abstract boolean isVanillaBlock(Key id);

View File

@@ -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 {

View File

@@ -0,0 +1,6 @@
package net.momirealms.craftengine.core.util;
import java.util.HashMap;
public class MarkedHashMap<K, V> extends HashMap<K, V> {
}

View File

@@ -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