Fix double-dialing race and cross-server landing race

Double-dial: isOpen() only becomes true once the chevron animation
finishes, so a second click during that animation (another player,
or the same player double-clicking) passed the existing guard and
started an overlapping dial. RuntimeGate now has a separate
isDialing() flag set the instant dial() starts and cleared only when
closeGate() runs, so a gate stays blocked for its entire
dialing-through-open lifecycle, not just while fully open.
GateManager.dial() also defensively re-checks this itself and returns
false if either gate is busy, in case two calls race in before the
caller's own guard catches it.

Cross-server landing: the proxy only sends its "deliver" message
after confirming the server switch succeeded, so there's no
guaranteed ordering between that message arriving and this backend
finishing its own join processing for the player. A single
Bukkit.getPlayer() null-check at message-receipt time could lose that
race and silently drop the landing teleport, leaving the player at
the server's normal spawn instead of the gate - which is what was
being reported. CrossServerBridge now stashes the pending delivery
and retries on PlayerJoinEvent as well, so it lands regardless of
which order the message and the join actually resolve in.
This commit is contained in:
Michael Burgess
2026-08-09 14:22:13 -04:00
parent 67330744eb
commit 8a8faf8ffe
5 changed files with 88 additions and 32 deletions
+4 -1
View File
@@ -68,7 +68,10 @@ material, unsealed interior, too far from the sign, etc.
water) and travel opens up. It auto-closes after `dialing.open-seconds`. That water
is contained to exactly the iris blocks - the plugin actively cancels any attempt
by Minecraft's own fluid physics to spread it further, so it can't leak out through
a gap or an odd ring shape and flood the ground around the gate.
a gap or an odd ring shape and flood the ground around the gate. A gate that's
already dialing or open won't dial again - the animation itself, not just the fully
open state, blocks re-entry - so two people clicking the same sign can't start
overlapping dials or connect it to two destinations at once.
- **Shift + left-click** the sign: destroys the gate on the spot (same permission
check as `/sg destroy` - owner or `stargate.admin`), breaking the sign as if
you'd mined it. Quicker than looking at the sign and typing the command.