From 492afce3096b65afa4d273336db125662913d3a3 Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Sat, 13 May 2017 14:55:37 +0200 Subject: [PATCH] Possible fix for #986 - "Disks Disappearing" --- .../refinedstorage/api/IRSAPI.java | 13 +-- .../api/network/node/INetworkNodeManager.java | 10 +- .../refinedstorage/apiimpl/API.java | 19 ++-- .../apiimpl/network/NetworkNodeListener.java | 26 ++--- .../apiimpl/network/NetworkNodeManager.java | 99 ++++++++++++++++--- .../apiimpl/network/node/NetworkNode.java | 4 +- .../node/WorldSavedDataNetworkNode.java | 92 ----------------- .../refinedstorage/block/BlockNode.java | 7 +- .../network/MessageNodeRemove.java | 46 --------- .../refinedstorage/proxy/ProxyCommon.java | 1 - .../refinedstorage/tile/TileNode.java | 17 +++- 11 files changed, 133 insertions(+), 201 deletions(-) delete mode 100755 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/WorldSavedDataNetworkNode.java delete mode 100644 src/main/java/com/raoulvdberge/refinedstorage/network/MessageNodeRemove.java diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/IRSAPI.java b/src/main/java/com/raoulvdberge/refinedstorage/api/IRSAPI.java index efefc67e9..9afec5e9f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/IRSAPI.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/IRSAPI.java @@ -37,17 +37,14 @@ public interface IRSAPI { INetworkNodeRegistry getNetworkNodeRegistry(); /** - * @param dimension the dimension - * @return the network node manager for the given dimension - */ - INetworkNodeManager getNetworkNodeManager(int dimension); - - /** - * Marks the network node saved data dirty for a given world. + * Gets a network node manager for a given world. + * This can only be called on the server side! + * There is no such concept of a network node manager on the client. * * @param world the world + * @return the network node manager for the given world */ - void markNetworkNodesDirty(World world); + INetworkNodeManager getNetworkNodeManager(World world); /** * @return the default storage disk behavior diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/network/node/INetworkNodeManager.java b/src/main/java/com/raoulvdberge/refinedstorage/api/network/node/INetworkNodeManager.java index b0649f77b..aa03aed85 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/network/node/INetworkNodeManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/network/node/INetworkNodeManager.java @@ -21,10 +21,9 @@ public interface INetworkNodeManager { /** * Removes a node from the registry at a given position. * - * @param pos the position of the node - * @param notifyClient true to notify the client of the removal, false otherwise + * @param pos the position of the node */ - void removeNode(BlockPos pos, boolean notifyClient); + void removeNode(BlockPos pos); /** * Sets a node in the registry at a given position. @@ -43,4 +42,9 @@ public interface INetworkNodeManager { * Clears all the nodes. */ void clear(); + + /** + * Marks the network node manager for saving. + */ + void markForSaving(); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/API.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/API.java index 900ce2394..e894b762f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/API.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/API.java @@ -23,7 +23,6 @@ import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPrev import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry.CraftingTaskRegistry; import com.raoulvdberge.refinedstorage.apiimpl.network.NetworkNodeManager; import com.raoulvdberge.refinedstorage.apiimpl.network.NetworkNodeRegistry; -import com.raoulvdberge.refinedstorage.apiimpl.network.node.WorldSavedDataNetworkNode; import com.raoulvdberge.refinedstorage.apiimpl.network.readerwriter.ReaderWriterChannel; import com.raoulvdberge.refinedstorage.apiimpl.network.readerwriter.ReaderWriterHandlerRegistry; import com.raoulvdberge.refinedstorage.apiimpl.solderer.SoldererRegistry; @@ -38,9 +37,7 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.discovery.ASMDataTable; -import net.minecraftforge.fml.relauncher.Side; import javax.annotation.Nonnull; import java.lang.reflect.Field; @@ -53,8 +50,7 @@ public class API implements IRSAPI { private IComparer comparer = new Comparer(); private INetworkNodeRegistry networkNodeRegistry = new NetworkNodeRegistry(); - private Map networkNodeProviderServer = new HashMap<>(); - private Map networkNodeProviderClient = new HashMap<>(); + private Map networkNodeManagers = new HashMap<>(); private IStorageDiskBehavior storageDiskBehavior = new StorageDiskBehavior(); private ISoldererRegistry soldererRegistry = new SoldererRegistry(); private ICraftingTaskRegistry craftingTaskRegistry = new CraftingTaskRegistry(); @@ -97,15 +93,12 @@ public class API implements IRSAPI { } @Override - public INetworkNodeManager getNetworkNodeManager(final int dimension) { - Map provider = FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT ? networkNodeProviderClient : networkNodeProviderServer; + public INetworkNodeManager getNetworkNodeManager(World world) { + if (world.isRemote) { + throw new IllegalStateException("Attempting to access network node manager on the client"); + } - return provider.computeIfAbsent(dimension, r -> new NetworkNodeManager(dimension)); - } - - @Override - public void markNetworkNodesDirty(World world) { - WorldSavedDataNetworkNode.getOrLoadData(world).markDirty(); + return networkNodeManagers.computeIfAbsent(world.provider.getDimension(), m -> NetworkNodeManager.getManager(world)); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeListener.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeListener.java index 69e0fa0a5..be8c62aa8 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeListener.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeListener.java @@ -5,29 +5,29 @@ import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy; import com.raoulvdberge.refinedstorage.api.network.security.Permission; import com.raoulvdberge.refinedstorage.apiimpl.API; -import com.raoulvdberge.refinedstorage.apiimpl.network.node.WorldSavedDataNetworkNode; import com.raoulvdberge.refinedstorage.proxy.CapabilityNetworkNodeProxy; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraftforge.event.world.BlockEvent; -import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; public class NetworkNodeListener { @SubscribeEvent public void onWorldTick(TickEvent.WorldTickEvent e) { - e.world.profiler.startSection("network node ticking"); + if (!e.world.isRemote) { + e.world.profiler.startSection("network node ticking"); - if (e.phase == TickEvent.Phase.END) { - for (INetworkNode node : API.instance().getNetworkNodeManager(e.world.provider.getDimension()).all()) { - if (e.world.isBlockLoaded(node.getPos())) { - node.update(); + if (e.phase == TickEvent.Phase.END) { + for (INetworkNode node : API.instance().getNetworkNodeManager(e.world).all()) { + if (e.world.isBlockLoaded(node.getPos())) { + node.update(); + } } } - } - e.world.profiler.endSection(); + e.world.profiler.endSection(); + } } @SubscribeEvent @@ -69,12 +69,4 @@ public class NetworkNodeListener { } } } - - @SubscribeEvent - public void onWorldLoad(WorldEvent.Load e) { - // Clear all data from a possible previous load, so we start with a clean slate - API.instance().getNetworkNodeManager(e.getWorld().provider.getDimension()).clear(); - - WorldSavedDataNetworkNode.getOrLoadData(e.getWorld()); - } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeManager.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeManager.java index f1fc6767d..4a28da04e 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeManager.java @@ -1,38 +1,107 @@ package com.raoulvdberge.refinedstorage.apiimpl.network; -import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeManager; -import com.raoulvdberge.refinedstorage.network.MessageNodeRemove; +import com.raoulvdberge.refinedstorage.apiimpl.API; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldSavedData; +import net.minecraft.world.storage.MapStorage; +import net.minecraftforge.common.util.Constants; import javax.annotation.Nullable; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.function.Function; + +public class NetworkNodeManager extends WorldSavedData implements INetworkNodeManager { + private static final String NAME = "refinedstorage_nodes"; + + private static final String NBT_NODES = "Nodes"; + private static final String NBT_NODE_ID = "Id"; + private static final String NBT_NODE_DATA = "Data"; + private static final String NBT_NODE_POS = "Pos"; -public class NetworkNodeManager implements INetworkNodeManager { private Map nodes = new HashMap<>(); - private int dimension; - - public NetworkNodeManager(int dimension) { - this.dimension = dimension; + public NetworkNodeManager(String s) { + super(s); } @Override + public void readFromNBT(NBTTagCompound tag) { + System.out.println("[RS DEBUG] Reading network nodes, first clearing data..."); + + clear(); + + NBTTagList list = tag.getTagList(NBT_NODES, Constants.NBT.TAG_COMPOUND); + + for (int i = 0; i < list.tagCount(); ++i) { + NBTTagCompound nodeTag = list.getCompoundTagAt(i); + + String id = nodeTag.getString(NBT_NODE_ID); + NBTTagCompound data = nodeTag.getCompoundTag(NBT_NODE_DATA); + BlockPos pos = BlockPos.fromLong(nodeTag.getLong(NBT_NODE_POS)); + + Function factory = API.instance().getNetworkNodeRegistry().get(id); + + if (factory != null) { + setNode(pos, factory.apply(data)); + } + } + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound tag) { + System.out.println("[RS DEBUG] Writing network nodes"); + + NBTTagList list = new NBTTagList(); + + for (INetworkNode node : all()) { + NBTTagCompound nodeTag = new NBTTagCompound(); + + nodeTag.setString(NBT_NODE_ID, node.getId()); + nodeTag.setLong(NBT_NODE_POS, node.getPos().toLong()); + nodeTag.setTag(NBT_NODE_DATA, node.write(new NBTTagCompound())); + + list.appendTag(nodeTag); + } + + tag.setTag(NBT_NODES, list); + + return tag; + } + + public static NetworkNodeManager getManager(World world) { + MapStorage storage = world.getPerWorldStorage(); + NetworkNodeManager instance = (NetworkNodeManager) storage.getOrLoadData(NetworkNodeManager.class, NAME); + + if (instance == null) { + System.out.println("[RS DEBUG] Initializing Network Node Manager for " + world.provider.getDimension()); + instance = new NetworkNodeManager(NAME); + + storage.setData(NAME, instance); + } else { + System.out.println("[RS DEBUG] Network Node Manager for " + world.provider.getDimension() + " already exists, OK..."); + } + + return instance; + } + @Nullable + @Override public INetworkNode getNode(BlockPos pos) { return nodes.get(pos); } @Override - public void removeNode(BlockPos pos, boolean notifyClient) { - nodes.remove(pos); + public void removeNode(BlockPos pos) { + System.out.println("[RS DEBUG] Removing node at " + pos); - if (notifyClient) { - RS.INSTANCE.network.sendToAll(new MessageNodeRemove(dimension, pos)); - } + nodes.remove(pos); } @Override @@ -47,6 +116,12 @@ public class NetworkNodeManager implements INetworkNodeManager { @Override public void clear() { + System.out.println("[RS DEBUG] Clearing data!"); nodes.clear(); } + + @Override + public void markForSaving() { + markDirty(); + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNode.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNode.java index 08cac3ff2..a50e359e5 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNode.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNode.java @@ -82,8 +82,8 @@ public abstract class NetworkNode implements INetworkNode, INetworkNeighborhoodA @Override public void markDirty() { - if (holder.world() != null) { - API.instance().markNetworkNodesDirty(holder.world()); + if (holder.world() != null && !holder.world().isRemote) { + API.instance().getNetworkNodeManager(holder.world()).markForSaving(); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/WorldSavedDataNetworkNode.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/WorldSavedDataNetworkNode.java deleted file mode 100755 index dc29528a6..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/WorldSavedDataNetworkNode.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.raoulvdberge.refinedstorage.apiimpl.network.node; - -import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; -import com.raoulvdberge.refinedstorage.apiimpl.API; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import net.minecraft.world.WorldSavedData; -import net.minecraft.world.storage.MapStorage; -import net.minecraftforge.common.util.Constants; - -import java.util.function.Function; - -public class WorldSavedDataNetworkNode extends WorldSavedData { - private static final String NAME = "refinedstorage_nodes"; - - private static final String NBT_NODES = "Nodes"; - private static final String NBT_NODE_ID = "Id"; - private static final String NBT_NODE_DATA = "Data"; - private static final String NBT_NODE_POS = "Pos"; - private static final String NBT_DIMENSION = "Dimension"; - - private int dimension; - - public WorldSavedDataNetworkNode(int dimension) { - super(NAME); - - this.dimension = dimension; - } - - public WorldSavedDataNetworkNode(String s) { - super(s); - } - - @Override - public void readFromNBT(NBTTagCompound tag) { - if (tag.hasKey(NBT_NODES) && tag.hasKey(NBT_DIMENSION)) { - dimension = tag.getInteger(NBT_DIMENSION); - - NBTTagList list = tag.getTagList(NBT_NODES, Constants.NBT.TAG_COMPOUND); - - for (int i = 0; i < list.tagCount(); ++i) { - NBTTagCompound nodeTag = list.getCompoundTagAt(i); - - String id = nodeTag.getString(NBT_NODE_ID); - NBTTagCompound data = nodeTag.getCompoundTag(NBT_NODE_DATA); - BlockPos pos = BlockPos.fromLong(nodeTag.getLong(NBT_NODE_POS)); - - Function factory = API.instance().getNetworkNodeRegistry().get(id); - - if (factory != null) { - API.instance().getNetworkNodeManager(dimension).setNode(pos, factory.apply(data)); - } - } - } - } - - @Override - public NBTTagCompound writeToNBT(NBTTagCompound tag) { - NBTTagList list = new NBTTagList(); - - for (INetworkNode node : API.instance().getNetworkNodeManager(dimension).all()) { - NBTTagCompound nodeTag = new NBTTagCompound(); - - nodeTag.setString(NBT_NODE_ID, node.getId()); - nodeTag.setLong(NBT_NODE_POS, node.getPos().toLong()); - nodeTag.setTag(NBT_NODE_DATA, node.write(new NBTTagCompound())); - - list.appendTag(nodeTag); - } - - tag.setTag(NBT_NODES, list); - - tag.setInteger(NBT_DIMENSION, dimension); - - return tag; - } - - public static WorldSavedDataNetworkNode getOrLoadData(World world) { - MapStorage storage = world.getPerWorldStorage(); - WorldSavedDataNetworkNode instance = (WorldSavedDataNetworkNode) storage.getOrLoadData(WorldSavedDataNetworkNode.class, NAME); - - if (instance == null) { - instance = new WorldSavedDataNetworkNode(world.provider.getDimension()); - - storage.setData(NAME, instance); - } - - return instance; - } -} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockNode.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockNode.java index 3c018c624..54484844f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockNode.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockNode.java @@ -50,7 +50,7 @@ public abstract class BlockNode extends BlockBase { @Override public void breakBlock(World world, BlockPos pos, IBlockState state) { - INetworkNodeManager manager = API.instance().getNetworkNodeManager(world.provider.getDimension()); + INetworkNodeManager manager = API.instance().getNetworkNodeManager(world); INetworkNode node = manager.getNode(pos); @@ -58,9 +58,8 @@ public abstract class BlockNode extends BlockBase { removeTile(world, pos, state); - manager.removeNode(pos, true); - - API.instance().markNetworkNodesDirty(world); + manager.removeNode(pos); + manager.markForSaving(); if (node.getNetwork() != null) { node.getNetwork().getNodeGraph().rebuild(); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageNodeRemove.java b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageNodeRemove.java deleted file mode 100644 index a5184ca69..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageNodeRemove.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.raoulvdberge.refinedstorage.network; - -import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeManager; -import com.raoulvdberge.refinedstorage.apiimpl.API; -import io.netty.buffer.ByteBuf; -import net.minecraft.client.Minecraft; -import net.minecraft.util.math.BlockPos; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; - -public class MessageNodeRemove implements IMessage, IMessageHandler { - private int dim; - private BlockPos pos; - - public MessageNodeRemove() { - } - - public MessageNodeRemove(int dim, BlockPos pos) { - this.dim = dim; - this.pos = pos; - } - - @Override - public void fromBytes(ByteBuf buf) { - dim = buf.readInt(); - pos = BlockPos.fromLong(buf.readLong()); - } - - @Override - public void toBytes(ByteBuf buf) { - buf.writeInt(dim); - buf.writeLong(pos.toLong()); - } - - @Override - public IMessage onMessage(MessageNodeRemove message, MessageContext ctx) { - Minecraft.getMinecraft().addScheduledTask(() -> { - INetworkNodeManager manager = API.instance().getNetworkNodeManager(message.dim); - - manager.removeNode(message.pos, false); - }); - - return null; - } -} \ No newline at end of file diff --git a/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java b/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java index 727c3d43b..16f76287b 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyCommon.java @@ -123,7 +123,6 @@ public class ProxyCommon { RS.INSTANCE.network.registerMessage(MessageReaderWriterChannelRemove.class, MessageReaderWriterChannelRemove.class, id++, Side.SERVER); RS.INSTANCE.network.registerMessage(MessageSecurityManagerUpdate.class, MessageSecurityManagerUpdate.class, id++, Side.SERVER); RS.INSTANCE.network.registerMessage(MessageWirelessFluidGridSettingsUpdate.class, MessageWirelessFluidGridSettingsUpdate.class, id++, Side.SERVER); - RS.INSTANCE.network.registerMessage(MessageNodeRemove.class, MessageNodeRemove.class, id++, Side.CLIENT); RS.INSTANCE.network.registerMessage(MessageWirelessCraftingMonitorViewAutomated.class, MessageWirelessCraftingMonitorViewAutomated.class, id++, Side.SERVER); NetworkRegistry.INSTANCE.registerGuiHandler(RS.INSTANCE, new GuiHandler()); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileNode.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileNode.java index 84957f7d9..fcbf4dc22 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileNode.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileNode.java @@ -25,6 +25,8 @@ public abstract class TileNode extends TileBase implement private NBTTagCompound legacyTag; + private N clientNode; + protected static final String NBT_ACTIVE = "Active"; public TileNode() { @@ -90,14 +92,21 @@ public abstract class TileNode extends TileBase implement @Nonnull @SuppressWarnings("unchecked") public N getNode() { - INetworkNodeManager manager = API.instance().getNetworkNodeManager(getWorld().provider.getDimension()); + if (getWorld().isRemote) { + if (clientNode == null) { + clientNode = createNode(); + } + + return clientNode; + } + + INetworkNodeManager manager = API.instance().getNetworkNodeManager(getWorld()); NetworkNode node = (NetworkNode) manager.getNode(pos); if (node == null) { manager.setNode(pos, node = createNode()); - - API.instance().markNetworkNodesDirty(getWorld()); + manager.markForSaving(); } if (node.getHolder().world() == null) { @@ -125,6 +134,8 @@ public abstract class TileNode extends TileBase implement } else if (legacyTag.getSize() == 6 + 1 && hasMeta && hasForgeData && hasForgeCaps) { // NO OP } else { + System.out.println("[RS DEBUG] Reading legacy tag for node at " + pos + "!"); + node.read(legacyTag); node.markDirty();