feat(presence): publish the network-wide player lookup#22
Merged
Conversation
plugin-proxy's ProxyService resolves a player locally and then falls back to a PlayerSessionQuery — but nothing ever registered one, so the fallback returned null and a proxy could only ever see its own players. That is why /msg and party invites did not cross proxies. Register one, backed by service-player (contract 0.3.0): name -> uuid, uuid -> session, and prefix suggestions for tab-complete. Every lookup fails soft — an unavailable presence service means "unknown", and the caller falls back to the players it can see locally, rather than an exception on Velocity's event loop. Login now carries the player's name and PROXY_ID: without the name a session exists but nobody can address it, and ServerConnectedEvent keeps the session pointing at the backend the player is actually on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E92vTegZqXd2HqjE7jnDJz
plugin-player has never shipped an image, so the platform bundle could not deploy it — and without it in the proxy, nothing registers the session lookup that cross-proxy chat and social depend on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E92vTegZqXd2HqjE7jnDJz
service-player runs with `grounds.auth.enabled=true` and rejects calls without a Bearer token with UNAUTHENTICATED — and every failure in this client is swallowed into "unknown". Logins would have looked like a flaky presence service, and the whole cross-proxy lookup chain would have failed silently. Attach the projected ServiceAccount JWT (audience grounds-services) the charts already mount into the proxy pod, re-read per call for kubelet rotation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E92vTegZqXd2HqjE7jnDJz
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
plugin-proxy's
ProxyServiceImplalready resolves a player locally first and falls back to aPlayerSessionQueryfor anyone on another proxy. Nothing ever registered one, so that fallback returnednull— a proxy could only ever see its own players. That is the reason/msgand party invites silently did not cross proxies.What
PlayerSessionQueryImplregisters into theProxyServiceRegistryand answers from service-player (contractlibrary-grpc-contracts-player:0.3.0):resolveByName(name)→ the session, network-widegetSession(playerId)→ who and wheresuggestNames(prefix, limit)→ tab-complete, prefix-based and capped (never a roster dump)Every lookup fails soft: an unavailable presence service means "I don't know", and the caller falls back to what it can see locally. These run on the command path — an exception there would land on Velocity's event loop.
TryPlayerLoginnow carries the player's name andPROXY_ID. Without the name a session exists but nobody can address it by name, which is the whole point.ServerConnectedEventkeeps the session pointing at the backend the player is actually on, so a party warp can send someone to the leader's server.plugin-proxyis now a hard plugin dependency (@Plugin(dependencies = ...)) andplugin-proxy-apiiscompileOnly— it must not be shaded, or the registry this plugin writes into would be a different class from the one chat and social read.Chain
groundsgg/library-grpc-contracts#68 (player 0.3.0) → groundsgg/service-player#75 (implements the RPCs) → this → plugin-chat + plugin-social drop their local-only lookups and use
ProxyService.🤖 Generated with Claude Code
https://claude.ai/code/session_01E92vTegZqXd2HqjE7jnDJz