From 92ab246bb0b8800a0743e031d9d63645205cfd3e Mon Sep 17 00:00:00 2001 From: Jet-fuel Date: Sun, 15 Mar 2026 07:31:58 +0900 Subject: [PATCH] Fix: validate drawer handler existence (#491) --- .../block/tile/ControllableDrawerTile.java | 47 ++++++++++++++++--- .../inventory/ControllerInventoryHandler.java | 21 ++++++++- .../util/ConnectedDrawers.java | 9 ++++ 3 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/buuz135/functionalstorage/block/tile/ControllableDrawerTile.java b/src/main/java/com/buuz135/functionalstorage/block/tile/ControllableDrawerTile.java index acebd406..ee2e6c2e 100644 --- a/src/main/java/com/buuz135/functionalstorage/block/tile/ControllableDrawerTile.java +++ b/src/main/java/com/buuz135/functionalstorage/block/tile/ControllableDrawerTile.java @@ -23,6 +23,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.api.distmarker.Dist; @@ -76,7 +77,35 @@ public ControllableDrawerTile(BasicTileBlock base, BlockEntityType entityT } } - + @Override + public void onLoad() { + super.onLoad(); + if (level == null || level.isClientSide()) return; + + // Loaded at a new location after block movement + // If controllerPos exists but current position is missing from Controller list -> Moved + if (controllerPos != null) { + BlockEntity be = level.getBlockEntity(controllerPos); + if (be instanceof StorageControllerTile controllerTile) { + boolean isInController = controllerTile.getConnectedDrawers() + .getConnectedDrawers() + .contains(this.getBlockPos().asLong()); + + if (!isInController) { + // Moved Drawer: Remove old link + Force cache reconstruction + controllerTile.getConnectedDrawers() + .getConnectedDrawers() + .removeIf(aLong -> aLong == this.getBlockPos().asLong()); + this.controllerPos = null; + controllerTile.getConnectedDrawers().rebuild(); // selectors[] 재구성 + controllerTile.markForUpdate(); + } + } else { + // No Controller found + this.controllerPos = null; + } + } + } @Override @OnlyIn(Dist.CLIENT) public void initClient() { @@ -298,11 +327,6 @@ public InventoryComponent> getStorageUpgrades() { return storageUpgrades; } - @Override - public void invalidateCaps() { - super.invalidateCaps(); - } - public boolean isEverythingEmpty() { for (int i = 0; i < getStorageUpgrades().getSlots(); i++) { if (!getStorageUpgrades().getStackInSlot(i).isEmpty()) { @@ -316,6 +340,17 @@ public boolean isEverythingEmpty() { } return true; } + @Override + public void invalidateCaps() { + super.invalidateCaps(); + // Rebuild Controller cache immediately on caps invalidation + if (level != null && !level.isClientSide() && controllerPos != null) { + BlockEntity be = level.getBlockEntity(controllerPos); + if (be instanceof StorageControllerTile controllerTile) { + controllerTile.getConnectedDrawers().rebuild(); + } + } + } public abstract InventoryComponent> getStorageUpgradesConstructor(); diff --git a/src/main/java/com/buuz135/functionalstorage/inventory/ControllerInventoryHandler.java b/src/main/java/com/buuz135/functionalstorage/inventory/ControllerInventoryHandler.java index b67a83bf..3a4552e4 100644 --- a/src/main/java/com/buuz135/functionalstorage/inventory/ControllerInventoryHandler.java +++ b/src/main/java/com/buuz135/functionalstorage/inventory/ControllerInventoryHandler.java @@ -75,7 +75,15 @@ private HandlerSlotSelector selectorForSlot(int slot) { @Override public ItemStack getStackInSlot(int slot) { HandlerSlotSelector selector = selectorForSlot(slot); - return null != selector ? selector.getStackInSlot() : ItemStack.EMPTY; + if (null == selector) return ItemStack.EMPTY; + + // Block access to invalid handlers + if (!getDrawers().getItemHandlers().contains(selector.handler)) { + invalidateSlots(); + return ItemStack.EMPTY; + } + + return selector.getStackInSlot(); } @NotNull @@ -89,7 +97,16 @@ public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { HandlerSlotSelector selector = selectorForSlot(slot); - return null != selector ? selector.extractItem(amount, simulate) : ItemStack.EMPTY; + if (null == selector) return ItemStack.EMPTY; + + //Verify if the handler is still valid before extraction + if (!getDrawers().getItemHandlers().contains(selector.handler)) { + // Invalid handler: Rebuild slots and return empty stack + invalidateSlots(); + return ItemStack.EMPTY; + } + + return selector.extractItem(amount, simulate); } @Override diff --git a/src/main/java/com/buuz135/functionalstorage/util/ConnectedDrawers.java b/src/main/java/com/buuz135/functionalstorage/util/ConnectedDrawers.java index 21fe9874..e95b4db5 100644 --- a/src/main/java/com/buuz135/functionalstorage/util/ConnectedDrawers.java +++ b/src/main/java/com/buuz135/functionalstorage/util/ConnectedDrawers.java @@ -60,6 +60,15 @@ public void rebuild() { } var area = new AABB(controllerTile.getBlockPos()).inflate(FunctionalStorageConfig.DRAWER_CONTROLLER_LINKING_RANGE + extraRange); this.connectedDrawers.removeIf(aLong -> !area.contains(Vec3.atCenterOf(BlockPos.of(aLong)))); + + //Check if the Drawer is present within the range. + this.connectedDrawers.removeIf(aLong -> { + BlockEntity entity = level.getBlockEntity(BlockPos.of(aLong)); + return !(entity instanceof ItemControllableDrawerTile) + && !(entity instanceof FluidDrawerTile) + && !(entity instanceof StorageControllerExtensionTile); + }); + this.connectedDrawers.sort(Comparator.comparingDouble(value -> BlockPos.of(value).distSqr(controllerTile.getBlockPos()))); for (Long connectedDrawer : this.connectedDrawers) { BlockPos pos = BlockPos.of(connectedDrawer);