Premium detection#
The point of the plugin: a player whose name belongs to a paid Minecraft account is verified by Mojang and logged in automatically, while everyone else joins offline and uses a password. Both on the same server, at the same time.
What the player sees#
| Premium player | Cracked player | |
|---|---|---|
| First join | Logged in immediately | Asked to /register |
| Later joins | Logged in immediately | /login, or session/trusted IP |
| UUID | Their real Mojang UUID | Offline UUID derived from the name |
| Skin | Their own | Default |
| Reconnects needed | None | None |
How it works#
The server is in offline mode, so the vanilla login never asks for encryption. The plugin intercepts the login handshake in Netty and decides, per connection, whether to demand Mojang verification.
The trick that makes it seamless: since Minecraft 1.20.2 the client sends its own UUID in the login hello. So the plugin can compare that against the account's real Mojang UUID before challenging anyone:
- Name is a paid account and the client claims that account's real UUID → send the encryption request. A genuine premium client passes; the vanilla server then completes the login itself, with the correct UUID and skin.
- Anything else → the hello is passed straight through and the player joins offline.
A cracked client is therefore never challenged, never sees "Invalid session", and never has to reconnect.
No ProtocolLib
The hook is installed by wrapping the child handler of Netty's ServerBootstrapAcceptor,
which is version-independent. It does not hand-drive the handshake — it primes the vanilla
login listener and lets the server finish the job.
Velocity and BungeeCord both expose the same decision as a first-class API, so there is no packet work at all. Before the player is let in, the username is looked up with Mojang (cached for 5 minutes) and compared against the UUID the client claims:
- Paid account and the client claims its real UUID → the proxy is told to run the Mojang handshake; the player joins verified, with their real UUID and skin.
- Paid account but the client claims something else → it is a cracked client wearing somebody
else's name; it is refused with the
kick-premium-namemessage. - Not a paid account → offline join; normal register/login.
The proxy also stays out of the way of Floodgate: a Bedrock connection is left exactly as Floodgate set it up, so Geyser keeps working.
Configuration#
mode#
Every username is checked against Mojang automatically. Premium players are logged in on their first join without doing anything.
Everyone joins offline by default. A premium player runs /premium once; from then on their
name is verified on every join. /premium off turns it back off.
Use this if you would rather not have the plugin query Mojang for every unknown name.
protect-premium-names#
Reserves a premium name for its real owner: a cracked client cannot impersonate a premium player while they are offline.
true refuses the cracked login with your own message (kick-premium-name in messages.yml).
false allows it — the impostor still has to register a password.
This works on both platforms, and for the same reason: since MC 1.20.2 the client sends its own UUID when logging in, so a real premium client can be told apart from an impostor before anyone is challenged.
Old clients still see 'Invalid session'
A client older than 1.20.2 does not send a UUID, so there is nothing to compare. Those
connections are challenged by Mojang as before, and a cracked one is refused by the client
itself with Failed to log in: Invalid session — a screen no server can customise, because
the connection ends inside the encryption handshake.
If you see that message on a modern client, the name really did claim the premium account's UUID (a deliberate spoof) — Mojang then refuses it, which is exactly what should happen.
bedrock-autologin#
On by default. A Bedrock player arriving through Geyser + Floodgate joins straight into the
game — no /register, no password.
They were authenticated by Xbox Live before Geyser ever handed them to your proxy, so Floodgate is trusted here the same way Mojang is trusted for a Java premium player.
They are recognised by the UUID Floodgate builds for them — new UUID(0, xuid), all zeroes in the
high half. No Java account's UUID can look like that, and no Floodgate API has to be on the
classpath.
Geyser must be the only Bedrock door in
This trusts anything that arrives with a Floodgate-shaped UUID. If someone can reach a backend server directly, bypassing the proxy, they could hand it such a UUID themselves. Keep the backend ports closed and use modern forwarding — the same requirement bridge mode already has.
Set it to false to make Bedrock players register with a password like cracked Java players. Either
way they are never challenged by Mojang, and protect-premium-names never blocks them — their
gamertag is not a Java account's name.
debug#
Logs every decision: the Mojang API answer, the UUID the client claimed, and why the player was treated as premium or cracked. Turn it on first whenever premium login misbehaves.
[Premium][debug] Notch is a paid account (069a79f4-...) -> Mojang verification.
[Premium][debug] Steve_2011 is not a paid account -> offline join.
[Premium][debug] Notch is a paid account but the client claims 8f4b1c... -> treating as cracked.
Two players, one name#
In offline mode the UUID comes from the name — so BeboNaiem and bebonaiem are different
players to the server, and its own duplicate check would let both in at once. Slime Login refuses
any login whose name (ignoring case) is already online, with the kick-duplicate-name message.
When Mojang cannot be reached#
A failed lookup is never cached. An outage must not turn a reserved premium name into a free one for the next five minutes. During an outage the affected names fall back to an offline join, so the server keeps working — a premium player who has a password can still use it, and one who does not can register.
Requirements checklist#
- Offline mode where the player connects:
online-mode=false(server.properties),online-mode = false(velocity.toml) oronline_mode: false(BungeeCord config.yml) -
premium-bypass.enabled: true - Outbound HTTPS to
api.mojang.comandsessionserver.mojang.com - Minecraft 1.20.2+ clients for the seamless path (older clients still work; a cracked client using a premium name may need one reconnect)