From bf7760c5fb3e2957064cd07d756226c47bf38193 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 11 Feb 2022 21:17:30 +0100 Subject: [PATCH 1/4] clear caches more aggressively in an attempt to fix rare caching issues --- .../java/de/ellpeck/prettypipes/network/PipeNetwork.java | 8 ++++---- .../java/de/ellpeck/prettypipes/pipe/PipeBlockEntity.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java index a98d10e..df767ad 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java @@ -461,13 +461,13 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL return ret; } - public void clearDestinationCache(BlockPos... nodes) { + public void clearDestinationCache(List nodes) { this.startProfile("clear_node_cache"); // remove caches for the nodes for (var node : nodes) this.nodeToConnectedNodes.keySet().remove(node); // remove caches that contain the nodes as a destination - this.nodeToConnectedNodes.values().removeIf(cached -> Arrays.stream(nodes).anyMatch(cached::contains)); + this.nodeToConnectedNodes.values().removeIf(cached -> nodes.stream().anyMatch(cached::contains)); this.endProfile(); } @@ -490,12 +490,12 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL @Override public void edgeAdded(GraphEdgeChangeEvent e) { - this.clearDestinationCache(e.getEdgeSource(), e.getEdgeTarget()); + this.clearDestinationCache(e.getEdge().pipes); } @Override public void edgeRemoved(GraphEdgeChangeEvent e) { - this.clearDestinationCache(e.getEdgeSource(), e.getEdgeTarget()); + this.clearDestinationCache(e.getEdge().pipes); } @Override diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlockEntity.java b/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlockEntity.java index 7d29092..acb78a7 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlockEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlockEntity.java @@ -437,7 +437,7 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC if (prio != pipe.priority) { pipe.priority = prio; // clear the cache so that it's reevaluated based on priority - PipeNetwork.get(pipe.level).clearDestinationCache(pipe.worldPosition); + PipeNetwork.get(pipe.level).clearDestinationCache(Collections.singletonList(pipe.worldPosition)); } profiler.pop(); } From 33f4d47889d544666f611c44a552f4b083b9db6c Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 11 Feb 2022 21:19:55 +0100 Subject: [PATCH 2/4] changed the pipe recipe to require some copper --- src/main/resources/data/prettypipes/recipes/pipe.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/resources/data/prettypipes/recipes/pipe.json b/src/main/resources/data/prettypipes/recipes/pipe.json index b889960..4f5c002 100644 --- a/src/main/resources/data/prettypipes/recipes/pipe.json +++ b/src/main/resources/data/prettypipes/recipes/pipe.json @@ -2,7 +2,8 @@ "type": "minecraft:crafting_shaped", "pattern": [ " R ", - "IGI" + "IGI", + " C " ], "key": { "R": { @@ -13,6 +14,9 @@ }, "G": { "tag": "forge:glass" + }, + "C": { + "item": "minecraft:copper_ingot" } }, "result": { From d04dd4054ae75961fb610a00162cd9befb346099 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 11 Feb 2022 21:56:02 +0100 Subject: [PATCH 3/4] added some commands to log debug information about pretty pipes and clear invalid caches --- .../de/ellpeck/prettypipes/misc/Events.java | 38 +++++++++++++++++++ .../prettypipes/network/NetworkLock.java | 5 +++ .../ellpeck/prettypipes/network/PipeItem.java | 5 +++ .../prettypipes/network/PipeNetwork.java | 22 ++++++++++- 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/ellpeck/prettypipes/misc/Events.java b/src/main/java/de/ellpeck/prettypipes/misc/Events.java index 0407f36..3fbe9c1 100644 --- a/src/main/java/de/ellpeck/prettypipes/misc/Events.java +++ b/src/main/java/de/ellpeck/prettypipes/misc/Events.java @@ -2,12 +2,20 @@ package de.ellpeck.prettypipes.misc; import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.network.PipeNetwork; +import net.minecraft.commands.Commands; +import net.minecraft.network.chat.TextComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.Level; import net.minecraftforge.event.AttachCapabilitiesEvent; +import net.minecraftforge.event.server.ServerStartingEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + @Mod.EventBusSubscriber public final class Events { @@ -15,4 +23,34 @@ public final class Events { public static void onWorldCaps(AttachCapabilitiesEvent event) { event.addCapability(new ResourceLocation(PrettyPipes.ID, "network"), new PipeNetwork(event.getObject())); } + + @SubscribeEvent + public static void onServerStarting(ServerStartingEvent event) { + event.getServer().getCommands().getDispatcher().register(Commands.literal(PrettyPipes.ID).requires(s -> s.hasPermission(2)) + .then(Commands.literal("dump").executes(c -> { + var source = c.getSource(); + var file = Paths.get('_' + PrettyPipes.ID + "dump.txt"); + var dump = PipeNetwork.get(source.getLevel()).toString(); + try { + Files.writeString(file, dump, StandardCharsets.UTF_8); + source.sendSuccess(new TextComponent("Wrote network dump to file " + file.toAbsolutePath()), true); + } catch (IOException e) { + source.sendFailure(new TextComponent("Failed to write network dump to file " + file.toAbsolutePath())); + return -1; + } + return 0; + })) + .then(Commands.literal("uncache").executes(c -> { + var source = c.getSource(); + PipeNetwork.get(source.getLevel()).clearCaches(); + source.sendSuccess(new TextComponent("Cleared all pipe caches in the world"), true); + return 0; + })) + .then(Commands.literal("unlock").executes(c -> { + var source = c.getSource(); + PipeNetwork.get(source.getLevel()).unlock(); + source.sendSuccess(new TextComponent("Resolved all network locks in the world"), true); + return 0; + }))); + } } diff --git a/src/main/java/de/ellpeck/prettypipes/network/NetworkLock.java b/src/main/java/de/ellpeck/prettypipes/network/NetworkLock.java index dbb5c1e..23745f1 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/NetworkLock.java +++ b/src/main/java/de/ellpeck/prettypipes/network/NetworkLock.java @@ -51,4 +51,9 @@ public class NetworkLock implements INBTSerializable { public int hashCode() { return Objects.hash(this.lockId); } + + @Override + public String toString() { + return "NetworkLock{" + "location=" + this.location.pipePos + ", stack=" + this.stack + '}'; + } } diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java b/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java index bbe9e07..1de24ce 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java @@ -317,6 +317,11 @@ public class PipeItem implements IPipeItem { } } + @Override + public String toString() { + return "PipeItem{" + "stack=" + this.stack + ", x=" + this.x + ", y=" + this.y + ", z=" + this.z + ", startInventory=" + this.startInventory + ", destInventory=" + this.destInventory + '}'; + } + protected int getModelCount() { var i = 1; if (this.stack.getCount() > 48) { diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java index df767ad..5510c9e 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java @@ -245,7 +245,8 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL var tile = this.tileCache.get(pos); if (tile == null || tile.isRemoved()) { tile = Utility.getBlockEntity(PipeBlockEntity.class, this.world, pos); - this.tileCache.put(pos, tile); + if (tile != null) + this.tileCache.put(pos, tile); } return tile; } @@ -387,6 +388,15 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL return null; } + public void clearCaches() { + this.nodeToConnectedNodes.clear(); + this.tileCache.clear(); + } + + public void unlock() { + this.networkLocks.clear(); + } + private List createAllEdges(BlockPos pos, BlockState state, boolean ignoreCurrBlocked) { this.startProfile("create_all_edges"); List edges = new ArrayList<>(); @@ -506,6 +516,16 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL public void vertexRemoved(GraphVertexChangeEvent e) { } + @Override + public String toString() { + return "PipeNetwork{" + + "\ngraph=" + this.graph + + ",\nnodeToConnectedNodes=" + this.nodeToConnectedNodes + + ",\ntileCache=" + this.tileCache.keySet() + + ",\npipeItems=" + this.pipeItems + + ",\nnetworkLocks=" + this.networkLocks + '}'; + } + public void startProfile(String name) { this.world.getProfiler().push(() -> PrettyPipes.ID + ":pipe_network_" + name); } From b63799893800b432dd749db83dd5fc7c6aba6aa2 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 11 Feb 2022 21:59:17 +0100 Subject: [PATCH 4/4] 1.11.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index cc0f5c4..09f8a3e 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ apply plugin: 'net.minecraftforge.gradle' apply plugin: 'eclipse' apply plugin: 'maven-publish' -version = '1.10.5' +version = '1.11.0' group = 'de.ellpeck.prettypipes' // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = 'PrettyPipes'