mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-28 13:05:25 +01:00
Make clearer distinction between filled and empty data component patch, simplify direct value getting
This commit is contained in:
parent
451b3a2637
commit
c358c39027
@ -52,16 +52,14 @@ public interface StructuredData<T> extends IdHolder {
|
|||||||
return new EmptyStructuredData<>(key, id);
|
return new EmptyStructuredData<>(key, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setValue(final T value);
|
@Nullable T value();
|
||||||
|
|
||||||
void write(final ByteBuf buffer);
|
void setValue(final T value);
|
||||||
|
|
||||||
void setId(final int id);
|
void setId(final int id);
|
||||||
|
|
||||||
StructuredDataKey<T> key();
|
StructuredDataKey<T> key();
|
||||||
|
|
||||||
@Nullable T value();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the structured data is present. Even if true, the value may be null.
|
* Returns whether the structured data is present. Even if true, the value may be null.
|
||||||
*
|
*
|
||||||
@ -77,4 +75,6 @@ public interface StructuredData<T> extends IdHolder {
|
|||||||
* @return true if the structured data is empty
|
* @return true if the structured data is empty
|
||||||
*/
|
*/
|
||||||
boolean isEmpty();
|
boolean isEmpty();
|
||||||
|
|
||||||
|
void write(final ByteBuf buffer);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,26 @@ import java.util.Map;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loosely represents Minecraft's data component patch, but may also be used for an item's full data components.
|
||||||
|
* <p>
|
||||||
|
* The most commonly used methods will ignore empty data (aka empty overrides that remove item defaults) since those will rarely be needed.
|
||||||
|
* These are:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link #get(StructuredDataKey)}</li>
|
||||||
|
* <li>{@link #set(StructuredDataKey, Object)}</li>
|
||||||
|
* <li>{@link #set(StructuredDataKey)}</li>
|
||||||
|
* <li>{@link #getNonEmptyData(StructuredDataKey)}</li>
|
||||||
|
* <li>{@link #hasValue(StructuredDataKey)}</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* To interact with empty patches specifically, use:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link #setEmpty(StructuredDataKey)}</li>
|
||||||
|
* <li>{@link #hasEmpty(StructuredDataKey)}</li>
|
||||||
|
* </ul>
|
||||||
|
* Other methods (e.g. {@link #getData(StructuredDataKey)} and {@link #has(StructuredDataKey)}) will handle both empty and non-empty data.
|
||||||
|
*/
|
||||||
public final class StructuredDataContainer {
|
public final class StructuredDataContainer {
|
||||||
|
|
||||||
private final Map<StructuredDataKey<?>, StructuredData<?>> data;
|
private final Map<StructuredDataKey<?>, StructuredData<?>> data;
|
||||||
@ -55,66 +75,45 @@ public final class StructuredDataContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns structured data by id if present.
|
* Returns the non-empty value by id if present.
|
||||||
|
*
|
||||||
|
* @param key serializer id
|
||||||
|
* @param <T> data type
|
||||||
|
* @return structured data
|
||||||
|
* @see #hasEmpty(StructuredDataKey)
|
||||||
|
*/
|
||||||
|
public @Nullable <T> T get(final StructuredDataKey<T> key) {
|
||||||
|
final StructuredData<?> data = this.data.get(key);
|
||||||
|
if (data == null || data.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//noinspection unchecked
|
||||||
|
return ((StructuredData<T>) data).value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns structured data by id if present, either empty or non-empty.
|
||||||
*
|
*
|
||||||
* @param key serializer id
|
* @param key serializer id
|
||||||
* @param <T> data type
|
* @param <T> data type
|
||||||
* @return structured data
|
* @return structured data
|
||||||
*/
|
*/
|
||||||
public @Nullable <T> StructuredData<T> get(final StructuredDataKey<T> key) {
|
public @Nullable <T> StructuredData<T> getData(final StructuredDataKey<T> key) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return (StructuredData<T>) this.data.get(key);
|
return (StructuredData<T>) this.data.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns structured data by id if not empty.
|
* Returns non-empty structured data by id if present.
|
||||||
*
|
*
|
||||||
* @param key serializer id
|
* @param key serializer id
|
||||||
* @param <T> data type
|
* @param <T> data type
|
||||||
* @return structured data if not empty
|
* @return non-empty structured data
|
||||||
*/
|
*/
|
||||||
public @Nullable <T> StructuredData<T> getNonEmpty(final StructuredDataKey<T> key) {
|
public @Nullable <T> StructuredData<T> getNonEmptyData(final StructuredDataKey<T> key) {
|
||||||
|
final StructuredData<?> data = this.data.get(key);
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
final StructuredData<T> data = (StructuredData<T>) this.data.get(key);
|
return data != null && data.isPresent() ? (StructuredData<T>) data : null;
|
||||||
return data != null && data.isPresent() ? data : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns structured data by id if not empty, or creates it.
|
|
||||||
*
|
|
||||||
* @param key serializer id
|
|
||||||
* @param mappingFunction function to create structured data if not present
|
|
||||||
* @param <T> data type
|
|
||||||
* @return structured data if not empty
|
|
||||||
*/
|
|
||||||
public <T> StructuredData<T> computeIfAbsent(final StructuredDataKey<T> key, final Function<StructuredDataKey<T>, T> mappingFunction) {
|
|
||||||
final StructuredData<T> data = this.getNonEmpty(key);
|
|
||||||
if (data != null) {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int id = serializerId(key);
|
|
||||||
final StructuredData<T> empty = StructuredData.of(key, mappingFunction.apply(key), id);
|
|
||||||
this.data.put(key, empty);
|
|
||||||
return empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates and returns the structured data by id if not empty.
|
|
||||||
*
|
|
||||||
* @param key serializer id
|
|
||||||
* @param mappingFunction function to update existing data
|
|
||||||
* @param <T> data type
|
|
||||||
* @return updated structured data if not empty
|
|
||||||
*/
|
|
||||||
public <T> @Nullable StructuredData<T> updateIfPresent(final StructuredDataKey<T> key, final Function<T, T> mappingFunction) {
|
|
||||||
final StructuredData<T> data = this.getNonEmpty(key);
|
|
||||||
if (data == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setValue(mappingFunction.apply(data.value()));
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void set(final StructuredDataKey<T> key, final T value) {
|
public <T> void set(final StructuredDataKey<T> key, final T value) {
|
||||||
@ -124,49 +123,105 @@ public final class StructuredDataContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void replaceKey(final StructuredDataKey<T> key, final StructuredDataKey<T> toKey) {
|
|
||||||
replace(key, toKey, Function.identity());
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T, V> void replace(final StructuredDataKey<T> key, final StructuredDataKey<V> toKey, final Function<T, V> valueMapper) {
|
|
||||||
final StructuredData<T> data = remove(key);
|
|
||||||
if (data == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.isPresent()) {
|
|
||||||
set(toKey, valueMapper.apply(data.value()));
|
|
||||||
} else {
|
|
||||||
addEmpty(toKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set(final StructuredDataKey<Unit> key) {
|
public void set(final StructuredDataKey<Unit> key) {
|
||||||
this.set(key, Unit.INSTANCE);
|
this.set(key, Unit.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEmpty(final StructuredDataKey<?> key) {
|
public void setEmpty(final StructuredDataKey<?> key) {
|
||||||
// Empty optional to override the Minecraft default
|
// Empty optional to override the Minecraft default
|
||||||
this.data.put(key, StructuredData.empty(key, serializerId(key)));
|
this.data.put(key, StructuredData.empty(key, serializerId(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes and returns structured data by the given key.
|
* Updates the structured data by id if not empty.
|
||||||
*
|
*
|
||||||
* @param key serializer key
|
* @param key serializer id
|
||||||
* @param <T> data type
|
* @param valueMapper function to update existing data
|
||||||
* @return removed structured data
|
* @param <T> data type
|
||||||
*/
|
*/
|
||||||
public @Nullable <T> StructuredData<T> remove(final StructuredDataKey<T> key) {
|
public <T> void replace(final StructuredDataKey<T> key, final Function<T, @Nullable T> valueMapper) {
|
||||||
final StructuredData<?> data = this.data.remove(key);
|
final StructuredData<T> data = this.getNonEmptyData(key);
|
||||||
//noinspection unchecked
|
if (data == null) {
|
||||||
return data != null ? (StructuredData<T>) data : null;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final T replacement = valueMapper.apply(data.value());
|
||||||
|
if (replacement != null) {
|
||||||
|
data.setValue(replacement);
|
||||||
|
} else {
|
||||||
|
this.data.remove(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(final StructuredDataKey<?> key) {
|
public <T> void replaceKey(final StructuredDataKey<T> key, final StructuredDataKey<T> toKey) {
|
||||||
|
replace(key, toKey, Function.identity());
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T, V> void replace(final StructuredDataKey<T> key, final StructuredDataKey<V> toKey, final Function<T, @Nullable V> valueMapper) {
|
||||||
|
final StructuredData<?> data = this.data.remove(key);
|
||||||
|
if (data == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.isPresent()) {
|
||||||
|
//noinspection unchecked
|
||||||
|
final T value = (T) data.value();
|
||||||
|
final V replacement = valueMapper.apply(value);
|
||||||
|
if (replacement != null) {
|
||||||
|
set(toKey, replacement);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Also replace the key for empty data
|
||||||
|
setEmpty(toKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes data by the given key.
|
||||||
|
*
|
||||||
|
* @param key data key
|
||||||
|
* @see #replace(StructuredDataKey, Function)
|
||||||
|
* @see #replace(StructuredDataKey, StructuredDataKey, Function)
|
||||||
|
* @see #replaceKey(StructuredDataKey, StructuredDataKey)
|
||||||
|
*/
|
||||||
|
public void remove(final StructuredDataKey<?> key) {
|
||||||
|
this.data.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether there is data for the given key, either empty or non-empty.
|
||||||
|
*
|
||||||
|
* @param key data key
|
||||||
|
* @return whether there data for the given key
|
||||||
|
* @see #hasEmpty(StructuredDataKey)
|
||||||
|
* @see #hasValue(StructuredDataKey)
|
||||||
|
*/
|
||||||
|
public boolean has(final StructuredDataKey<?> key) {
|
||||||
return this.data.containsKey(key);
|
return this.data.containsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether there is non-empty data for the given key.
|
||||||
|
*
|
||||||
|
* @param key data key
|
||||||
|
* @return whether there is non-empty data for the given key
|
||||||
|
*/
|
||||||
|
public boolean hasValue(final StructuredDataKey<?> key) {
|
||||||
|
final StructuredData<?> data = this.data.get(key);
|
||||||
|
return data != null && data.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the structured data has an empty patch/override.
|
||||||
|
*
|
||||||
|
* @param key serializer id
|
||||||
|
* @return whether the structured data has an empty patch/override
|
||||||
|
*/
|
||||||
|
public boolean hasEmpty(final StructuredDataKey<?> key) {
|
||||||
|
final StructuredData<?> data = this.data.get(key);
|
||||||
|
return data != null && data.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the lookup for serializer ids. Required to call most of the other methods.
|
* Sets the lookup for serializer ids. Required to call most of the other methods.
|
||||||
*
|
*
|
||||||
|
@ -416,7 +416,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
|
|||||||
final StructuredDataContainer data = item.dataContainer();
|
final StructuredDataContainer data = item.dataContainer();
|
||||||
data.setIdLookup(protocol, true);
|
data.setIdLookup(protocol, true);
|
||||||
|
|
||||||
final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
|
final StructuredData<CompoundTag> customData = data.getNonEmptyData(StructuredDataKey.CUSTOM_DATA);
|
||||||
final CompoundTag tag = customData != null ? customData.value() : new CompoundTag();
|
final CompoundTag tag = customData != null ? customData.value() : new CompoundTag();
|
||||||
final DataItem dataItem = new DataItem(item.identifier(), (byte) item.amount(), tag);
|
final DataItem dataItem = new DataItem(item.identifier(), (byte) item.amount(), tag);
|
||||||
if (!dataConverter.backupInconvertibleData() && customData != null && tag.remove(nbtTagName()) != null) {
|
if (!dataConverter.backupInconvertibleData() && customData != null && tag.remove(nbtTagName()) != null) {
|
||||||
|
@ -20,7 +20,6 @@ package com.viaversion.viaversion.protocols.v1_20_5to1_21.rewriter;
|
|||||||
import com.viaversion.nbt.tag.ByteTag;
|
import com.viaversion.nbt.tag.ByteTag;
|
||||||
import com.viaversion.nbt.tag.CompoundTag;
|
import com.viaversion.nbt.tag.CompoundTag;
|
||||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||||
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
|
|
||||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
|
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
|
||||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||||
@ -123,7 +122,7 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter<Cl
|
|||||||
updateItemData(item);
|
updateItemData(item);
|
||||||
|
|
||||||
final StructuredDataContainer dataContainer = item.dataContainer();
|
final StructuredDataContainer dataContainer = item.dataContainer();
|
||||||
if (dataContainer.contains(StructuredDataKey.RARITY)) {
|
if (dataContainer.has(StructuredDataKey.RARITY)) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,14 +193,14 @@ public final class BlockItemPacketRewriter1_21 extends StructuredItemRewriter<Cl
|
|||||||
|
|
||||||
public static void resetRarityValues(final Item item, final String tagName) {
|
public static void resetRarityValues(final Item item, final String tagName) {
|
||||||
final StructuredDataContainer dataContainer = item.dataContainer();
|
final StructuredDataContainer dataContainer = item.dataContainer();
|
||||||
|
final CompoundTag customData = dataContainer.get(StructuredDataKey.CUSTOM_DATA);
|
||||||
final StructuredData<CompoundTag> customData = dataContainer.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
|
|
||||||
if (customData == null) {
|
if (customData == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (customData.value().remove(tagName) != null) {
|
|
||||||
|
if (customData.remove(tagName) != null) {
|
||||||
dataContainer.remove(StructuredDataKey.RARITY);
|
dataContainer.remove(StructuredDataKey.RARITY);
|
||||||
if (customData.value().isEmpty()) {
|
if (customData.isEmpty()) {
|
||||||
dataContainer.remove(StructuredDataKey.CUSTOM_DATA);
|
dataContainer.remove(StructuredDataKey.CUSTOM_DATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,27 +114,27 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
|
|||||||
final MappingData mappingData = protocol.getMappingData();
|
final MappingData mappingData = protocol.getMappingData();
|
||||||
if (mappingData.getItemMappings() != null) {
|
if (mappingData.getItemMappings() != null) {
|
||||||
final Int2IntFunction itemIdRewriter = clientbound ? mappingData::getNewItemId : mappingData::getOldItemId;
|
final Int2IntFunction itemIdRewriter = clientbound ? mappingData::getNewItemId : mappingData::getOldItemId;
|
||||||
container.updateIfPresent(StructuredDataKey.TRIM, value -> value.rewrite(itemIdRewriter));
|
container.replace(StructuredDataKey.TRIM, value -> value.rewrite(itemIdRewriter));
|
||||||
container.updateIfPresent(StructuredDataKey.POT_DECORATIONS, value -> value.rewrite(itemIdRewriter));
|
container.replace(StructuredDataKey.POT_DECORATIONS, value -> value.rewrite(itemIdRewriter));
|
||||||
}
|
}
|
||||||
if (mappingData.getBlockMappings() != null) {
|
if (mappingData.getBlockMappings() != null) {
|
||||||
final Int2IntFunction blockIdRewriter = clientbound ? mappingData::getNewBlockId : mappingData::getOldBlockId;
|
final Int2IntFunction blockIdRewriter = clientbound ? mappingData::getNewBlockId : mappingData::getOldBlockId;
|
||||||
container.updateIfPresent(StructuredDataKey.TOOL, value -> value.rewrite(blockIdRewriter));
|
container.replace(StructuredDataKey.TOOL, value -> value.rewrite(blockIdRewriter));
|
||||||
container.updateIfPresent(StructuredDataKey.CAN_PLACE_ON, value -> value.rewrite(blockIdRewriter));
|
container.replace(StructuredDataKey.CAN_PLACE_ON, value -> value.rewrite(blockIdRewriter));
|
||||||
container.updateIfPresent(StructuredDataKey.CAN_BREAK, value -> value.rewrite(blockIdRewriter));
|
container.replace(StructuredDataKey.CAN_BREAK, value -> value.rewrite(blockIdRewriter));
|
||||||
}
|
}
|
||||||
if (mappingData.getSoundMappings() != null) {
|
if (mappingData.getSoundMappings() != null) {
|
||||||
final Int2IntFunction soundIdRewriter = clientbound ? mappingData::getNewSoundId : mappingData::getOldSoundId;
|
final Int2IntFunction soundIdRewriter = clientbound ? mappingData::getNewSoundId : mappingData::getOldSoundId;
|
||||||
container.updateIfPresent(StructuredDataKey.INSTRUMENT, value -> value.isDirect() ? Holder.of(value.value().rewrite(soundIdRewriter)) : value);
|
container.replace(StructuredDataKey.INSTRUMENT, value -> value.isDirect() ? Holder.of(value.value().rewrite(soundIdRewriter)) : value);
|
||||||
container.updateIfPresent(StructuredDataKey.JUKEBOX_PLAYABLE, value -> value.rewrite(soundIdRewriter));
|
container.replace(StructuredDataKey.JUKEBOX_PLAYABLE, value -> value.rewrite(soundIdRewriter));
|
||||||
}
|
}
|
||||||
if (clientbound && protocol.getComponentRewriter() != null) {
|
if (clientbound && protocol.getComponentRewriter() != null) {
|
||||||
updateComponent(connection, item, StructuredDataKey.ITEM_NAME, "item_name");
|
updateComponent(connection, item, StructuredDataKey.ITEM_NAME, "item_name");
|
||||||
updateComponent(connection, item, StructuredDataKey.CUSTOM_NAME, "custom_name");
|
updateComponent(connection, item, StructuredDataKey.CUSTOM_NAME, "custom_name");
|
||||||
|
|
||||||
final StructuredData<Tag[]> loreData = container.getNonEmpty(StructuredDataKey.LORE);
|
final Tag[] lore = container.get(StructuredDataKey.LORE);
|
||||||
if (loreData != null) {
|
if (lore != null) {
|
||||||
for (final Tag tag : loreData.value()) {
|
for (final Tag tag : lore) {
|
||||||
protocol.getComponentRewriter().processTag(connection, tag);
|
protocol.getComponentRewriter().processTag(connection, tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,35 +166,35 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void updateComponent(final UserConnection connection, final Item item, final StructuredDataKey<Tag> key, final String backupKey) {
|
protected void updateComponent(final UserConnection connection, final Item item, final StructuredDataKey<Tag> key, final String backupKey) {
|
||||||
final StructuredData<Tag> name = item.dataContainer().getNonEmpty(key);
|
final Tag name = item.dataContainer().get(key);
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Tag originalName = name.value().copy();
|
final Tag originalName = name.copy();
|
||||||
protocol.getComponentRewriter().processTag(connection, name.value());
|
protocol.getComponentRewriter().processTag(connection, name);
|
||||||
if (!name.value().equals(originalName)) {
|
if (!name.equals(originalName)) {
|
||||||
saveTag(createCustomTag(item), originalName, backupKey);
|
saveTag(createCustomTag(item), originalName, backupKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void restoreTextComponents(final Item item) {
|
protected void restoreTextComponents(final Item item) {
|
||||||
final StructuredDataContainer data = item.dataContainer();
|
final StructuredDataContainer data = item.dataContainer();
|
||||||
final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
|
final CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA);
|
||||||
if (customData == null) {
|
if (customData == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove custom name
|
// Remove custom name
|
||||||
if (customData.value().remove(nbtTagName("added_custom_name")) != null) {
|
if (customData.remove(nbtTagName("added_custom_name")) != null) {
|
||||||
data.remove(StructuredDataKey.CUSTOM_NAME);
|
data.remove(StructuredDataKey.CUSTOM_NAME);
|
||||||
} else {
|
} else {
|
||||||
final Tag customName = removeBackupTag(customData.value(), "custom_name");
|
final Tag customName = removeBackupTag(customData, "custom_name");
|
||||||
if (customName != null) {
|
if (customName != null) {
|
||||||
data.set(StructuredDataKey.CUSTOM_NAME, customName);
|
data.set(StructuredDataKey.CUSTOM_NAME, customName);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Tag itemName = removeBackupTag(customData.value(), "item_name");
|
final Tag itemName = removeBackupTag(customData, "item_name");
|
||||||
if (itemName != null) {
|
if (itemName != null) {
|
||||||
data.set(StructuredDataKey.ITEM_NAME, itemName);
|
data.set(StructuredDataKey.ITEM_NAME, itemName);
|
||||||
}
|
}
|
||||||
@ -203,14 +203,12 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
|
|||||||
|
|
||||||
protected CompoundTag createCustomTag(final Item item) {
|
protected CompoundTag createCustomTag(final Item item) {
|
||||||
final StructuredDataContainer data = item.dataContainer();
|
final StructuredDataContainer data = item.dataContainer();
|
||||||
final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
|
CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA);
|
||||||
if (customData != null) {
|
if (customData == null) {
|
||||||
return customData.value();
|
customData = new CompoundTag();
|
||||||
|
data.set(StructuredDataKey.CUSTOM_DATA, customData);
|
||||||
}
|
}
|
||||||
|
return customData;
|
||||||
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) {
|
protected void saveTag(final CompoundTag customData, final Tag tag, final String name) {
|
||||||
|
Loading…
Reference in New Issue
Block a user