Skip to content

fix: prevent red alloy/insulated wire from becoming unpowerable after a thrown lookup#2006

Open
arsdragonfly wants to merge 1 commit into
MrTJP:1.20.1from
arsdragonfly:fix/redwire-flag-exception-safety-1.20.1
Open

fix: prevent red alloy/insulated wire from becoming unpowerable after a thrown lookup#2006
arsdragonfly wants to merge 1 commit into
MrTJP:1.20.1from
arsdragonfly:fix/redwire-flag-exception-safety-1.20.1

Conversation

@arsdragonfly

Copy link
Copy Markdown

Summary

RedstonePropagator's global redstone flags are toggled around connection discovery and signal calculation without try/finally, so a neighbor lookup that throws mid-way leaves 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/unloaded chunk during the lookup), the restore line is skipped and the flag is left false.

RedwirePart#canConnectRedstone is the only consumer of canConnectRedwires(). Once it is stuck false, every face red alloy / insulated wire reports no redstone connection and reads zero vanilla power through RedstoneInteractions.getPowerTo — so newly placed (and existing) wires can no longer be powered at all. Gates and vanilla redstone dust are unaffected (different flags / code paths), which is exactly why only the wires appear broken.

The flags are only reset on ServerAboutToStartEvent, so:

  • on a dedicated server the corruption persists for the entire session (matches the reported "lever-next-to-red-alloy-wire stops working mid-session, even a straight line"), while
  • in singleplayer it silently recovers on each world reload, which is why it's hard to reproduce there.

Fix

Wrap every RedstonePropagator flag toggle in try/finally so the flags are always restored, even if a lookup throws:

  • canConnectRedwires in discoverStraightOverride (RedwirePart, FramedRedwirePart, RedstoneTubePart)
  • the dustProvidesPower / redwiresProvidePower flags in calculateSignal (RedwirePart, FramedRedwirePart, RedstoneTubePart, ArrayGatePart)

No behavioral change on the happy path — only exception safety. The flag handling is identical across 1.20.1, 1.20.4, and 1.21.1, so the same fix is being submitted to each active branch.

… 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant