From a1cdd6e22c8b4501f2bfd266f73f5638e322ac45 Mon Sep 17 00:00:00 2001 From: Zaxar163 Date: Fri, 23 Oct 2020 19:48:45 +0300 Subject: [PATCH 01/31] =?UTF-8?q?[ANY]=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D0=B8?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index 71c224e4..79b821bd 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 71c224e4d7a0950d3b5599ba4dec8d6fd04ededd +Subproject commit 79b821bdf505784af08f2addb8cb086d113a38d0 From d9e71d08d7030825910bc09dde6da5f1d2ae1d46 Mon Sep 17 00:00:00 2001 From: Gravit Date: Fri, 23 Oct 2020 01:02:56 +0700 Subject: [PATCH 02/31] [ANY] 5.1.9-dev --- LauncherCore/src/main/java/pro/gravit/utils/Version.java | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LauncherCore/src/main/java/pro/gravit/utils/Version.java b/LauncherCore/src/main/java/pro/gravit/utils/Version.java index 6198a0fb..49c4c07e 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/Version.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/Version.java @@ -6,9 +6,9 @@ public final class Version { public static final int MAJOR = 5; public static final int MINOR = 1; - public static final int PATCH = 8; + public static final int PATCH = 9; public static final int BUILD = 1; - public static final Version.Type RELEASE = Type.STABLE; + public static final Version.Type RELEASE = Type.DEV; public final int major; public final int minor; public final int patch; diff --git a/build.gradle b/build.gradle index 01c64481..6535c3ae 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ id 'org.openjfx.javafxplugin' version '0.0.8' apply false } group = 'pro.gravit.launcher' -version = '5.1.8' +version = '5.1.9-SNAPSHOT' apply from: 'props.gradle' From 2164fda2880525df237131e6efb2c14615009b78 Mon Sep 17 00:00:00 2001 From: Gravit Date: Mon, 26 Oct 2020 20:42:08 +0700 Subject: [PATCH 03/31] =?UTF-8?q?[ANY]=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index 79b821bd..d797ee95 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 79b821bdf505784af08f2addb8cb086d113a38d0 +Subproject commit d797ee95e5712c2f30fb40749150ec88d042eecd From 3a80a74912748e0af17aa7608721565ee24d845f Mon Sep 17 00:00:00 2001 From: Gravit Date: Mon, 26 Oct 2020 21:23:36 +0700 Subject: [PATCH 04/31] =?UTF-8?q?[ANY]=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index d797ee95..e990b35b 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit d797ee95e5712c2f30fb40749150ec88d042eecd +Subproject commit e990b35b4001e29793b383dfa7b179aa0b27b307 From 18b23b195a0fc1811b17628022d421e4603206e9 Mon Sep 17 00:00:00 2001 From: Gravit Date: Mon, 26 Oct 2020 23:17:05 +0700 Subject: [PATCH 05/31] =?UTF-8?q?[FEATURE][EXPERIMENTAL]=20=D0=A0=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0=20=D1=81=20=D1=81=D0=B5=D1=81=D1=81?= =?UTF-8?q?=D0=B8=D1=8F=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pro/gravit/launchserver/LaunchServer.java | 2 +- .../gravit/launchserver/auth/RequiredDAO.java | 4 ++ .../auth/provider/HibernateAuthProvider.java | 3 +- .../manangers/SessionManager.java | 72 ++++++++++++++----- .../gravit/launchserver/socket/Client.java | 3 + .../handlers/WebSocketFrameHandler.java | 15 ++++ .../socket/response/auth/AuthResponse.java | 2 +- .../response/auth/RestoreSessionResponse.java | 21 ++++-- 8 files changed, 98 insertions(+), 24 deletions(-) create mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/auth/RequiredDAO.java diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java index eaa40fb1..e4f23832 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java @@ -139,7 +139,7 @@ public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, La // build hooks, anti-brutforce and other proguardConf = new ProguardConf(this); - sessionManager = new SessionManager(); + sessionManager = new SessionManager(this); mirrorManager = new MirrorManager(); reconfigurableManager = new ReconfigurableManager(); authHookManager = new AuthHookManager(); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/RequiredDAO.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/RequiredDAO.java new file mode 100644 index 00000000..b543e653 --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/RequiredDAO.java @@ -0,0 +1,4 @@ +package pro.gravit.launchserver.auth; + +public interface RequiredDAO { +} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/HibernateAuthProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/HibernateAuthProvider.java index 05cd046c..7e7b3c65 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/HibernateAuthProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/HibernateAuthProvider.java @@ -3,11 +3,12 @@ import pro.gravit.launcher.request.auth.AuthRequest; import pro.gravit.launcher.request.auth.password.AuthPlainPassword; import pro.gravit.launchserver.auth.AuthException; +import pro.gravit.launchserver.auth.RequiredDAO; import pro.gravit.launchserver.dao.User; import pro.gravit.launchserver.manangers.hook.AuthHookManager; import pro.gravit.utils.helper.SecurityHelper; -public class HibernateAuthProvider extends AuthProvider { +public class HibernateAuthProvider extends AuthProvider implements RequiredDAO { public boolean autoReg; @Override diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java index 268e9196..163e41c4 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java @@ -1,63 +1,101 @@ package pro.gravit.launchserver.manangers; +import pro.gravit.launcher.Launcher; import pro.gravit.launcher.NeedGarbageCollection; +import pro.gravit.launchserver.LaunchServer; +import pro.gravit.launchserver.auth.RequiredDAO; import pro.gravit.launchserver.socket.Client; +import pro.gravit.utils.helper.LogHelper; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.stream.Collectors; public class SessionManager implements NeedGarbageCollection { public static final long SESSION_TIMEOUT = 3 * 60 * 60 * 1000; // 3 часа - private final Map clientSet = new HashMap<>(128); + private final Map clientSet = new ConcurrentHashMap<>(128); + private final LaunchServer server; + + public SessionManager(LaunchServer server) { + this.server = server; + } public boolean addClient(Client client) { - clientSet.put(client.session, client); + if(client == null) return false; + clientSet.put(client.session, new Entry(compressClient(client))); return true; } + private String compressClient(Client client) { + return Launcher.gsonManager.gson.toJson(client); //Compress using later + } + + private Client decompressClient(String client) { + return Launcher.gsonManager.gson.fromJson(client, Client.class); //Compress using later + } + private Client restoreFromString(String data) { + Client result = decompressClient(data); + result.updateAuth(server); + if(result.auth != null && (result.username != null)) { + if(result.auth.handler instanceof RequiredDAO || result.auth.provider instanceof RequiredDAO || result.auth.textureProvider instanceof RequiredDAO) { + result.daoObject = server.config.dao.userDAO.findByUsername(result.username); + } + } + + return result; + } + @Override public void garbageCollection() { long time = System.currentTimeMillis(); clientSet.entrySet().removeIf(entry -> { - Client c = entry.getValue(); - return (c.timestamp + SESSION_TIMEOUT < time); + long timestamp = entry.getValue().timestamp; + return (timestamp + SESSION_TIMEOUT < time); }); } public Client getClient(UUID session) { - return clientSet.get(session); + Entry e = clientSet.get(session); + if(e == null) return null; + return restoreFromString(e.data); } public Client getOrNewClient(UUID session) { - return clientSet.computeIfAbsent(session, Client::new); + Client client = getClient(session); + return client == null ? new Client(session) : client; } - public Client removeClient(UUID session) { - return clientSet.remove(session); + public void removeClient(UUID session) { + clientSet.remove(session); } public void updateClient(UUID session) { - Client c = clientSet.get(session); - if (c != null) { - c.up(); - return; - } - Client newClient = new Client(session); - clientSet.put(session, newClient); + LogHelper.warning("Using deprecated method: sessionManager.updateClient"); } public Set getSessions() { // TODO: removeme - return new HashSet<>(clientSet.values()); + LogHelper.warning("Using deprecated method: sessionManager.getSession"); + return new HashSet<>(); } public void loadSessions(Set set) { - clientSet.putAll(set.stream().collect(Collectors.toMap(c -> c.session, Function.identity()))); + LogHelper.warning("Using deprecated method: sessionManager.loadSessions"); + //clientSet.putAll(set.stream().collect(Collectors.toMap(c -> c.session, Function.identity()))); + } + private static class Entry { + public String data; + public long timestamp; + + public Entry(String data) { + this.data = data; + this.timestamp = System.currentTimeMillis(); + } } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/Client.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/Client.java index 1b5639d5..441ef732 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/Client.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/Client.java @@ -11,6 +11,7 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; public class Client { public UUID session; @@ -30,6 +31,8 @@ public class Client { public transient Map properties; + public transient AtomicInteger refCount = new AtomicInteger(1); + public Client(UUID session) { this.session = session; timestamp = System.currentTimeMillis(); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/WebSocketFrameHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/WebSocketFrameHandler.java index b8948f25..4406b39f 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/WebSocketFrameHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/WebSocketFrameHandler.java @@ -37,7 +37,9 @@ public Client getClient() { } public void setClient(Client client) { + if(this.client != null) this.client.refCount.decrementAndGet(); this.client = client; + if(client != null) client.refCount.incrementAndGet(); } public final UUID getConnectUUID() { @@ -85,6 +87,7 @@ protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) { } else if ((frame instanceof PongWebSocketFrame)) { LogHelper.dev("WebSocket Client received pong"); } else if ((frame instanceof CloseWebSocketFrame)) { + int statusCode = ((CloseWebSocketFrame) frame).statusCode(); ctx.channel().close(); } else { String message = "unsupported frame type: " + frame.getClass().getName(); @@ -95,6 +98,18 @@ protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) { @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { if (future != null) future.cancel(true); + if(LogHelper.isDevEnabled()) { + LogHelper.dev("Client %s disconnected", IOHelper.getIP(ctx.channel().remoteAddress())); + } + int refCount = client.refCount.decrementAndGet(); + if(client.session != null) { + if(refCount == 0) { + srv.sessionManager.addClient(client); + } + else if(refCount < 0) { + LogHelper.warning("Client session %s reference counter invalid - %d", client.session, refCount); + } + } super.channelInactive(ctx); } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AuthResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AuthResponse.java index 6465617a..d3dab518 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AuthResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AuthResponse.java @@ -100,7 +100,7 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti if (getSession) { if (clientData.session == null) { clientData.session = UUID.randomUUID(); - server.sessionManager.addClient(clientData); + //server.sessionManager.addClient(clientData); } result.session = clientData.session; } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RestoreSessionResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RestoreSessionResponse.java index f68aefb6..aed2765c 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RestoreSessionResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RestoreSessionResponse.java @@ -21,15 +21,28 @@ public String getType() { @Override public void execute(ChannelHandlerContext ctx, Client client) throws Exception { - Client rClient = server.sessionManager.getClient(session); - if (rClient == null) { + if(session == null) { + sendError("Session invalid"); + return; + } + final Client[] rClient = {null}; + service.forEachActiveChannels((channel, handler) -> { + Client c = handler.getClient(); + if(c != null && session.equals(c.session)) { + rClient[0] = c; + } + }); + if(rClient[0] == null) { + rClient[0] = server.sessionManager.getClient(session); + } + if (rClient[0] == null) { sendError("Session invalid"); return; } WebSocketFrameHandler frameHandler = ctx.pipeline().get(WebSocketFrameHandler.class); - frameHandler.setClient(rClient); + frameHandler.setClient(rClient[0]); if (needUserInfo) { - sendResult(new RestoreSessionRequestEvent(CurrentUserResponse.collectUserInfoFromClient(rClient))); + sendResult(new RestoreSessionRequestEvent(CurrentUserResponse.collectUserInfoFromClient(rClient[0]))); } else { sendResult(new RestoreSessionRequestEvent()); } From 94e60c3e51b8d90da483f9d39f1e191d5dd609a0 Mon Sep 17 00:00:00 2001 From: Gravit Date: Tue, 27 Oct 2020 20:13:31 +0700 Subject: [PATCH 06/31] [FIX] MemoryHWIDProvider --- .../launchserver/auth/protect/hwid/MemoryHWIDProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/hwid/MemoryHWIDProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/hwid/MemoryHWIDProvider.java index a4d679c7..5cc24c5b 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/hwid/MemoryHWIDProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/hwid/MemoryHWIDProvider.java @@ -84,11 +84,11 @@ public boolean addPublicKeyToHardwareInfo(HardwareReportRequest.HardwareInfo har for (MemoryHWIDEntity e : db) { HardwareInfoCompareResult result = compareHardwareInfo(e.hardware, hardwareInfo); if (warningSpoofingLevel > 0 && result.firstSpoofingLevel > warningSpoofingLevel && !isAlreadyWarning) { - LogHelper.warning("HardwareInfo spoofing level too high: %d", result.firstSpoofingLevel); + LogHelper.warning("HardwareInfo spoofing level too high: %f", result.firstSpoofingLevel); isAlreadyWarning = true; } if (result.compareLevel > criticalCompareLevel) { - LogHelper.debug("HardwareInfo publicKey change: compareLevel %d", result.compareLevel); + LogHelper.debug("HardwareInfo publicKey change: compareLevel %f", result.compareLevel); if (e.banned) throw new HWIDException("You HWID banned"); e.publicKey = publicKey; return true; From aee051627b1284a7c19e4d1f1c821665103740e5 Mon Sep 17 00:00:00 2001 From: Gravit Date: Wed, 28 Oct 2020 00:55:32 +0700 Subject: [PATCH 07/31] [FIX] NPE in SessionManager --- .../java/pro/gravit/launchserver/manangers/SessionManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java index 163e41c4..8741344a 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java @@ -9,6 +9,7 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.stream.Collectors; @@ -44,7 +45,7 @@ private Client restoreFromString(String data) { result.daoObject = server.config.dao.userDAO.findByUsername(result.username); } } - + if(result.refCount == null) result.refCount = new AtomicInteger(1); return result; } From fb5609b864be80e21d95d1087e6412860ff2a36f Mon Sep 17 00:00:00 2001 From: Gravit Date: Wed, 28 Oct 2020 01:55:08 +0700 Subject: [PATCH 08/31] [FIX] ClientProcessLaunchEvent --- .../pro/gravit/launcher/client/ClientLauncherEntryPoint.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java index b4d8550f..00001648 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java @@ -159,8 +159,7 @@ public static void main(String[] args) throws Throwable { verifyHDir(clientDir, params.clientHDir, clientMatcher, digest); if (javaWatcher != null) verifyHDir(javaDir, params.javaHDir, null, digest); - if (params.javaHDir != null) - LauncherEngine.modulesManager.invokeEvent(new ClientProcessLaunchEvent(engine, params)); + LauncherEngine.modulesManager.invokeEvent(new ClientProcessLaunchEvent(engine, params)); launch(profile, params); } } From 86d3b3365d3031bc31e931f82479b129e746ccf3 Mon Sep 17 00:00:00 2001 From: XuTpbl_JIuC Date: Tue, 3 Nov 2020 11:56:38 +0300 Subject: [PATCH 09/31] =?UTF-8?q?[FEATURE]=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5?= =?UTF-8?q?=D1=80=D0=B6=D0=BA=D0=B0=201.16.4=20(#420)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/pro/gravit/launcher/profiles/ClientProfile.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java index 7695fb7d..e5298443 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java @@ -428,7 +428,8 @@ public enum Version { MC1152("1.15.2", 578), MC1161("1.16.1", 736), MC1162("1.16.2", 751), - MC1163("1.16.3", 753); + MC1163("1.16.3", 753), + MC1164("1.16.4", 754); private static final Map VERSIONS; static { From 447866d001d9eaa52046b2f6deacd20baa4d3f4d Mon Sep 17 00:00:00 2001 From: Gravit Date: Sun, 8 Nov 2020 23:25:15 +0700 Subject: [PATCH 10/31] [FIX] daoObject null --- .../gravit/launchserver/auth/handler/HibernateAuthHandler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/handler/HibernateAuthHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/handler/HibernateAuthHandler.java index 62cf5fd6..0491e7c6 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/handler/HibernateAuthHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/handler/HibernateAuthHandler.java @@ -1,10 +1,11 @@ package pro.gravit.launchserver.auth.handler; +import pro.gravit.launchserver.auth.RequiredDAO; import pro.gravit.launchserver.dao.User; import java.util.UUID; -public class HibernateAuthHandler extends CachedAuthHandler { +public class HibernateAuthHandler extends CachedAuthHandler implements RequiredDAO { @Override protected Entry fetchEntry(String username) { User user = srv.config.dao.userDAO.findByUsername(username); From 0f8f51ea977cbe29a38ec0a736cd9a28291f97e7 Mon Sep 17 00:00:00 2001 From: Gravit Date: Sat, 21 Nov 2020 20:08:39 +0700 Subject: [PATCH 11/31] [FEATURE] SessionManager: uuidIndex --- .../config/LaunchServerConfig.java | 1 + .../manangers/SessionManager.java | 84 ++++++++++++++++--- .../gravit/launchserver/socket/Client.java | 1 + .../socket/response/auth/AuthResponse.java | 10 +-- .../response/auth/CurrentUserResponse.java | 2 +- .../socket/response/auth/ExitResponse.java | 4 +- 6 files changed, 84 insertions(+), 18 deletions(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java index bc450975..3c242394 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java @@ -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 { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java index 8741344a..fd14780c 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java @@ -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 clientSet = new ConcurrentHashMap<>(128); + private final Map> uuidIndex = new ConcurrentHashMap<>(32); private final LaunchServer server; + public HookSet 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 uuidSet = uuidIndex.computeIfAbsent(client.uuid, k -> ConcurrentHashMap.newKeySet()); + uuidSet.add(e); + } return true; } + public Stream findSessionsByUUID(UUID uuid) { + Set set = uuidIndex.get(uuid); + if(set != null) return set.stream().map((e) -> e.sessionUuid); + return null; + } + + public boolean removeByUUID(UUID uuid) { + Set set = uuidIndex.get(uuid); + if(set != null) { + for(Entry e : set) { + clientSet.remove(e.sessionUuid); + } + set.clear(); + uuidIndex.remove(uuid); + } + return false; + } + + public Set 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 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 set = uuidIndex.get(session); + if(set != null) { + removeUuidFromIndexSet(set, e, session); + } + return true; + } + return false; + } + + private void removeUuidFromIndexSet(Set 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 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(); } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/Client.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/Client.java index 441ef732..57113f14 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/Client.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/Client.java @@ -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; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AuthResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AuthResponse.java index d3dab518..6fd35b41 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AuthResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AuthResponse.java @@ -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); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/CurrentUserResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/CurrentUserResponse.java index 6d5cfd33..5aa7514c 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/CurrentUserResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/CurrentUserResponse.java @@ -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); } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java index 66d3cec1..1a32823e 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java @@ -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); From ae2ef5e7c2f7352fc2abeaafa91e81fa20104e60 Mon Sep 17 00:00:00 2001 From: xxDark <19853368+xxDark@users.noreply.github.com> Date: Sat, 21 Nov 2020 16:10:04 +0300 Subject: [PATCH 12/31] [FIX] Remove Xms to make peeps stop crying (#422) --- .../java/pro/gravit/launcher/client/ClientLauncherProcess.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java index 136b7400..8b05806a 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java @@ -103,7 +103,6 @@ private void applyClientProfile() { this.systemEnv.put("JAVA_HOME", javaDir.toString()); Collections.addAll(this.systemClassPath, this.params.profile.getAlternativeClassPath()); if (params.ram > 0) { - this.jvmArgs.add("-Xms" + params.ram + 'M'); this.jvmArgs.add("-Xmx" + params.ram + 'M'); } this.params.session = Request.getSession(); From 5e048905ccb75097dc73d32124ecbaeb9e69da29 Mon Sep 17 00:00:00 2001 From: Gravit Date: Sat, 21 Nov 2020 20:33:10 +0700 Subject: [PATCH 13/31] [FEATURE] Netty maxWebSocketRequestBytes --- .../java/pro/gravit/launchserver/config/LaunchServerConfig.java | 1 + .../pro/gravit/launchserver/socket/LauncherNettyServer.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java index 3c242394..8bd46f99 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java @@ -313,6 +313,7 @@ public static class NettyPerformanceConfig { public int bossThread; public int workerThread; public long sessionLifetimeMs = 24 * 60 * 60 * 1000; + public int maxWebSocketRequestBytes = 1024 * 1024; } public static class NettyBindAddress { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java index 668df90d..f6af5b05 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java @@ -56,7 +56,7 @@ public void initChannel(SocketChannel ch) { NettyConnectContext context = new NettyConnectContext(); //p.addLast(new LoggingHandler(LogLevel.INFO)); pipeline.addLast("http-codec", new HttpServerCodec()); - pipeline.addLast("http-codec-compressor", new HttpObjectAggregator(65536)); + pipeline.addLast("http-codec-compressor", new HttpObjectAggregator(server.config.netty.performance.maxWebSocketRequestBytes)); if (server.config.netty.ipForwarding) pipeline.addLast("forward-http", new NettyIpForwardHandler(context)); pipeline.addLast("websock-comp", new WebSocketServerCompressionHandler()); From 2688270fa07f2f67b1f138f68eda61bc8e284466 Mon Sep 17 00:00:00 2001 From: Gravit Date: Sat, 21 Nov 2020 21:30:21 +0700 Subject: [PATCH 14/31] [FEATURE] Advanced Client API --- .../command/service/ClientsCommand.java | 6 ++ .../launchserver/socket/WebSocketService.java | 90 ++++++++++++++++++- 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java index 63e68d1b..d3e004e6 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java @@ -8,6 +8,8 @@ import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.LogHelper; +import java.util.Base64; + public class ClientsCommand extends Command { public ClientsCommand(LaunchServer server) { super(server); @@ -34,8 +36,12 @@ public void invoke(String... args) { LogHelper.info("Channel %s | connectUUID %s | checkSign %s", ip, frameHandler.getConnectUUID(), client.checkSign ? "true" : "false"); else { LogHelper.info("Client name %s | ip %s | connectUUID %s", client.username == null ? "null" : client.username, ip, frameHandler.getConnectUUID()); + LogHelper.subInfo("userUUID: %s | session %s", client.uuid == null ? "null" : client.uuid.toString(), client.session == null ? "null" : client.session); LogHelper.subInfo("Data: checkSign %s | auth_id %s", client.checkSign ? "true" : "false", client.auth_id); + if(client.trustLevel != null) { + LogHelper.subInfo("trustLevel | key %s | pubkey %s", client.trustLevel.keyChecked ? "checked" : "unchecked", client.trustLevel.publicKey == null ? "null" : Base64.getEncoder().encode(client.trustLevel.publicKey)); + } LogHelper.subInfo("Permissions: %s (permissions %d | flags %d)", client.permissions == null ? "null" : client.permissions.toString(), client.permissions == null ? 0 : client.permissions.permissions, client.permissions == null ? 0 : client.permissions.flags); } })); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java index 41588e9e..79c24113 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java @@ -11,8 +11,10 @@ import pro.gravit.launcher.events.ExceptionEvent; import pro.gravit.launcher.events.RequestEvent; import pro.gravit.launcher.events.request.ErrorRequestEvent; +import pro.gravit.launcher.events.request.ExitRequestEvent; import pro.gravit.launcher.request.WebSocketEvent; import pro.gravit.launchserver.LaunchServer; +import pro.gravit.launchserver.dao.User; import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler; import pro.gravit.launchserver.socket.response.SimpleResponse; import pro.gravit.launchserver.socket.response.WebSocketServerResponse; @@ -36,8 +38,10 @@ import pro.gravit.utils.helper.LogHelper; import java.lang.reflect.Type; +import java.util.UUID; import java.util.concurrent.atomic.AtomicLong; import java.util.function.BiConsumer; +import java.util.function.Consumer; public class WebSocketService { public static final ProviderMap providers = new ProviderMap<>(); @@ -68,12 +72,12 @@ public WebSocketService(ChannelGroup channels, LaunchServer server) { } public void forEachActiveChannels(BiConsumer callback) { - channels.forEach((channel) -> { + for(Channel channel : channels) { if (channel == null || channel.pipeline() == null) return; WebSocketFrameHandler wsHandler = channel.pipeline().get(WebSocketFrameHandler.class); if (wsHandler == null) return; callback.accept(channel, wsHandler); - }); + }; } public static void registerResponses() { @@ -208,6 +212,88 @@ public void sendObjectAll(Object obj, Type type) { } } + public void sendObjectToUUID(UUID userUuid, Object obj, Type type) { + for (Channel ch : channels) { + if (ch == null || ch.pipeline() == null) continue; + WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class); + if (wsHandler == null) continue; + Client client = wsHandler.getClient(); + if(client == null || !userUuid.equals(client.uuid)) continue; + ch.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type)), ch.voidPromise()); + } + } + + public void updateDaoObject(UUID userUuid, User daoObject, Consumer callback) { + for(Channel ch : channels) { + if (ch == null || ch.pipeline() == null) continue; + WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class); + if (wsHandler == null) continue; + Client client = wsHandler.getClient(); + if(client == null || client.daoObject == null || !userUuid.equals(client.uuid)) continue; + client.daoObject = daoObject; + if(callback != null) callback.accept(ch); + } + } + + public Channel getChannelFromConnectUUID(UUID connectUuid) { + for(Channel ch : channels) { + if (ch == null || ch.pipeline() == null) continue; + WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class); + if (wsHandler == null) continue; + if(connectUuid.equals(wsHandler.getConnectUUID())) { + return ch; + } + } + return null; + } + + public boolean kickByUserUUID(UUID userUuid, boolean isClose) { + boolean result = false; + for(Channel ch : channels) { + if (ch == null || ch.pipeline() == null) continue; + WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class); + if (wsHandler == null) continue; + Client client = wsHandler.getClient(); + if(client == null || client.daoObject == null || !userUuid.equals(client.uuid)) continue; + ExitResponse.exit(server, wsHandler, ch, ExitRequestEvent.ExitReason.SERVER); + if(isClose) ch.close(); + result = true; + } + return result; + } + + public boolean kickByConnectUUID(UUID connectUuid, boolean isClose) { + for(Channel ch : channels) { + if (ch == null || ch.pipeline() == null) continue; + WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class); + if (wsHandler == null) continue; + if(connectUuid.equals(wsHandler.getConnectUUID())) { + ExitResponse.exit(server, wsHandler, ch, ExitRequestEvent.ExitReason.SERVER); + if(isClose) ch.close(); + return true; + } + } + return false; + } + + public boolean kickByIP(String ip, boolean isClose) { + boolean result = false; + for(Channel ch : channels) { + if (ch == null || ch.pipeline() == null) continue; + WebSocketFrameHandler wsHandler = ch.pipeline().get(WebSocketFrameHandler.class); + if(wsHandler == null) continue; + String clientIp; + if(wsHandler.context != null && wsHandler.context.ip != null) clientIp = wsHandler.context.ip; + else clientIp = IOHelper.getIP(ch.remoteAddress()); + if(ip.equals(clientIp)) { + ExitResponse.exit(server, wsHandler, ch, ExitRequestEvent.ExitReason.SERVER); + if(isClose) ch.close(); + result = true; + } + } + return result; + } + public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj) { ctx.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, WebSocketEvent.class))).addListener(ChannelFutureListener.CLOSE); } From 06aa6976e0edf5671591e64374ad704d3aed0b15 Mon Sep 17 00:00:00 2001 From: Gravit Date: Sun, 22 Nov 2020 16:09:54 +0700 Subject: [PATCH 15/31] [FIX] Small fixes --- .../launchserver/command/service/SecurityCheckCommand.java | 6 ++++-- .../java/pro/gravit/launcher/profiles/ClientProfile.java | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/SecurityCheckCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/SecurityCheckCommand.java index fea875b8..30b83662 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/SecurityCheckCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/SecurityCheckCommand.java @@ -158,8 +158,10 @@ public void invoke(String... args) throws Exception { if (tokenizer.hasMoreTokens() && tokenizer.nextToken().equals("mods")) { String nextToken = tokenizer.nextToken(); if (!tokenizer.hasMoreTokens()) { - printCheckResult(LogHelper.Level.INFO, profileModuleName, String.format("updateExclusions %s not safe. Cheats may be injected very easy!", exc), false); - bad = true; + if(!exc.endsWith("/")) { + printCheckResult(LogHelper.Level.INFO, profileModuleName, String.format("updateExclusions %s not safe. Cheats may be injected very easy!", exc), false); + bad = true; + } } else { if (nextToken.equals("memory_repo") || nextToken.equals(profile.getVersion().name)) { printCheckResult(LogHelper.Level.INFO, profileModuleName, String.format("updateExclusions %s not safe. Cheats may be injected very easy!", exc), false); diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java index e5298443..1c0f8e99 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java @@ -352,8 +352,6 @@ public void verify() { // Client VerifyHelper.verify(getTitle(), VerifyHelper.NOT_EMPTY, "Profile title can't be empty"); VerifyHelper.verify(getInfo(), VerifyHelper.NOT_EMPTY, "Profile info can't be empty"); - VerifyHelper.verify(getServerAddress(), VerifyHelper.NOT_EMPTY, "Server address can't be empty"); - VerifyHelper.verifyInt(getServerPort(), VerifyHelper.range(0, 65535), "Illegal server port: " + getServerPort()); // Client launcher VerifyHelper.verify(getTitle(), VerifyHelper.NOT_EMPTY, "Main class can't be empty"); From f971356955047b26969cc8a610c2ef1665b2e513 Mon Sep 17 00:00:00 2001 From: Gravit Date: Sun, 22 Nov 2020 17:33:37 +0700 Subject: [PATCH 16/31] [FEATURE] pingServersCommand --- .../command/handler/CommandHandler.java | 1 + .../command/service/PingServersCommand.java | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/command/service/PingServersCommand.java diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java index 78b75119..cbda2b48 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java @@ -78,6 +78,7 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand service.registerCommand("clients", new ClientsCommand(server)); service.registerCommand("signJar", new SignJarCommand(server)); service.registerCommand("signDir", new SignDirCommand(server)); + service.registerCommand("pingServers", new PingServersCommand(server)); service.registerCommand("securitycheck", new SecurityCheckCommand(server)); Category serviceCategory = new Category(service, "service", "Managing LaunchServer Components"); handler.registerCategory(serviceCategory); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/PingServersCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/PingServersCommand.java new file mode 100644 index 00000000..1181391b --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/PingServersCommand.java @@ -0,0 +1,36 @@ +package pro.gravit.launchserver.command.service; + +import pro.gravit.launcher.request.management.PingServerReportRequest; +import pro.gravit.launchserver.LaunchServer; +import pro.gravit.launchserver.command.Command; +import pro.gravit.utils.helper.LogHelper; + +public class PingServersCommand extends Command { + public PingServersCommand(LaunchServer server) { + super(server); + } + + @Override + public String getArgsDescription() { + return "[]"; + } + + @Override + public String getUsageDescription() { + return "show modern pings status"; + } + + @Override + public void invoke(String... args) throws Exception { + server.pingServerManager.map.forEach((name, data) -> { + LogHelper.info("[%s] online %d / %d", name, data.lastReport == null ? -1 : data.lastReport.playersOnline, data.lastReport == null ? -1 : data.lastReport.maxPlayers); + if(data.lastReport != null && data.lastReport.users != null) + { + for(PingServerReportRequest.PingServerReport.UsernameInfo user : data.lastReport.users) + { + LogHelper.subInfo("User %s", user.username == null ? "null" : user.username); + } + } + }); + } +} From 08b23db5c6f14edbed59d47e1f1bac335661d256 Mon Sep 17 00:00:00 2001 From: Gravit Date: Mon, 23 Nov 2020 22:30:04 +0700 Subject: [PATCH 17/31] [FIX] Small fix --- .../java/pro/gravit/launchserver/socket/WebSocketService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java index 79c24113..71c5da51 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java @@ -73,9 +73,9 @@ public WebSocketService(ChannelGroup channels, LaunchServer server) { public void forEachActiveChannels(BiConsumer callback) { for(Channel channel : channels) { - if (channel == null || channel.pipeline() == null) return; + if (channel == null || channel.pipeline() == null) continue; WebSocketFrameHandler wsHandler = channel.pipeline().get(WebSocketFrameHandler.class); - if (wsHandler == null) return; + if (wsHandler == null) continue; callback.accept(channel, wsHandler); }; } From c24b74ab912d266f7a83007fdf0aeeb519ab75c0 Mon Sep 17 00:00:00 2001 From: Gravit Date: Tue, 1 Dec 2020 16:12:16 +0700 Subject: [PATCH 18/31] Create codeql-analysis.yml (#423) * Create codeql-analysis.yml * Update codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000..d25b94bc --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,70 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ master, dev ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master, dev ] + schedule: + - cron: '28 4 * * 0' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'java' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From acf2d2d9cd4ccd11e09da4a30f92df4173e885b4 Mon Sep 17 00:00:00 2001 From: KR33PY <75280223+KR33PY@users.noreply.github.com> Date: Tue, 1 Dec 2020 15:44:16 +0300 Subject: [PATCH 19/31] =?UTF-8?q?[FIX]=20NPE=20=D0=B2=20BatchProfileByUser?= =?UTF-8?q?nameRequest=20(#424)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../launcher/request/uuid/BatchProfileByUsernameRequest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/uuid/BatchProfileByUsernameRequest.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/uuid/BatchProfileByUsernameRequest.java index f1038f48..b120341c 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/uuid/BatchProfileByUsernameRequest.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/uuid/BatchProfileByUsernameRequest.java @@ -16,6 +16,7 @@ public final class BatchProfileByUsernameRequest extends Request Date: Tue, 15 Dec 2020 19:27:38 +0700 Subject: [PATCH 20/31] [ANY] New Sessions system completed --- .../pro/gravit/launchserver/LaunchServer.java | 6 +- .../auth/session/MemorySessionStorage.java | 108 ++++++++++++++++++ .../auth/session/SessionStorage.java | 26 +++++ .../command/dump/DumpSessionsCommand.java | 67 ----------- .../command/handler/CommandHandler.java | 7 -- .../command/service/ServerStatusCommand.java | 2 +- .../config/LaunchServerConfig.java | 18 +-- .../manangers/LaunchServerGsonManager.java | 2 + .../manangers/SessionManager.java | 91 +++------------ modules | 2 +- 10 files changed, 171 insertions(+), 158 deletions(-) create mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/MemorySessionStorage.java create mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/SessionStorage.java delete mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/command/dump/DumpSessionsCommand.java diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java index e4f23832..2a7d58b8 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java @@ -10,6 +10,7 @@ import pro.gravit.launcher.modules.events.ClosePhase; import pro.gravit.launcher.profiles.ClientProfile; import pro.gravit.launchserver.auth.AuthProviderPair; +import pro.gravit.launchserver.auth.session.MemorySessionStorage; import pro.gravit.launchserver.binary.*; import pro.gravit.launchserver.config.LaunchServerConfig; import pro.gravit.launchserver.config.LaunchServerRuntimeConfig; @@ -128,6 +129,7 @@ public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, La runtime.verify(); config.verify(); + if(config.sessions == null) config.sessions = new MemorySessionStorage(); if (config.components != null) { LogHelper.debug("PreInit components"); config.components.forEach((k, v) -> { @@ -147,7 +149,8 @@ public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, La pingServerManager = new PingServerManager(this); //Generate or set new Certificate API certificateManager.orgName = config.projectName; - if (config.certificate != null && config.certificate.enabled) { + /* + if (false) { if (IOHelper.isFile(caCertFile) && IOHelper.isFile(caKeyFile)) { certificateManager.ca = certificateManager.readCertificate(caCertFile); certificateManager.caKey = certificateManager.readPrivateKey(caKeyFile); @@ -175,6 +178,7 @@ public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, La } } } + */ config.init(ReloadType.FULL); registerObject("launchServer", this); GarbageManager.registerNeedGC(sessionManager); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/MemorySessionStorage.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/MemorySessionStorage.java new file mode 100644 index 00000000..bb1043d9 --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/MemorySessionStorage.java @@ -0,0 +1,108 @@ +package pro.gravit.launchserver.auth.session; + +import pro.gravit.launcher.NeedGarbageCollection; +import pro.gravit.launchserver.manangers.SessionManager; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Stream; + +public class MemorySessionStorage extends SessionStorage implements NeedGarbageCollection { + + private final Map clientSet = new ConcurrentHashMap<>(128); + private final Map> uuidIndex = new ConcurrentHashMap<>(32); + + @Override + public byte[] getSessionData(UUID session) { + + Entry e = clientSet.get(session); + if(e == null) return null; + return e.data; + } + + @Override + public Stream getSessionsFromUserUUID(UUID userUUID) { + Set set = uuidIndex.get(userUUID); + if(set != null) return set.stream().map((e) -> e.sessionUuid); + return null; + } + + @Override + public boolean writeSession(UUID userUUID, UUID sessionUUID, byte[] data) { + deleteSession(sessionUUID); + Entry e = new Entry(data, sessionUUID); + clientSet.put(sessionUUID, e); + if(userUUID != null) { + Set uuidSet = uuidIndex.computeIfAbsent(userUUID, k -> ConcurrentHashMap.newKeySet()); + uuidSet.add(e); + } + return false; + } + + @Override + public boolean deleteSession(UUID sessionUUID) { + Entry e =clientSet.remove(sessionUUID); + if(e != null) { + Set set = uuidIndex.get(sessionUUID); + if(set != null) { + removeUuidFromIndexSet(set, e, sessionUUID); + } + return true; + } + return false; + } + + @Override + public boolean deleteSessionsByUserUUID(UUID userUUID) { + Set set = uuidIndex.get(userUUID); + if(set != null) { + for(Entry e : set) { + clientSet.remove(e.sessionUuid); + } + set.clear(); + uuidIndex.remove(userUUID); + } + return true; + } + + @Override + public void clear() { + clientSet.clear(); + uuidIndex.clear(); + } + + private void removeUuidFromIndexSet(Set set, Entry e, UUID session) { + set.remove(e); + if(set.isEmpty()) { + uuidIndex.remove(session); + } + } + + @Override + public void garbageCollection() { + long time = System.currentTimeMillis(); + long session_timeout = server.config.netty.performance.sessionLifetimeMs; + Set 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) { + deleteSession(session); + } + to_delete.clear(); + } + + private static class Entry { + public byte[] data; + public UUID sessionUuid; + public long timestamp; + + public Entry(byte[] data, UUID sessionUuid) { + this.data = data; + this.sessionUuid = sessionUuid; + this.timestamp = System.currentTimeMillis(); + } + } +} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/SessionStorage.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/SessionStorage.java new file mode 100644 index 00000000..463b7a60 --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/SessionStorage.java @@ -0,0 +1,26 @@ +package pro.gravit.launchserver.auth.session; + +import pro.gravit.launchserver.LaunchServer; +import pro.gravit.utils.ProviderMap; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Stream; + +public abstract class SessionStorage { + protected transient LaunchServer server; + public static ProviderMap providers = new ProviderMap<>(); + public abstract byte[] getSessionData(UUID session); + public abstract Stream getSessionsFromUserUUID(UUID userUUID); + public abstract boolean writeSession(UUID userUUID, UUID sessionUUID, byte[] data); + public abstract boolean deleteSession(UUID sessionUUID); + public boolean deleteSessionsByUserUUID(UUID userUUID) { + getSessionsFromUserUUID(userUUID).forEach(this::deleteSession); + return true; + } + public abstract void clear(); + public void init(LaunchServer server) + { + this.server = server; + } +} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/dump/DumpSessionsCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/dump/DumpSessionsCommand.java deleted file mode 100644 index 4eff81ff..00000000 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/dump/DumpSessionsCommand.java +++ /dev/null @@ -1,67 +0,0 @@ -package pro.gravit.launchserver.command.dump; - -import com.google.gson.reflect.TypeToken; -import pro.gravit.launcher.Launcher; -import pro.gravit.launchserver.LaunchServer; -import pro.gravit.launchserver.command.Command; -import pro.gravit.launchserver.socket.Client; -import pro.gravit.utils.command.SubCommand; -import pro.gravit.utils.helper.IOHelper; -import pro.gravit.utils.helper.LogHelper; - -import java.io.Reader; -import java.io.Writer; -import java.lang.reflect.Type; -import java.nio.file.Paths; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -public class DumpSessionsCommand extends Command { - public DumpSessionsCommand(LaunchServer server) { - super(server); - childCommands.put("load", new SubCommand() { - @Override - public void invoke(String... args) throws Exception { - verifyArgs(args, 1); - LogHelper.info("Sessions read from %s", args[0]); - int size; - try (Reader reader = IOHelper.newReader(Paths.get(args[0]))) { - Type setType = new TypeToken>() { - }.getType(); - Set clientSet = Launcher.gsonManager.configGson.fromJson(reader, setType); - size = clientSet.size(); - server.sessionManager.loadSessions(clientSet); - } - LogHelper.subInfo("Readed %d sessions", size); - } - }); - childCommands.put("unload", new SubCommand() { - @Override - public void invoke(String... args) throws Exception { - verifyArgs(args, 1); - LogHelper.info("Sessions write to %s", args[0]); - Collection clientSet = server.sessionManager.getSessions(); - try (Writer writer = IOHelper.newWriter(Paths.get(args[0]))) { - Launcher.gsonManager.configGson.toJson(clientSet, writer); - } - LogHelper.subInfo("Write %d sessions", clientSet.size()); - } - }); - } - - @Override - public String getArgsDescription() { - return "[load/unload] [filename]"; - } - - @Override - public String getUsageDescription() { - return "Load or unload sessions"; - } - - @Override - public void invoke(String... args) throws Exception { - invokeSubcommands(args); - } -} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java index cbda2b48..d001f466 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java @@ -5,7 +5,6 @@ import pro.gravit.launchserver.command.auth.UUIDToUsernameCommand; import pro.gravit.launchserver.command.auth.UsernameToUUIDCommand; import pro.gravit.launchserver.command.basic.*; -import pro.gravit.launchserver.command.dump.DumpSessionsCommand; import pro.gravit.launchserver.command.hash.*; import pro.gravit.launchserver.command.install.CheckInstallCommand; import pro.gravit.launchserver.command.install.MultiCommand; @@ -61,12 +60,6 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand Category authCategory = new Category(auth, "auth", "User Management"); handler.registerCategory(authCategory); - //Register dump commands - BaseCommandCategory dump = new BaseCommandCategory(); - dump.registerCommand("dumpSessions", new DumpSessionsCommand(server)); - Category dumpCategory = new Category(dump, "dump", "Dump runtime data"); - handler.registerCategory(dumpCategory); - //Register service commands BaseCommandCategory service = new BaseCommandCategory(); service.registerCommand("config", new ConfigCommand(server)); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ServerStatusCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ServerStatusCommand.java index f7c1b9cd..bc0aef04 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ServerStatusCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ServerStatusCommand.java @@ -38,7 +38,7 @@ public void invoke(String... args) { for (CommandHandler.Category category : server.commandHandler.getCategories()) { commands += category.category.commandsMap().size(); } - LogHelper.info("Sessions: %d | Commands: %d(%d categories)", server.sessionManager.getSessions().size(), commands, server.commandHandler.getCategories().size() + 1); + LogHelper.info("Commands: %d(%d categories)", commands, server.commandHandler.getCategories().size() + 1); for (AuthProviderPair pair : server.config.auth.values()) { if (pair.handler instanceof CachedAuthHandler) { LogHelper.info("AuthHandler %s: EntryCache: %d | usernameCache: %d", pair.name, ((CachedAuthHandler) pair.handler).getEntryCache().size(), ((CachedAuthHandler) pair.handler).getUsernamesCache().size()); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java index 8bd46f99..170cc4c4 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java @@ -10,6 +10,8 @@ import pro.gravit.launchserver.auth.protect.ProtectHandler; import pro.gravit.launchserver.auth.protect.StdProtectHandler; import pro.gravit.launchserver.auth.provider.RejectAuthProvider; +import pro.gravit.launchserver.auth.session.MemorySessionStorage; +import pro.gravit.launchserver.auth.session.SessionStorage; import pro.gravit.launchserver.auth.texture.RequestTextureProvider; import pro.gravit.launchserver.binary.tasks.exe.Launch4JTask; import pro.gravit.launchserver.components.AuthLimiterComponent; @@ -33,6 +35,7 @@ public final class LaunchServerConfig { public LauncherConfig.LauncherEnvironment env; public Map auth; public DaoProvider dao; + public SessionStorage sessions; // Handlers & Providers public ProtectHandler protectHandler; @@ -40,7 +43,6 @@ public final class LaunchServerConfig { public ExeConf launch4j; public NettyConfig netty; public LauncherConf launcher; - public CertificateConf certificate; public JarSignerConf sign; public String startScript; private transient LaunchServer server = null; @@ -71,6 +73,7 @@ public static LaunchServerConfig getDefault(LaunchServer.LaunchServerEnv env) { a.displayName = "Default"; newConfig.auth.put("std", a); newConfig.protectHandler = new StdProtectHandler(); + newConfig.sessions = new MemorySessionStorage(); newConfig.binaryName = "Launcher"; newConfig.netty = new NettyConfig(); @@ -97,8 +100,6 @@ public static LaunchServerConfig getDefault(LaunchServer.LaunchServerEnv env) { newConfig.launcher.stripLineNumbers = true; newConfig.launcher.proguardGenMappings = true; - newConfig.certificate = new LaunchServerConfig.CertificateConf(); - newConfig.certificate.enabled = false; newConfig.sign = new JarSignerConf(); newConfig.components = new HashMap<>(); @@ -187,6 +188,10 @@ public void init(LaunchServer.ReloadType type) { protectHandler.init(server); protectHandler.checkLaunchServerLicense(); } + if(sessions != null) { + sessions.init(server); + server.registerObject("sessions", sessions); + } if (components != null) { components.forEach((k, v) -> server.registerObject("component.".concat(k), v)); } @@ -229,6 +234,9 @@ public void close(LaunchServer.ReloadType type) { server.unregisterObject("protectHandler", protectHandler); protectHandler.close(); } + if(sessions != null) { + server.unregisterObject("sessions", sessions); + } if (dao != null) { server.unregisterObject("dao", dao); if (dao instanceof AutoCloseable) { @@ -260,10 +268,6 @@ public static class ExeConf { public String txtProductVersion; } - public static class CertificateConf { - public boolean enabled; - } - public static class JarSignerConf { public boolean enabled = false; public String keyStore = "pathToKey"; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/LaunchServerGsonManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/LaunchServerGsonManager.java index b4d3d9c8..1cdf41e1 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/LaunchServerGsonManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/LaunchServerGsonManager.java @@ -11,6 +11,7 @@ import pro.gravit.launchserver.auth.protect.ProtectHandler; import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider; import pro.gravit.launchserver.auth.provider.AuthProvider; +import pro.gravit.launchserver.auth.session.SessionStorage; import pro.gravit.launchserver.auth.texture.TextureProvider; import pro.gravit.launchserver.components.Component; import pro.gravit.launchserver.dao.provider.DaoProvider; @@ -41,6 +42,7 @@ public void registerAdapters(GsonBuilder builder) { builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers)); builder.registerTypeAdapter(HWIDProvider.class, new UniversalJsonAdapter<>(HWIDProvider.providers)); builder.registerTypeAdapter(OptionalAction.class, new UniversalJsonAdapter<>(OptionalAction.providers)); + builder.registerTypeAdapter(SessionStorage.class, new UniversalJsonAdapter<>(SessionStorage.providers)); modulesManager.invokeEvent(new PreGsonPhase(builder)); //ClientWebSocketService.appendTypeAdapters(builder); } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java index fd14780c..d6066868 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java @@ -8,6 +8,7 @@ import pro.gravit.utils.HookSet; import pro.gravit.utils.helper.LogHelper; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; @@ -15,8 +16,6 @@ public class SessionManager implements NeedGarbageCollection { - private final Map clientSet = new ConcurrentHashMap<>(128); - private final Map> uuidIndex = new ConcurrentHashMap<>(32); private final LaunchServer server; public HookSet clientRestoreHook = new HookSet<>(); @@ -27,52 +26,35 @@ public SessionManager(LaunchServer server) { public boolean addClient(Client 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 uuidSet = uuidIndex.computeIfAbsent(client.uuid, k -> ConcurrentHashMap.newKeySet()); - uuidSet.add(e); - } - return true; + return server.config.sessions.writeSession(client.uuid, client.session, compressClient(client)); } public Stream findSessionsByUUID(UUID uuid) { - Set set = uuidIndex.get(uuid); - if(set != null) return set.stream().map((e) -> e.sessionUuid); - return null; + return server.config.sessions.getSessionsFromUserUUID(uuid); } public boolean removeByUUID(UUID uuid) { - Set set = uuidIndex.get(uuid); - if(set != null) { - for(Entry e : set) { - clientSet.remove(e.sessionUuid); - } - set.clear(); - uuidIndex.remove(uuid); - } - return false; + return server.config.sessions.deleteSessionsByUserUUID(uuid); } + @Deprecated public Set getSavedUUIDs() { - return uuidIndex.keySet(); + throw new UnsupportedOperationException(); } public void clear() { - clientSet.clear(); - uuidIndex.clear(); + server.config.sessions.clear(); } - private String compressClient(Client client) { - return Launcher.gsonManager.gson.toJson(client); //Compress using later + private byte[] compressClient(Client client) { + return Launcher.gsonManager.gson.toJson(client).getBytes(StandardCharsets.UTF_8); //Compress using later } - private Client decompressClient(String client) { - return Launcher.gsonManager.gson.fromJson(client, Client.class); //Compress using later + private Client decompressClient(byte[] client) { + return Launcher.gsonManager.gson.fromJson(new String(client, StandardCharsets.UTF_8), Client.class); //Compress using later } - private Client restoreFromString(String data) { + private Client restoreFromString(byte[] data) { Client result = decompressClient(data); result.updateAuth(server); if(result.auth != null && (result.username != null)) { @@ -87,25 +69,11 @@ private Client restoreFromString(String data) { @Override public void garbageCollection() { - long time = System.currentTimeMillis(); - long session_timeout = server.config.netty.performance.sessionLifetimeMs; - Set 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(); } public Client getClient(UUID session) { - Entry e = clientSet.get(session); - if(e == null) return null; - return restoreFromString(e.data); + return restoreFromString(server.config.sessions.getSessionData(session)); } @@ -115,52 +83,27 @@ public Client getOrNewClient(UUID session) { } public boolean remove(UUID session) { - Entry e =clientSet.remove(session); - if(e != null) { - Set set = uuidIndex.get(session); - if(set != null) { - removeUuidFromIndexSet(set, e, session); - } - return true; - } - return false; + return server.config.sessions.deleteSession(session); } - private void removeUuidFromIndexSet(Set set, Entry e, UUID session) { - set.remove(e); - if(set.isEmpty()) { - uuidIndex.remove(session); - } - } @Deprecated public void removeClient(UUID session) { remove(session); } - + @Deprecated public void updateClient(UUID session) { LogHelper.warning("Using deprecated method: sessionManager.updateClient"); } + @Deprecated public Set getSessions() { - // TODO: removeme LogHelper.warning("Using deprecated method: sessionManager.getSession"); return new HashSet<>(); } - + @Deprecated public void loadSessions(Set set) { LogHelper.warning("Using deprecated method: sessionManager.loadSessions"); //clientSet.putAll(set.stream().collect(Collectors.toMap(c -> c.session, Function.identity()))); } - private static class Entry { - public String data; - public UUID sessionUuid; - public long timestamp; - - public Entry(String data, UUID sessionUuid) { - this.data = data; - this.sessionUuid = sessionUuid; - this.timestamp = System.currentTimeMillis(); - } - } } diff --git a/modules b/modules index e990b35b..5c4f6850 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit e990b35b4001e29793b383dfa7b179aa0b27b307 +Subproject commit 5c4f6850bd4feeee0caff5561564b7e54bb94774 From aced575921e691458a7ef4bfeaaae80ea079d425 Mon Sep 17 00:00:00 2001 From: Gravita Date: Wed, 16 Dec 2020 14:07:46 +0700 Subject: [PATCH 21/31] [FIX] SessionManager NPE --- .../pro/gravit/launchserver/manangers/SessionManager.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java index d6066868..92c2a7d2 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java @@ -73,7 +73,10 @@ public void garbageCollection() { public Client getClient(UUID session) { - return restoreFromString(server.config.sessions.getSessionData(session)); + if(session == null) return null; + byte[] data = server.config.sessions.getSessionData(session); + if(data == null) return null; + return restoreFromString(data); } From 62c8ca878e598bb8e001fc608e33aa54352a3d33 Mon Sep 17 00:00:00 2001 From: Gravita Date: Thu, 17 Dec 2020 01:39:24 +0700 Subject: [PATCH 22/31] [FIX] SessionStorage NPE --- .../java/pro/gravit/launchserver/LaunchServerStarter.java | 2 ++ .../gravit/launchserver/auth/session/SessionStorage.java | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServerStarter.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServerStarter.java index 7e012dfe..8c49e94b 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServerStarter.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServerStarter.java @@ -10,6 +10,7 @@ import pro.gravit.launchserver.auth.protect.ProtectHandler; import pro.gravit.launchserver.auth.protect.hwid.HWIDProvider; import pro.gravit.launchserver.auth.provider.AuthProvider; +import pro.gravit.launchserver.auth.session.SessionStorage; import pro.gravit.launchserver.auth.texture.TextureProvider; import pro.gravit.launchserver.components.Component; import pro.gravit.launchserver.config.LaunchServerConfig; @@ -215,6 +216,7 @@ public static void registerAll() { AuthRequest.registerProviders(); HWIDProvider.registerProviders(); OptionalAction.registerProviders(); + SessionStorage.registerProviders(); } public static void generateConfigIfNotExists(Path configFile, CommandHandler commandHandler, LaunchServer.LaunchServerEnv env) throws IOException { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/SessionStorage.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/SessionStorage.java index 463b7a60..e576c07f 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/SessionStorage.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/SessionStorage.java @@ -10,6 +10,7 @@ public abstract class SessionStorage { protected transient LaunchServer server; public static ProviderMap providers = new ProviderMap<>(); + private static boolean registeredProviders = false; public abstract byte[] getSessionData(UUID session); public abstract Stream getSessionsFromUserUUID(UUID userUUID); public abstract boolean writeSession(UUID userUUID, UUID sessionUUID, byte[] data); @@ -23,4 +24,10 @@ public void init(LaunchServer server) { this.server = server; } + public static void registerProviders() { + if(!registeredProviders) { + providers.register("memory", MemorySessionStorage.class); + registeredProviders = true; + } + } } From ce70cab736cbb1f31072edff4324811e81276000 Mon Sep 17 00:00:00 2001 From: Gravita Date: Thu, 17 Dec 2020 17:52:25 +0700 Subject: [PATCH 23/31] [FEATURE] serverName in ServerWrapper --- .../gravit/launcher/server/ServerWrapper.java | 34 +++++++++++++------ .../server/setup/ServerWrapperSetup.java | 6 ++-- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java b/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java index 1b4edb25..e590f7bf 100644 --- a/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java +++ b/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java @@ -4,10 +4,12 @@ import pro.gravit.launcher.Launcher; import pro.gravit.launcher.LauncherConfig; import pro.gravit.launcher.config.JsonConfigurable; +import pro.gravit.launcher.events.request.AuthRequestEvent; import pro.gravit.launcher.events.request.ProfilesRequestEvent; import pro.gravit.launcher.modules.events.PostInitPhase; import pro.gravit.launcher.modules.events.PreConfigPhase; import pro.gravit.launcher.profiles.ClientProfile; +import pro.gravit.launcher.profiles.PlayerProfile; import pro.gravit.launcher.profiles.optional.actions.OptionalAction; import pro.gravit.launcher.request.Request; import pro.gravit.launcher.request.RequestException; @@ -46,6 +48,8 @@ public class ServerWrapper extends JsonConfigurable { public ClassLoader loader; public ClientPermissions permissions; public ClientProfile profile; + public PlayerProfile playerProfile; + public ClientProfile.ServerProfile serverProfile; public ServerWrapper(Type type, Path configPath) { super(type, configPath); @@ -70,20 +74,28 @@ public boolean auth() { try { Launcher.getConfig(); AuthRequest request = new AuthRequest(config.login, config.password, config.auth_id, AuthRequest.ConnectTypes.API); - permissions = request.request().permissions; + AuthRequestEvent authResult = request.request(); + permissions = authResult.permissions; + playerProfile = authResult.playerProfile; ProfilesRequestEvent result = new ProfilesRequest().request(); for (ClientProfile p : result.profiles) { LogHelper.debug("Get profile: %s", p.getTitle()); - if (p.getTitle().equals(config.title)) { - profile = p; - Launcher.profile = p; - LogHelper.debug("Found profile: %s", Launcher.profile.getTitle()); - break; + boolean isFound = false; + for(ClientProfile.ServerProfile srv : p.getServers()) + { + if(srv != null && srv.name.equals(config.serverName)) { + this.serverProfile = srv; + this.profile = p; + Launcher.profile = p; + LogHelper.debug("Found profile: %s", Launcher.profile.getTitle()); + isFound = true; + break; + } } + if(isFound) break; } if (profile == null) { - LogHelper.error("Your profile not found"); - if (config.stopOnError) System.exit(-1); + LogHelper.warning("Not connected to ServerProfile. May be serverName incorrect?"); } return true; } catch (Throwable e) { @@ -183,7 +195,7 @@ public void run(String... args) throws Throwable { } auth(); }; - LogHelper.info("ServerWrapper: Project %s, LaunchServer address: %s. Title: %s", config.projectname, config.address, config.title); + LogHelper.info("ServerWrapper: Project %s, LaunchServer address: %s. Title: %s", config.projectname, config.address, Launcher.profile != null ? Launcher.profile.getTitle() : "unknown"); LogHelper.info("Minecraft Version (for profile): %s", wrapper.profile == null ? "unknown" : wrapper.profile.getVersion().name); LogHelper.info("Start Minecraft Server"); LogHelper.debug("Invoke main method %s", mainClass.getName()); @@ -228,7 +240,7 @@ public void setConfig(Config config) { @Override public Config getDefaultConfig() { Config newConfig = new Config(); - newConfig.title = "Your profile title"; + newConfig.serverName = "your server name"; newConfig.projectname = "MineCraft"; newConfig.login = "login"; newConfig.password = "password"; @@ -244,9 +256,11 @@ public Config getDefaultConfig() { } public static final class Config { + @Deprecated public String title; public String projectname; public String address; + public String serverName; public WebSocketConf websocket; public int reconnectCount; public int reconnectSleep; diff --git a/ServerWrapper/src/main/java/pro/gravit/launcher/server/setup/ServerWrapperSetup.java b/ServerWrapper/src/main/java/pro/gravit/launcher/server/setup/ServerWrapperSetup.java index 70e30e85..9bcd7118 100644 --- a/ServerWrapper/src/main/java/pro/gravit/launcher/server/setup/ServerWrapperSetup.java +++ b/ServerWrapper/src/main/java/pro/gravit/launcher/server/setup/ServerWrapperSetup.java @@ -46,6 +46,8 @@ public void run() throws IOException { } } LogHelper.info("Found MainClass %s", mainClassName); + System.out.println("Print your server name:"); + wrapper.config.serverName = commands.commandHandler.readLine(); System.out.println("Print launchserver websocket host( ws://host:port/api ):"); String address = commands.commandHandler.readLine(); wrapper.config.mainclass = mainClassName; @@ -56,14 +58,10 @@ public void run() throws IOException { String login = commands.commandHandler.readLine(); System.out.println("Print server account password:"); String password = commands.commandHandler.readLine(); - System.out.println("Print profile title:"); - String title = commands.commandHandler.readLine(); wrapper.config.login = login; wrapper.config.password = password; - wrapper.config.title = title; wrapper.config.stopOnError = false; wrapper.updateLauncherConfig(); - if (wrapper.auth()) { break; } else { From cafe8df3a9ab743d0632cee094c2f2611fb8aeda Mon Sep 17 00:00:00 2001 From: Gravita Date: Thu, 17 Dec 2020 23:56:11 +0700 Subject: [PATCH 24/31] [FEATURE] final SessionStorage API --- .../auth/session/MemorySessionStorage.java | 20 +++++++++++++++++++ .../auth/session/SessionStorage.java | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/MemorySessionStorage.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/MemorySessionStorage.java index bb1043d9..7676bdab 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/MemorySessionStorage.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/MemorySessionStorage.java @@ -71,6 +71,26 @@ public void clear() { uuidIndex.clear(); } + @Override + public void lockSession(UUID sessionUUID) { + + } + + @Override + public void lockUser(UUID userUUID) { + + } + + @Override + public void unlockSession(UUID sessionUUID) { + + } + + @Override + public void unlockUser(UUID userUUID) { + + } + private void removeUuidFromIndexSet(Set set, Entry e, UUID session) { set.remove(e); if(set.isEmpty()) { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/SessionStorage.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/SessionStorage.java index e576c07f..a1ac65e2 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/SessionStorage.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/session/SessionStorage.java @@ -20,6 +20,10 @@ public boolean deleteSessionsByUserUUID(UUID userUUID) { return true; } public abstract void clear(); + public abstract void lockSession(UUID sessionUUID); + public abstract void lockUser(UUID userUUID); + public abstract void unlockSession(UUID sessionUUID); + public abstract void unlockUser(UUID userUUID); public void init(LaunchServer server) { this.server = server; From 4f5c3370acdac000b4d213acb8ae7e1ecb6ffd83 Mon Sep 17 00:00:00 2001 From: Gravita Date: Sat, 19 Dec 2020 21:24:28 +0700 Subject: [PATCH 25/31] [ANY] Dockerfile --- Dockerfile | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..b2095924 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM archlinux/base +RUN pacman -Sy --noconfirm jdk11-openjdk unzip && pacman -Scc --noconfirm +ADD https://download2.gluonhq.com/openjfx/11.0.2/openjfx-11.0.2_linux-x64_bin-jmods.zip . +RUN unzip openjfx-11.0.2_linux-x64_bin-jmods.zip && mv javafx-jmods-11.0.2/* /usr/lib/jvm/java-11-openjdk/jmods/ && rmdir javafx-jmods-11.0.2 && rm openjfx-11.0.2_linux-x64_bin-jmods.zip +RUN mkdir ./libraries ./launcher-libraries ./launcher-libraries-compile +COPY ./LaunchServer/build/libs/LaunchServer.jar . +COPY ./LaunchServer/build/libs/libraries ./libraries +COPY ./LaunchServer/build/libs/launcher-libraries ./launcher-libraries +COPY ./LaunchServer/build/libs/launcher-libraries-compile ./launcher-libraries-compile +RUN mkdir ./compat/ +COPY ./compat/authlib/authlib-clean.jar ./compat +COPY ./LauncherAuthlib/build/libs/* ./compat/ +COPY ./ServerWrapper/build/libs/ServerWrapper.jar ./compat/ +RUN mkdir ./compat/modules +COPY ./modules/*_module/build/libs/* ./compat/modules/ +COPY ./modules/*_lmodule/build/libs/* ./compat/modules/ +CMD java -javaagent:LaunchServer.jar -jar LaunchServer.jar From cb5535b8ec8e9f8d5791f2ec878db4a40969010c Mon Sep 17 00:00:00 2001 From: Gravita Date: Sun, 20 Dec 2020 15:27:29 +0700 Subject: [PATCH 26/31] [FEATURE] FeaturesManager --- .../pro/gravit/launchserver/LaunchServer.java | 2 ++ .../manangers/FeaturesManager.java | 35 +++++++++++++++++++ .../response/management/FeaturesResponse.java | 18 ++++++++++ .../events/request/FeaturesRequestEvent.java | 21 +++++++++++ .../request/management/FeaturesRequest.java | 11 ++++++ 5 files changed, 87 insertions(+) create mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/manangers/FeaturesManager.java create mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/FeaturesResponse.java create mode 100644 LauncherAPI/src/main/java/pro/gravit/launcher/events/request/FeaturesRequestEvent.java create mode 100644 LauncherAPI/src/main/java/pro/gravit/launcher/request/management/FeaturesRequest.java diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java index 2a7d58b8..b74d8de7 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java @@ -81,6 +81,7 @@ public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurab public final ReconfigurableManager reconfigurableManager; public final ConfigManager configManager; public final PingServerManager pingServerManager; + public final FeaturesManager featuresManager; // HWID ban + anti-brutforce public final CertificateManager certificateManager; public final ProguardConf proguardConf; @@ -147,6 +148,7 @@ public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, La authHookManager = new AuthHookManager(); configManager = new ConfigManager(); pingServerManager = new PingServerManager(this); + featuresManager = new FeaturesManager(this); //Generate or set new Certificate API certificateManager.orgName = config.projectName; /* diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/FeaturesManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/FeaturesManager.java new file mode 100644 index 00000000..da1d15c8 --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/FeaturesManager.java @@ -0,0 +1,35 @@ +package pro.gravit.launchserver.manangers; + +import pro.gravit.launchserver.LaunchServer; +import pro.gravit.utils.Version; + +import java.util.HashMap; +import java.util.Map; + +public class FeaturesManager { + private transient LaunchServer server; + private Map map; + + public FeaturesManager(LaunchServer server) { + this.server = server; + map = new HashMap<>(); + addFeatureInfo("version", Version.getVersion().getVersionString()); + + } + + public Map getMap() { + return map; + } + + public String getFeatureInfo(String name) { + return map.get(name); + } + + public String addFeatureInfo(String name, String featureInfo) { + return map.put(name, featureInfo); + } + + public String removeFeatureInfo(String name) { + return map.remove(name); + } +} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/FeaturesResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/FeaturesResponse.java new file mode 100644 index 00000000..09eb4118 --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/FeaturesResponse.java @@ -0,0 +1,18 @@ +package pro.gravit.launchserver.socket.response.management; + +import io.netty.channel.ChannelHandlerContext; +import pro.gravit.launcher.events.request.FeaturesRequestEvent; +import pro.gravit.launchserver.socket.Client; +import pro.gravit.launchserver.socket.response.SimpleResponse; + +public class FeaturesResponse extends SimpleResponse { + @Override + public String getType() { + return "features"; + } + + @Override + public void execute(ChannelHandlerContext ctx, Client client) throws Exception { + sendResult(new FeaturesRequestEvent(server.featuresManager.getMap())); + } +} diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/FeaturesRequestEvent.java b/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/FeaturesRequestEvent.java new file mode 100644 index 00000000..d6151b19 --- /dev/null +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/FeaturesRequestEvent.java @@ -0,0 +1,21 @@ +package pro.gravit.launcher.events.request; + +import pro.gravit.launcher.events.RequestEvent; + +import java.util.Map; + +public class FeaturesRequestEvent extends RequestEvent { + public Map features; + + public FeaturesRequestEvent() { + } + + public FeaturesRequestEvent(Map features) { + this.features = features; + } + + @Override + public String getType() { + return "features"; + } +} diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/management/FeaturesRequest.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/management/FeaturesRequest.java new file mode 100644 index 00000000..d203cdff --- /dev/null +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/management/FeaturesRequest.java @@ -0,0 +1,11 @@ +package pro.gravit.launcher.request.management; + +import pro.gravit.launcher.events.request.FeaturesRequestEvent; +import pro.gravit.launcher.request.Request; + +public class FeaturesRequest extends Request { + @Override + public String getType() { + return "features"; + } +} From 826eb4c80f591bb40aa9a40d5ce5ad59abf0286f Mon Sep 17 00:00:00 2001 From: Gravita Date: Sun, 20 Dec 2020 15:31:17 +0700 Subject: [PATCH 27/31] [FEATURE] FeaturesResponse and FeaturesRequest --- .../java/pro/gravit/launchserver/socket/WebSocketService.java | 2 ++ .../launcher/request/websockets/ClientWebSocketService.java | 1 + 2 files changed, 3 insertions(+) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java index 71c5da51..abe90139 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java @@ -19,6 +19,7 @@ import pro.gravit.launchserver.socket.response.SimpleResponse; import pro.gravit.launchserver.socket.response.WebSocketServerResponse; import pro.gravit.launchserver.socket.response.auth.*; +import pro.gravit.launchserver.socket.response.management.FeaturesResponse; import pro.gravit.launchserver.socket.response.management.PingServerReportResponse; import pro.gravit.launchserver.socket.response.management.PingServerResponse; import pro.gravit.launchserver.socket.response.management.ServerStatusResponse; @@ -103,6 +104,7 @@ public static void registerResponses() { providers.register("pingServerReport", PingServerReportResponse.class); providers.register("pingServer", PingServerResponse.class); providers.register("currentUser", CurrentUserResponse.class); + providers.register("features", FeaturesResponse.class); } public void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client, String ip) { diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientWebSocketService.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientWebSocketService.java index 7f0ef48e..49bac8bc 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientWebSocketService.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientWebSocketService.java @@ -106,6 +106,7 @@ public void registerResults() { results.register("pingServerReport", PingServerReportRequestEvent.class); results.register("pingServer", PingServerRequestEvent.class); results.register("currentUser", CurrentUserRequestEvent.class); + results.register("features", FeaturesRequestEvent.class); } public void waitIfNotConnected() { From de95a667420bfff3fb1c19f0ac22384933dd07e8 Mon Sep 17 00:00:00 2001 From: Gravita Date: Sun, 20 Dec 2020 18:12:28 +0700 Subject: [PATCH 28/31] [FIX] CorruptedWebSocketFrameException: Max frame length of 65536 has been exceeded --- .../pro/gravit/launchserver/socket/LauncherNettyServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java index f6af5b05..6042d2d2 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java @@ -60,7 +60,7 @@ public void initChannel(SocketChannel ch) { if (server.config.netty.ipForwarding) pipeline.addLast("forward-http", new NettyIpForwardHandler(context)); pipeline.addLast("websock-comp", new WebSocketServerCompressionHandler()); - pipeline.addLast("websock-codec", new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true)); + pipeline.addLast("websock-codec", new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true, server.config.netty.performance.maxWebSocketRequestBytes)); if (!server.config.netty.disableWebApiInterface) pipeline.addLast("webapi", new NettyWebAPIHandler(context)); if (server.config.netty.fileServerEnabled) From b897fa55fd3e151fd012064ccc0c9a7ec801fcb8 Mon Sep 17 00:00:00 2001 From: Gravita Date: Mon, 21 Dec 2020 02:36:20 +0700 Subject: [PATCH 29/31] [FIX] Invalid field InstantSeconds for get() method, use getLong() instead --- .../handlers/fileserver/FileServerHandler.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/fileserver/FileServerHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/fileserver/FileServerHandler.java index 54c5cee4..cf547058 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/fileserver/FileServerHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/fileserver/FileServerHandler.java @@ -7,6 +7,7 @@ import io.netty.handler.stream.ChunkedFile; import io.netty.util.CharsetUtil; import pro.gravit.launchserver.socket.handlers.ContentType; +import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.VerifyHelper; import java.io.File; @@ -24,6 +25,7 @@ import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAccessor; +import java.time.temporal.UnsupportedTemporalTypeException; import java.util.Arrays; import java.util.Locale; import java.util.Objects; @@ -220,11 +222,17 @@ public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) thr // Only compare up to the second because the datetime format we send to the client // does not have milliseconds - long ifModifiedSinceDateSeconds = ifModifiedSinceDate.get(ChronoField.INSTANT_SECONDS); - long fileLastModifiedSeconds = file.lastModified() / 1000; - if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) { - sendNotModified(ctx); - return; + try { + long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getLong(ChronoField.INSTANT_SECONDS); + long fileLastModifiedSeconds = file.lastModified() / 1000; + if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) { + sendNotModified(ctx); + return; + } + } catch (UnsupportedTemporalTypeException e) { + if(LogHelper.isDebugEnabled()) { + LogHelper.warning("Request access If-Modifed-Since: %s not parsed correctly", ifModifiedSince); + } } } From 3cf5ee6d2ccbb9632da6248b62966fd71969275b Mon Sep 17 00:00:00 2001 From: Gravita Date: Tue, 22 Dec 2020 15:41:21 +0700 Subject: [PATCH 30/31] =?UTF-8?q?[FIX]=20NPE=20=D0=B2=20ProfileByUUIDRespo?= =?UTF-8?q?nse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../socket/response/profile/ProfileByUUIDResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/profile/ProfileByUUIDResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/profile/ProfileByUUIDResponse.java index 816c5920..b468c12d 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/profile/ProfileByUUIDResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/profile/ProfileByUUIDResponse.java @@ -63,6 +63,6 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception { sendError(String.format("ProfileByUUIDResponse: User with uuid %s not found or AuthProvider#uuidToUsername returned null", uuid)); return; } - sendResult(new ProfileByUUIDRequestEvent(getProfile(uuid, username, this.client, client.auth.textureProvider))); + sendResult(new ProfileByUUIDRequestEvent(getProfile(uuid, username, this.client, pair.textureProvider))); } } From 098a429c1357e62c2125cfa3e21aa9169d5e828a Mon Sep 17 00:00:00 2001 From: Gravita Date: Fri, 25 Dec 2020 11:45:17 +0700 Subject: [PATCH 31/31] [ANY] 5.1.9-stable --- LauncherCore/src/main/java/pro/gravit/utils/Version.java | 2 +- build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LauncherCore/src/main/java/pro/gravit/utils/Version.java b/LauncherCore/src/main/java/pro/gravit/utils/Version.java index 49c4c07e..f94eaf4f 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/Version.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/Version.java @@ -8,7 +8,7 @@ public final class Version { public static final int MINOR = 1; public static final int PATCH = 9; public static final int BUILD = 1; - public static final Version.Type RELEASE = Type.DEV; + public static final Version.Type RELEASE = Type.STABLE; public final int major; public final int minor; public final int patch; diff --git a/build.gradle b/build.gradle index 6535c3ae..915ab739 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ id 'org.openjfx.javafxplugin' version '0.0.8' apply false } group = 'pro.gravit.launcher' -version = '5.1.9-SNAPSHOT' +version = '5.1.9' apply from: 'props.gradle'