Fixed cases where Refined Storage unwillingly acts like a chunkloader.
This commit is contained in:
@@ -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)
|
||||
|
||||
|
@@ -21,12 +21,12 @@ public interface IExternalStorageProvider<T> {
|
||||
|
||||
/**
|
||||
* @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<T> provide(IExternalStorageContext context, Supplier<TileEntity> tile, Direction direction);
|
||||
IExternalStorage<T> provide(IExternalStorageContext context, TileEntity tile, Direction direction);
|
||||
|
||||
/**
|
||||
* Returns the priority of this external storage provider.
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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();
|
||||
|
@@ -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));
|
||||
|
@@ -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;
|
||||
|
@@ -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<ItemStack> 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<FluidStack> 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;
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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<World>?
|
||||
// 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();
|
||||
|
@@ -20,8 +20,14 @@ public class FluidExternalStorageProvider implements IExternalStorageProvider<Fl
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IExternalStorage<FluidStack> provide(IExternalStorageContext context, Supplier<TileEntity> tile, Direction direction) {
|
||||
return new FluidExternalStorage(context, () -> WorldUtils.getFluidHandler(tile.get(), direction.getOpposite()), tile.get() instanceof FluidInterfaceTile);
|
||||
public IExternalStorage<FluidStack> 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
|
||||
|
@@ -29,8 +29,14 @@ public class ItemExternalStorageProvider implements IExternalStorageProvider<Ite
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IExternalStorage<ItemStack> provide(IExternalStorageContext context, Supplier<TileEntity> tile, Direction direction) {
|
||||
return new ItemExternalStorage(context, () -> WorldUtils.getItemHandler(tile.get(), direction.getOpposite()), tile.get() instanceof InterfaceTile);
|
||||
public IExternalStorage<ItemStack> 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
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user