From f3cbab06ef39bf8ffe9fbc91940b5af4d167de86 Mon Sep 17 00:00:00 2001 From: Zheyu Shen Date: Mon, 22 Jun 2026 03:46:04 +0000 Subject: [PATCH] fix: prevent red alloy/insulated wire from becoming unpowerable after a thrown lookup RedstonePropagator's global redstone flags were toggled around connection discovery and signal calculation without try/finally, so a neighbor lookup that threw mid-way left the static flag stuck in its temporary value for the rest of the session. Most visibly, FramedRedwirePart and RedstoneTubePart#discoverStraightOverride set canConnectRedwires=false and restore it afterwards. If RedstoneInteractions.{otherConnectionMask,connectionMask} throws (e.g. a modded neighbor or a partially-loaded chunk), the restore is skipped and the flag is left false. RedwirePart#canConnectRedstone then returns false for every face red alloy/insulated wire, so they report no redstone connection and read zero vanilla power -- they can no longer be powered. Gates and vanilla redstone are unaffected (different flags / code paths), which is why only the wires appear broken. The flags are only reset on ServerAboutToStartEvent, so the corruption persists for an entire dedicated-server session while singleplayer silently recovers on each world reload. Wrap every RedstonePropagator flag toggle (canConnectRedwires in discoverStraightOverride, and the dust/redwire power flags in calculateSignal) in try/finally so global state is always restored even if a lookup throws. Affects RedwirePart, FramedRedwirePart, RedstoneTubePart, and ArrayGatePart. --- .../expansion/part/RedstoneTubePart.java | 48 ++++++------ .../integration/part/ArrayGatePart.java | 54 ++++++------- .../transmission/part/FramedRedwirePart.java | 48 ++++++------ .../transmission/part/RedwirePart.java | 77 ++++++++++--------- 4 files changed, 120 insertions(+), 107 deletions(-) diff --git a/expansion/src/main/java/mrtjp/projectred/expansion/part/RedstoneTubePart.java b/expansion/src/main/java/mrtjp/projectred/expansion/part/RedstoneTubePart.java index 9290991f8..7b014b1a3 100644 --- a/expansion/src/main/java/mrtjp/projectred/expansion/part/RedstoneTubePart.java +++ b/expansion/src/main/java/mrtjp/projectred/expansion/part/RedstoneTubePart.java @@ -209,10 +209,12 @@ public boolean discoverStraightOverride(int s) { boolean prevCanConnectRW = RedstonePropagator.canConnectRedwires(); RedstonePropagator.setCanConnectRedwires(false); - boolean discovered = (RedstoneInteractions.otherConnectionMask(level(), pos(), s, false) & - RedstoneInteractions.connectionMask(this, s)) != 0; - RedstonePropagator.setCanConnectRedwires(prevCanConnectRW); - return discovered; + try { + return (RedstoneInteractions.otherConnectionMask(level(), pos(), s, false) & + RedstoneInteractions.connectionMask(this, s)) != 0; + } finally { + RedstonePropagator.setCanConnectRedwires(prevCanConnectRW); + } } @Override @@ -249,28 +251,30 @@ public int calculateSignal() { RedstonePropagator.setDustProvidesPower(false); RedstonePropagator.setRedwiresProvidePower(false); - - int signal = 0; - for (int s = 0; s < 6; s++) { - int sig = 0; - if (maskConnectsIn(s)) { - CenterLookup lookup = CenterLookup.lookupInsideFace(level(), pos(), s); - sig = resolveSignal(lookup); - - } else if (maskConnectsOut(s)) { - CenterLookup lookup = CenterLookup.lookupStraightCenter(level(), pos(), s); - sig = resolveSignal(lookup); - if (sig == 0) { - sig = RedstoneCenterLookup.resolveVanillaSignal(lookup, this); + try { + int signal = 0; + for (int s = 0; s < 6; s++) { + int sig = 0; + if (maskConnectsIn(s)) { + CenterLookup lookup = CenterLookup.lookupInsideFace(level(), pos(), s); + sig = resolveSignal(lookup); + + } else if (maskConnectsOut(s)) { + CenterLookup lookup = CenterLookup.lookupStraightCenter(level(), pos(), s); + sig = resolveSignal(lookup); + if (sig == 0) { + sig = RedstoneCenterLookup.resolveVanillaSignal(lookup, this); + } } + + signal = Math.max(sig, signal); } - signal = Math.max(sig, signal); + return signal; + } finally { + RedstonePropagator.setDustProvidesPower(true); + RedstonePropagator.setRedwiresProvidePower(true); } - - RedstonePropagator.setDustProvidesPower(true); - RedstonePropagator.setRedwiresProvidePower(true); - return signal; } @Override diff --git a/integration/src/main/java/mrtjp/projectred/integration/part/ArrayGatePart.java b/integration/src/main/java/mrtjp/projectred/integration/part/ArrayGatePart.java index 8c422a845..e191519e8 100644 --- a/integration/src/main/java/mrtjp/projectred/integration/part/ArrayGatePart.java +++ b/integration/src/main/java/mrtjp/projectred/integration/part/ArrayGatePart.java @@ -118,38 +118,40 @@ public int calculateSignal() { RedstonePropagator.setDustProvidesPower(false); RedstonePropagator.setRedwiresProvidePower(false); - - int signal = 0; - for (int r = 0; r < 4; r++) { - if ((propagationMask & 1 << r) == 0) { continue; } - int s; - - if (maskConnectsInside(r)) { - FaceLookup lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), r); - s = RedstoneFaceLookup.resolveSignal(lookup, true); - - } else if (maskConnectsStraight(r)) { - FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); - s = RedstoneFaceLookup.resolveSignal(lookup, true); - if (s == 0) { + try { + int signal = 0; + for (int r = 0; r < 4; r++) { + if ((propagationMask & 1 << r) == 0) { continue; } + int s; + + if (maskConnectsInside(r)) { + FaceLookup lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), r); + s = RedstoneFaceLookup.resolveSignal(lookup, true); + + } else if (maskConnectsStraight(r)) { + FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); + s = RedstoneFaceLookup.resolveSignal(lookup, true); + if (s == 0) { + s = RedstoneFaceLookup.resolveVanillaSignal(lookup, this, true, true); + } + + } else if (maskConnectsCorner(r)) { + FaceLookup lookup = FaceLookup.lookupCorner(level(), pos(), getSide(), r); + s = RedstoneFaceLookup.resolveSignal(lookup, true); + + } else { // For non-connected sides, just do a vanilla signal lookup + FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); s = RedstoneFaceLookup.resolveVanillaSignal(lookup, this, true, true); } - } else if (maskConnectsCorner(r)) { - FaceLookup lookup = FaceLookup.lookupCorner(level(), pos(), getSide(), r); - s = RedstoneFaceLookup.resolveSignal(lookup, true); - - } else { // For non-connected sides, just do a vanilla signal lookup - FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); - s = RedstoneFaceLookup.resolveVanillaSignal(lookup, this, true, true); + signal = Math.max(s, signal); } - signal = Math.max(s, signal); + return signal; + } finally { + RedstonePropagator.setDustProvidesPower(true); + RedstonePropagator.setRedwiresProvidePower(true); } - - RedstonePropagator.setDustProvidesPower(true); - RedstonePropagator.setRedwiresProvidePower(true); - return signal; } @Override diff --git a/transmission/src/main/java/mrtjp/projectred/transmission/part/FramedRedwirePart.java b/transmission/src/main/java/mrtjp/projectred/transmission/part/FramedRedwirePart.java index 7aaf4b155..b0a6c4414 100644 --- a/transmission/src/main/java/mrtjp/projectred/transmission/part/FramedRedwirePart.java +++ b/transmission/src/main/java/mrtjp/projectred/transmission/part/FramedRedwirePart.java @@ -114,10 +114,12 @@ public boolean canConnectPart(IConnectable part, int dir) { public boolean discoverStraightOverride(int s) { boolean prevCanConnectRW = RedstonePropagator.canConnectRedwires(); RedstonePropagator.setCanConnectRedwires(false); - boolean discovered = (RedstoneInteractions.otherConnectionMask(level(), pos(), s, false) & - RedstoneInteractions.connectionMask(this, s)) != 0; - RedstonePropagator.setCanConnectRedwires(prevCanConnectRW); - return discovered; + try { + return (RedstoneInteractions.otherConnectionMask(level(), pos(), s, false) & + RedstoneInteractions.connectionMask(this, s)) != 0; + } finally { + RedstonePropagator.setCanConnectRedwires(prevCanConnectRW); + } } @Override @@ -150,28 +152,30 @@ public void onSignalUpdate() { public int calculateSignal() { RedstonePropagator.setDustProvidesPower(false); RedstonePropagator.setRedwiresProvidePower(false); - - int signal = 0; - for (int s = 0; s < 6; s++) { - int sig = 0; - if (maskConnectsIn(s)) { - CenterLookup lookup = CenterLookup.lookupInsideFace(level(), pos(), s); - sig = resolveSignal(lookup); - - } else if (maskConnectsOut(s)) { - CenterLookup lookup = CenterLookup.lookupStraightCenter(level(), pos(), s); - sig = resolveSignal(lookup); - if (sig == 0) { - sig = RedstoneCenterLookup.resolveVanillaSignal(lookup, this); + try { + int signal = 0; + for (int s = 0; s < 6; s++) { + int sig = 0; + if (maskConnectsIn(s)) { + CenterLookup lookup = CenterLookup.lookupInsideFace(level(), pos(), s); + sig = resolveSignal(lookup); + + } else if (maskConnectsOut(s)) { + CenterLookup lookup = CenterLookup.lookupStraightCenter(level(), pos(), s); + sig = resolveSignal(lookup); + if (sig == 0) { + sig = RedstoneCenterLookup.resolveVanillaSignal(lookup, this); + } } + + signal = Math.max(sig, signal); } - signal = Math.max(sig, signal); + return signal; + } finally { + RedstonePropagator.setDustProvidesPower(true); + RedstonePropagator.setRedwiresProvidePower(true); } - - RedstonePropagator.setDustProvidesPower(true); - RedstonePropagator.setRedwiresProvidePower(true); - return signal; } @Override diff --git a/transmission/src/main/java/mrtjp/projectred/transmission/part/RedwirePart.java b/transmission/src/main/java/mrtjp/projectred/transmission/part/RedwirePart.java index c5a50b500..ebe7536cc 100644 --- a/transmission/src/main/java/mrtjp/projectred/transmission/part/RedwirePart.java +++ b/transmission/src/main/java/mrtjp/projectred/transmission/part/RedwirePart.java @@ -124,10 +124,12 @@ public boolean discoverOpen(int r) { public boolean discoverStraightOverride(int absDir) { boolean prevCanConnectRW = RedstonePropagator.canConnectRedwires(); RedstonePropagator.setCanConnectRedwires(true); - boolean discovered = (RedstoneInteractions.otherConnectionMask(level(), pos(), absDir, false) & - RedstoneInteractions.connectionMask(this, absDir)) != 0; - RedstonePropagator.setCanConnectRedwires(prevCanConnectRW); - return discovered; + try { + return (RedstoneInteractions.otherConnectionMask(level(), pos(), absDir, false) & + RedstoneInteractions.connectionMask(this, absDir)) != 0; + } finally { + RedstonePropagator.setCanConnectRedwires(prevCanConnectRW); + } } @Override @@ -165,46 +167,47 @@ public void setSignal(int signal) { public int calculateSignal() { RedstonePropagator.setDustProvidesPower(false); RedstonePropagator.setRedwiresProvidePower(false); - - int signal = 0; - - for (int r = 0; r < 4; r++) { - int s = 0; - if (maskConnectsInside(r)) { - FaceLookup lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), r); - s = resolveSignal(lookup); - - } else if (maskConnectsStraight(r)) { - FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); - s = resolveSignal(lookup); - if (s <= 0) { - s = RedstoneFaceLookup.resolveVanillaSignal(lookup, this, true, true); + try { + int signal = 0; + + for (int r = 0; r < 4; r++) { + int s = 0; + if (maskConnectsInside(r)) { + FaceLookup lookup = FaceLookup.lookupInsideFace(level(), pos(), getSide(), r); + s = resolveSignal(lookup); + + } else if (maskConnectsStraight(r)) { + FaceLookup lookup = FaceLookup.lookupStraight(level(), pos(), getSide(), r); + s = resolveSignal(lookup); + if (s <= 0) { + s = RedstoneFaceLookup.resolveVanillaSignal(lookup, this, true, true); + } + + } else if (maskConnectsCorner(r)) { + FaceLookup lookup = FaceLookup.lookupCorner(level(), pos(), getSide(), r); + s = resolveSignal(lookup); } - } else if (maskConnectsCorner(r)) { - FaceLookup lookup = FaceLookup.lookupCorner(level(), pos(), getSide(), r); - s = resolveSignal(lookup); + signal = Math.max(s, signal); } - signal = Math.max(s, signal); - } + if (powerUnderside()) { + Direction face = Direction.values()[getSide()]; + int s = level().getSignal(pos().relative(face), face) * 17; + signal = Math.max(s, signal); + } - if (powerUnderside()) { - Direction face = Direction.values()[getSide()]; - int s = level().getSignal(pos().relative(face), face) * 17; - signal = Math.max(s, signal); - } + if (maskConnectsCenter()) { + FaceLookup lookup = FaceLookup.lookupInsideCenter(level(), pos(), getSide()); + int s = resolveSignal(lookup); + signal = Math.max(s, signal); + } - if (maskConnectsCenter()) { - FaceLookup lookup = FaceLookup.lookupInsideCenter(level(), pos(), getSide()); - int s = resolveSignal(lookup); - signal = Math.max(s, signal); + return signal; + } finally { + RedstonePropagator.setDustProvidesPower(true); + RedstonePropagator.setRedwiresProvidePower(true); } - - RedstonePropagator.setDustProvidesPower(true); - RedstonePropagator.setRedwiresProvidePower(true); - - return signal; } //endregion