mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-22 16:41:46 +03:00
[FEATURE] SessionManager: uuidIndex
This commit is contained in:
parent
447866d001
commit
0f8f51ea97
6 changed files with 84 additions and 18 deletions
|
@ -312,6 +312,7 @@ public static class NettyPerformanceConfig {
|
|||
public boolean usingEpoll;
|
||||
public int bossThread;
|
||||
public int workerThread;
|
||||
public long sessionLifetimeMs = 24 * 60 * 60 * 1000;
|
||||
}
|
||||
|
||||
public static class NettyBindAddress {
|
||||
|
|
|
@ -5,19 +5,20 @@
|
|||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.auth.RequiredDAO;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.utils.HookSet;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SessionManager implements NeedGarbageCollection {
|
||||
|
||||
public static final long SESSION_TIMEOUT = 3 * 60 * 60 * 1000; // 3 часа
|
||||
private final Map<UUID, Entry> clientSet = new ConcurrentHashMap<>(128);
|
||||
private final Map<UUID, Set<Entry>> uuidIndex = new ConcurrentHashMap<>(32);
|
||||
private final LaunchServer server;
|
||||
public HookSet<Client> clientRestoreHook = new HookSet<>();
|
||||
|
||||
public SessionManager(LaunchServer server) {
|
||||
this.server = server;
|
||||
|
@ -25,11 +26,45 @@ public SessionManager(LaunchServer server) {
|
|||
|
||||
|
||||
public boolean addClient(Client client) {
|
||||
if(client == null) return false;
|
||||
clientSet.put(client.session, new Entry(compressClient(client)));
|
||||
if(client == null || client.session == null) return false;
|
||||
remove(client.session);
|
||||
Entry e = new Entry(compressClient(client), client.session);
|
||||
clientSet.put(client.session, e);
|
||||
if(client.isAuth && client.uuid != null) {
|
||||
Set<Entry> uuidSet = uuidIndex.computeIfAbsent(client.uuid, k -> ConcurrentHashMap.newKeySet());
|
||||
uuidSet.add(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Stream<UUID> findSessionsByUUID(UUID uuid) {
|
||||
Set<Entry> set = uuidIndex.get(uuid);
|
||||
if(set != null) return set.stream().map((e) -> e.sessionUuid);
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean removeByUUID(UUID uuid) {
|
||||
Set<Entry> set = uuidIndex.get(uuid);
|
||||
if(set != null) {
|
||||
for(Entry e : set) {
|
||||
clientSet.remove(e.sessionUuid);
|
||||
}
|
||||
set.clear();
|
||||
uuidIndex.remove(uuid);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Set<UUID> getSavedUUIDs()
|
||||
{
|
||||
return uuidIndex.keySet();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
clientSet.clear();
|
||||
uuidIndex.clear();
|
||||
}
|
||||
|
||||
private String compressClient(Client client) {
|
||||
return Launcher.gsonManager.gson.toJson(client); //Compress using later
|
||||
}
|
||||
|
@ -46,16 +81,24 @@ private Client restoreFromString(String data) {
|
|||
}
|
||||
}
|
||||
if(result.refCount == null) result.refCount = new AtomicInteger(1);
|
||||
clientRestoreHook.hook(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void garbageCollection() {
|
||||
long time = System.currentTimeMillis();
|
||||
clientSet.entrySet().removeIf(entry -> {
|
||||
long timestamp = entry.getValue().timestamp;
|
||||
return (timestamp + SESSION_TIMEOUT < time);
|
||||
long session_timeout = server.config.netty.performance.sessionLifetimeMs;
|
||||
Set<UUID> to_delete = new HashSet<>(32);
|
||||
clientSet.forEach((uuid, entry) -> {
|
||||
long timestamp = entry.timestamp;
|
||||
if(timestamp + session_timeout < time)
|
||||
to_delete.add(uuid);
|
||||
});
|
||||
for(UUID session : to_delete) {
|
||||
remove(session);
|
||||
}
|
||||
to_delete.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -71,8 +114,27 @@ public Client getOrNewClient(UUID session) {
|
|||
return client == null ? new Client(session) : client;
|
||||
}
|
||||
|
||||
public boolean remove(UUID session) {
|
||||
Entry e =clientSet.remove(session);
|
||||
if(e != null) {
|
||||
Set<Entry> set = uuidIndex.get(session);
|
||||
if(set != null) {
|
||||
removeUuidFromIndexSet(set, e, session);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void removeUuidFromIndexSet(Set<Entry> set, Entry e, UUID session) {
|
||||
set.remove(e);
|
||||
if(set.isEmpty()) {
|
||||
uuidIndex.remove(session);
|
||||
}
|
||||
}
|
||||
@Deprecated
|
||||
public void removeClient(UUID session) {
|
||||
clientSet.remove(session);
|
||||
remove(session);
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,10 +154,12 @@ public void loadSessions(Set<Client> set) {
|
|||
}
|
||||
private static class Entry {
|
||||
public String data;
|
||||
public UUID sessionUuid;
|
||||
public long timestamp;
|
||||
|
||||
public Entry(String data) {
|
||||
public Entry(String data, UUID sessionUuid) {
|
||||
this.data = data;
|
||||
this.sessionUuid = sessionUuid;
|
||||
this.timestamp = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ public class Client {
|
|||
public boolean checkSign;
|
||||
public ClientPermissions permissions;
|
||||
public String username;
|
||||
public UUID uuid;
|
||||
public TrustLevel trustLevel;
|
||||
|
||||
public transient AuthProviderPair auth;
|
||||
|
|
|
@ -104,17 +104,17 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
|
|||
}
|
||||
result.session = clientData.session;
|
||||
}
|
||||
UUID uuid;
|
||||
if (authType == ConnectTypes.CLIENT && server.config.protectHandler.allowGetAccessToken(context)) {
|
||||
uuid = pair.handler.auth(aresult);
|
||||
clientData.uuid = pair.handler.auth(aresult);
|
||||
if (LogHelper.isDebugEnabled()) {
|
||||
LogHelper.debug("Auth: %s accessToken %s uuid: %s", login, result.accessToken, uuid.toString());
|
||||
LogHelper.debug("Auth: %s accessToken %s uuid: %s", login, result.accessToken, clientData.uuid.toString());
|
||||
}
|
||||
} else {
|
||||
uuid = pair.handler.usernameToUUID(aresult.username);
|
||||
clientData.uuid = pair.handler.usernameToUUID(aresult.username);
|
||||
result.accessToken = null;
|
||||
}
|
||||
result.playerProfile = ProfileByUUIDResponse.getProfile(uuid, aresult.username, client, clientData.auth.textureProvider);
|
||||
|
||||
result.playerProfile = ProfileByUUIDResponse.getProfile(clientData.uuid, aresult.username, client, clientData.auth.textureProvider);
|
||||
|
||||
clientData.type = authType;
|
||||
sendResult(result);
|
||||
|
|
|
@ -23,7 +23,7 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
|||
public static CurrentUserRequestEvent.UserInfo collectUserInfoFromClient(Client client) throws IOException {
|
||||
CurrentUserRequestEvent.UserInfo result = new CurrentUserRequestEvent.UserInfo();
|
||||
if (client.auth != null && client.isAuth && client.username != null) {
|
||||
UUID uuid = client.auth.handler.usernameToUUID(client.username);
|
||||
UUID uuid = client.uuid != null ? client.uuid : client.auth.handler.usernameToUUID(client.username);
|
||||
if (uuid != null) {
|
||||
result.playerProfile = ProfileByUUIDResponse.getProfile(uuid, client.username, client.profile == null ? null : client.profile.getTitle(), client.auth.textureProvider);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
|||
Client newClient = new Client(null);
|
||||
newClient.checkSign = client.checkSign;
|
||||
handler.setClient(newClient);
|
||||
if (client.session != null) server.sessionManager.removeClient(client.session);
|
||||
if (client.session != null) server.sessionManager.remove(client.session);
|
||||
if (exitAll) {
|
||||
service.forEachActiveChannels(((channel, webSocketFrameHandler) -> {
|
||||
Client client1 = webSocketFrameHandler.getClient();
|
||||
|
@ -68,7 +68,7 @@ public static void exit(LaunchServer server, WebSocketFrameHandler wsHandler, Ch
|
|||
Client newCusClient = new Client(null);
|
||||
newCusClient.checkSign = chClient.checkSign;
|
||||
wsHandler.setClient(newCusClient);
|
||||
if (chClient.session != null) server.sessionManager.removeClient(chClient.session);
|
||||
if (chClient.session != null) server.sessionManager.remove(chClient.session);
|
||||
ExitRequestEvent event = new ExitRequestEvent(reason);
|
||||
event.requestUUID = RequestEvent.eventUUID;
|
||||
wsHandler.service.sendObject(channel, event);
|
||||
|
|
Loading…
Reference in a new issue