Skip to content

feat(api): publish stable connect-player channel marker - #75

Merged
robinbraemer merged 1 commit into
mainfrom
fm/connect-java-connect-player-marker
Jul 28, 2026
Merged

feat(api): publish stable connect-player channel marker#75
robinbraemer merged 1 commit into
mainfrom
fm/connect-java-connect-player-marker

Conversation

@robinbraemer

Copy link
Copy Markdown
Member

Intent

Ship a stable, public "externally authenticated by Connect" marker on the proxy-facing connection so any login/auth plugin (LibreLogin, AuthMe, nLogin, future ones) can detect a Connect-tunneled player and skip its own login flow. This is Part A of a LibreLogin compatibility fix, backed by a scout report.

Background the reviewer will not see in the diff: Connect authenticates players at its edge and hands the proxy an already-verified, offline-mode connection. Login plugins that run later and force ONLINE mode on that connection hang the login, because no second Mojang session exists. LibreLogin already solves exactly this for Floodgate by checking a 'floodgate-player' channel attribute at every conflict point; it just has no equivalent signal for Connect. This task publishes that signal.

Deliberate decisions (do not flag these as mistakes):

  • The wire-visible attribute name MUST be exactly 'connect-player', deliberately mirroring Floodgate's 'floodgate-player' convention so plugin authors who already handle Floodgate apply the identical pattern. The literal is intentionally duplicated in the boundary test rather than referencing the constant, so that renaming the constant's value fails the test - that duplication is the point of the test.
  • The attribute value type is ConnectPlayer rather than a bare UUID. Netty interns attribute keys by name, so a third-party presence check needs no compile-time dependency on Connect, while integrators who do depend on the api jar get UUID, username, game profile and Auth for free. This tradeoff is documented in the Javadoc and the integration doc.
  • The marker is set in LocalServerChannelWrapper#newLocalChannel, alongside the existing wrapper().setContext(...). That is the earliest point at which both the proxy-facing channel and the Connect player identity exist, so a single set-site covers Velocity, BungeeCord and Spigot at once, before any platform login event fires. The context/player availability at that exact point was confirmed against LocalSession.Context.
  • The marker is set ONLY when !auth.isPassthrough(). Passthrough sessions are genuinely not authenticated by Connect and must still go through the login plugin's own flow; their absence of the marker is intended behavior, pinned by a test.
  • The captain has committed to 'connect-player' as a PERMANENT public contract: once external plugins depend on the name it can never be removed or renamed. The docs state this explicitly and somewhat emphatically on purpose, so a future contributor cannot mistake the attribute for an internal detail they are free to refactor. The stability language in ConnectAttributes' Javadoc, docs/login-plugin-integration.md, and AGENTS.md is captain-directed and non-negotiable, not accidental over-documentation.
  • Documentation was an explicit first-class deliverable of this task, not an afterthought; the size of docs/login-plugin-integration.md relative to the code diff is intended.

Hard scope line, deliberately observed: this change only ADDS a readable marker. It does NOT change Connect's PreLogin or GameProfile injection behavior, and it must not affect login for anyone not reading the attribute. The diff is intentionally limited to the new api attribute class, the one marker set-site, the boundary test, and the integration docs (plus a README link and a short AGENTS.md pointer). It does not depend on any LibreLogin change; the upstream PR is a separate later task.

Verification done: ./gradlew build is green; the boundary test is mutation-checked (renaming the attribute value fails 2 of its 3 tests).

What Changed

  • Added the stable connect-player Netty attribute and documented its ConnectPlayer value and integration semantics.
  • Marked proxy-facing channels only for non-passthrough sessions authenticated by Connect, before platform login events.
  • Added boundary coverage and integration documentation pinning the exact name, set-site, timing, passthrough behavior, and permanent stability contract.

Risk Assessment

✅ Low: The marker is set on the shared proxy-facing channel path for non-passthrough sessions, with matching public API, tests, and documentation; no source-verifiable material issues were found.

Testing

The focused boundary test passed for exact naming, authenticated marker visibility through the external Netty key, and passthrough absence. No visual artifact applies because this is a Netty connection contract.

Evidence: Connect player boundary test report
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.minekube.connect.network.netty.ConnectPlayerAttributeBoundaryTest" tests="3" skipped="0" failures="0" errors="0" timestamp="2026-07-28T01:52:13" hostname="Robins-MacBook-Pro.fritz.box" time="0.188">
  <properties/>
  <testcase name="markerIsSetOnProxyFacingChannelForAuthenticatedSession()" classname="com.minekube.connect.network.netty.ConnectPlayerAttributeBoundaryTest" time="0.185"/>
  <testcase name="markerIsAbsentForPassthroughSession()" classname="com.minekube.connect.network.netty.ConnectPlayerAttributeBoundaryTest" time="0.001"/>
  <testcase name="attributeNameIsExactlyConnectPlayer()" classname="com.minekube.connect.network.netty.ConnectPlayerAttributeBoundaryTest" time="0.001"/>
  <system-out><![CDATA[]]></system-out>
  <system-err><![CDATA[SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details.
]]></system-err>
</testsuite>

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • ./gradlew :core:test --tests com.minekube.connect.network.netty.ConnectPlayerAttributeBoundaryTest --rerun-tasks
  • Reviewed target diff and focused JUnit report
  • ./gradlew clean and verified transient build outputs were removed
✅ **Document** - passed

✅ No issues found.

⚠️ **Lint** - 2 errors
  • 🚨 core/src/main/java/com/minekube/connect/util/ReflectionUtils.java:294 - Core Javadoc still fails on unescaped <T> tags at lines 294 and 308; unchanged and outside this change’s scope.
  • 🚨 core/src/main/java/com/minekube/connect/util/Utils.java:178 - Core Javadoc cannot resolve GameProfile.Property; unchanged and outside this change’s scope.
✅ **Push** - passed

✅ No issues found.

Connect authenticates players at its edge and hands the proxy an
already-verified, offline-mode connection. Login/auth plugins that run
later and force ONLINE mode on that connection hang the login, because
no second Mojang session exists.

Publish a stable marker any login plugin can read to detect a
Connect-tunneled player and skip its own flow, mirroring Floodgate's
'floodgate-player' convention:

- new ConnectAttributes.CONNECT_PLAYER, wire name exactly 'connect-player',
  valued with the ConnectPlayer so integrators get identity and skin
  properties while a plain presence check needs no dependency on Connect
- set in LocalServerChannelWrapper#newLocalChannel, the earliest point at
  which both the proxy-facing channel and the Connect player exist, so it
  is readable before any Velocity/Bungee/Spigot login event fires; only
  for non-passthrough sessions, since passthrough is not authenticated by
  Connect and must still go through the server's login flow
- ConnectPlayerAttributeBoundaryTest pins both the name and the set-site
- docs/login-plugin-integration.md publishes the contract, the ConnectApi
  UUID lookups, and the permanent-stability commitment

Adds a readable marker only; no change to Connect's PreLogin or
GameProfile behavior.
@robinbraemer
robinbraemer merged commit 974fa05 into main Jul 28, 2026
2 checks passed
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