Use a shared per-proxy session ID for 26.2 login metrics

The 26.2 login success session ID is purely a metrics identifier. Mint
one shared UUID per proxy, regenerated when the proxy empties, mirroring
the vanilla server, instead of a random UUID per connection.
This commit is contained in:
Shane Freeder
2026-06-16 12:26:19 +01:00
parent d7ad0522e9
commit a7581821fb
2 changed files with 33 additions and 1 deletions

View File

@@ -165,6 +165,8 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
private final Map<UUID, ConnectedPlayer> connectionsByUuid = new ConcurrentHashMap<>(); private final Map<UUID, ConnectedPlayer> connectionsByUuid = new ConcurrentHashMap<>();
private final Map<String, ConnectedPlayer> connectionsByName = new ConcurrentHashMap<>(); private final Map<String, ConnectedPlayer> connectionsByName = new ConcurrentHashMap<>();
private final Object sessionIdLock = new Object();
private volatile @Nullable UUID sessionId;
private final VelocityConsole console; private final VelocityConsole console;
private @MonotonicNonNull Ratelimiter<InetAddress> ipAttemptLimiter; private @MonotonicNonNull Ratelimiter<InetAddress> ipAttemptLimiter;
private @MonotonicNonNull Ratelimiter<UUID> commandRateLimiter; private @MonotonicNonNull Ratelimiter<UUID> commandRateLimiter;
@@ -743,6 +745,36 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
connectionsByName.remove(connection.getUsername().toLowerCase(Locale.US), connection); connectionsByName.remove(connection.getUsername().toLowerCase(Locale.US), connection);
connectionsByUuid.remove(connection.getUniqueId(), connection); connectionsByUuid.remove(connection.getUniqueId(), connection);
connection.disconnected(); connection.disconnected();
if (this.sessionId != null && connectionsByUuid.isEmpty()) {
synchronized (this.sessionIdLock) {
if (connectionsByUuid.isEmpty()) {
this.sessionId = null;
}
}
}
}
/**
* Returns the metrics session ID for this proxy, generating one if none is currently active. The
* ID is shared by every player connected during a populated period and is regenerated once the
* proxy empties.
*
* @return the current session ID
*/
public UUID getSessionId() {
UUID uuid = this.sessionId;
if (uuid != null) {
return uuid;
}
synchronized (this.sessionIdLock) {
uuid = this.sessionId;
if (uuid == null) {
uuid = UUID.randomUUID();
this.sessionId = uuid;
}
return uuid;
}
} }
@Override @Override

View File

@@ -237,7 +237,7 @@ public class AuthSessionHandler implements MinecraftSessionHandler {
success.setProperties(player.getGameProfileProperties()); success.setProperties(player.getGameProfileProperties());
success.setUuid(player.getUniqueId()); success.setUuid(player.getUniqueId());
if (inbound.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_26_2)) { if (inbound.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_26_2)) {
success.setSessionId(UUID.randomUUID()); // use random uuid for now success.setSessionId(server.getSessionId());
} }
mcConnection.write(success); mcConnection.write(success);