Clean up component rewriter

This commit is contained in:
Nassim Jahnke 2024-04-30 16:09:11 +02:00
parent 4854b131b8
commit 57c0d83608
No known key found for this signature in database
GPG Key ID: EF6771C01F6EF02F
5 changed files with 134 additions and 131 deletions

View File

@ -79,10 +79,10 @@ public class StructuredDataType extends Type<StructuredData<?>> {
types = new StructuredDataKey[mappings.mappedSize()]; types = new StructuredDataKey[mappings.mappedSize()];
} }
public DataFiller add(final StructuredDataKey<?> reader) { public DataFiller add(final StructuredDataKey<?> key) {
final int id = mappings.mappedId(reader.identifier()); final int id = mappings.mappedId(key.identifier());
Preconditions.checkArgument(id != -1, "No mapped id found for %s", reader.identifier()); Preconditions.checkArgument(id != -1, "No mapped id found for %s", key.identifier());
types[id] = reader; types[id] = key;
return this; return this;
} }
} }

View File

@ -68,7 +68,7 @@ public final class Protocol1_20_5To1_20_3 extends AbstractProtocol<ClientboundPa
private final EntityPacketRewriter1_20_5 entityRewriter = new EntityPacketRewriter1_20_5(this); private final EntityPacketRewriter1_20_5 entityRewriter = new EntityPacketRewriter1_20_5(this);
private final BlockItemPacketRewriter1_20_5 itemRewriter = new BlockItemPacketRewriter1_20_5(this); private final BlockItemPacketRewriter1_20_5 itemRewriter = new BlockItemPacketRewriter1_20_5(this);
private final TagRewriter<ClientboundPacket1_20_3> tagRewriter = new TagRewriter<>(this); private final TagRewriter<ClientboundPacket1_20_3> tagRewriter = new TagRewriter<>(this);
private final ComponentRewriter<ClientboundPacket1_20_3> componentRewriter = new ComponentRewriter1_20_5(this); private final ComponentRewriter1_20_5<ClientboundPacket1_20_3> componentRewriter = new ComponentRewriter1_20_5<>(this, Types1_20_5.STRUCTURED_DATA);
public Protocol1_20_5To1_20_3() { public Protocol1_20_5To1_20_3() {
super(ClientboundPacket1_20_3.class, ClientboundPacket1_20_5.class, ServerboundPacket1_20_3.class, ServerboundPacket1_20_5.class); super(ClientboundPacket1_20_3.class, ClientboundPacket1_20_5.class, ServerboundPacket1_20_3.class, ServerboundPacket1_20_5.class);

View File

@ -71,7 +71,8 @@ import com.viaversion.viaversion.api.minecraft.item.data.ToolRule;
import com.viaversion.viaversion.api.minecraft.item.data.Unbreakable; import com.viaversion.viaversion.api.minecraft.item.data.Unbreakable;
import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook; import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook;
import com.viaversion.viaversion.api.protocol.Protocol; import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPacket1_20_3; import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.type.types.item.StructuredDataType;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.Protocol1_20_5To1_20_3; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.Protocol1_20_5To1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.ArmorMaterials1_20_5; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.ArmorMaterials1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Attributes1_20_5; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Attributes1_20_5;
@ -93,18 +94,25 @@ import com.viaversion.viaversion.util.UUIDUtil;
import com.viaversion.viaversion.util.Unit; import com.viaversion.viaversion.util.Unit;
import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import java.util.HashMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import org.checkerframework.checker.nullness.qual.Nullable;
// 1.20.5 data component -> 1.20.5 nbt conversion public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends ComponentRewriter<C> {
public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket1_20_3> {
@SuppressWarnings("rawtypes") private final Map<StructuredDataKey<?>, ConverterPair<?>> converters = new Reference2ObjectOpenHashMap<>();
protected final Map<StructuredDataKey, DataConverter> rewriters = new HashMap<>(); private final StructuredDataType structuredDataType;
public ComponentRewriter1_20_5(final Protocol<ClientboundPacket1_20_3, ?, ?, ?> protocol) { /**
* @param protocol protocol
* @param structuredDataType unmapped structured data type
*/
public ComponentRewriter1_20_5(final Protocol<C, ?, ?, ?> protocol, final StructuredDataType structuredDataType) {
super(protocol, ReadType.NBT); super(protocol, ReadType.NBT);
this.structuredDataType = structuredDataType;
register(StructuredDataKey.CUSTOM_DATA, this::convertCustomData); register(StructuredDataKey.CUSTOM_DATA, this::convertCustomData);
register(StructuredDataKey.MAX_STACK_SIZE, this::convertMaxStackSize); register(StructuredDataKey.MAX_STACK_SIZE, this::convertMaxStackSize);
@ -166,6 +174,8 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
@Override @Override
protected void handleHoverEvent(final UserConnection connection, final CompoundTag hoverEventTag) { protected void handleHoverEvent(final UserConnection connection, final CompoundTag hoverEventTag) {
super.handleHoverEvent(connection, hoverEventTag);
final StringTag actionTag = hoverEventTag.getStringTag("action"); final StringTag actionTag = hoverEventTag.getStringTag("action");
if (actionTag == null) { if (actionTag == null) {
return; return;
@ -268,34 +278,62 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
} }
} }
protected CompoundTag toTag(final Map<StructuredDataKey<?>, StructuredData<?>> data, final boolean empty) { public CompoundTag toTag(final Map<StructuredDataKey<?>, StructuredData<?>> data, final boolean empty) {
final CompoundTag tag = new CompoundTag(); final CompoundTag tag = new CompoundTag();
for (final Map.Entry<StructuredDataKey<?>, StructuredData<?>> entry : data.entrySet()) { for (final Map.Entry<StructuredDataKey<?>, StructuredData<?>> entry : data.entrySet()) {
final StructuredDataKey<?> key = entry.getKey(); final StructuredDataKey<?> key = entry.getKey();
if (!rewriters.containsKey(key)) { // Should NOT happen final String identifier = key.identifier();
Via.getPlatform().getLogger().severe("No converter for " + key.identifier() + " found!");
//noinspection rawtypes
final ConverterPair converter = converters.get(key);
if (converter == null) { // Should NOT happen
Via.getPlatform().getLogger().severe("No converter found for data component: " + identifier);
continue; continue;
} }
final StructuredData<?> value = entry.getValue(); final StructuredData<?> value = entry.getValue();
if (value.isEmpty()) { if (value.isEmpty()) {
if (empty) { if (empty) {
// Theoretically not needed here, but we'll keep it for consistency // Theoretically not needed here, but we'll keep it for consistency
tag.put("!" + key.identifier(), new CompoundTag()); tag.put("!" + identifier, new CompoundTag());
continue; continue;
} }
throw new IllegalArgumentException("Empty structured data: " + key.identifier()); throw new IllegalArgumentException("Empty structured data: " + identifier);
} }
//noinspection unchecked //noinspection unchecked
final Tag valueTag = rewriters.get(key).convert(value.value()); final Tag valueTag = converter.dataConverter.convert(value.value());
if (valueTag == null) { if (valueTag == null) {
continue; continue;
} }
tag.put(key.identifier(), valueTag);
tag.put(identifier, valueTag);
} }
return tag; return tag;
} }
public List<StructuredData<?>> toData(final CompoundTag tag) {
final List<StructuredData<?>> list = new ArrayList<>();
for (final Map.Entry<String, Tag> entry : tag.entrySet()) {
final StructuredData<?> data = readFromTag(entry.getKey(), entry.getValue());
list.add(data);
}
return list;
}
public StructuredData<?> readFromTag(final String identifier, final Tag tag) {
final int id = protocol.getMappingData().getDataComponentSerializerMappings().mappedId(identifier);
Preconditions.checkArgument(id != -1, "Unknown data component: %s", identifier);
final StructuredDataKey<?> key = structuredDataType.key(id);
return readFromTag(key, id, tag);
}
private <T> StructuredData<T> readFromTag(final StructuredDataKey<T> key, final int id, final Tag tag) {
final TagConverter<T> converter = tagConverter(key);
Preconditions.checkNotNull(converter, "No converter found for: %s", key);
return StructuredData.of(key, converter.convert(tag), id);
}
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Conversion methods, can be overridden in future protocols to handle new changes // Conversion methods, can be overridden in future protocols to handle new changes
@ -363,27 +401,11 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
convertHolderSet(predicateTag, "blocks", predicate.holderSet()); convertHolderSet(predicateTag, "blocks", predicate.holderSet());
} }
if (predicate.propertyMatchers() != null) { if (predicate.propertyMatchers() != null) {
final CompoundTag state = new CompoundTag(); final CompoundTag state = convertPredicate(predicate);
for (final StatePropertyMatcher matcher : predicate.propertyMatchers()) {
final Either<String, StatePropertyMatcher.RangedMatcher> match = matcher.matcher();
if (match.isLeft()) {
state.putString(matcher.name(), match.left());
} else {
final StatePropertyMatcher.RangedMatcher range = match.right();
final CompoundTag rangeTag = new CompoundTag();
if (range.minValue() != null) {
rangeTag.putString("min", range.minValue());
}
if (range.maxValue() != null) {
rangeTag.putString("max", range.maxValue());
}
state.put(matcher.name(), rangeTag);
}
}
predicateTag.put("state", state); predicateTag.put("state", state);
} }
if (predicate.tag() != null) { if (predicate.tag() != null) {
predicateTag.putString("nbt", serializerVersion().toSNBT(predicate.tag())); predicateTag.put("nbt", predicate.tag());
} }
predicates.add(predicateTag); predicates.add(predicateTag);
@ -395,6 +417,27 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
return tag; return tag;
} }
protected CompoundTag convertPredicate(final BlockPredicate predicate) {
final CompoundTag state = new CompoundTag();
for (final StatePropertyMatcher matcher : predicate.propertyMatchers()) {
final Either<String, StatePropertyMatcher.RangedMatcher> match = matcher.matcher();
if (match.isLeft()) {
state.putString(matcher.name(), match.left());
} else {
final StatePropertyMatcher.RangedMatcher range = match.right();
final CompoundTag rangeTag = new CompoundTag();
if (range.minValue() != null) {
rangeTag.putString("min", range.minValue());
}
if (range.maxValue() != null) {
rangeTag.putString("max", range.maxValue());
}
state.put(matcher.name(), rangeTag);
}
}
return state;
}
protected CompoundTag convertCanBreak(final AdventureModePredicate value) { protected CompoundTag convertCanBreak(final AdventureModePredicate value) {
return convertCanPlaceOn(value); return convertCanPlaceOn(value);
} }
@ -585,7 +628,7 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
final ListTag<CompoundTag> pagesTag = new ListTag<>(CompoundTag.class); final ListTag<CompoundTag> pagesTag = new ListTag<>(CompoundTag.class);
for (final FilterableString page : value) { for (final FilterableString page : value) {
final CompoundTag pageTag = new CompoundTag(); final CompoundTag pageTag = new CompoundTag();
convertFilterableString(pageTag, page, 0, 1024); convertFilterableString(pageTag, page, 1024);
pagesTag.add(pageTag); pagesTag.add(pageTag);
} }
tag.put("pages", pagesTag); tag.put("pages", pagesTag);
@ -594,14 +637,14 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
protected CompoundTag convertWrittenBookContent(final WrittenBook value) { protected CompoundTag convertWrittenBookContent(final WrittenBook value) {
final CompoundTag tag = new CompoundTag(); final CompoundTag tag = new CompoundTag();
convertFilterableString(tag, value.title(), 0, 32); convertFilterableString(tag, value.title(), 32);
tag.putString("author", value.author()); tag.putString("author", value.author());
if (value.generation() != 0) { if (value.generation() != 0) {
tag.put("generation", convertIntRange(value.generation(), 0, 3)); tag.put("generation", convertIntRange(value.generation(), 0, 3));
} }
final CompoundTag title = new CompoundTag(); final CompoundTag title = new CompoundTag();
convertFilterableString(title, value.title(), 0, 32); convertFilterableString(title, value.title(), 32);
tag.put("title", title); tag.put("title", title);
final ListTag<CompoundTag> pagesTag = new ListTag<>(CompoundTag.class); final ListTag<CompoundTag> pagesTag = new ListTag<>(CompoundTag.class);
@ -728,7 +771,7 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
protected CompoundTag convertLodestoneTracker(final LodestoneTracker value) { protected CompoundTag convertLodestoneTracker(final LodestoneTracker value) {
final CompoundTag tag = new CompoundTag(); final CompoundTag tag = new CompoundTag();
if (value.pos() != null) { if (value.pos() != null) {
convertGlobalPos(tag, "target", value.pos()); convertGlobalPos(tag, value.pos());
} }
if (!value.tracked()) { if (!value.tracked()) {
tag.putBoolean("tracked", false); tag.putBoolean("tracked", false);
@ -779,7 +822,7 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
tag.put("id", new IntArrayTag(UUIDUtil.toIntArray(value.id()))); tag.put("id", new IntArrayTag(UUIDUtil.toIntArray(value.id())));
} }
if (value.properties().length > 0) { if (value.properties().length > 0) {
convertProperties(tag, "properties", value.properties()); convertProperties(tag, value.properties());
} }
return tag; return tag;
} }
@ -792,7 +835,7 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
final ListTag<CompoundTag> tag = new ListTag<>(CompoundTag.class); final ListTag<CompoundTag> tag = new ListTag<>(CompoundTag.class);
for (final BannerPatternLayer layer : value) { for (final BannerPatternLayer layer : value) {
final CompoundTag layerTag = new CompoundTag(); final CompoundTag layerTag = new CompoundTag();
convertBannerPattern(layerTag, "pattern", layer.pattern()); convertBannerPattern(layerTag, layer.pattern());
layerTag.put("color", convertDyeColor(layer.dyeColor())); layerTag.put("color", convertDyeColor(layer.dyeColor()));
tag.add(layerTag); tag.add(layerTag);
} }
@ -895,7 +938,7 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
} }
} }
protected void convertHolderSet(final CompoundTag tag, final String name, HolderSet set) { protected void convertHolderSet(final CompoundTag tag, final String name, final HolderSet set) {
if (set.hasTagKey()) { if (set.hasTagKey()) {
tag.putString(name, set.tagKey()); tag.putString(name, set.tagKey());
} else { } else {
@ -928,10 +971,10 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
tag.put("components", toTag(components, true)); tag.put("components", toTag(components, true));
} }
protected void convertFilterableString(final CompoundTag tag, final FilterableString string, final int min, final int max) { protected void convertFilterableString(final CompoundTag tag, final FilterableString string, final int max) {
tag.put("raw", convertString(string.raw(), min, max)); tag.put("raw", convertString(string.raw(), 0, max));
if (string.filtered() != null) { if (string.filtered() != null) {
tag.put("filtered", convertString(string.filtered(), min, max)); tag.put("filtered", convertString(string.filtered(), 0, max));
} }
} }
@ -942,14 +985,14 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
} }
} }
protected void convertGlobalPos(final CompoundTag tag, final String name, final GlobalPosition position) { protected void convertGlobalPos(final CompoundTag tag, final GlobalPosition position) {
final CompoundTag posTag = new CompoundTag(); final CompoundTag posTag = new CompoundTag();
posTag.putString("dimension", position.dimension()); posTag.putString("dimension", position.dimension());
posTag.put("pos", new IntArrayTag(new int[]{position.x(), position.y(), position.z()})); posTag.put("pos", new IntArrayTag(new int[]{position.x(), position.y(), position.z()}));
tag.put(name, posTag); tag.put("target", posTag);
} }
protected void convertProperties(final CompoundTag tag, final String name, final GameProfile.Property[] properties) { protected void convertProperties(final CompoundTag tag, final GameProfile.Property[] properties) {
final ListTag<CompoundTag> propertiesTag = new ListTag<>(CompoundTag.class); final ListTag<CompoundTag> propertiesTag = new ListTag<>(CompoundTag.class);
for (final GameProfile.Property property : properties) { for (final GameProfile.Property property : properties) {
final CompoundTag propertyTag = new CompoundTag(); final CompoundTag propertyTag = new CompoundTag();
@ -960,12 +1003,12 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
} }
propertiesTag.add(propertyTag); propertiesTag.add(propertyTag);
} }
tag.put(name, propertiesTag); tag.put("properties", propertiesTag);
} }
protected void convertBannerPattern(final CompoundTag tag, final String name, final Holder<BannerPattern> pattern) { protected void convertBannerPattern(final CompoundTag tag, final Holder<BannerPattern> pattern) {
if (pattern.hasId()) { if (pattern.hasId()) {
tag.putString(name, BannerPatterns1_20_5.idToKey(pattern.id())); tag.putString("pattern", BannerPatterns1_20_5.idToKey(pattern.id()));
return; return;
} }
@ -973,7 +1016,7 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
final CompoundTag patternTag = new CompoundTag(); final CompoundTag patternTag = new CompoundTag();
patternTag.put("asset_id", convertIdentifier(bannerPattern.assetId())); patternTag.put("asset_id", convertIdentifier(bannerPattern.assetId()));
patternTag.putString("translation_key", bannerPattern.translationKey()); patternTag.putString("translation_key", bannerPattern.translationKey());
tag.put(name, patternTag); tag.put("pattern", patternTag);
} }
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
@ -1010,12 +1053,12 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
} }
protected StringTag convertComponent(final Tag value) { protected StringTag convertComponent(final Tag value) {
return convertComponent(value, 0, Integer.MAX_VALUE); return convertComponent(value, Integer.MAX_VALUE);
} }
protected StringTag convertComponent(final Tag value, final int min, final int max) { protected StringTag convertComponent(final Tag value, final int max) {
final String json = serializerVersion().toString(serializerVersion().toComponent(value)); final String json = serializerVersion().toString(serializerVersion().toComponent(value));
return new StringTag(checkStringRange(min, max, json)); return new StringTag(checkStringRange(0, max, json));
} }
protected ListTag<StringTag> convertComponents(final Tag[] value, final int maxLength) { protected ListTag<StringTag> convertComponents(final Tag[] value, final int maxLength) {
@ -1079,8 +1122,24 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
private <T> void register(final StructuredDataKey<T> key, final DataConverter<T> converter) { protected <T> void register(final StructuredDataKey<T> key, final DataConverter<T> dataConverter) { // TODO Remove this method
rewriters.put(key, converter); converters.put(key, new ConverterPair<>(dataConverter, null));
}
protected <T> void register(final StructuredDataKey<T> key, final DataConverter<T> dataConverter, final TagConverter<T> tagConverter) {
converters.put(key, new ConverterPair<>(dataConverter, tagConverter));
}
protected @Nullable <T> DataConverter<T> dataConverter(final StructuredDataKey<T> key) {
//noinspection unchecked
final ConverterPair<T> converters = (ConverterPair<T>) this.converters.get(key);
return converters != null ? converters.dataConverter : null;
}
protected @Nullable <T> TagConverter<T> tagConverter(final StructuredDataKey<T> key) {
//noinspection unchecked
final ConverterPair<T> converters = (ConverterPair<T>) this.converters.get(key);
return converters != null ? converters.tagConverter : null;
} }
public SerializerVersion serializerVersion() { public SerializerVersion serializerVersion() {
@ -1092,4 +1151,20 @@ public class ComponentRewriter1_20_5 extends ComponentRewriter<ClientboundPacket
Tag convert(T value); Tag convert(T value);
} }
@FunctionalInterface
protected interface TagConverter<T> {
T convert(final Tag tag);
}
private static final class ConverterPair<T> {
private final DataConverter<T> dataConverter;
private final TagConverter<T> tagConverter;
ConverterPair(final DataConverter<T> dataConverter, final TagConverter<T> tagConverter) {
this.dataConverter = dataConverter;
this.tagConverter = tagConverter;
}
}
} }

