mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-14 12:10:30 +00:00
Correctly obey stack limits in OffsetStorage.extract/insert
Many thanks to Lem for managing to reproduce it. It was actually an easy bug bug to spot on second look, but having a reliable way to verify was super helpful. Fixes #1338
This commit is contained in:
parent
e96ac35d67
commit
44f945c040
@ -42,7 +42,7 @@ jqwik = "1.7.2"
|
||||
junit = "5.9.2"
|
||||
|
||||
# Build tools
|
||||
cctJavadoc = "1.6.0"
|
||||
cctJavadoc = "1.6.1"
|
||||
checkstyle = "10.3.4"
|
||||
curseForgeGradle = "1.0.11"
|
||||
errorProne-core = "2.18.0"
|
||||
|
@ -22,7 +22,7 @@ public class InventoryUtilTest {
|
||||
|
||||
var remainder = InventoryUtil.storeItemsFromOffset(container, new ItemStack(Items.COBBLESTONE, 32), 4);
|
||||
assertThat("Remainder is empty", remainder, isStack(ItemStack.EMPTY));
|
||||
assertThat("Was inserted into slot", container.getItem(4), isStack(new ItemStack(Items.COBBLESTONE, 32)));
|
||||
assertThat("Was inserted into slot", container.getItem(4), isStack(Items.COBBLESTONE, 32));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -33,6 +33,6 @@ public class InventoryUtilTest {
|
||||
|
||||
var remainder = InventoryUtil.storeItemsFromOffset(container, new ItemStack(Items.COBBLESTONE, 32), 4);
|
||||
assertThat("Remainder is empty", remainder, isStack(ItemStack.EMPTY));
|
||||
assertThat("Was inserted into slot", container.getItem(1), isStack(new ItemStack(Items.COBBLESTONE, 32)));
|
||||
assertThat("Was inserted into slot", container.getItem(1), isStack(Items.COBBLESTONE, 32));
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
package dan200.computercraft.test.shared;
|
||||
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
@ -30,4 +31,8 @@ public class ItemStackMatcher extends TypeSafeMatcher<ItemStack> {
|
||||
public static Matcher<ItemStack> isStack(ItemStack stack) {
|
||||
return new ItemStackMatcher(stack);
|
||||
}
|
||||
|
||||
public static Matcher<ItemStack> isStack(Item item, int size) {
|
||||
return new ItemStackMatcher(new ItemStack(item, size));
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
@ -34,7 +36,7 @@ public interface ContainerTransferContract {
|
||||
var move = wrap(inv).singleSlot(0).moveTo(wrap(inv).singleSlot(0), 64);
|
||||
assertEquals(ContainerTransfer.NO_SPACE, move);
|
||||
|
||||
assertThat(inv.getItem(0), isStack(new ItemStack(Items.DIRT, 64)));
|
||||
assertThat(inv.getItem(0), isStack(Items.DIRT, 64));
|
||||
|
||||
assertNoOverlap(inv);
|
||||
}
|
||||
@ -48,7 +50,7 @@ public interface ContainerTransferContract {
|
||||
assertEquals(64, move);
|
||||
|
||||
assertThat(inv.getItem(0), isStack(ItemStack.EMPTY));
|
||||
assertThat(inv.getItem(1), isStack(new ItemStack(Items.DIRT, 64)));
|
||||
assertThat(inv.getItem(1), isStack(Items.DIRT, 64));
|
||||
|
||||
assertNoOverlap(inv);
|
||||
}
|
||||
@ -64,7 +66,7 @@ public interface ContainerTransferContract {
|
||||
assertEquals(64, move);
|
||||
|
||||
assertThat(source.getItem(0), isStack(ItemStack.EMPTY));
|
||||
assertThat(destination.getItem(0), isStack(new ItemStack(Items.DIRT, 64)));
|
||||
assertThat(destination.getItem(0), isStack(Items.DIRT, 64));
|
||||
|
||||
assertNoOverlap(source, destination);
|
||||
}
|
||||
@ -85,12 +87,40 @@ public interface ContainerTransferContract {
|
||||
|
||||
assertThat(source.getItem(0), isStack(ItemStack.EMPTY));
|
||||
for (var i = 0; i < 4; i++) {
|
||||
assertThat("Stack in slot " + i, destination.getItem(i), isStack(new ItemStack(Items.DIRT, 64)));
|
||||
assertThat("Stack in slot " + i, destination.getItem(i), isStack(Items.DIRT, 64));
|
||||
}
|
||||
|
||||
assertNoOverlap(source, destination);
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "offset = {0}")
|
||||
@ValueSource(ints = { 0, 1, 2 })
|
||||
default void testMoveDistributeWithLimit(int offset) {
|
||||
// We create a specific setup here such that each slot has room for strictly less than the limit(=17).
|
||||
// There was a bug (https://github.com/cc-tweaked/CC-Tweaked/issues/1338) where this would insert items beyond
|
||||
// the limit as it did not account for the number of items already transferred.
|
||||
var destination = new SimpleContainer(4);
|
||||
destination.setItem(offset, new ItemStack(Items.DIRT, 48));
|
||||
destination.setItem((offset + 1) % 4, new ItemStack(Items.DIRT, 48));
|
||||
|
||||
var source = new SimpleContainer(4);
|
||||
source.setItem(0, new ItemStack(Items.DIRT, 64));
|
||||
source.setItem(1, new ItemStack(Items.DIRT, 64));
|
||||
|
||||
var move = wrap(source).moveTo(wrap(destination).rotate(offset), 17);
|
||||
assertEquals(17, move);
|
||||
|
||||
assertThat("Source stack in slot 0", source.getItem(0), isStack(Items.DIRT, 47));
|
||||
assertThat("Source stack in slot 1", source.getItem(1), isStack(Items.DIRT, 64));
|
||||
|
||||
assertThat("Dest stack in slot 0", destination.getItem(offset), isStack(Items.DIRT, 64));
|
||||
assertThat("Dest stack in slot 2", destination.getItem((offset + 1) % 4), isStack(Items.DIRT, 49));
|
||||
assertThat("Dest stack in slot 3", destination.getItem((offset + 2) % 4), isStack(ItemStack.EMPTY));
|
||||
assertThat("Dest stack in slot 3", destination.getItem((offset + 3) % 4), isStack(ItemStack.EMPTY));
|
||||
|
||||
assertNoOverlap(source, destination);
|
||||
}
|
||||
|
||||
@Test
|
||||
default void testMoveSkipFullSlot() {
|
||||
var destination = new SimpleContainer(4);
|
||||
@ -103,8 +133,8 @@ public interface ContainerTransferContract {
|
||||
assertEquals(64, move);
|
||||
|
||||
assertThat(source.getItem(1), isStack(ItemStack.EMPTY));
|
||||
assertThat(destination.getItem(0), isStack(new ItemStack(Items.DIRT, 64)));
|
||||
assertThat(destination.getItem(1), isStack(new ItemStack(Items.DIRT, 64)));
|
||||
assertThat(destination.getItem(0), isStack(Items.DIRT, 64));
|
||||
assertThat(destination.getItem(1), isStack(Items.DIRT, 64));
|
||||
|
||||
assertNoOverlap(source, destination);
|
||||
}
|
||||
@ -124,7 +154,7 @@ public interface ContainerTransferContract {
|
||||
var move = wrap(source).moveTo(wrap(destination), 64);
|
||||
assertEquals(ContainerTransfer.NO_SPACE, move);
|
||||
|
||||
assertThat(source.getItem(0), isStack(new ItemStack(Items.DIRT, 64)));
|
||||
assertThat(source.getItem(0), isStack(Items.DIRT, 64));
|
||||
assertThat(destination.getItem(0), isStack(ItemStack.EMPTY));
|
||||
|
||||
assertNoOverlap(source, destination);
|
||||
@ -143,7 +173,7 @@ public interface ContainerTransferContract {
|
||||
assertEquals(32, move);
|
||||
|
||||
assertThat("Source is empty", source.getItem(0), isStack(ItemStack.EMPTY));
|
||||
assertThat("Was inserted into slot", destination.getItem(1), isStack(new ItemStack(Items.COBBLESTONE, 32)));
|
||||
assertThat("Was inserted into slot", destination.getItem(1), isStack(Items.COBBLESTONE, 32));
|
||||
}
|
||||
|
||||
static void assertNoOverlap(Container... containers) {
|
||||
|
@ -111,7 +111,7 @@ public class FabricContainerTransfer implements ContainerTransfer {
|
||||
|
||||
long transferred = 0;
|
||||
for (var i = 0; i < size; i++) {
|
||||
transferred += slots.get(wrap(i, size)).insert(resource, maxAmount, transaction);
|
||||
transferred += slots.get(wrap(i, size)).insert(resource, maxAmount - transferred, transaction);
|
||||
if (transferred >= maxAmount) break;
|
||||
}
|
||||
|
||||
@ -125,7 +125,7 @@ public class FabricContainerTransfer implements ContainerTransfer {
|
||||
|
||||
long transferred = 0;
|
||||
for (var i = 0; i < size; i++) {
|
||||
transferred += slots.get(wrap(i, size)).extract(resource, maxAmount, transaction);
|
||||
transferred += slots.get(wrap(i, size)).extract(resource, maxAmount - transferred, transaction);
|
||||
if (transferred >= maxAmount) break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user