diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ca2805f25..9e8596c70 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ # Minecraft # MC version is specified in gradle.properties, as we need that in settings.gradle. # Remember to update corresponding versions in fabric.mod.json/mods.toml -fabric-api = "0.75.3+1.19.4" +fabric-api = "0.78.0+1.19.4" fabric-loader = "0.14.17" forge = "45.0.42" forgeSpi = "6.0.0" diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java b/projects/fabric/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java index 45012e403..fa15b1dd9 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java @@ -14,18 +14,15 @@ import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.PeripheralType; import dan200.computercraft.shared.peripheral.generic.SidedGenericPeripheral; import dan200.computercraft.shared.platform.FabricContainerTransfer; -import net.fabricmc.fabric.api.transfer.v1.item.InventoryStorage; import net.fabricmc.fabric.api.transfer.v1.item.ItemStorage; import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant; -import net.fabricmc.fabric.api.transfer.v1.storage.Storage; +import net.fabricmc.fabric.api.transfer.v1.storage.SlottedStorage; import net.fabricmc.fabric.api.transfer.v1.storage.base.SingleSlotStorage; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.ChestBlock; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.ChestBlockEntity; import net.minecraft.world.level.block.state.BlockState; import javax.annotation.Nullable; @@ -50,15 +47,25 @@ public class InventoryMethods implements GenericPeripheral { return ComputerCraftAPI.MOD_ID + ":inventory"; } - @LuaFunction(mainThread = true) - public static int size(InventoryStorage inventory) { - return inventory.getSlots().size(); + /** + * Wrapper over a {@link SlottedStorage}. + *

