diff --git a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java index 95f10bcbb..83e443e9c 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java @@ -165,6 +165,8 @@ public class VelocityServer implements ProxyServer, ForwardingAudience { private final Map connectionsByUuid = new ConcurrentHashMap<>(); private final Map connectionsByName = new ConcurrentHashMap<>(); + private final Object sessionIdLock = new Object(); + private volatile @Nullable UUID sessionId; private final VelocityConsole console; private @MonotonicNonNull Ratelimiter ipAttemptLimiter; private @MonotonicNonNull Ratelimiter commandRateLimiter; @@ -743,6 +745,36 @@ public class VelocityServer implements ProxyServer, ForwardingAudience { connectionsByName.remove(connection.getUsername().toLowerCase(Locale.US), connection); connectionsByUuid.remove(connection.getUniqueId(), connection); 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 diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/AuthSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/AuthSessionHandler.java index 4d05da9ea..fee642b49 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/AuthSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/AuthSessionHandler.java @@ -237,7 +237,7 @@ public class AuthSessionHandler implements MinecraftSessionHandler { success.setProperties(player.getGameProfileProperties()); success.setUuid(player.getUniqueId()); if (inbound.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_26_2)) { - success.setSessionId(UUID.randomUUID()); // use random uuid for now + success.setSessionId(server.getSessionId()); } mcConnection.write(success);