View File

@ -1,65 +0,0 @@
/*
* 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.protocol1_20_5to1_20_3.rewriter;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// 1.20.5 nbt -> 1.20.5 data component conversion, technically only needed in VB but kept here to make maintenance easier
public final class StructuredNBTConverter {
private static final Map<String, DataConverter<?>> rewriters = new HashMap<>();
static {
register(StructuredDataKey.CUSTOM_DATA, tag -> (CompoundTag) tag);
// TODO Add missing handlers for other data types, this will probably be done after the component rework
}
public static List<StructuredData<?>> toData(final CompoundTag tag) {
final List<StructuredData<?>> data = new ArrayList<>();
for (final Map.Entry<String, Tag> entry : tag.entrySet()) {
final StructuredData<?> structuredData = readFromTag(entry.getKey(), entry.getValue());
data.add(structuredData);
}
return data;
}
@SuppressWarnings("unchecked")
public static <T> StructuredData<T> readFromTag(final String identifier, final Tag tag) {
final DataConverter<T> converter = (DataConverter<T>) rewriters.get(identifier);
Preconditions.checkNotNull(converter, "No converter for %s found", identifier);
return (StructuredData<T>) converter.convert(tag);
}
private static <T> void register(final StructuredDataKey<T> key, final DataConverter<T> converter) {
rewriters.put(key.identifier(), converter);
}
@FunctionalInterface
interface DataConverter<T> {
T convert(final Tag tag);
}
}

View File

@ -19,17 +19,10 @@ package com.viaversion.viaversion.rewriter;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData; import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.data.Mappings;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol; import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType; import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType; 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.RewriterBase;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;