+ * The generic peripheral system doesn't (currently) support generics, and so we need put the inventory in a box. + * + * @param storage The underlying storage + */ + public record StorageWrapper(SlottedStorage storage) { } @LuaFunction(mainThread = true) - public static Map> list(InventoryStorage inventory) { + public static int size(StorageWrapper inventory) { + return inventory.storage().getSlots().size(); + } + + @LuaFunction(mainThread = true) + public static Map> list(StorageWrapper inventory) { Map> result = new HashMap<>(); - var slots = inventory.getSlots(); + var slots = inventory.storage().getSlots(); var size = slots.size(); for (var i = 0; i < size; i++) { var stack = toStack(slots.get(i)); @@ -70,22 +77,22 @@ public class InventoryMethods implements GenericPeripheral { @Nullable @LuaFunction(mainThread = true) - public static Map getItemDetail(InventoryStorage inventory, int slot) throws LuaException { - assertBetween(slot, 1, inventory.getSlots().size(), "Slot out of range (%s)"); + public static Map getItemDetail(StorageWrapper inventory, int slot) throws LuaException { + assertBetween(slot, 1, inventory.storage().getSlotCount(), "Slot out of range (%s)"); - var stack = toStack(inventory.getSlot(slot - 1)); + var stack = toStack(inventory.storage().getSlot(slot - 1)); return stack.isEmpty() ? null : VanillaDetailRegistries.ITEM_STACK.getDetails(stack); } @LuaFunction(mainThread = true) - public static long getItemLimit(InventoryStorage inventory, int slot) throws LuaException { - assertBetween(slot, 1, inventory.getSlots().size(), "Slot out of range (%s)"); - return inventory.getSlot(slot - 1).getCapacity(); + public static long getItemLimit(StorageWrapper inventory, int slot) throws LuaException { + assertBetween(slot, 1, inventory.storage().getSlotCount(), "Slot out of range (%s)"); + return inventory.storage().getSlot(slot - 1).getCapacity(); } @LuaFunction(mainThread = true) public static int pushItems( - InventoryStorage from, IComputerAccess computer, + StorageWrapper from, IComputerAccess computer, String toName, int fromSlot, Optional limit, Optional toSlot ) throws LuaException { // Find location to transfer to @@ -95,65 +102,68 @@ public class InventoryMethods implements GenericPeripheral { var to = extractHandler(location); if (to == null) throw new LuaException("Target '" + toName + "' is not an inventory"); + var fromStorage = from.storage(); + // Validate slots int actualLimit = limit.orElse(Integer.MAX_VALUE); - assertBetween(fromSlot, 1, from.getSlots().size(), "From slot out of range (%s)"); + assertBetween(fromSlot, 1, fromStorage.getSlotCount(), "From slot out of range (%s)"); if (toSlot.isPresent()) assertBetween(toSlot.get(), 1, to.getSlots().size(), "To slot out of range (%s)"); if (actualLimit <= 0) return 0; - return moveItem(from, fromSlot - 1, to, toSlot.orElse(0) - 1, actualLimit); + return moveItem(fromStorage, fromSlot - 1, to, toSlot.orElse(0) - 1, actualLimit); } @LuaFunction(mainThread = true) public static int pullItems( - InventoryStorage to, IComputerAccess computer, + StorageWrapper to, IComputerAccess computer, String fromName, int fromSlot, Optional limit, Optional toSlot ) throws LuaException { // Find location to transfer to var location = computer.getAvailablePeripheral(fromName); if (location == null) throw new LuaException("Source '" + fromName + "' does not exist"); + var toStorage = to.storage(); + var from = extractHandler(location); if (from == null) throw new LuaException("Source '" + fromName + "' is not an inventory"); // Validate slots int actualLimit = limit.orElse(Integer.MAX_VALUE); assertBetween(fromSlot, 1, from.getSlots().size(), "From slot out of range (%s)"); - if (toSlot.isPresent()) assertBetween(toSlot.get(), 1, to.getSlots().size(), "To slot out of range (%s)"); + if (toSlot.isPresent()) assertBetween(toSlot.get(), 1, toStorage.getSlotCount(), "To slot out of range (%s)"); if (actualLimit <= 0) return 0; - return moveItem(from, fromSlot - 1, to, toSlot.orElse(0) - 1, actualLimit); + return moveItem(from, fromSlot - 1, toStorage, toSlot.orElse(0) - 1, actualLimit); + } + + public static @Nullable StorageWrapper extractContainer(Level level, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, @Nullable Direction direction) { + var storage = extractContainerImpl(level, pos, state, blockEntity, direction); + return storage == null ? null : new StorageWrapper(storage); } @SuppressWarnings("NullAway") // FIXME: Doesn't cope with @Nullable type parameter. - public static @Nullable Storage extractContainer(Level level, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, @Nullable Direction direction) { - // ItemStorage returns a CombinedStorage rather than an InventoryStorage for double chests. - if (blockEntity instanceof ChestBlockEntity && state.getBlock() instanceof ChestBlock chestBlock) { - var inventory = ChestBlock.getContainer(chestBlock, state, level, pos, true); - return inventory == null ? null : InventoryStorage.of(inventory, null); + private static @Nullable SlottedStorage extractContainerImpl(Level level, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, @Nullable Direction direction) { + var internal = ItemStorage.SIDED.find(level, pos, state, blockEntity, null); + if (internal instanceof SlottedStorage storage) return storage; + + if (direction != null) { + var external = ItemStorage.SIDED.find(level, pos, state, blockEntity, direction); + if (external instanceof SlottedStorage storage) return storage; } - var internal = ItemStorage.SIDED.find(level, pos, state, blockEntity, null); - if (internal instanceof InventoryStorage || direction == null) return internal; - - var external = ItemStorage.SIDED.find(level, pos, state, blockEntity, direction); - if (external instanceof InventoryStorage) return external; - - return internal != null ? internal : external; + return null; } @Nullable - private static InventoryStorage extractHandler(IPeripheral peripheral) { + private static SlottedStorage extractHandler(IPeripheral peripheral) { var object = peripheral.getTarget(); var direction = peripheral instanceof SidedGenericPeripheral sided ? sided.direction() : null; - if (object instanceof BlockEntity blockEntity && blockEntity.isRemoved()) return null; - - if (object instanceof InventoryStorage storage) return storage; - if (object instanceof BlockEntity blockEntity) { - var found = extractContainer(blockEntity.getLevel(), blockEntity.getBlockPos(), blockEntity.getBlockState(), blockEntity, direction); - if (found instanceof InventoryStorage storage) return storage; + if (blockEntity.isRemoved()) return null; + + var found = extractContainerImpl(blockEntity.getLevel(), blockEntity.getBlockPos(), blockEntity.getBlockState(), blockEntity, direction); + if (found != null) return found; } return null; @@ -169,7 +179,7 @@ public class InventoryMethods implements GenericPeripheral { * @param limit The max number to move. {@link Integer#MAX_VALUE} for no limit. * @return The number of items moved. */ - private static int moveItem(InventoryStorage from, int fromSlot, InventoryStorage to, int toSlot, final int limit) { + private static int moveItem(SlottedStorage from, int fromSlot, SlottedStorage to, int toSlot, final int limit) { var fromWrapper = FabricContainerTransfer.of(from).singleSlot(fromSlot); var toWrapper = FabricContainerTransfer.of(to); diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FabricContainerTransfer.java b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FabricContainerTransfer.java index 5036fffc7..589fe2235 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FabricContainerTransfer.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FabricContainerTransfer.java @@ -4,8 +4,8 @@ package dan200.computercraft.shared.platform; -import net.fabricmc.fabric.api.transfer.v1.item.InventoryStorage; import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant; +import net.fabricmc.fabric.api.transfer.v1.storage.SlottedStorage; import net.fabricmc.fabric.api.transfer.v1.storage.Storage; import net.fabricmc.fabric.api.transfer.v1.storage.StorageUtil; import net.fabricmc.fabric.api.transfer.v1.storage.StorageView; @@ -25,10 +25,10 @@ public class FabricContainerTransfer implements ContainerTransfer { } public static ContainerTransfer of(Storage storage) { - return storage instanceof InventoryStorage inv ? new SlottedImpl(inv) : new FabricContainerTransfer(storage); + return storage instanceof SlottedStorage inv ? new SlottedImpl(inv) : new FabricContainerTransfer(storage); } - public static ContainerTransfer.Slotted of(InventoryStorage storage) { + public static ContainerTransfer.Slotted of(SlottedStorage storage) { return new SlottedImpl(storage); } @@ -68,9 +68,9 @@ public class FabricContainerTransfer implements ContainerTransfer { } private static class SlottedImpl extends FabricContainerTransfer implements ContainerTransfer.Slotted { - private final InventoryStorage storage; + private final SlottedStorage storage; - SlottedImpl(InventoryStorage storage) { + SlottedImpl(SlottedStorage storage) { super(storage); this.storage = storage; } @@ -86,7 +86,7 @@ public class FabricContainerTransfer implements ContainerTransfer { } } - private record OffsetStorage(InventoryStorage storage, int offset) implements Storage { + private record OffsetStorage(SlottedStorage storage, int offset) implements Storage { @Override public boolean supportsInsertion() { for (var slot : storage.getSlots()) { diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FakeNetHandler.java b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FakeNetHandler.java index 633826e3c..ddbe5f737 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FakeNetHandler.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FakeNetHandler.java @@ -153,7 +153,6 @@ class FakeNetHandler extends ServerGamePacketListenerImpl { @Override public void send(Packet packet, @Nullable PacketSendListener packetSendListener) { - super.send(packet, packetSendListener); } @Override diff --git a/projects/fabric/src/main/resources/fabric.mod.json b/projects/fabric/src/main/resources/fabric.mod.json index bb09ea85f..0e638d0c4 100644 --- a/projects/fabric/src/main/resources/fabric.mod.json +++ b/projects/fabric/src/main/resources/fabric.mod.json @@ -47,7 +47,7 @@ ], "depends": { "fabricloader": ">=0.14.17", - "fabric-api": ">=0.75.3", + "fabric-api": ">=0.78.0", "minecraft": ">=1.19.4 <1.20" }, "accessWidener": "computercraft.accesswidener"