Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-27 08:30:09 +01:00
Handle item changes in show item components
Dieser Commit ist enthalten in:
Ursprung
5d0846abe2
Commit
8bc22a1bad
@ -33,6 +33,7 @@ import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
|
||||
import com.viaversion.viaversion.api.protocol.packet.State;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
|
||||
import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
|
||||
import com.viaversion.viaversion.api.rewriter.EntityRewriter;
|
||||
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
|
||||
import com.viaversion.viaversion.api.rewriter.TagRewriter;
|
||||
@ -382,6 +383,10 @@ public interface Protocol<CU extends ClientboundPacketType, CM extends Clientbou
|
||||
return null;
|
||||
}
|
||||
|
||||
default @Nullable ComponentRewriter getComponentRewriter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this protocol is a base protocol.
|
||||
*
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package com.viaversion.viaversion.api.rewriter;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public interface ComponentRewriter {
|
||||
|
||||
void processTag(UserConnection connection, @Nullable Tag tag);
|
||||
|
||||
void processText(UserConnection connection, @Nullable JsonElement element);
|
||||
}
|
@ -41,7 +41,9 @@ import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfi
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPacket1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.rewriter.BlockItemPacketRewriter1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.rewriter.ComponentRewriter1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.rewriter.EntityPacketRewriter1_21;
|
||||
import com.viaversion.viaversion.rewriter.ComponentRewriter;
|
||||
import com.viaversion.viaversion.rewriter.SoundRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
@ -58,6 +60,7 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
|
||||
private final EntityPacketRewriter1_21 entityRewriter = new EntityPacketRewriter1_21(this);
|
||||
private final BlockItemPacketRewriter1_21 itemRewriter = new BlockItemPacketRewriter1_21(this);
|
||||
private final TagRewriter<ClientboundPacket1_20_5> tagRewriter = new TagRewriter<>(this);
|
||||
private final ComponentRewriter<ClientboundPacket1_20_5> componentRewriter = new ComponentRewriter1_21(this);
|
||||
|
||||
public Protocol1_20_5To1_21() {
|
||||
super(ClientboundPacket1_20_5.class, ClientboundPacket1_21.class, ServerboundPacket1_20_5.class, ServerboundPacket1_20_5.class);
|
||||
@ -76,8 +79,18 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
|
||||
|
||||
new StatisticsRewriter<>(this).register(ClientboundPackets1_20_5.AWARD_STATS);
|
||||
|
||||
componentRewriter.registerOpenScreen(ClientboundPackets1_20_5.OPEN_SCREEN);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_20_5.SET_ACTION_BAR_TEXT);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_20_5.SET_TITLE_TEXT);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_20_5.SET_SUBTITLE_TEXT);
|
||||
componentRewriter.registerBossEvent(ClientboundPackets1_20_5.BOSS_EVENT);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_20_5.DISCONNECT);
|
||||
componentRewriter.registerTabList(ClientboundPackets1_20_5.TAB_LIST);
|
||||
componentRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_20_5.PLAYER_COMBAT_KILL);
|
||||
componentRewriter.registerComponentPacket(ClientboundPackets1_20_5.SYSTEM_CHAT);
|
||||
|
||||
registerClientbound(ClientboundPackets1_20_5.DISGUISED_CHAT, wrapper -> {
|
||||
wrapper.passthrough(Types.TAG); // Message
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.TAG)); // Message
|
||||
|
||||
// Holder time
|
||||
final int chatType = wrapper.read(Types.VAR_INT);
|
||||
@ -99,7 +112,7 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.passthrough(Types.OPTIONAL_TAG); // Unsigned content
|
||||
componentRewriter.processTag(wrapper.user(), wrapper.passthrough(Types.OPTIONAL_TAG)); // Unsigned content
|
||||
|
||||
final int filterMaskType = wrapper.passthrough(Types.VAR_INT);
|
||||
if (filterMaskType == 2) {
|
||||
@ -223,6 +236,11 @@ public final class Protocol1_20_5To1_21 extends AbstractProtocol<ClientboundPack
|
||||
return tagRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentRewriter<ClientboundPacket1_20_5> getComponentRewriter() {
|
||||
return componentRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PacketTypesProvider<ClientboundPacket1_20_5, ClientboundPacket1_21, ServerboundPacket1_20_5, ServerboundPacket1_20_5> createPacketTypesProvider() {
|
||||
return new SimplePacketTypesProvider<>(
|
||||
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.v1_20_5to1_21.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ClientboundPacket1_20_5;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.Protocol1_20_5To1_21;
|
||||
import com.viaversion.viaversion.rewriter.ComponentRewriter;
|
||||
import com.viaversion.viaversion.util.SerializerVersion;
|
||||
import com.viaversion.viaversion.util.TagUtil;
|
||||
import com.viaversion.viaversion.util.UUIDUtil;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class ComponentRewriter1_21 extends ComponentRewriter<ClientboundPacket1_20_5> {
|
||||
|
||||
public ComponentRewriter1_21(final Protocol1_20_5To1_21 protocol) {
|
||||
super(protocol, ReadType.NBT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleShowItem(final UserConnection connection, final CompoundTag componentsTag) {
|
||||
final CompoundTag attributeModifiers = TagUtil.getNamespacedCompoundTag(componentsTag, "minecraft:attribute_modifiers");
|
||||
if (attributeModifiers != null) {
|
||||
final ListTag<CompoundTag> modifiers = attributeModifiers.getListTag("modifiers", CompoundTag.class);
|
||||
for (final CompoundTag modifier : modifiers) {
|
||||
final String name = modifier.getString("name");
|
||||
final UUID uuid = UUIDUtil.fromIntArray(modifier.getIntArrayTag("uuid").getValue());
|
||||
final String id = Protocol1_20_5To1_21.mapAttributeUUID(uuid, name);
|
||||
modifier.putString("id", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SerializerVersion inputSerializerVersion() {
|
||||
return SerializerVersion.V1_20_5;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SerializerVersion outputSerializerVersion() {
|
||||
return SerializerVersion.V1_20_5;
|
||||
}
|
||||
}
|
@ -36,13 +36,15 @@ import com.viaversion.viaversion.api.protocol.packet.State;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
|
||||
import com.viaversion.viaversion.util.ComponentUtil;
|
||||
import com.viaversion.viaversion.util.SerializerVersion;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Handles json and tag components, containing methods to override certain parts of the handling.
|
||||
* Also contains methods to register a few of the packets using components.
|
||||
*/
|
||||
public class ComponentRewriter<C extends ClientboundPacketType> {
|
||||
public class ComponentRewriter<C extends ClientboundPacketType> implements com.viaversion.viaversion.api.rewriter.ComponentRewriter {
|
||||
protected final Protocol<C, ?, ?, ?> protocol;
|
||||
protected final ReadType type;
|
||||
|
||||
@ -249,6 +251,7 @@ public class ComponentRewriter<C extends ClientboundPacketType> {
|
||||
// -----------------------------------------------------------------------
|
||||
// Tag methods
|
||||
|
||||
@Override
|
||||
public void processTag(final UserConnection connection, @Nullable final Tag tag) {
|
||||
if (tag == null) {
|
||||
return;
|
||||
@ -309,6 +312,48 @@ public class ComponentRewriter<C extends ClientboundPacketType> {
|
||||
if (contents != null) {
|
||||
processTag(connection, contents.get("name"));
|
||||
}
|
||||
} else if (action.equals("show_item")) {
|
||||
convertLegacyContents(hoverEventTag);
|
||||
|
||||
final CompoundTag contentsTag = hoverEventTag.getCompoundTag("contents");
|
||||
if (contentsTag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final CompoundTag componentsTag = contentsTag.getCompoundTag("components");
|
||||
if (componentsTag != null) {
|
||||
handleShowItem(connection, componentsTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleShowItem(final UserConnection connection, final CompoundTag componentsTag) {
|
||||
// To override if needed
|
||||
}
|
||||
|
||||
protected SerializerVersion inputSerializerVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected SerializerVersion outputSerializerVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void convertLegacyContents(final CompoundTag hoverEvent) {
|
||||
if (inputSerializerVersion() == null || outputSerializerVersion() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Tag valueTag = hoverEvent.remove("value");
|
||||
if (valueTag != null) {
|
||||
final CompoundTag tag = ComponentUtil.deserializeShowItem(valueTag, inputSerializerVersion());
|
||||
final CompoundTag contentsTag = new CompoundTag();
|
||||
contentsTag.put("id", tag.getStringTag("id"));
|
||||
contentsTag.put("count", tag.getIntTag("count"));
|
||||
if (tag.get("tag") instanceof CompoundTag) {
|
||||
contentsTag.putString("tag", outputSerializerVersion().toSNBT(tag.getCompoundTag("tag")));
|
||||
}
|
||||
hoverEvent.put("contents", contentsTag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.Mappings;
|
||||
import com.viaversion.viaversion.api.data.ParticleMappings;
|
||||
@ -28,6 +29,7 @@ import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
|
||||
import com.viaversion.viaversion.api.rewriter.RewriterBase;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
@ -381,15 +383,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
});
|
||||
}
|
||||
|
||||
public void registerAdvancements1_20_2(C packetType) {
|
||||
registerAdvancements1_20_2(packetType, Types.COMPONENT);
|
||||
}
|
||||
|
||||
public void registerAdvancements1_20_3(C packetType) {
|
||||
registerAdvancements1_20_2(packetType, Types.TAG);
|
||||
}
|
||||
|
||||
private void registerAdvancements1_20_2(C packetType, Type<?> componentType) {
|
||||
protocol.registerClientbound(packetType, wrapper -> {
|
||||
wrapper.passthrough(Types.BOOLEAN); // Reset/clear
|
||||
int size = wrapper.passthrough(Types.VAR_INT); // Mapping size
|
||||
@ -399,8 +393,14 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
|
||||
|
||||
// Display data
|
||||
if (wrapper.passthrough(Types.BOOLEAN)) {
|
||||
wrapper.passthrough(componentType); // Title
|
||||
wrapper.passthrough(componentType); // Description
|
||||
final Tag title = wrapper.passthrough(Types.TAG);
|
||||
final Tag description = wrapper.passthrough(Types.TAG);
|
||||
final ComponentRewriter componentRewriter = protocol.getComponentRewriter();
|
||||
if (componentRewriter != null) {
|
||||
componentRewriter.processTag(wrapper.user(), title);
|
||||
componentRewriter.processTag(wrapper.user(), description);
|
||||
}
|
||||
|
||||
handleClientboundItem(wrapper); // Icon
|
||||
wrapper.passthrough(Types.VAR_INT); // Frame type
|
||||
int flags = wrapper.passthrough(Types.INT); // Flags
|
||||
|
@ -17,6 +17,8 @@
|
||||
*/
|
||||
package com.viaversion.viaversion.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.data.FullMappings;
|
||||
import com.viaversion.viaversion.api.data.MappingData;
|
||||
@ -29,6 +31,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.PotDecorations;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
|
||||
import com.viaversion.viaversion.api.rewriter.ComponentRewriter;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||
import java.util.Map;
|
||||
@ -64,6 +67,26 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
|
||||
}
|
||||
}
|
||||
|
||||
final ComponentRewriter componentRewriter = protocol.getComponentRewriter();
|
||||
if (componentRewriter != null) {
|
||||
// Handle name and lore components
|
||||
final StructuredData<Tag> customNameData = dataContainer.getNonEmpty(StructuredDataKey.CUSTOM_NAME);
|
||||
if (customNameData != null) {
|
||||
final Tag originalName = customNameData.value().copy();
|
||||
componentRewriter.processTag(connection, customNameData.value());
|
||||
if (!customNameData.value().equals(originalName)) {
|
||||
saveTag(createCustomTag(item), originalName, "Name");
|
||||
}
|
||||
}
|
||||
|
||||
final StructuredData<Tag[]> loreData = dataContainer.getNonEmpty(StructuredDataKey.LORE);
|
||||
if (loreData != null) {
|
||||
for (final Tag tag : loreData.value()) {
|
||||
componentRewriter.processTag(connection, tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateItemComponents(connection, dataContainer, this::handleItemToClient, mappingData != null ? mappingData::getNewItemId : null);
|
||||
return item;
|
||||
}
|
||||
@ -88,11 +111,12 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
|
||||
}
|
||||
}
|
||||
|
||||
restoreTextComponents(item);
|
||||
updateItemComponents(connection, dataContainer, this::handleItemToServer, mappingData != null ? mappingData::getOldItemId : null);
|
||||
return item;
|
||||
}
|
||||
|
||||
public static void updateItemComponents(UserConnection connection, StructuredDataContainer container, ItemHandler itemHandler, @Nullable Int2IntFunction idRewriter) {
|
||||
protected void updateItemComponents(UserConnection connection, StructuredDataContainer container, ItemHandler itemHandler, @Nullable Int2IntFunction idRewriter) {
|
||||
// Specific types that need deep handling
|
||||
final StructuredData<ArmorTrim> trimData = container.getNonEmpty(StructuredDataKey.TRIM);
|
||||
if (trimData != null && idRewriter != null) {
|
||||
@ -128,6 +152,47 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
|
||||
}
|
||||
}
|
||||
|
||||
protected void restoreTextComponents(final Item item) {
|
||||
final StructuredDataContainer data = item.structuredData();
|
||||
final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
|
||||
if (customData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove custom name
|
||||
if (customData.value().remove(nbtTagName("customName")) != null) {
|
||||
data.remove(StructuredDataKey.CUSTOM_NAME);
|
||||
} else {
|
||||
final Tag name = removeBackupTag(customData.value(), "Name");
|
||||
if (name != null) {
|
||||
data.set(StructuredDataKey.CUSTOM_NAME, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected CompoundTag createCustomTag(final Item item) {
|
||||
final StructuredDataContainer data = item.structuredData();
|
||||
final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
|
||||
if (customData != null) {
|
||||
return customData.value();
|
||||
}
|
||||
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
data.set(StructuredDataKey.CUSTOM_DATA, tag);
|
||||
return tag;
|
||||
}
|
||||
|
||||
protected void saveTag(final CompoundTag customData, final Tag tag, final String name) {
|
||||
final String backupName = nbtTagName(name);
|
||||
if (!customData.contains(backupName)) {
|
||||
customData.put(backupName, tag);
|
||||
}
|
||||
}
|
||||
|
||||
protected @Nullable Tag removeBackupTag(final CompoundTag customData, final String tagName) {
|
||||
return customData.remove(nbtTagName(tagName));
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ItemHandler {
|
||||
|
||||
|
@ -30,12 +30,9 @@ public final class TagUtil {
|
||||
}
|
||||
|
||||
public static ListTag<CompoundTag> getRegistryEntries(final CompoundTag tag, final String key, final @Nullable ListTag<CompoundTag> defaultValue) {
|
||||
CompoundTag registry = tag.getCompoundTag(Key.namespaced(key));
|
||||
CompoundTag registry = getNamespacedCompoundTag(tag, key);
|
||||
if (registry == null) {
|
||||
registry = tag.getCompoundTag(Key.stripMinecraftNamespace(key));
|
||||
if (registry == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
return registry.getListTag("value", CompoundTag.class);
|
||||
}
|
||||
@ -62,6 +59,11 @@ public final class TagUtil {
|
||||
return tag.remove(Key.namespaced(key)) != null || tag.remove(Key.stripMinecraftNamespace(key)) != null;
|
||||
}
|
||||
|
||||
public static @Nullable CompoundTag getNamespacedCompoundTag(final CompoundTag tag, final String key) {
|
||||
final CompoundTag compoundTag = tag.getCompoundTag(Key.namespaced(key));
|
||||
return compoundTag != null ? compoundTag : tag.getCompoundTag(Key.stripMinecraftNamespace(key));
|
||||
}
|
||||
|
||||
public static Tag handleDeep(final Tag tag, final TagUpdater consumer) {
|
||||
return handleDeep(null, tag, consumer);
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren