diff --git a/CHANGELOG.md b/CHANGELOG.md index b17f25d58..47f18bc0a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### 1.9.2 - Fixed crash with Forge version 67 (Darkere) +- Fixed cases where Refined Storage unwillingly acts like a chunkloader (raoulvdberge) - Networks that are in a chunk that isn't loaded will no longer work, they will turn off. Chunkload the Controller to maintain a functioning network over long distances (Darkere/raoulvdberge) - Re-added interdimensional networks with the Network Transmitter and Network Receiver (raoulvdberge) diff --git a/src/main/java/com/refinedmods/refinedstorage/api/storage/externalstorage/IExternalStorageProvider.java b/src/main/java/com/refinedmods/refinedstorage/api/storage/externalstorage/IExternalStorageProvider.java index ea13f8997..ae9480308 100644 --- a/src/main/java/com/refinedmods/refinedstorage/api/storage/externalstorage/IExternalStorageProvider.java +++ b/src/main/java/com/refinedmods/refinedstorage/api/storage/externalstorage/IExternalStorageProvider.java @@ -21,12 +21,12 @@ public interface IExternalStorageProvider { /** * @param context the context of the external storage - * @param tile the tile supplier + * @param tile the tile * @param direction the direction of the external storage * @return the external storage handler */ @Nonnull - IExternalStorage provide(IExternalStorageContext context, Supplier tile, Direction direction); + IExternalStorage provide(IExternalStorageContext context, TileEntity tile, Direction direction); /** * Returns the priority of this external storage provider. diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/Network.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/Network.java index a11280e51..7ce66d66f 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/Network.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/Network.java @@ -80,11 +80,13 @@ public class Network implements INetwork, IRedstoneConfigurable { private ControllerBlock.EnergyType lastEnergyType = ControllerBlock.EnergyType.OFF; private int lastEnergyUsage; private RedstoneMode redstoneMode = RedstoneMode.IGNORE; + private boolean redstonePowered = false; private boolean amILoaded = false; private boolean throttlingDisabled = true; // Will be enabled after first update private boolean couldRun; private int ticksSinceUpdateChanged; + private int ticks; public Network(World world, BlockPos pos, NetworkType type) { this.pos = pos; @@ -115,7 +117,11 @@ public class Network implements INetwork, IRedstoneConfigurable { @Override public boolean canRun() { - return amILoaded && energy.getEnergyStored() >= getEnergyUsage() && redstoneMode.isEnabled(world, pos); + return amILoaded && energy.getEnergyStored() >= getEnergyUsage() && redstoneMode.isEnabled(redstonePowered); + } + + public void setRedstonePowered(boolean redstonePowered) { + this.redstonePowered = redstonePowered; } @Override @@ -136,6 +142,12 @@ public class Network implements INetwork, IRedstoneConfigurable { @Override public void update() { if (!world.isRemote) { + if (ticks == 0) { + redstonePowered = world.isBlockPowered(pos); + } + + ++ticks; + amILoaded = world.isBlockPresent(pos); updateEnergyUsage(); @@ -498,7 +510,7 @@ public class Network implements INetwork, IRedstoneConfigurable { } public ControllerBlock.EnergyType getEnergyType() { - if (!redstoneMode.isEnabled(world, pos)) { + if (!redstoneMode.isEnabled(redstonePowered)) { return ControllerBlock.EnergyType.OFF; } @@ -532,7 +544,7 @@ public class Network implements INetwork, IRedstoneConfigurable { } private void updateEnergyUsage() { - if (!redstoneMode.isEnabled(world, pos)) { + if (!redstoneMode.isEnabled(redstonePowered)) { this.lastEnergyUsage = 0; return; } diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ConstructorNetworkNode.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ConstructorNetworkNode.java index 7148b51a6..5356ae9f5 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ConstructorNetworkNode.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ConstructorNetworkNode.java @@ -77,7 +77,7 @@ public class ConstructorNetworkNode extends NetworkNode implements IComparable, public void update() { super.update(); - if (canUpdate() && ticks % upgrades.getSpeed(BASE_SPEED, 4) == 0) { + if (canUpdate() && ticks % upgrades.getSpeed(BASE_SPEED, 4) == 0 && world.isBlockPresent(pos)) { if (type == IType.ITEMS && !itemFilters.getStackInSlot(0).isEmpty()) { ItemStack stack = itemFilters.getStackInSlot(0); diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/DestructorNetworkNode.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/DestructorNetworkNode.java index 492a3055a..d7dd37643 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/DestructorNetworkNode.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/DestructorNetworkNode.java @@ -84,7 +84,7 @@ public class DestructorNetworkNode extends NetworkNode implements IComparable, I public void update() { super.update(); - if (canUpdate() && ticks % upgrades.getSpeed(BASE_SPEED, 4) == 0) { + if (canUpdate() && ticks % upgrades.getSpeed(BASE_SPEED, 4) == 0 && world.isBlockPresent(pos)) { if (type == IType.ITEMS) { if (pickupItem) { pickupItems(); diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/DetectorNetworkNode.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/DetectorNetworkNode.java index 6a1cd8c86..f72860540 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/DetectorNetworkNode.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/DetectorNetworkNode.java @@ -61,7 +61,7 @@ public class DetectorNetworkNode extends NetworkNode implements IComparable, ITy public void update() { super.update(); - if (powered != wasPowered) { + if (powered != wasPowered && world.isBlockPresent(pos)) { wasPowered = powered; world.setBlockState(pos, world.getBlockState(pos).with(DetectorBlock.POWERED, powered)); diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ExporterNetworkNode.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ExporterNetworkNode.java index 6afc40cc8..5c5f2cac0 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ExporterNetworkNode.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ExporterNetworkNode.java @@ -85,7 +85,7 @@ public class ExporterNetworkNode extends NetworkNode implements IComparable, ITy public void update() { super.update(); - if (canUpdate() && ticks % upgrades.getSpeed() == 0) { + if (canUpdate() && ticks % upgrades.getSpeed() == 0 && world.isBlockPresent(pos)) { if (type == IType.ITEMS) { IItemHandler handler = WorldUtils.getItemHandler(getFacingTile(), getDirection().getOpposite()); @@ -236,7 +236,6 @@ public class ExporterNetworkNode extends NetworkNode implements IComparable, ITy markDirty(); } - @Override public ResourceLocation getId() { return ID; diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ExternalStorageNetworkNode.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ExternalStorageNetworkNode.java index 230159125..bac6bcb36 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ExternalStorageNetworkNode.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ExternalStorageNetworkNode.java @@ -85,7 +85,7 @@ public class ExternalStorageNetworkNode extends NetworkNode implements IStorageP public void update() { super.update(); - if (canUpdate()) { + if (canUpdate() && world.isBlockPresent(pos)) { if (networkTicks++ == 0) { updateStorage(network, InvalidateCause.INITIAL_TICK_INVALIDATION); @@ -214,7 +214,7 @@ public class ExternalStorageNetworkNode extends NetworkNode implements IStorageP if (type == IType.ITEMS) { for (IExternalStorageProvider provider : API.instance().getExternalStorageProviders(StorageType.ITEM)) { if (provider.canProvide(facing, getDirection())) { - itemStorages.add(provider.provide(this, this::getFacingTile, getDirection())); + itemStorages.add(provider.provide(this, getFacingTile(), getDirection())); break; } @@ -222,7 +222,7 @@ public class ExternalStorageNetworkNode extends NetworkNode implements IStorageP } else if (type == IType.FLUIDS) { for (IExternalStorageProvider provider : API.instance().getExternalStorageProviders(StorageType.FLUID)) { if (provider.canProvide(facing, getDirection())) { - fluidStorages.add(provider.provide(this, this::getFacingTile, getDirection())); + fluidStorages.add(provider.provide(this, getFacingTile(), getDirection())); break; } diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/FluidInterfaceNetworkNode.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/FluidInterfaceNetworkNode.java index c77489e0d..d3cc13530 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/FluidInterfaceNetworkNode.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/FluidInterfaceNetworkNode.java @@ -250,7 +250,7 @@ public class FluidInterfaceNetworkNode extends NetworkNode { } private void onTankOutChanged() { - if (!world.isRemote) { + if (!world.isRemote && world.isBlockPresent(pos)) { ((FluidInterfaceTile) world.getTileEntity(pos)).getDataManager().sendParameterToWatchers(FluidInterfaceTile.TANK_OUT); } diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ImporterNetworkNode.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ImporterNetworkNode.java index bbc104cd3..75e25c838 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ImporterNetworkNode.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/ImporterNetworkNode.java @@ -60,7 +60,7 @@ public class ImporterNetworkNode extends NetworkNode implements IComparable, IWh public void update() { super.update(); - if (!canUpdate()) { + if (!canUpdate() || !world.isBlockPresent(pos)) { return; } diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/NetworkNode.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/NetworkNode.java index d87654fda..7f4eed301 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/NetworkNode.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/NetworkNode.java @@ -30,10 +30,21 @@ public abstract class NetworkNode implements INetworkNode, INetworkNodeVisitor { @Nullable protected INetwork network; + // @Volatile: Mental note. At this moment world instances are retained in Minecraft (since 1.16). + // This means that during the entire server lifetime, all worlds are present and will not change their instance. + // However, due to the memory footprint of worlds and modded minecraft having the tendency to have lots of worlds, + // Forge is planning to unload (aka remove) worlds so their instances will change. + // This is problematic as this attribute will target the wrong world in that case. + // Idea: possibly change to a getter based on RegistryKey? + // Another note: this attribute isn't the *real* problem. Because network nodes are in WorldSavedData in a tick handler, + // new instances of network nodes will be created when the world refreshes (causing this field to be different too). + // However, network nodes in the network graph *AREN'T* recreated when the world refreshes, causing the graph to have the incorrect instance, and even worse, + // having multiple different instances of the same network node. protected World world; protected BlockPos pos; protected int ticks; protected RedstoneMode redstoneMode = RedstoneMode.IGNORE; + private boolean redstonePowered = false; @Nullable protected UUID owner; protected String version; @@ -102,7 +113,7 @@ public abstract class NetworkNode implements INetworkNode, INetworkNodeVisitor { @Override public boolean isActive() { - return redstoneMode.isEnabled(world, pos); + return redstoneMode.isEnabled(redstonePowered); } protected final boolean canUpdate() { @@ -121,8 +132,16 @@ public abstract class NetworkNode implements INetworkNode, INetworkNodeVisitor { return 4; } + public void setRedstonePowered(boolean redstonePowered) { + this.redstonePowered = redstonePowered; + } + @Override public void update() { + if (ticks == 0) { + redstonePowered = world.isBlockPowered(pos); + } + ++ticks; boolean canUpdate = canUpdate(); diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/storage/externalstorage/FluidExternalStorageProvider.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/storage/externalstorage/FluidExternalStorageProvider.java index 9ec9bdc79..34a304c2b 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/storage/externalstorage/FluidExternalStorageProvider.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/storage/externalstorage/FluidExternalStorageProvider.java @@ -20,8 +20,14 @@ public class FluidExternalStorageProvider implements IExternalStorageProvider provide(IExternalStorageContext context, Supplier tile, Direction direction) { - return new FluidExternalStorage(context, () -> WorldUtils.getFluidHandler(tile.get(), direction.getOpposite()), tile.get() instanceof FluidInterfaceTile); + public IExternalStorage provide(IExternalStorageContext context, TileEntity tile, Direction direction) { + return new FluidExternalStorage(context, () -> { + if (!tile.getWorld().isBlockPresent(tile.getPos())) { + return null; + } + + return WorldUtils.getFluidHandler(tile, direction.getOpposite()); + }, tile instanceof FluidInterfaceTile); } @Override diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/storage/externalstorage/ItemExternalStorageProvider.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/storage/externalstorage/ItemExternalStorageProvider.java index 17205302d..5fe956359 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/storage/externalstorage/ItemExternalStorageProvider.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/storage/externalstorage/ItemExternalStorageProvider.java @@ -29,8 +29,14 @@ public class ItemExternalStorageProvider implements IExternalStorageProvider provide(IExternalStorageContext context, Supplier tile, Direction direction) { - return new ItemExternalStorage(context, () -> WorldUtils.getItemHandler(tile.get(), direction.getOpposite()), tile.get() instanceof InterfaceTile); + public IExternalStorage provide(IExternalStorageContext context, TileEntity tile, Direction direction) { + return new ItemExternalStorage(context, () -> { + if (!tile.getWorld().isBlockPresent(tile.getPos())) { + return null; + } + + return WorldUtils.getItemHandler(tile, direction.getOpposite()); + }, tile instanceof InterfaceTile); } @Override diff --git a/src/main/java/com/refinedmods/refinedstorage/block/ControllerBlock.java b/src/main/java/com/refinedmods/refinedstorage/block/ControllerBlock.java index 3d38cf29d..1605503be 100644 --- a/src/main/java/com/refinedmods/refinedstorage/block/ControllerBlock.java +++ b/src/main/java/com/refinedmods/refinedstorage/block/ControllerBlock.java @@ -1,7 +1,10 @@ package com.refinedmods.refinedstorage.block; import com.refinedmods.refinedstorage.RS; +import com.refinedmods.refinedstorage.api.network.INetwork; import com.refinedmods.refinedstorage.api.network.NetworkType; +import com.refinedmods.refinedstorage.apiimpl.API; +import com.refinedmods.refinedstorage.apiimpl.network.Network; import com.refinedmods.refinedstorage.container.ControllerContainer; import com.refinedmods.refinedstorage.tile.ControllerTile; import com.refinedmods.refinedstorage.util.BlockUtils; @@ -27,6 +30,7 @@ import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; import net.minecraftforge.energy.CapabilityEnergy; import net.minecraftforge.fml.network.NetworkHooks; @@ -105,6 +109,19 @@ public class ControllerBlock extends BaseBlock { } } + @Override + @SuppressWarnings("deprecation") + public void neighborChanged(BlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) { + super.neighborChanged(state, world, pos, blockIn, fromPos, isMoving); + + if (!world.isRemote) { + INetwork network = API.instance().getNetworkManager((ServerWorld) world).getNetwork(pos); + if (network instanceof Network) { + ((Network) network).setRedstonePowered(world.isBlockPowered(pos)); + } + } + } + @Override @SuppressWarnings("deprecation") public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) { diff --git a/src/main/java/com/refinedmods/refinedstorage/block/NetworkNodeBlock.java b/src/main/java/com/refinedmods/refinedstorage/block/NetworkNodeBlock.java index 28de1597a..0497734a1 100644 --- a/src/main/java/com/refinedmods/refinedstorage/block/NetworkNodeBlock.java +++ b/src/main/java/com/refinedmods/refinedstorage/block/NetworkNodeBlock.java @@ -2,6 +2,7 @@ package com.refinedmods.refinedstorage.block; import com.refinedmods.refinedstorage.api.network.node.INetworkNode; import com.refinedmods.refinedstorage.api.network.node.INetworkNodeProxy; +import com.refinedmods.refinedstorage.apiimpl.API; import com.refinedmods.refinedstorage.apiimpl.network.node.NetworkNode; import com.refinedmods.refinedstorage.tile.NetworkNodeTile; import net.minecraft.block.Block; @@ -15,6 +16,7 @@ import net.minecraft.util.Direction; import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; import net.minecraftforge.items.IItemHandler; public abstract class NetworkNodeBlock extends BaseBlock { @@ -28,6 +30,19 @@ public abstract class NetworkNodeBlock extends BaseBlock { } } + @Override + @SuppressWarnings("deprecation") + public void neighborChanged(BlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) { + super.neighborChanged(state, world, pos, blockIn, fromPos, isMoving); + + if (!world.isRemote) { + INetworkNode node = API.instance().getNetworkNodeManager((ServerWorld) world).getNode(pos); + if (node instanceof NetworkNode) { + ((NetworkNode) node).setRedstonePowered(world.isBlockPowered(pos)); + } + } + } + @Override @SuppressWarnings("deprecation") public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { @@ -80,7 +95,7 @@ public abstract class NetworkNodeBlock extends BaseBlock { public boolean hasTileEntity(BlockState state) { return true; } - + public boolean hasConnectedState() { return false; } diff --git a/src/main/java/com/refinedmods/refinedstorage/tile/config/RedstoneMode.java b/src/main/java/com/refinedmods/refinedstorage/tile/config/RedstoneMode.java index e9f47d273..be98790d4 100644 --- a/src/main/java/com/refinedmods/refinedstorage/tile/config/RedstoneMode.java +++ b/src/main/java/com/refinedmods/refinedstorage/tile/config/RedstoneMode.java @@ -12,14 +12,14 @@ public enum RedstoneMode { private static final String NBT = "RedstoneMode"; - public boolean isEnabled(World world, BlockPos pos) { + public boolean isEnabled(boolean powered) { switch (this) { case IGNORE: return true; case HIGH: - return world.isBlockPowered(pos); + return powered; case LOW: - return !world.isBlockPowered(pos); + return !powered; default: return false; } diff --git a/src/main/java/com/refinedmods/refinedstorage/tile/grid/portable/PortableGridTile.java b/src/main/java/com/refinedmods/refinedstorage/tile/grid/portable/PortableGridTile.java index 242852924..51ffa46a8 100644 --- a/src/main/java/com/refinedmods/refinedstorage/tile/grid/portable/PortableGridTile.java +++ b/src/main/java/com/refinedmods/refinedstorage/tile/grid/portable/PortableGridTile.java @@ -541,7 +541,7 @@ public class PortableGridTile extends BaseTile implements IGrid, IPortableGrid, return false; } - return redstoneMode.isEnabled(world, pos); + return redstoneMode.isEnabled(world.isBlockPowered(pos)); } @Override @@ -565,7 +565,7 @@ public class PortableGridTile extends BaseTile implements IGrid, IPortableGrid, public void drainEnergy(int energy) { if (RS.SERVER_CONFIG.getPortableGrid().getUseEnergy() && type != PortableGridBlockItem.Type.CREATIVE && - redstoneMode.isEnabled(world, pos)) { + redstoneMode.isEnabled(world.isBlockPowered(pos))) { energyStorage.extractEnergy(energy, false); updateState(); diff --git a/src/main/java/com/refinedmods/refinedstorage/util/WorldUtils.java b/src/main/java/com/refinedmods/refinedstorage/util/WorldUtils.java index b76728279..2aa8215b4 100644 --- a/src/main/java/com/refinedmods/refinedstorage/util/WorldUtils.java +++ b/src/main/java/com/refinedmods/refinedstorage/util/WorldUtils.java @@ -31,7 +31,7 @@ import java.util.UUID; public final class WorldUtils { public static void updateBlock(@Nullable World world, BlockPos pos) { - if (world != null) { + if (world != null && world.isBlockPresent(pos)) { BlockState state = world.getBlockState(pos); world.notifyBlockUpdate(pos, state, state, 1 | 2);