Add P2P infinite loop detection (#1723)

This commit is contained in:
Riever authored and GitHub committed 2026-11-01 12:35:54 +01:00
1 parent b61ed2ce52
commit 2d5bd34123
2 files changed
+46 -1

No files matched your search

@@ -10,8 +10,10 @@
package appeng.parts.p2p;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
@@ -88,6 +90,9 @@ public class PartP2PItems extends PartP2PTunnelNormal<PartP2PItems>
}
for (final PartP2PItems t : itemTunnels) {
if (t.loopsBackTo(this, new HashSet<>())) {
continue;
}
final IInventory inv = t.getOutputInv();
if (inv != null) {
if (Platform.getRandomInt() % 2 == 0) {
@@ -313,4 +318,29 @@ public class PartP2PItems extends PartP2PTunnelNormal<PartP2PItems>
public ConnectOverride overridePipeConnection(final PipeType type, final ForgeDirection with) {
return this.getSide() == with && type == PipeType.ITEM ? ConnectOverride.CONNECT : ConnectOverride.DEFAULT;
}
private boolean loopsBackTo(final PartP2PItems tunnel, final Set<PartP2PItems> visited) {
final TileEntity te = this.getTile().getWorldObj().getTileEntity(
this.getTile().xCoord + this.getSide().offsetX,
this.getTile().yCoord + this.getSide().offsetY,
this.getTile().zCoord + this.getSide().offsetZ);
if (Platform.getPartFromTE(te, this.getSide().getOpposite()) instanceof PartP2PItems next) {
if (next == tunnel) {
return true;
}
if (!visited.contains(next)) {
visited.add(next);
try {
for (final PartP2PItems t : next.getOutputs()) {
if (t.loopsBackTo(tunnel, visited)) {
return true;
}
}
} catch (final GridAccessException ignored) {
// :P
}
}
}
return false;
}
}
@@ -221,7 +221,22 @@ public class PartP2PLiquids extends PartP2PTunnelNormal<PartP2PLiquids> implemen
@Override
public boolean canFill(final ForgeDirection from, final Fluid fluid) {
return from == this.getSide() && (!this.getOutputs(fluid).isEmpty() || inputAcceptsFluid(fluid));
if (from != this.getSide()) {
return false;
}
final Stack<PartP2PLiquids> stack = this.getDepth();
for (final PartP2PLiquids t : stack) {
if (t == this) {
return false;
}
}
stack.push(this);
try {
return !this.getOutputs(fluid).isEmpty() || inputAcceptsFluid(fluid);
} finally {
stack.pop();
}
}
@Override