3
0
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:
Nassim Jahnke 2024-05-29 19:32:30 +02:00
Ursprung 5d0846abe2
Commit 8bc22a1bad
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: EF6771C01F6EF02F
8 geänderte Dateien mit 249 neuen und 19 gelöschten Zeilen

Datei anzeigen

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

Datei anzeigen

@ -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);
}

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

@ -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);
}
}

Datei anzeigen

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

Datei anzeigen

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

Datei anzeigen

@ -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);
}