Skip to content

Commit cdd03f3

Browse files
committed
Fix support for oversized stacks and remove the need for adding our own extra tag to track it (#8098)
1 parent cda1c7d commit cdd03f3

File tree

6 files changed

+59
-33
lines changed

6 files changed

+59
-33
lines changed

src/api/java/mekanism/api/MekanismAPI.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ private MekanismAPI() {
3434
/**
3535
* The version of the api classes - may not always match the mod's version
3636
*/
37-
public static final String API_VERSION = "10.6.0";
37+
public static final String API_VERSION = "10.6.1";
3838
/**
3939
* Mekanism's Mod ID
4040
*/

src/api/java/mekanism/api/SerializationConstants.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,6 @@ private SerializationConstants() {
260260
public static final String SILK_TOUCH = "silk_touch";
261261
public static final String SINGLE_ITEM = "single_item";
262262
public static final String SIZE = "size";
263-
public static final String SIZE_OVERRIDE = "size_override";
264263
public static final String SLOT = "slot";
265264
public static final String SLURRY_TANKS = "slurry_tanks";
266265
public static final String SORTING = "sorting";

src/api/java/mekanism/api/SerializerHelper.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@
1515
import java.util.stream.Stream;
1616
import mekanism.api.annotations.NothingNullByDefault;
1717
import net.minecraft.Util;
18+
import net.minecraft.core.HolderLookup;
19+
import net.minecraft.core.HolderLookup.Provider;
20+
import net.minecraft.core.component.DataComponentPatch;
21+
import net.minecraft.nbt.CompoundTag;
22+
import net.minecraft.nbt.NbtOps;
23+
import net.minecraft.nbt.Tag;
24+
import net.minecraft.util.ExtraCodecs;
25+
import net.minecraft.world.item.ItemStack;
1826
import org.jetbrains.annotations.NotNull;
1927

2028
//TODO - 1.21: Update the wiki docs to fix the syntax
@@ -40,6 +48,48 @@ private SerializerHelper() {
4048
return Codec.LONG.flatXmap(checker, checker);
4149
});
4250

51+
/**
52+
* Custom codec to allow serializing an item stack without the upper bounds.
53+
*
54+
* @since 10.6.1
55+
*/
56+
public static final Codec<ItemStack> OVERSIZED_ITEM_CODEC = Codec.lazyInitialized(() -> RecordCodecBuilder.create(instance -> instance.group(
57+
ItemStack.ITEM_NON_AIR_CODEC.fieldOf(SerializationConstants.ID).forGetter(ItemStack::getItemHolder),
58+
ExtraCodecs.POSITIVE_INT.fieldOf(SerializationConstants.COUNT).orElse(1).forGetter(ItemStack::getCount),
59+
DataComponentPatch.CODEC.optionalFieldOf(SerializationConstants.COMPONENTS, DataComponentPatch.EMPTY).forGetter(ItemStack::getComponentsPatch)
60+
).apply(instance, ItemStack::new)));
61+
62+
/**
63+
* Helper similar to {@link ItemStack#save(Provider)} but with support for oversized stacks.
64+
*
65+
* @since 10.6.1
66+
*/
67+
public static Tag saveOversized(HolderLookup.Provider registryAccess, ItemStack stack) {
68+
if (stack.isEmpty()) {
69+
throw new IllegalStateException("Cannot encode empty ItemStack");
70+
}
71+
return OVERSIZED_ITEM_CODEC.encodeStart(registryAccess.createSerializationContext(NbtOps.INSTANCE), stack).getOrThrow();
72+
}
73+
74+
/**
75+
* Helper similar to {@link ItemStack#parse(Provider, Tag)} but with support for oversized stacks.
76+
*
77+
* @since 10.6.1
78+
*/
79+
public static Optional<ItemStack> parseOversized(HolderLookup.Provider pLookupProvider, Tag pTag) {
80+
return OVERSIZED_ITEM_CODEC.parse(pLookupProvider.createSerializationContext(NbtOps.INSTANCE), pTag)
81+
.resultOrPartial(p_330102_ -> MekanismAPI.logger.error("Tried to load invalid item: '{}'", p_330102_));
82+
}
83+
84+
/**
85+
* Helper similar to {@link ItemStack#parseOptional(Provider, CompoundTag)} but with support for oversized stacks.
86+
*
87+
* @since 10.6.1
88+
*/
89+
public static ItemStack parseOversizedOptional(HolderLookup.Provider pLookupProvider, CompoundTag tag) {
90+
return tag.isEmpty() ? ItemStack.EMPTY : parseOversized(pLookupProvider, tag).orElse(ItemStack.EMPTY);
91+
}
92+
4393
/**
4494
* Generate a RecordCodecBuilder which is required only if the 'primary' is present. If this field is present, it will be returned regardless. Does not eat errors
4595
*

src/api/java/mekanism/api/inventory/IInventorySlot.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
import mekanism.api.AutomationType;
55
import mekanism.api.IContentsListener;
66
import mekanism.api.SerializationConstants;
7+
import mekanism.api.SerializerHelper;
78
import mekanism.api.annotations.NothingNullByDefault;
89
import net.minecraft.core.HolderLookup;
910
import net.minecraft.nbt.CompoundTag;
10-
import net.minecraft.nbt.Tag;
1111
import net.minecraft.world.inventory.Slot;
1212
import net.minecraft.world.item.ItemStack;
1313
import net.neoforged.neoforge.common.util.INBTSerializable;
@@ -297,12 +297,7 @@ default int getCount() {
297297
default CompoundTag serializeNBT(HolderLookup.Provider provider) {
298298
CompoundTag nbt = new CompoundTag();
299299
if (!isEmpty()) {
300-
ItemStack current = getStack();
301-
Tag stackTag = current.save(provider);
302-
nbt.put(SerializationConstants.ITEM, stackTag);
303-
if (getCount() > current.getMaxStackSize()) {
304-
nbt.putInt(SerializationConstants.SIZE_OVERRIDE, getCount());
305-
}
300+
nbt.put(SerializationConstants.ITEM, SerializerHelper.saveOversized(provider, getStack()));
306301
}
307302
return nbt;
308303
}

src/main/java/mekanism/common/attachments/containers/item/ComponentBackedInventorySlot.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
import mekanism.api.Action;
66
import mekanism.api.AutomationType;
77
import mekanism.api.SerializationConstants;
8+
import mekanism.api.SerializerHelper;
89
import mekanism.api.annotations.NothingNullByDefault;
910
import mekanism.api.inventory.IInventorySlot;
1011
import mekanism.common.attachments.containers.ComponentBackedContainer;
1112
import mekanism.common.attachments.containers.ContainerType;
12-
import mekanism.common.util.NBTUtils;
1313
import net.minecraft.core.HolderLookup;
1414
import net.minecraft.core.HolderLookup.Provider;
1515
import net.minecraft.nbt.CompoundTag;
16-
import net.minecraft.nbt.Tag;
1716
import net.minecraft.world.item.Item;
1817
import net.minecraft.world.item.ItemStack;
1918
import org.jetbrains.annotations.NotNull;
@@ -203,21 +202,13 @@ public CompoundTag serializeNBT(HolderLookup.Provider provider) {
203202
CompoundTag nbt = new CompoundTag();
204203
ItemStack current = getStack();
205204
if (!current.isEmpty()) {
206-
nbt.put(SerializationConstants.ITEM, current.save(provider));
207-
if (getCount() > current.getMaxStackSize()) {
208-
nbt.putInt(SerializationConstants.SIZE_OVERRIDE, getCount());
209-
}
205+
nbt.put(SerializationConstants.ITEM, SerializerHelper.saveOversized(provider, current));
210206
}
211207
return nbt;
212208
}
213209

214210
@Override
215211
public void deserializeNBT(Provider provider, CompoundTag nbt) {
216-
ItemStack stack = ItemStack.EMPTY;
217-
if (nbt.contains(SerializationConstants.ITEM, Tag.TAG_COMPOUND)) {
218-
stack = ItemStack.parseOptional(provider, nbt.getCompound(SerializationConstants.ITEM));
219-
NBTUtils.setIntIfPresent(nbt, SerializationConstants.SIZE_OVERRIDE, stack::setCount);
220-
}
221-
setStack(stack);
212+
setStack(SerializerHelper.parseOversizedOptional(provider, nbt.getCompound(SerializationConstants.ITEM)));
222213
}
223214
}

src/main/java/mekanism/common/inventory/slot/BasicInventorySlot.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,16 @@
88
import mekanism.api.AutomationType;
99
import mekanism.api.IContentsListener;
1010
import mekanism.api.SerializationConstants;
11+
import mekanism.api.SerializerHelper;
1112
import mekanism.api.annotations.NothingNullByDefault;
1213
import mekanism.api.functions.ConstantPredicates;
1314
import mekanism.api.inventory.IInventorySlot;
1415
import mekanism.common.inventory.container.slot.ContainerSlotType;
1516
import mekanism.common.inventory.container.slot.InventoryContainerSlot;
1617
import mekanism.common.inventory.container.slot.SlotOverlay;
1718
import mekanism.common.inventory.warning.ISupportsWarning;
18-
import mekanism.common.util.NBTUtils;
1919
import net.minecraft.core.HolderLookup;
2020
import net.minecraft.nbt.CompoundTag;
21-
import net.minecraft.nbt.Tag;
2221
import net.minecraft.world.item.Item;
2322
import net.minecraft.world.item.ItemStack;
2423
import org.jetbrains.annotations.NotNull;
@@ -333,23 +332,15 @@ public int getCount() {
333332
public CompoundTag serializeNBT(HolderLookup.Provider provider) {
334333
CompoundTag nbt = new CompoundTag();
335334
if (!isEmpty()) {
336-
nbt.put(SerializationConstants.ITEM, current.save(provider));
337-
if (getCount() > current.getMaxStackSize()) {
338-
nbt.putInt(SerializationConstants.SIZE_OVERRIDE, getCount());
339-
}
335+
nbt.put(SerializationConstants.ITEM, SerializerHelper.saveOversized(provider, current));
340336
}
341337
return nbt;
342338
}
343339

344340
@Override
345341
public void deserializeNBT(HolderLookup.Provider provider, CompoundTag nbt) {
346-
ItemStack stack = ItemStack.EMPTY;
347-
if (nbt.contains(SerializationConstants.ITEM, Tag.TAG_COMPOUND)) {
348-
stack = ItemStack.parseOptional(provider, nbt.getCompound(SerializationConstants.ITEM));
349-
NBTUtils.setIntIfPresent(nbt, SerializationConstants.SIZE_OVERRIDE, stack::setCount);
350-
}
351342
//Set the stack in an unchecked way so that if it is no longer valid, we don't end up
352343
// crashing due to the stack not being valid
353-
setStackUnchecked(stack);
344+
setStackUnchecked(SerializerHelper.parseOversizedOptional(provider, nbt.getCompound(SerializationConstants.ITEM)));
354345
}
355346
}

0 commit comments

Comments
 (0)