Add player presence reconciliation for proxy servers#9
Open
frederickbaier wants to merge 1 commit intofeat/platformfrom
Open
Add player presence reconciliation for proxy servers#9frederickbaier wants to merge 1 commit intofeat/platformfrom
frederickbaier wants to merge 1 commit intofeat/platformfrom
Conversation
Add ProxyPresenceResponder to answer controller presence-compare requests, allowing the controller to detect ghost players by comparing its known player set against the proxy's actual connected players via hash comparison over NATS. ProxyPresenceTracker maintains stable per-player metadata (login timestamp, session ID) for accurate snapshots. The responder is owned by proxy plugins (Velocity/BungeeCord) rather than CloudApiImpl, ensuring only one NATS subscription per proxy. CloudApi now extends AutoCloseable with proper shutdown. PlayerIntegration simplified to accept CloudApiImpl directly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The controller already implements player presence reconciliation — it periodically sends compare requests to each proxy to detect drift between its known player state and reality. This handles two failure modes: lost disconnect events (stale ghost players in the controller) and lost login events (connected players invisible to the network). Until now, the proxy-side counterpart to answer these requests did not exist.
What this PR does
Proxy-side presence responder
Implements the proxy-side handler for the controller's presence reconciliation protocol:
PresenceCompareRequestcontaining an FNV-32a hash of the players it believes are on a given proxymatch: true— no further action neededThe hash-first approach minimizes NATS traffic during normal operation — the full player list is only transferred when there's actually a discrepancy.
New components:
ProxyPresenceResponder— subscribes to{networkId}.server.{serverId}.presence.compareand handles compare requests. Owned by the proxy plugins (Velocity / BungeeCord) directly, since only proxies need to respond — this avoids everyCloudApi.create()caller (lobby plugins, minigame plugins, etc.) creating redundant NATS subscriptions.ProxyPresenceTracker— tracks stable per-player metadata (login timestamp, session ID) that isn't available from the platform API at snapshot timeProxyPresencePlayer/ProxyPresencePlayerProvider— immutable player snapshot and provider interfaceOther improvements
CloudApiextendsAutoCloseable—CloudApiImpl.close()properly shuts down cache, event listeners, and the NATS connection, guarded byAtomicBooleanto prevent double-closePlayerIntegrationacceptsCloudApiImpldirectly — removes the runtime type check and cast, since only proxy plugins use itSimpleCloudRuntimeutility — centralizes environment variable access (SIMPLECLOUD_UNIQUE_ID,SIMPLECLOUD_GROUP,SIMPLECLOUD_NUMERICAL_ID) replacing scatteredSystem.getenv()callsconnection.getListener().getDefaultServer()where the locale parameter was expected