mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-22 16:39:28 +00:00
@@ -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<CommandSender> {
|
||||
public static final Collection<Suggestion> TARGET_BLOCK_SUGGESTIONS = new HashSet<>();
|
||||
|
||||
static {
|
||||
for (Material material : Material.values()) {
|
||||
TARGET_BLOCK_SUGGESTIONS.add(Suggestion.suggestion(material.getKey().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
public TestCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
|
||||
super(commandManager, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public Command.Builder<? extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager<CommandSender> manager, Command.Builder<CommandSender> 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<? extends @NonNull Iterable<? extends @NonNull Suggestion>> suggestionsFuture(@NonNull CommandContext<Object> 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<ItemStack> ceItem = BukkitItemManager.instance().createWrappedItem(Key.of(namespacedKey.asString()), null);
|
||||
Optional<Integer> 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("结束测试");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<Key, Object> 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<Object, Map<String, IntList>> addTags = new HashMap<>();
|
||||
if (!reset) {
|
||||
Object registries = Reflections.instance$BuiltInRegistries$BLOCK;
|
||||
Object key = FastNMS.INSTANCE.method$Registry$key(registries);
|
||||
Map<String, IntList> blockTags = new HashMap<>();
|
||||
IntList blockId = new IntArrayList();
|
||||
Object blockKey = KeyUtils.toResourceLocation(Key.of(targetBlock));
|
||||
Object block = FastNMS.INSTANCE.method$Registry$get(registries, blockKey);
|
||||
Optional<Integer> 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 需要添加的标签数据,结构为嵌套映射:
|
||||
* <pre>{@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)
|
||||
* },
|
||||
* ....
|
||||
* }
|
||||
* }</pre>
|
||||
* 其中:</br>
|
||||
* - 外层键:注册表对象(如物品/方块注册表)</br>
|
||||
* - 中间层键:标签的命名空间:值(字符串)</br>
|
||||
* - 值:包含注册表内项目数字ID的IntList
|
||||
*
|
||||
* @return 可发送给客户端的 ClientboundUpdateTagsPacket 数据包对象
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Object buildFakeUpdateTagsPacket(Map<Object, Map<String, IntList>> addTags) {
|
||||
Map<Object, Object> registriesNetworkPayload = (Map<Object, Object>) FastNMS.INSTANCE.method$TagNetworkSerialization$serializeTagsToNetwork();
|
||||
for (Map.Entry<Object, Map<String, IntList>> entry : addTags.entrySet()) {
|
||||
Object registryKey = entry.getKey();
|
||||
Map<String, IntList> 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<String, IntList> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user