3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-07-11 09:48:03 +02:00

Change items to not be nullable in 1.20.5+

With the server and client actually having empty checks in many places now, this simplifies empty checks going forward
Dieser Commit ist enthalten in:
Nassim Jahnke 2024-06-07 13:34:46 +02:00
Ursprung 5053d739c0
Commit 842cb8dac5
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: EF6771C01F6EF02F
10 geänderte Dateien mit 54 neuen und 51 gelöschten Zeilen

Datei anzeigen

@ -93,7 +93,7 @@ public class DataItem implements Item {
} }
@Override @Override
public StructuredDataContainer structuredData() { public StructuredDataContainer dataContainer() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

Datei anzeigen

@ -90,7 +90,12 @@ public interface Item {
*/ */
void setTag(@Nullable CompoundTag tag); void setTag(@Nullable CompoundTag tag);
StructuredDataContainer structuredData(); /**
* Returns the data container for item data components.
*
* @return the data container
*/
StructuredDataContainer dataContainer();
/** /**
* Returns a copy of the item. * Returns a copy of the item.

Datei anzeigen

@ -41,6 +41,11 @@ public class StructuredItem implements Item {
this.data = data; this.data = data;
} }
public static StructuredItem empty() {
// Data is mutable, create a new item
return new StructuredItem(0, 0);
}
@Override @Override
public int identifier() { public int identifier() {
return identifier; return identifier;
@ -72,7 +77,7 @@ public class StructuredItem implements Item {
} }
@Override @Override
public StructuredDataContainer structuredData() { public StructuredDataContainer dataContainer() {
return data; return data;
} }

Datei anzeigen

@ -54,7 +54,7 @@ public final class ItemCostType1_20_5 extends Type<Item> {
public void write(final ByteBuf buffer, final Item object) { public void write(final ByteBuf buffer, final Item object) {
Types.VAR_INT.writePrimitive(buffer, object.identifier()); Types.VAR_INT.writePrimitive(buffer, object.identifier());
Types.VAR_INT.writePrimitive(buffer, object.amount()); Types.VAR_INT.writePrimitive(buffer, object.amount());
dataArrayType.write(buffer, object.structuredData().data().values().toArray(EMPTY_DATA_ARRAY)); dataArrayType.write(buffer, object.dataContainer().data().values().toArray(EMPTY_DATA_ARRAY));
} }
public static final class OptionalItemCostType extends OptionalType<Item> { public static final class OptionalItemCostType extends OptionalType<Item> {

Datei anzeigen

@ -33,7 +33,6 @@ import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import java.util.Map; import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
public class ItemType1_20_5 extends Type<Item> { public class ItemType1_20_5 extends Type<Item> {
@ -45,10 +44,10 @@ public class ItemType1_20_5 extends Type<Item> {
} }
@Override @Override
public @Nullable Item read(final ByteBuf buffer) { public Item read(final ByteBuf buffer) {
final int amount = Types.VAR_INT.readPrimitive(buffer); final int amount = Types.VAR_INT.readPrimitive(buffer);
if (amount <= 0) { if (amount <= 0) {
return null; return StructuredItem.empty();
} }
final int id = Types.VAR_INT.readPrimitive(buffer); final int id = Types.VAR_INT.readPrimitive(buffer);
@ -81,8 +80,8 @@ public class ItemType1_20_5 extends Type<Item> {
} }
@Override @Override
public void write(final ByteBuf buffer, @Nullable final Item object) { public void write(final ByteBuf buffer, final Item object) {
if (object == null || object.isEmpty()) { if (object.isEmpty()) {
Types.VAR_INT.writePrimitive(buffer, 0); Types.VAR_INT.writePrimitive(buffer, 0);
return; return;
} }
@ -90,7 +89,7 @@ public class ItemType1_20_5 extends Type<Item> {
Types.VAR_INT.writePrimitive(buffer, object.amount()); Types.VAR_INT.writePrimitive(buffer, object.amount());
Types.VAR_INT.writePrimitive(buffer, object.identifier()); Types.VAR_INT.writePrimitive(buffer, object.identifier());
final Map<StructuredDataKey<?>, StructuredData<?>> data = object.structuredData().data(); final Map<StructuredDataKey<?>, StructuredData<?>> data = object.dataContainer().data();
int valuesSize = 0; int valuesSize = 0;
int markersSize = 0; int markersSize = 0;
for (final StructuredData<?> value : data.values()) { for (final StructuredData<?> value : data.values()) {

Datei anzeigen

@ -88,9 +88,9 @@ import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.BannerPatterns1_
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.DyeColors; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.DyeColors;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.Enchantments1_20_5; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.Enchantments1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.EquipmentSlots1_20_5; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.EquipmentSlots1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.MaxStackSize1_20_3;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.Instruments1_20_3; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.Instruments1_20_3;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.MapDecorations1_20_5; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.MapDecorations1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.MaxStackSize1_20_3;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.PotionEffects1_20_5; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.PotionEffects1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.Potions1_20_5; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.Potions1_20_5;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.TrimMaterials1_20_3; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.data.TrimMaterials1_20_3;
@ -197,7 +197,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
wrapper.passthrough(Types.TAG); // Title wrapper.passthrough(Types.TAG); // Title
wrapper.passthrough(Types.TAG); // Description wrapper.passthrough(Types.TAG); // Description
Item item = handleNonNullItemToClient(wrapper.user(), wrapper.read(itemType())); Item item = handleNonEmptyItemToClient(wrapper.user(), wrapper.read(itemType()));
wrapper.write(mappedItemType(), item); wrapper.write(mappedItemType(), item);
wrapper.passthrough(Types.VAR_INT); // Frame type wrapper.passthrough(Types.VAR_INT); // Frame type
@ -247,7 +247,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
final int blockStateId = wrapper.read(Types.VAR_INT); final int blockStateId = wrapper.read(Types.VAR_INT);
particle.add(Types.VAR_INT, protocol.getMappingData().getNewBlockStateId(blockStateId)); particle.add(Types.VAR_INT, protocol.getMappingData().getNewBlockStateId(blockStateId));
} else if (mappings.isItemParticle(particleId)) { } else if (mappings.isItemParticle(particleId)) {
final Item item = handleNonNullItemToClient(wrapper.user(), wrapper.read(Types.ITEM1_20_2)); final Item item = handleNonEmptyItemToClient(wrapper.user(), wrapper.read(Types.ITEM1_20_2));
particle.add(Types1_20_5.ITEM, item); particle.add(Types1_20_5.ITEM, item);
} else if (particleId == mappings.id("dust")) { } else if (particleId == mappings.id("dust")) {
// R, g, b, scale // R, g, b, scale
@ -301,10 +301,10 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
wrapper.passthrough(Types.VAR_INT); // Container id wrapper.passthrough(Types.VAR_INT); // Container id
final int size = wrapper.passthrough(Types.VAR_INT); final int size = wrapper.passthrough(Types.VAR_INT);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Item input = handleNonNullItemToClient(wrapper.user(), wrapper.read(Types.ITEM1_20_2)); Item input = handleNonEmptyItemToClient(wrapper.user(), wrapper.read(Types.ITEM1_20_2));
wrapper.write(Types1_20_5.ITEM_COST, input); wrapper.write(Types1_20_5.ITEM_COST, input);
final Item output = handleNonNullItemToClient(wrapper.user(), wrapper.read(Types.ITEM1_20_2)); final Item output = handleNonEmptyItemToClient(wrapper.user(), wrapper.read(Types.ITEM1_20_2));
wrapper.write(Types1_20_5.ITEM, output); wrapper.write(Types1_20_5.ITEM, output);
final Item secondInput = handleItemToClient(wrapper.user(), wrapper.read(Types.ITEM1_20_2)); final Item secondInput = handleItemToClient(wrapper.user(), wrapper.read(Types.ITEM1_20_2));
@ -323,12 +323,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
final RecipeRewriter1_20_3<ClientboundPacket1_20_3> recipeRewriter = new RecipeRewriter1_20_3<>(protocol) { final RecipeRewriter1_20_3<ClientboundPacket1_20_3> recipeRewriter = new RecipeRewriter1_20_3<>(protocol) {
@Override @Override
protected Item rewrite(final UserConnection connection, @Nullable Item item) { protected Item rewrite(final UserConnection connection, @Nullable Item item) {
item = super.rewrite(connection, item); return handleNonEmptyItemToClient(connection, item);
if (item == null || item.isEmpty()) {
// Does not allow empty items
return new StructuredItem(1, 1);
}
return item;
} }
}; };
protocol.registerClientbound(ClientboundPackets1_20_3.UPDATE_RECIPES, wrapper -> { protocol.registerClientbound(ClientboundPackets1_20_3.UPDATE_RECIPES, wrapper -> {
@ -344,18 +339,21 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
}); });
} }
public Item handleNonNullItemToClient(final UserConnection connection, @Nullable Item item) { public Item handleNonEmptyItemToClient(final UserConnection connection, @Nullable Item item) {
item = handleItemToClient(connection, item); item = handleItemToClient(connection, item);
// Items are no longer nullable in a few places // Items are no longer nullable in a few places
if (item == null || item.isEmpty()) { if (item.isEmpty()) {
return new StructuredItem(1, 1); return new StructuredItem(1, 1);
} }
return item; return item;
} }
@Override @Override
public @Nullable Item handleItemToClient(final UserConnection connection, @Nullable final Item item) { public Item handleItemToClient(final UserConnection connection, @Nullable final Item item) {
if (item == null) return null; if (item == null) {
// We no longer want null items, always unify them to empty
return StructuredItem.empty();
}
// Add the original as custom data, to be re-used for creative clients as well // Add the original as custom data, to be re-used for creative clients as well
final CompoundTag tag = item.tag(); final CompoundTag tag = item.tag();
@ -369,15 +367,18 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
// Server can send amounts which are higher than vanilla's default, and 1.20.4 will still accept them, // Server can send amounts which are higher than vanilla's default, and 1.20.4 will still accept them,
// let's use the new added data key to emulate this behavior // let's use the new added data key to emulate this behavior
if (structuredItem.amount() > MaxStackSize1_20_3.getMaxStackSize(structuredItem.identifier())) { if (structuredItem.amount() > MaxStackSize1_20_3.getMaxStackSize(structuredItem.identifier())) {
structuredItem.structuredData().set(StructuredDataKey.MAX_STACK_SIZE, structuredItem.amount()); structuredItem.dataContainer().set(StructuredDataKey.MAX_STACK_SIZE, structuredItem.amount());
} }
} }
return super.handleItemToClient(connection, structuredItem); return super.handleItemToClient(connection, structuredItem);
} }
@Override @Override
public @Nullable Item handleItemToServer(UserConnection connection, @Nullable final Item item) { public @Nullable Item handleItemToServer(UserConnection connection, final Item item) {
if (item == null) return null; if (item.isEmpty()) {
// Empty to null for the old protocols
return null;
}
super.handleItemToServer(connection, item); super.handleItemToServer(connection, item);
return toOldItem(connection, item, DATA_CONVERTER); return toOldItem(connection, item, DATA_CONVERTER);
@ -385,7 +386,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
public Item toOldItem(final UserConnection connection, final Item item, final StructuredDataConverter dataConverter) { public Item toOldItem(final UserConnection connection, final Item item, final StructuredDataConverter dataConverter) {
// Start out with custom data and add the rest on top, or short-curcuit with the original item // Start out with custom data and add the rest on top, or short-curcuit with the original item
final StructuredDataContainer data = item.structuredData(); 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.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
@ -405,7 +406,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
public Item toStructuredItem(final UserConnection connection, final Item old) { public Item toStructuredItem(final UserConnection connection, final Item old) {
final CompoundTag tag = old.tag(); final CompoundTag tag = old.tag();
final StructuredItem item = new StructuredItem(old.identifier(), (byte) old.amount(), new StructuredDataContainer()); final StructuredItem item = new StructuredItem(old.identifier(), (byte) old.amount(), new StructuredDataContainer());
final StructuredDataContainer data = item.structuredData(); final StructuredDataContainer data = item.dataContainer();
data.setIdLookup(protocol, true); data.setIdLookup(protocol, true);
if (tag == null) { if (tag == null) {
@ -453,7 +454,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
if (blockEntityTag != null) { if (blockEntityTag != null) {
final CompoundTag clonedTag = blockEntityTag.copy(); final CompoundTag clonedTag = blockEntityTag.copy();
updateBlockEntityTag(connection, data, clonedTag); updateBlockEntityTag(connection, data, clonedTag);
item.structuredData().set(StructuredDataKey.BLOCK_ENTITY_DATA, clonedTag); item.dataContainer().set(StructuredDataKey.BLOCK_ENTITY_DATA, clonedTag);
} }
final CompoundTag debugProperty = tag.getCompoundTag("DebugProperty"); final CompoundTag debugProperty = tag.getCompoundTag("DebugProperty");
@ -1176,14 +1177,13 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
final Item[] items = itemsTag.stream() final Item[] items = itemsTag.stream()
.limit(256) .limit(256)
.map(item -> itemFromTag(connection, item)) .map(item -> itemFromTag(connection, item))
.filter(Objects::nonNull)
.filter(item -> allowEmpty || !item.isEmpty()) .filter(item -> allowEmpty || !item.isEmpty())
.toArray(Item[]::new); .toArray(Item[]::new);
data.set(dataKey, items); data.set(dataKey, items);
} }
} }
private @Nullable Item itemFromTag(final UserConnection connection, final CompoundTag item) { private Item itemFromTag(final UserConnection connection, final CompoundTag item) {
final String id = item.getString("id"); final String id = item.getString("id");
if (id == null) { if (id == null) {
return null; return null;

Datei anzeigen

@ -243,7 +243,7 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
contentsTag.putString("id", "minecraft:stone"); contentsTag.putString("id", "minecraft:stone");
} }
final Map<StructuredDataKey<?>, StructuredData<?>> data = structuredItem.structuredData().data(); final Map<StructuredDataKey<?>, StructuredData<?>> data = structuredItem.dataContainer().data();
if (!data.isEmpty()) { if (!data.isEmpty()) {
final CompoundTag components; final CompoundTag components;
try { try {
@ -971,7 +971,7 @@ public class ComponentRewriter1_20_5<C extends ClientboundPacketType> extends Co
} catch (IllegalArgumentException ignored) { // Fallback value } catch (IllegalArgumentException ignored) { // Fallback value
tag.putInt("count", 1); tag.putInt("count", 1);
} }
final Map<StructuredDataKey<?>, StructuredData<?>> components = item.structuredData().data(); final Map<StructuredDataKey<?>, StructuredData<?>> components = item.dataContainer().data();
tag.put("components", toTag(components, true)); tag.put("components", toTag(components, true));
} }

Datei anzeigen

@ -709,16 +709,12 @@ public final class StructuredDataConverter {
// Check if item name could be mapped, if not, locate original/backup item id and use it // Check if item name could be mapped, if not, locate original/backup item id and use it
static int removeItemBackupTag(final CompoundTag tag, final int unmappedId) { static int removeItemBackupTag(final CompoundTag tag, final int unmappedId) {
if (unmappedId != -1) {
return unmappedId;
}
final IntTag itemBackupTag = tag.getIntTag(ITEM_BACKUP_TAG_KEY); final IntTag itemBackupTag = tag.getIntTag(ITEM_BACKUP_TAG_KEY);
if (itemBackupTag != null) { if (itemBackupTag != null) {
tag.remove(ITEM_BACKUP_TAG_KEY); tag.remove(ITEM_BACKUP_TAG_KEY);
return itemBackupTag.asInt(); return itemBackupTag.asInt();
} }
return -1; return unmappedId;
} }
private void convertBlockPredicates(final CompoundTag tag, final AdventureModePredicate data, final String key, final int hideFlag) { private void convertBlockPredicates(final CompoundTag tag, final AdventureModePredicate data, final String key, final int hideFlag) {
@ -808,7 +804,7 @@ public final class StructuredDataConverter {
savedItem.putByte("Count", (byte) item.amount()); savedItem.putByte("Count", (byte) item.amount());
final CompoundTag itemTag = new CompoundTag(); final CompoundTag itemTag = new CompoundTag();
for (final StructuredData<?> data : item.structuredData().data().values()) { for (final StructuredData<?> data : item.dataContainer().data().values()) {
writeToTag(connection, data, itemTag); writeToTag(connection, data, itemTag);
} }
savedItem.put("tag", itemTag); savedItem.put("tag", itemTag);

Datei anzeigen

@ -20,7 +20,6 @@ package com.viaversion.viaversion.protocols.v1_20_3to1_20_5.storage;
import com.viaversion.viaversion.api.connection.StorableObject; import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.minecraft.ProfileKey; import com.viaversion.viaversion.api.minecraft.ProfileKey;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types; import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ServerboundPackets1_20_3; import com.viaversion.viaversion.protocols.v1_20_2to1_20_3.packet.ServerboundPackets1_20_3;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.Protocol1_20_3To1_20_5; import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.Protocol1_20_3To1_20_5;

Datei anzeigen

@ -24,7 +24,6 @@ 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.ServerboundPacketType; import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import org.checkerframework.checker.nullness.qual.Nullable;
public class StructuredItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType, public class StructuredItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType,
T extends Protocol<C, ?, ?, S>> extends ItemRewriter<C, S, T> { T extends Protocol<C, ?, ?, S>> extends ItemRewriter<C, S, T> {
@ -38,9 +37,9 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
} }
@Override @Override
public @Nullable Item handleItemToClient(UserConnection connection, @Nullable Item item) { public Item handleItemToClient(UserConnection connection, Item item) {
if (item == null) { if (item.isEmpty()) {
return null; return item;
} }
final MappingData mappingData = protocol.getMappingData(); final MappingData mappingData = protocol.getMappingData();
@ -49,16 +48,16 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
item.setIdentifier(mappingData.getNewItemId(item.identifier())); item.setIdentifier(mappingData.getNewItemId(item.identifier()));
} }
if (mappingData.getDataComponentSerializerMappings() != null) { if (mappingData.getDataComponentSerializerMappings() != null) {
item.structuredData().setIdLookup(protocol, true); item.dataContainer().setIdLookup(protocol, true);
} }
} }
return item; return item;
} }
@Override @Override
public @Nullable Item handleItemToServer(UserConnection connection, @Nullable Item item) { public Item handleItemToServer(UserConnection connection, Item item) {
if (item == null) { if (item.isEmpty()) {
return null; return item;
} }
final MappingData mappingData = protocol.getMappingData(); final MappingData mappingData = protocol.getMappingData();
@ -67,7 +66,7 @@ public class StructuredItemRewriter<C extends ClientboundPacketType, S extends S
item.setIdentifier(mappingData.getOldItemId(item.identifier())); item.setIdentifier(mappingData.getOldItemId(item.identifier()));
} }
if (mappingData.getDataComponentSerializerMappings() != null) { if (mappingData.getDataComponentSerializerMappings() != null) {
item.structuredData().setIdLookup(protocol, false); item.dataContainer().setIdLookup(protocol, false);
} }
} }
return item; return item;