From 857901a667c662bffe74ea125b3fcff1f6698312 Mon Sep 17 00:00:00 2001 From: Gravita Date: Thu, 19 May 2022 00:38:12 +0700 Subject: [PATCH 01/38] [FEATURE] Isolate minecraft --- .../pro/gravit/launcher/client/ClientClassLoader.java | 9 +++++++++ .../gravit/launcher/client/ClientLauncherEntryPoint.java | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java index 55956b16..7bb96e7b 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java @@ -7,6 +7,7 @@ import java.net.URLClassLoader; public class ClientClassLoader extends URLClassLoader { + private static final ClassLoader SYSTEM_CLASS_LOADER = ClassLoader.getSystemClassLoader(); public String nativePath; /** @@ -58,6 +59,14 @@ public ClientClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); } + @Override + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + if(name != null && (name.startsWith("pro.gravit.launcher.") || name.startsWith("pro.gravit.utils."))) { + return SYSTEM_CLASS_LOADER.loadClass(name); + } + return super.loadClass(name, resolve); + } + @Override public String findLibrary(String name) { return nativePath.concat(IOHelper.PLATFORM_SEPARATOR).concat(getNativePrefix()).concat(name).concat(getNativeEx()); 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 af76d9f9..f46bf55e 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java @@ -145,7 +145,7 @@ public static void main(String[] args) throws Throwable { } ClientProfile.ClassLoaderConfig classLoaderConfig = profile.getClassLoaderConfig(); if (classLoaderConfig == ClientProfile.ClassLoaderConfig.LAUNCHER) { - ClientClassLoader classLoader = new ClientClassLoader(classpathURLs.toArray(new URL[0]), ClassLoader.getSystemClassLoader()); + ClientClassLoader classLoader = new ClientClassLoader(classpathURLs.toArray(new URL[0]), ClientLauncherEntryPoint.class.getClassLoader()); System.setProperty("java.class.path", classpath.stream().map(Path::toString).collect(Collectors.joining(File.pathSeparator))); ClientLauncherEntryPoint.classLoader = classLoader; Thread.currentThread().setContextClassLoader(classLoader); From 0818b3037c17a163d6ea8b1b5771fb139443da6b Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sun, 26 Feb 2023 18:00:44 +0700 Subject: [PATCH 02/38] [FEATURE] ClientProfile compat flags, remove deprecated --- .../pro/gravit/launchserver/LaunchServer.java | 11 +++- .../main/resources/experimental-build.json | 2 +- .../launchserver/defaults/profile1.10.2.cfg | 47 ----------------- .../launchserver/defaults/profile1.11.2.cfg | 47 ----------------- .../launchserver/defaults/profile1.12.2.cfg | 47 ----------------- .../launchserver/defaults/profile1.13.1.cfg | 45 ---------------- .../launchserver/defaults/profile1.13.cfg | 45 ---------------- .../launchserver/defaults/profile1.14.4.cfg | 44 ---------------- .../launchserver/defaults/profile1.15.1.cfg | 44 ---------------- .../launchserver/defaults/profile1.15.2.cfg | 44 ---------------- .../launchserver/defaults/profile1.16.1.cfg | 44 ---------------- .../launchserver/defaults/profile1.4.7.cfg | 44 ---------------- .../launchserver/defaults/profile1.5.2.cfg | 44 ---------------- .../launchserver/defaults/profile1.6.4.cfg | 49 ----------------- .../launchserver/defaults/profile1.7.10.cfg | 47 ----------------- .../launchserver/defaults/profile1.7.2.cfg | 47 ----------------- .../launchserver/defaults/profile1.8.9.cfg | 47 ----------------- .../launchserver/defaults/profile1.9.4.cfg | 47 ----------------- .../client/ClientLauncherEntryPoint.java | 34 +----------- .../client/ClientLauncherProcess.java | 19 +++---- .../launcher/profiles/ClientProfile.java | 52 ++++++------------- .../profiles/ClientProfileBuilder.java | 32 +++--------- .../launcher/profiles/PlayerProfile.java | 6 --- .../websockets/ClientWebSocketService.java | 6 +-- .../gravit/utils/UniversalJsonAdapter.java | 9 +++- .../main/java/pro/gravit/utils/Version.java | 6 +-- .../pro/gravit/utils/helper/JVMHelper.java | 1 - modules | 2 +- 28 files changed, 54 insertions(+), 858 deletions(-) delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.10.2.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.11.2.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.12.2.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.13.1.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.13.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.14.4.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.15.1.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.15.2.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.16.1.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.4.7.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.5.2.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.6.4.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.7.10.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.7.2.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.8.9.cfg delete mode 100644 LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.9.4.cfg diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java index e99e68e5..6f25a6e6 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java @@ -219,7 +219,14 @@ public void reload(ReloadType type) throws Exception { }); logger.debug("Init components successful"); } - + if(!type.equals(ReloadType.NO_AUTH)) { + nettyServerSocketHandler.nettyServer.service.forEachActiveChannels((channel, wsHandler) -> { + Client client = wsHandler.getClient(); + if(client.auth != null) { + client.auth = config.getAuthProviderPair(client.auth_id); + } + }); + } } @Override @@ -236,7 +243,7 @@ public void invoke(String... args) throws Exception { case "full" -> reload(ReloadType.FULL); case "no_auth" -> reload(ReloadType.NO_AUTH); case "no_components" -> reload(ReloadType.NO_COMPONENTS); - default -> reload(ReloadType.FULL); + default -> reload(ReloadType.NO_AUTH); } } }; diff --git a/LaunchServer/src/main/resources/experimental-build.json b/LaunchServer/src/main/resources/experimental-build.json index ab148d00..e5bb4564 100644 --- a/LaunchServer/src/main/resources/experimental-build.json +++ b/LaunchServer/src/main/resources/experimental-build.json @@ -1,4 +1,4 @@ { - "features": [], + "features": ["profiles-rework"], "info": [] } \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.10.2.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.10.2.cfg deleted file mode 100644 index 45e13630..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.10.2.cfg +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": "1.10.2", - "assetIndex": "1.10.2", - "assetDir": "asset1.10", - "dir": "HiTech", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "xxxxxxxx", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": ["servers.dat"], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", "natives", "mods", - "minecraft.jar", "forge.jar", "liteloader.jar" - ], - "updateOptional": [ - ], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.launchwrapper.Launch", - "jvmArgs": [ - "-Dfml.ignorePatchDiscrepancies=true", - "-Dfml.ignoreInvalidMinecraftCertificates=true", - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"], - "clientArgs": [ - "--tweakClass", "net.minecraftforge.fml.common.launcher.FMLTweaker", - "--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker" - ], - "optionalJVMArgs": [], - "optionalClientArgs": [], - "optionalClassPath": [], - "whitelist": [] -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.11.2.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.11.2.cfg deleted file mode 100644 index 81b5a96c..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.11.2.cfg +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": "1.11.2", - "assetIndex": "1.11.2", - "assetDir": "asset1.11", - "dir": "HiTech", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "xxxxxxxx", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": ["servers.dat"], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", "natives", "mods", - "minecraft.jar", "forge.jar", "liteloader.jar" - ], - "updateOptional": [ - ], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.launchwrapper.Launch", - "jvmArgs": [ - "-Dfml.ignorePatchDiscrepancies=true", - "-Dfml.ignoreInvalidMinecraftCertificates=true", - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"], - "clientArgs": [ - "--tweakClass", "net.minecraftforge.fml.common.launcher.FMLTweaker", - "--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker" - ], - "optionalJVMArgs": [], - "optionalClientArgs": [], - "optionalClassPath": [], - "whitelist": [] -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.12.2.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.12.2.cfg deleted file mode 100644 index a6896906..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.12.2.cfg +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": "1.12.2", - "assetIndex": "1.12.2", - "assetDir": "asset1.12", - "dir": "HiTech", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "xxxxxxxx", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": ["servers.dat"], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", "natives", "mods", - "minecraft.jar", "forge.jar", "liteloader.jar" - ], - "updateOptional": [ - ], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.launchwrapper.Launch", - "jvmArgs": [ - "-Dfml.ignorePatchDiscrepancies=true", - "-Dfml.ignoreInvalidMinecraftCertificates=true", - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"], - "clientArgs": [ - "--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker", - "--tweakClass", "net.minecraftforge.fml.common.launcher.FMLTweaker" - ], - "optionalJVMArgs": [], - "optionalClientArgs": [], - "optionalClassPath": [], - "whitelist": [] -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.13.1.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.13.1.cfg deleted file mode 100644 index 9fbd07dc..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.13.1.cfg +++ /dev/null @@ -1,45 +0,0 @@ -{ - "version": "1.13.1", - "assetIndex": "1.13.1", - "assetDir": "asset1.13.1", - "dir": "HiTech", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "xxxxxxxx", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": ["servers.dat"], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", "natives", "mods", - "minecraft.jar", "forge.jar", "liteloader.jar" - ], - "updateOptional": [ - ], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.client.main.Main", - "jvmArgs": [ - "-Dfml.ignorePatchDiscrepancies=true", - "-Dfml.ignoreInvalidMinecraftCertificates=true", - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"], - "clientArgs": [ - ], - "optionalJVMArgs": [], - "optionalClientArgs": [], - "optionalClassPath": [], - "whitelist": [] -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.13.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.13.cfg deleted file mode 100644 index 110c6c74..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.13.cfg +++ /dev/null @@ -1,45 +0,0 @@ -{ - "version": "1.13", - "assetIndex": "1.13", - "assetDir": "asset1.13", - "dir": "HiTech", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "xxxxxxxx", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": ["servers.dat"], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", "natives", "mods", - "minecraft.jar", "forge.jar", "liteloader.jar" - ], - "updateOptional": [ - ], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.client.main.Main", - "jvmArgs": [ - "-Dfml.ignorePatchDiscrepancies=true", - "-Dfml.ignoreInvalidMinecraftCertificates=true", - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"], - "clientArgs": [ - ], - "optionalJVMArgs": [], - "optionalClientArgs": [], - "optionalClassPath": [], - "whitelist": [] -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.14.4.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.14.4.cfg deleted file mode 100644 index a6cfc177..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.14.4.cfg +++ /dev/null @@ -1,44 +0,0 @@ -{ - "version": "1.14.4", - "assetIndex": "1.14.4", - "assetDir": "asset1.14.4", - "dir": "HiTech", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "xxxxxxxx", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": [ - "servers.dat" - ], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", - "natives", - "minecraft.jar" - ], - "updateOptional": [], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.client.main.Main", - "jvmArgs": [ - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": [ - "minecraft.jar", - "libraries" - ], - "clientArgs": [], - "whitelist": [] -} diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.15.1.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.15.1.cfg deleted file mode 100644 index 55c0fbe1..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.15.1.cfg +++ /dev/null @@ -1,44 +0,0 @@ -{ - "version": "1.15.1", - "assetIndex": "1.15.1", - "assetDir": "asset1.15.1", - "dir": "HiTech", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "xxxxxxxx", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": [ - "servers.dat" - ], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", - "natives", - "minecraft.jar" - ], - "updateOptional": [], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.client.main.Main", - "jvmArgs": [ - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": [ - "minecraft.jar", - "libraries" - ], - "clientArgs": [], - "whitelist": [] -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.15.2.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.15.2.cfg deleted file mode 100644 index b4889638..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.15.2.cfg +++ /dev/null @@ -1,44 +0,0 @@ -{ - "version": "1.15.2", - "assetIndex": "1.15.2", - "assetDir": "asset1.15.2", - "dir": "HiTech", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "xxxxxxxx", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": [ - "servers.dat" - ], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", - "natives", - "minecraft.jar" - ], - "updateOptional": [], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.client.main.Main", - "jvmArgs": [ - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": [ - "minecraft.jar", - "libraries" - ], - "clientArgs": [], - "whitelist": [] -} diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.16.1.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.16.1.cfg deleted file mode 100644 index db57fe05..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.16.1.cfg +++ /dev/null @@ -1,44 +0,0 @@ -{ - "version": "1.16.1", - "assetIndex": "1.16.1", - "assetDir": "asset1.16.1", - "dir": "HiTech", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "xxxxxxxx", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": [ - "servers.dat" - ], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", - "natives", - "minecraft.jar" - ], - "updateOptional": [], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.client.main.Main", - "jvmArgs": [ - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": [ - "minecraft.jar", - "libraries" - ], - "clientArgs": [], - "whitelist": [] -} diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.4.7.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.4.7.cfg deleted file mode 100644 index 058bec47..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.4.7.cfg +++ /dev/null @@ -1,44 +0,0 @@ -{ - "version": "1.4.7", - "assetIndex": "---", - "assetDir": "asset1.4.7", - "dir": "xxxxxxx", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "Test1.4.7", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": ["servers.dat"], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", "natives", "mods", - "minecraft.jar" - ], - "updateOptional": [ - ], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.launchwrapper.Launch", - "jvmArgs": [ - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism", - "-Dlauncher.legacy.skinsURL=http://skins.minecraft.net/MinecraftSkins/%username%.png", - "-Dlauncher.legacy.cloaksURL=http://skins.minecraft.net/MinecraftCloaks/%username%.png" - ], - "classPath": ["minecraft.jar", "libraries"], - "clientArgs": [], - "optionalJVMArgs": [], - "optionalClientArgs": [], - "optionalClassPath": [], - "whitelist": [] -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.5.2.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.5.2.cfg deleted file mode 100644 index bb7542f8..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.5.2.cfg +++ /dev/null @@ -1,44 +0,0 @@ -{ - "version": "1.5.2", - "assetIndex": "---", - "assetDir": "asset1.5.2", - "dir": "xxxxxxx", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "Test1.5.2", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": ["servers.dat"], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", "natives", "mods", - "minecraft.jar" - ], - "updateOptional": [ - ], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.launchwrapper.Launch", - "jvmArgs": [ - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism", - "-Dlauncher.legacy.skinsURL=http://skins.minecraft.net/MinecraftSkins/%username%.png", - "-Dlauncher.legacy.cloaksURL=http://skins.minecraft.net/MinecraftCloaks/%username%.png" - ], - "classPath": ["minecraft.jar", "libraries"], - "clientArgs": [], - "optionalJVMArgs": [], - "optionalClientArgs": [], - "optionalClassPath": [], - "whitelist": [] -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.6.4.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.6.4.cfg deleted file mode 100644 index e5585821..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.6.4.cfg +++ /dev/null @@ -1,49 +0,0 @@ -{ - "version": "1.6.4", - "assetIndex": "---", - "assetDir": "asset1.6.4", - "dir": "xxxxxxx", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "Test1.6.4", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": ["servers.dat"], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", "natives", "mods", - "minecraft.jar", "forge.jar", "liteloader.jar" - ], - "updateOptional": [ - ], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.launchwrapper.Launch", - "jvmArgs": [ - "-Dfml.ignorePatchDiscrepancies=true", - "-Dfml.ignoreInvalidMinecraftCertificates=true", - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism", - "-Dlauncher.legacy.skinsURL=http://skins.minecraft.net/MinecraftSkins/%username%.png", - "-Dlauncher.legacy.cloaksURL=http://skins.minecraft.net/MinecraftCloaks/%username%.png" - ], - "classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"], - "clientArgs": [ - "--tweakClass", "cpw.mods.fml.common.launcher.FMLTweaker", - "--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker" - ], - "optionalJVMArgs": [], - "optionalClientArgs": [], - "optionalClassPath": [], - "whitelist": [] -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.7.10.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.7.10.cfg deleted file mode 100644 index 2e20b6a0..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.7.10.cfg +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": "1.7.10", - "assetIndex": "1.7.10", - "assetDir": "asset1.7.10", - "dir": "xxxxxxx", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "Test1.7.10", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": ["servers.dat"], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", "natives", "mods", - "minecraft.jar", "forge.jar", "liteloader.jar" - ], - "updateOptional": [ - ], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.launchwrapper.Launch", - "jvmArgs": [ - "-Dfml.ignorePatchDiscrepancies=true", - "-Dfml.ignoreInvalidMinecraftCertificates=true", - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"], - "clientArgs": [ - "--tweakClass", "cpw.mods.fml.common.launcher.FMLTweaker", - "--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker" - ], - "optionalJVMArgs": [], - "optionalClientArgs": [], - "optionalClassPath": [], - "whitelist": [] -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.7.2.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.7.2.cfg deleted file mode 100644 index 890f7b82..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.7.2.cfg +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": "1.7.2", - "assetIndex": "1.7.2", - "assetDir": "asset1.7.2", - "dir": "xxxxxxx", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "Test1.7.2", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": ["servers.dat"], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", "natives", "mods", - "minecraft.jar", "forge.jar", "liteloader.jar" - ], - "updateOptional": [ - ], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.launchwrapper.Launch", - "jvmArgs": [ - "-Dfml.ignorePatchDiscrepancies=true", - "-Dfml.ignoreInvalidMinecraftCertificates=true", - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"], - "clientArgs": [ - "--tweakClass", "cpw.mods.fml.common.launcher.FMLTweaker", - "--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker" - ], - "optionalJVMArgs": [], - "optionalClientArgs": [], - "optionalClassPath": [], - "whitelist": [] -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.8.9.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.8.9.cfg deleted file mode 100644 index 68c1d1ce..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.8.9.cfg +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": "1.8.9", - "assetIndex": "1.8.9", - "assetDir": "asset1.8.9", - "dir": "xxxxxxx", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "Test1.8.9", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": ["servers.dat"], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", "natives", "mods", - "minecraft.jar", "forge.jar", "liteloader.jar" - ], - "updateOptional": [ - ], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.launchwrapper.Launch", - "jvmArgs": [ - "-Dfml.ignorePatchDiscrepancies=true", - "-Dfml.ignoreInvalidMinecraftCertificates=true", - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"], - "clientArgs": [ - "--tweakClass", "net.minecraftforge.fml.common.launcher.FMLTweaker", - "--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker" - ], - "optionalJVMArgs": [], - "optionalClientArgs": [], - "optionalClassPath": [], - "whitelist": [] -} \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.9.4.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.9.4.cfg deleted file mode 100644 index 329b20c0..00000000 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/profile1.9.4.cfg +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": "1.9.4", - "assetIndex": "1.9.4", - "assetDir": "asset1.9.4", - "dir": "xxxxxxx", - "info": "Информация о сервере", - "sortIndex": 0, - "title": "Test1.9.4", - "servers": [ - { - "name": "----", - "serverAddress": "localhost", - "serverPort": 25565, - "isDefault": true - } - ], - "update": ["servers.dat"], - "updateExclusions": [], - "updateShared": [], - "updateVerify": [ - "libraries", "natives", "mods", - "minecraft.jar", "forge.jar", "liteloader.jar" - ], - "updateOptional": [ - ], - "updateFastCheck": true, - "useWhitelist": false, - "mainClass": "net.minecraft.launchwrapper.Launch", - "jvmArgs": [ - "-Dfml.ignorePatchDiscrepancies=true", - "-Dfml.ignoreInvalidMinecraftCertificates=true", - "-XX:+UseConcMarkSweepGC", - "-XX:+CMSIncrementalMode", - "-XX:-UseAdaptiveSizePolicy", - "-Xmn128M", - "-XX:+DisableAttachMechanism" - ], - "classPath": ["forge.jar", "liteloader.jar", "minecraft.jar", "libraries"], - "clientArgs": [ - "--tweakClass", "net.minecraftforge.fml.common.launcher.FMLTweaker", - "--tweakClass", "com.mumfrey.liteloader.launch.LiteLoaderTweaker" - ], - "optionalJVMArgs": [], - "optionalClientArgs": [], - "optionalClassPath": [], - "whitelist": [] -} \ No newline at end of file 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 8e88a405..24457b2d 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java @@ -107,7 +107,6 @@ public static void main(String[] args) throws Throwable { } else if (params.session != null) { throw new UnsupportedOperationException("Legacy session not supported"); } - checkJVMBitsAndVersion(params.profile.getMinJavaVersion(), params.profile.getRecommendJavaVersion(), params.profile.getMaxJavaVersion(), params.profile.isWarnMissJavaVersion()); LauncherEngine.modulesManager.invokeEvent(new ClientProcessInitPhase(engine, params)); Path clientDir = Paths.get(params.clientDir); @@ -174,15 +173,6 @@ public static void main(String[] args) throws Throwable { AuthService.username = params.playerProfile.username; AuthService.uuid = params.playerProfile.uuid; KeyService.serverRsaPublicKey = Launcher.getConfig().rsaPublicKey; - if (params.profile.getRuntimeInClientConfig() != ClientProfile.RuntimeInClientConfig.NONE) { - CommonHelper.newThread("Client Launcher Thread", true, () -> { - try { - engine.start(args); - } catch (Throwable throwable) { - LogHelper.error(throwable); - } - }).start(); - } LauncherEngine.modulesManager.invokeEvent(new ClientProcessReadyEvent(engine, params)); LogHelper.debug("Starting JVM and client WatchService"); FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher(); @@ -268,28 +258,6 @@ public static void verifyHDir(Path dir, HashedDir hdir, FileNameMatcher matcher, } } - public static boolean checkJVMBitsAndVersion(int minVersion, int recommendVersion, int maxVersion, boolean showMessage) { - boolean ok = true; - if (JVMHelper.JVM_BITS == 64 && JVMHelper.ARCH_TYPE == JVMHelper.ARCH.X86) { - String error = "У Вас установлена Java x64, но Ваша система определена как x32. Установите Java правильной разрядности"; - LogHelper.error(error); - if (showMessage) - JOptionPane.showMessageDialog(null, error); - ok = false; - } - String jvmVersion = JVMHelper.RUNTIME_MXBEAN.getVmVersion(); - LogHelper.info(jvmVersion); - int version = JVMHelper.getVersion(); - if (version < minVersion || version > maxVersion) { - String error = String.format("У Вас установлена Java %d, но этот клиент требует Java %d", JVMHelper.getVersion(), recommendVersion); - LogHelper.error(error); - if (showMessage) - JOptionPane.showMessageDialog(null, error); - ok = false; - } - return ok; - } - private static LinkedList resolveClassPathList(Path clientDir, String... classPath) throws IOException { return resolveClassPathStream(clientDir, classPath).collect(Collectors.toCollection(LinkedList::new)); } @@ -353,7 +321,7 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa List compatClasses = profile.getCompatClasses(); for (String e : compatClasses) { Class clazz = classLoader.loadClass(e); - MethodHandle runMethod = MethodHandles.publicLookup().findStatic(clazz, "run", MethodType.methodType(void.class)); + MethodHandle runMethod = MethodHandles.lookup().findStatic(clazz, "run", MethodType.methodType(void.class)); runMethod.invoke(); } } 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 98e2ba96..66bcc917 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java @@ -76,9 +76,14 @@ public ClientLauncherProcess(Path clientDir, Path assetDir, JavaHelper.JavaVersi this.params.clientDir = this.workDir.toString(); this.params.resourcePackDir = resourcePackDir.toAbsolutePath().toString(); this.params.assetDir = assetDir.toAbsolutePath().toString(); - Path nativesPath = workDir.resolve("natives").resolve(JVMHelper.OS_TYPE.name).resolve(javaVersion.arch.name); - if (!Files.isDirectory(nativesPath)) { + Path nativesPath; + if(profile.hasFlag(ClientProfile.CompatibilityFlags.LEGACY_NATIVES_DIR)) { nativesPath = workDir.resolve("natives"); + } else { + nativesPath = workDir.resolve("natives").resolve(JVMHelper.OS_TYPE.name).resolve(javaVersion.arch.name); + } + if (!Files.isDirectory(nativesPath)) { + throw new RuntimeException(String.format("Natives dir %s not exist! Your operating system or architecture not supported", nativesPath.toAbsolutePath())); } this.params.nativesDir = nativesPath.toString(); this.params.profile = profile; @@ -123,16 +128,6 @@ private void applyClientProfile() { } this.jvmModules.addAll(this.params.profile.getModules()); this.jvmModulesPaths.addAll(this.params.profile.getModulePath()); - if (this.params.profile.getRuntimeInClientConfig() != ClientProfile.RuntimeInClientConfig.NONE) { - jvmModules.add("javafx.base"); - jvmModules.add("javafx.graphics"); - jvmModules.add("javafx.fxml"); - jvmModules.add("javafx.controls"); - jvmModules.add("javafx.swing"); - jvmModules.add("javafx.media"); - jvmModules.add("javafx.web"); - } - LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderCreateEvent(this)); } 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 388efdcc..ff1af074 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java @@ -62,13 +62,10 @@ public final class ClientProfile implements Comparable { @LauncherNetworkAPI private List servers; @LauncherNetworkAPI - private SecurityManagerConfig securityManagerConfig; - @LauncherNetworkAPI private ClassLoaderConfig classLoaderConfig; + @LauncherNetworkAPI - private SignedClientConfig signedClientConfig; - @LauncherNetworkAPI - private RuntimeInClientConfig runtimeInClientConfig; + private List flags; @LauncherNetworkAPI private int recommendJavaVersion = 8; @LauncherNetworkAPI @@ -76,8 +73,6 @@ public final class ClientProfile implements Comparable { @LauncherNetworkAPI private int maxJavaVersion = 999; @LauncherNetworkAPI - private boolean warnMissJavaVersion = true; - @LauncherNetworkAPI private ProfileDefaultSettings settings = new ProfileDefaultSettings(); @LauncherNetworkAPI private boolean limited; @@ -99,13 +94,11 @@ public ClientProfile() { compatClasses = new ArrayList<>(); properties = new HashMap<>(); servers = new ArrayList<>(1); - securityManagerConfig = SecurityManagerConfig.CLIENT; classLoaderConfig = ClassLoaderConfig.LAUNCHER; - signedClientConfig = SignedClientConfig.NONE; - runtimeInClientConfig = RuntimeInClientConfig.NONE; + flags = new ArrayList<>(); } - public ClientProfile(List update, List updateExclusions, List updateShared, List updateVerify, Set updateOptional, List jvmArgs, List classPath, List modulePath, List modules, List altClassPath, List clientArgs, List compatClasses, Map properties, List servers, SecurityManagerConfig securityManagerConfig, ClassLoaderConfig classLoaderConfig, SignedClientConfig signedClientConfig, RuntimeInClientConfig runtimeInClientConfig, String version, String assetIndex, String dir, String assetDir, int recommendJavaVersion, int minJavaVersion, int maxJavaVersion, boolean warnMissJavaVersion, ProfileDefaultSettings settings, int sortIndex, UUID uuid, String title, String info, String mainClass) { + public ClientProfile(List update, List updateExclusions, List updateShared, List updateVerify, Set updateOptional, List jvmArgs, List classPath, List modulePath, List modules, List altClassPath, List clientArgs, List compatClasses, Map properties, List servers, ClassLoaderConfig classLoaderConfig, List flags, String version, String assetIndex, String dir, String assetDir, int recommendJavaVersion, int minJavaVersion, int maxJavaVersion, ProfileDefaultSettings settings, int sortIndex, UUID uuid, String title, String info, String mainClass) { this.update = update; this.updateExclusions = updateExclusions; this.updateShared = updateShared; @@ -120,10 +113,7 @@ public ClientProfile(List update, List updateExclusions, List update, List updateExclusions, List getFlags() { + return flags; + } + public enum Version { MC125("1.2.5", 29), MC147("1.4.7", 51), @@ -513,20 +499,12 @@ public String toString() { } } - public enum SecurityManagerConfig { - NONE, CLIENT, LAUNCHER, MIXED - } - public enum ClassLoaderConfig { AGENT, LAUNCHER, MODULE, SYSTEM_ARGS } - public enum SignedClientConfig { - NONE, SIGNED - } - - public enum RuntimeInClientConfig { - NONE, BASIC, FULL + public enum CompatibilityFlags { + LEGACY_NATIVES_DIR } @FunctionalInterface diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileBuilder.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileBuilder.java index dff6de45..fe83469e 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileBuilder.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileBuilder.java @@ -19,10 +19,8 @@ public class ClientProfileBuilder { private List compatClasses = new ArrayList<>(); private Map properties = new HashMap<>(); private List servers = new ArrayList<>(); - private ClientProfile.SecurityManagerConfig securityManagerConfig = ClientProfile.SecurityManagerConfig.LAUNCHER; private ClientProfile.ClassLoaderConfig classLoaderConfig = ClientProfile.ClassLoaderConfig.LAUNCHER; - private ClientProfile.SignedClientConfig signedClientConfig = ClientProfile.SignedClientConfig.NONE; - private ClientProfile.RuntimeInClientConfig runtimeInClientConfig = ClientProfile.RuntimeInClientConfig.NONE; + private List flags = new ArrayList<>(); private String version; private String assetIndex; private String dir; @@ -30,7 +28,6 @@ public class ClientProfileBuilder { private int recommendJavaVersion = 8; private int minJavaVersion = 8; private int maxJavaVersion = 999; - private boolean warnMissJavaVersion = true; private ClientProfile.ProfileDefaultSettings settings = new ClientProfile.ProfileDefaultSettings(); private int sortIndex; private UUID uuid; @@ -98,26 +95,11 @@ public ClientProfileBuilder setServers(List servers return this; } - public ClientProfileBuilder setSecurityManagerConfig(ClientProfile.SecurityManagerConfig securityManagerConfig) { - this.securityManagerConfig = securityManagerConfig; - return this; - } - public ClientProfileBuilder setClassLoaderConfig(ClientProfile.ClassLoaderConfig classLoaderConfig) { this.classLoaderConfig = classLoaderConfig; return this; } - public ClientProfileBuilder setSignedClientConfig(ClientProfile.SignedClientConfig signedClientConfig) { - this.signedClientConfig = signedClientConfig; - return this; - } - - public ClientProfileBuilder setRuntimeInClientConfig(ClientProfile.RuntimeInClientConfig runtimeInClientConfig) { - this.runtimeInClientConfig = runtimeInClientConfig; - return this; - } - public ClientProfileBuilder setVersion(String version) { this.version = version; return this; @@ -163,11 +145,6 @@ public ClientProfileBuilder setMaxJavaVersion(int maxJavaVersion) { return this; } - public ClientProfileBuilder setWarnMissJavaVersion(boolean warnMissJavaVersion) { - this.warnMissJavaVersion = warnMissJavaVersion; - return this; - } - public ClientProfileBuilder setSettings(ClientProfile.ProfileDefaultSettings settings) { this.settings = settings; return this; @@ -198,7 +175,12 @@ public ClientProfileBuilder setMainClass(String mainClass) { return this; } + public ClientProfileBuilder setFlags(List flags) { + this.flags = flags; + return this; + } + public ClientProfile createClientProfile() { - return new ClientProfile(update, updateExclusions, updateShared, updateVerify, updateOptional, jvmArgs, classPath, modulePath, modules, altClassPath, clientArgs, compatClasses, properties, servers, securityManagerConfig, classLoaderConfig, signedClientConfig, runtimeInClientConfig, version, assetIndex, dir, assetDir, recommendJavaVersion, minJavaVersion, maxJavaVersion, warnMissJavaVersion, settings, sortIndex, uuid, title, info, mainClass); + return new ClientProfile(update, updateExclusions, updateShared, updateVerify, updateOptional, jvmArgs, classPath, modulePath, modules, altClassPath, clientArgs, compatClasses, properties, servers, classLoaderConfig, flags, version, assetIndex, dir, assetDir, recommendJavaVersion, minJavaVersion, maxJavaVersion, settings, sortIndex, uuid, title, info, mainClass); } } \ No newline at end of file diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/PlayerProfile.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/PlayerProfile.java index 3678e0ea..b08cff5d 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/PlayerProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/PlayerProfile.java @@ -11,8 +11,6 @@ public final class PlayerProfile { public final UUID uuid; public final String username; - @Deprecated - public final Texture skin, cloak; public final Map assets; public final Map properties; @@ -26,8 +24,6 @@ public PlayerProfile(UUID uuid, String username, Texture skin, Texture cloak) { public PlayerProfile(UUID uuid, String username, Texture skin, Texture cloak, Map properties) { this.uuid = Objects.requireNonNull(uuid, "uuid"); this.username = username; - this.skin = skin; - this.cloak = cloak; this.assets = new HashMap<>(); if (skin != null) { this.assets.put("SKIN", skin); @@ -43,8 +39,6 @@ public PlayerProfile(UUID uuid, String username, Map assets, Ma this.username = username; this.assets = assets; this.properties = properties; - this.skin = assets.get("SKIN"); - this.cloak = assets.get("CAPE"); } public static PlayerProfile newOfflineProfile(String username) { 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 02959606..8b234a4a 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 @@ -28,6 +28,7 @@ public abstract class ClientWebSocketService extends ClientJSONPoint { private static boolean resultsRegistered = false; public final Gson gson; public final Boolean onConnect; + public final Object waitObject = new Object(); public OnCloseCallback onCloseCallback; public ReconnectCallback reconnectCallback; @@ -71,8 +72,8 @@ void onDisconnect() { @Override void onOpen() { - synchronized (onConnect) { - onConnect.notifyAll(); + synchronized (waitObject) { + waitObject.notifyAll(); } } @@ -80,7 +81,6 @@ public void registerRequests() { } - @SuppressWarnings("deprecation") public void registerResults() { if (!resultsRegistered) { results.register("auth", AuthRequestEvent.class); diff --git a/LauncherCore/src/main/java/pro/gravit/utils/UniversalJsonAdapter.java b/LauncherCore/src/main/java/pro/gravit/utils/UniversalJsonAdapter.java index 0b7eede7..6fe3e639 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/UniversalJsonAdapter.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/UniversalJsonAdapter.java @@ -51,13 +51,16 @@ public UniversalJsonAdapter(ProviderMap providerMap, String name, String PROP public R deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString(); + if(typename == null) { + throw new JsonParseException(String.format("%s: missing type property", name)); + } Class cls = providerMap.getClass(typename); if (cls == null) { - //if (printErrorIfUnknownType) LogHelper.error("%s %s not found", name, typename); if (defaultClass != null) { return context.deserialize(json, defaultClass); + } else { + throw new JsonParseException(String.format("%s: type %s not registered", name, typename)); } - return null; } return context.deserialize(json, cls); } @@ -72,6 +75,8 @@ public JsonElement serialize(R src, Type typeOfSrc, JsonSerializationContext con } if (classPath != null) { jo.add(PROP_NAME, new JsonPrimitive(classPath)); + } else { + throw new JsonParseException(String.format("Class %s not registered", src.getClass().getName())); } return jo; } diff --git a/LauncherCore/src/main/java/pro/gravit/utils/Version.java b/LauncherCore/src/main/java/pro/gravit/utils/Version.java index 83cdc0fb..694800ac 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/Version.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/Version.java @@ -5,10 +5,10 @@ public final class Version implements Comparable { public static final int MAJOR = 5; - public static final int MINOR = 3; - public static final int PATCH = 6; + public static final int MINOR = 4; + public static final int PATCH = 0; public static final int BUILD = 1; - public static final Version.Type RELEASE = Type.DEV; + public static final Version.Type RELEASE = Type.EXPERIMENTAL; public final int major; public final int minor; public final int patch; diff --git a/LauncherCore/src/main/java/pro/gravit/utils/helper/JVMHelper.java b/LauncherCore/src/main/java/pro/gravit/utils/helper/JVMHelper.java index 43acfbe7..ec0c26e1 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/helper/JVMHelper.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/helper/JVMHelper.java @@ -26,7 +26,6 @@ public final class JVMHelper { public static final String OS_VERSION = OPERATING_SYSTEM_MXBEAN.getVersion(); public static final ARCH ARCH_TYPE = getArch(System.getProperty("os.arch")); public static final int JVM_BITS = Integer.parseInt(System.getProperty("sun.arch.data.model")); - public static final SecurityManager SECURITY_MANAGER = System.getSecurityManager(); // Public static fields public static final Runtime RUNTIME = Runtime.getRuntime(); public static final ClassLoader LOADER = ClassLoader.getSystemClassLoader(); diff --git a/modules b/modules index 1f34a8f8..2ea978f0 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 1f34a8f8bcb6399469da0e27e8d3e7e3a20d3e00 +Subproject commit 2ea978f02d44893b7f02ae63eac3d3a07a1e0e11 From ffad29f53bebc1a1ae3d588b7710efc7b78fe631 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sun, 26 Feb 2023 18:40:11 +0700 Subject: [PATCH 03/38] [FEATURE] Isolate Minecraft: Support add packages to ignore --- .../launcher/client/ClientClassLoader.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java index 7bb96e7b..192e0741 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java @@ -5,11 +5,15 @@ import java.net.URL; import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; public class ClientClassLoader extends URLClassLoader { private static final ClassLoader SYSTEM_CLASS_LOADER = ClassLoader.getSystemClassLoader(); public String nativePath; + private List packages = new ArrayList<>(); + /** * Constructs a new URLClassLoader for the specified URLs using the * default delegation parent {@code ClassLoader}. The URLs will @@ -32,6 +36,8 @@ public class ClientClassLoader extends URLClassLoader { */ public ClientClassLoader(URL[] urls) { super(urls); + packages.add("pro.gravit.launcher."); + packages.add("pro.gravit.utils."); } /** @@ -61,8 +67,12 @@ public ClientClassLoader(URL[] urls, ClassLoader parent) { @Override protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if(name != null && (name.startsWith("pro.gravit.launcher.") || name.startsWith("pro.gravit.utils."))) { - return SYSTEM_CLASS_LOADER.loadClass(name); + if(name != null) { + for(String pkg : packages) { + if(name.startsWith(pkg)) { + return SYSTEM_CLASS_LOADER.loadClass(name); + } + } } return super.loadClass(name, resolve); } @@ -90,6 +100,10 @@ else if (JVMHelper.OS_TYPE == JVMHelper.OS.MACOSX) return ""; } + public void addAllowedPackage(String pkg) { + packages.add(pkg); + } + @Override public void addURL(URL url) { super.addURL(url); From 930a5caf746c7599e7b50672b7c8636605c5bfe2 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sun, 26 Feb 2023 19:01:43 +0700 Subject: [PATCH 04/38] [ANY] Remove old guard/antiinject support --- .../binary/JARLauncherBinary.java | 2 - .../binary/tasks/MainBuildTask.java | 2 - .../binary/tasks/PrepareBuildTask.java | 1 - .../config/LaunchServerConfig.java | 2 - .../pro/gravit/launcher/LauncherEngine.java | 15 ------- .../client/ClientLauncherProcess.java | 1 - .../gravit/launcher/guard/LauncherGuard.java | 9 ----- .../launcher/guard/LauncherNoGuard.java | 15 ------- .../launcher/guard/LauncherWrapperGuard.java | 40 ------------------- .../java/pro/gravit/launcher/Launcher.java | 1 - .../pro/gravit/launcher/LauncherConfig.java | 5 --- 11 files changed, 93 deletions(-) delete mode 100644 Launcher/src/main/java/pro/gravit/launcher/guard/LauncherGuard.java delete mode 100644 Launcher/src/main/java/pro/gravit/launcher/guard/LauncherNoGuard.java delete mode 100644 Launcher/src/main/java/pro/gravit/launcher/guard/LauncherWrapperGuard.java diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/JARLauncherBinary.java b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/JARLauncherBinary.java index 77685633..72f60338 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/JARLauncherBinary.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/JARLauncherBinary.java @@ -16,7 +16,6 @@ public final class JARLauncherBinary extends LauncherBinary { public final AtomicLong count; public final Path runtimeDir; - public final Path guardDir; public final Path buildDir; public final List coreLibs; public final List addonLibs; @@ -27,7 +26,6 @@ public JARLauncherBinary(LaunchServer server) throws IOException { super(server, resolve(server, ".jar"), "Launcher-%s-%d.jar"); count = new AtomicLong(0); runtimeDir = server.dir.resolve(Launcher.RUNTIME_DIR); - guardDir = server.dir.resolve(Launcher.GUARD_DIR); buildDir = server.dir.resolve("build"); coreLibs = new ArrayList<>(); addonLibs = new ArrayList<>(); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/MainBuildTask.java b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/MainBuildTask.java index 27e06a7b..0b3a87bf 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/MainBuildTask.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/MainBuildTask.java @@ -72,7 +72,6 @@ public Path process(Path inputJar) throws IOException { } else { context.pushDir(server.launcherBinary.runtimeDir, Launcher.RUNTIME_DIR, runtime, false); } - context.pushDir(server.launcherBinary.guardDir, Launcher.GUARD_DIR, runtime, false); LauncherConfig launcherConfig = new LauncherConfig(server.config.netty.address, server.keyAgreementManager.ecdsaPublicKey, server.keyAgreementManager.rsaPublicKey, runtime, server.config.projectName); context.pushFile(Launcher.CONFIG_FILE, launcherConfig); @@ -108,7 +107,6 @@ protected void initProps() { properties.put("launcher.projectName", server.config.projectName); properties.put("runtimeconfig.secretKeyClient", SecurityHelper.randomStringAESKey()); properties.put("launcher.port", 32148 + SecurityHelper.newRandom().nextInt(512)); - properties.put("launcher.guardType", server.config.launcher.guardType); properties.put("launchercore.env", server.config.env); properties.put("launcher.memory", server.config.launcher.memoryLimit); properties.put("launcher.customJvmOptions", server.config.launcher.customJvmOptions); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/PrepareBuildTask.java b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/PrepareBuildTask.java index 0ab1675c..4772615b 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/PrepareBuildTask.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/PrepareBuildTask.java @@ -60,7 +60,6 @@ public boolean allowDelete() { public void tryUnpack() throws IOException { logger.info("Unpacking launcher native guard list and runtime"); - UnpackHelper.unpackZipNoCheck("guard.zip", server.launcherBinary.guardDir); UnpackHelper.unpackZipNoCheck("runtime.zip", server.launcherBinary.runtimeDir); } 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 583bf33b..af766e3c 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java @@ -84,7 +84,6 @@ public static LaunchServerConfig getDefault(LaunchServer.LaunchServerEnv env) { newConfig.netty.performance.schedulerThread = 2; newConfig.launcher = new LauncherConf(); - newConfig.launcher.guardType = "no"; newConfig.launcher.compress = true; newConfig.launcher.deleteTempFiles = true; newConfig.launcher.stripLineNumbers = true; @@ -269,7 +268,6 @@ public static class NettyUpdatesBind { } public static class LauncherConf { - public String guardType; public boolean compress; public boolean stripLineNumbers; public boolean deleteTempFiles; diff --git a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java index 793f151c..6f22d4f9 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java +++ b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java @@ -8,9 +8,6 @@ import pro.gravit.launcher.console.ModulesCommand; import pro.gravit.launcher.console.SignDataCommand; import pro.gravit.launcher.events.request.*; -import pro.gravit.launcher.guard.LauncherGuard; -import pro.gravit.launcher.guard.LauncherNoGuard; -import pro.gravit.launcher.guard.LauncherWrapperGuard; import pro.gravit.launcher.gui.NoRuntimeProvider; import pro.gravit.launcher.gui.RuntimeProvider; import pro.gravit.launcher.managers.ClientGsonManager; @@ -49,7 +46,6 @@ public class LauncherEngine { public static ClientLauncherProcess.ClientParams clientParams; - public static LauncherGuard guard; public static ClientModuleManager modulesManager; public final boolean clientInstance; // Instance @@ -153,16 +149,6 @@ public static void verifyNoAgent() { throw new SecurityException("JavaAgent found"); } - public static LauncherGuard tryGetStdGuard() { - switch (Launcher.getConfig().guardType) { - case "no": - return new LauncherNoGuard(); - case "wrapper": - return new LauncherWrapperGuard(); - } - return null; - } - public static RequestService initOffline() { OfflineRequestService service = new OfflineRequestService(); applyBasicOfflineProcessors(service); @@ -232,7 +218,6 @@ public void readKeys() throws IOException, InvalidKeySpecException { public void start(String... args) throws Throwable { //Launcher.modulesManager = new ClientModuleManager(this); - LauncherEngine.guard = tryGetStdGuard(); ClientPreGuiPhase event = new ClientPreGuiPhase(null); LauncherEngine.modulesManager.invokeEvent(event); runtimeProvider = event.runtimeProvider; 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 66bcc917..8a9343f6 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java @@ -133,7 +133,6 @@ private void applyClientProfile() { public void start(boolean pipeOutput) throws IOException, InterruptedException { if (isStarted) throw new IllegalStateException("Process already started"); - if (LauncherEngine.guard != null) LauncherEngine.guard.applyGuardParams(this); LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderPreLaunchEvent(this)); List processArgs = new LinkedList<>(); processArgs.add(executeFile.toString()); diff --git a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherGuard.java b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherGuard.java deleted file mode 100644 index 899cf1af..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherGuard.java +++ /dev/null @@ -1,9 +0,0 @@ -package pro.gravit.launcher.guard; - -import pro.gravit.launcher.client.ClientLauncherProcess; - -public interface LauncherGuard { - String getName(); - - void applyGuardParams(ClientLauncherProcess process); -} diff --git a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherNoGuard.java b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherNoGuard.java deleted file mode 100644 index d43bff54..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherNoGuard.java +++ /dev/null @@ -1,15 +0,0 @@ -package pro.gravit.launcher.guard; - -import pro.gravit.launcher.client.ClientLauncherProcess; - -public class LauncherNoGuard implements LauncherGuard { - @Override - public String getName() { - return "noGuard"; - } - - @Override - public void applyGuardParams(ClientLauncherProcess process) { - //IGNORED - } -} diff --git a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherWrapperGuard.java b/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherWrapperGuard.java deleted file mode 100644 index 0991673a..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/guard/LauncherWrapperGuard.java +++ /dev/null @@ -1,40 +0,0 @@ -package pro.gravit.launcher.guard; - -import pro.gravit.launcher.Launcher; -import pro.gravit.launcher.client.ClientLauncherProcess; -import pro.gravit.launcher.client.DirBridge; -import pro.gravit.utils.helper.JVMHelper; -import pro.gravit.utils.helper.UnpackHelper; - -import java.io.IOException; - -public class LauncherWrapperGuard implements LauncherGuard { - - public LauncherWrapperGuard() { - try { - String wrapperName = JVMHelper.JVM_BITS == 64 ? "wrapper64.exe" : "wrapper32.exe"; - String projectName = Launcher.getConfig().projectName; - String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe"); - String antiInjectName = JVMHelper.JVM_BITS == 64 ? "AntiInject64.dll" : "AntiInject32.dll"; - UnpackHelper.unpack(Launcher.getResourceURL(wrapperName, "guard"), DirBridge.getGuardDir().resolve(wrapperUnpackName)); - UnpackHelper.unpack(Launcher.getResourceURL(antiInjectName, "guard"), DirBridge.getGuardDir().resolve(antiInjectName)); - } catch (IOException e) { - throw new SecurityException(e); - } - } - - @Override - public String getName() { - return "wrapper"; - } - - @Override - public void applyGuardParams(ClientLauncherProcess process) { - if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) { - String projectName = Launcher.getConfig().projectName; - String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe"); - process.executeFile = DirBridge.getGuardDir().resolve(wrapperUnpackName); - process.useLegacyJavaClassPathProperty = true; - } - } -} diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/Launcher.java b/LauncherAPI/src/main/java/pro/gravit/launcher/Launcher.java index 384623cb..e9471df0 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/Launcher.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/Launcher.java @@ -41,7 +41,6 @@ public final class Launcher { public static final String RUNTIME_DIR = "runtime"; // Constants - public static final String GUARD_DIR = "guard"; public static final String CONFIG_FILE = "config.bin"; private static final AtomicReference CONFIG = new AtomicReference<>(); private static final Pattern UUID_PATTERN = Pattern.compile("-", Pattern.LITERAL); diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/LauncherConfig.java b/LauncherAPI/src/main/java/pro/gravit/launcher/LauncherConfig.java index 290d64e3..0d90c99d 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/LauncherConfig.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/LauncherConfig.java @@ -32,8 +32,6 @@ public final class LauncherConfig extends StreamObject { public final ECPublicKey ecdsaPublicKey; public final RSAPublicKey rsaPublicKey; public final Map runtime; - @LauncherInject("launcher.guardType") - public final String guardType; @LauncherInject("runtimeconfig.secureCheckHash") public final String secureCheckHash; @LauncherInject("runtimeconfig.secureCheckSalt") @@ -68,7 +66,6 @@ public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException } catch (CertificateException e) { throw new IOException(e); } - guardType = null; address = null; environment = LauncherEnvironment.STD; Launcher.applyLauncherEnv(environment); @@ -91,7 +88,6 @@ public LauncherConfig(String address, ECPublicKey ecdsaPublicKey, RSAPublicKey r this.runtime = Collections.unmodifiableMap(new HashMap<>(runtime)); this.projectName = projectName; this.clientPort = 32148; - guardType = "no"; environment = LauncherEnvironment.STD; secureCheckSalt = null; secureCheckHash = null; @@ -109,7 +105,6 @@ public LauncherConfig(String address, Map runtime, String projec this.rsaPublicKey = null; this.ecdsaPublicKey = null; environment = env; - guardType = "no"; secureCheckSalt = null; secureCheckHash = null; passwordEncryptKey = null; From 8ac98662586ac2628e5d23a7203d562d5fa9bb3e Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Tue, 7 Mar 2023 15:23:20 +0700 Subject: [PATCH 05/38] [FEATURE] SentryProguardUpload --- .../java/pro/gravit/launchserver/binary/BinaryPipeline.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/BinaryPipeline.java b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/BinaryPipeline.java index e63af2db..8e3fc539 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/BinaryPipeline.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/BinaryPipeline.java @@ -86,7 +86,7 @@ public void build(Path target, boolean deleteTempFiles) throws IOException { long time_task_end = System.currentTimeMillis(); long time_task = time_task_end - time_this; time_this = time_task_end; - if (isNeedDelete && deleteTempFiles) Files.deleteIfExists(oldPath); + if (isNeedDelete && deleteTempFiles && oldPath != thisPath) Files.deleteIfExists(oldPath); isNeedDelete = task.allowDelete(); logger.info("Task {} processed from {} millis", task.getName(), time_task); } From 57868a7136b0e0fa0f80508011ae4c3a9599f1ff Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Tue, 7 Mar 2023 15:23:49 +0700 Subject: [PATCH 06/38] [ANY] Update modules --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index e16960e7..85db9a5c 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit e16960e7eef248a217071638f0e68b14cec09cb8 +Subproject commit 85db9a5c07c56108485b1138f14cacb15b253c1f From cf802fb0b32f1c7af933650fada2733711d26c67 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Wed, 15 Mar 2023 18:50:15 +0700 Subject: [PATCH 07/38] [FEATURE] Support 1.19.4 --- .../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 ff1af074..c4a1342e 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java @@ -471,7 +471,8 @@ public enum Version { MC119("1.19", 759), MC1191("1.19.1", 760), MC1192("1.19.2", 760), - MC1193("1.19.3", 761); + MC1193("1.19.3", 761), + MC1194("1.19.4", 762); private static final Map VERSIONS; static { From a796b82a16e883976e7f26b4c9d3b4efb5798626 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Thu, 16 Mar 2023 21:57:33 +0700 Subject: [PATCH 08/38] [FIX] JavaHelper NPE --- .../src/main/java/pro/gravit/utils/helper/JavaHelper.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/LauncherCore/src/main/java/pro/gravit/utils/helper/JavaHelper.java b/LauncherCore/src/main/java/pro/gravit/utils/helper/JavaHelper.java index 8fa7cb7e..a0467b27 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/helper/JavaHelper.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/helper/JavaHelper.java @@ -76,10 +76,13 @@ public synchronized static List findJava() { if (Files.exists(javaExecPath)) { javaExecPath = javaExecPath.toRealPath(); p1 = javaExecPath.getParent().getParent(); + if(p1 == null) { + continue; + } tryAddJava(javaPaths, result, JavaVersion.getByPath(p1)); trySearchJava(javaPaths, result, p1.getParent()); } - } catch (InvalidPathException ignored) { + } catch (InvalidPathException | NullPointerException ignored) { } catch (IOException e) { LogHelper.error(e); @@ -128,7 +131,7 @@ public static boolean tryAddJava(List javaPaths, List resul } public static void trySearchJava(List javaPaths, List result, Path path) throws IOException { - if (!Files.isDirectory(path)) return; + if (path == null || !Files.isDirectory(path)) return; Files.list(path).filter(p -> Files.exists(p.resolve("bin").resolve(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE ? "java.exe" : "java"))).forEach(e -> { try { tryAddJava(javaPaths, result, JavaVersion.getByPath(e)); From e4bf8f1e9c58b1ebe0dc994f135b2f6cd3c96b61 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sun, 19 Mar 2023 21:22:37 +0700 Subject: [PATCH 09/38] [ANY] Update modules --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index 85db9a5c..6a284dff 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 85db9a5c07c56108485b1138f14cacb15b253c1f +Subproject commit 6a284dffdf683edc66d10e5c9e33e6d0b5051bd5 From 71739f5670ae5b86506989f4cea5fe41a8f07842 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sun, 19 Mar 2023 21:27:14 +0700 Subject: [PATCH 10/38] [ANY] Update modules --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index 6a284dff..648a1b06 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 6a284dffdf683edc66d10e5c9e33e6d0b5051bd5 +Subproject commit 648a1b06445a5a48847cd2f3e7077762c170dec4 From 17f9c28f3d233d5ef407e13bb0dc2d382919a9f9 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Mon, 20 Mar 2023 00:25:27 +0700 Subject: [PATCH 11/38] [FEATURE] WebSocket hook rework --- .../LaunchServerNettyFullInitEvent.java | 12 ++ .../launchserver/socket/WebSocketService.java | 140 ++++++------------ .../handlers/NettyServerSocketHandler.java | 2 + .../socket/response/SimpleResponse.java | 4 +- .../management/ServerStatusResponse.java | 27 ---- .../request/ServerStatusRequestEvent.java | 24 --- .../management/ServerStatusRequest.java | 11 -- .../websockets/ClientWebSocketService.java | 1 - 8 files changed, 59 insertions(+), 162 deletions(-) create mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/modules/events/LaunchServerNettyFullInitEvent.java delete mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/ServerStatusResponse.java delete mode 100644 LauncherAPI/src/main/java/pro/gravit/launcher/events/request/ServerStatusRequestEvent.java delete mode 100644 LauncherAPI/src/main/java/pro/gravit/launcher/request/management/ServerStatusRequest.java diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/modules/events/LaunchServerNettyFullInitEvent.java b/LaunchServer/src/main/java/pro/gravit/launchserver/modules/events/LaunchServerNettyFullInitEvent.java new file mode 100644 index 00000000..dae7d45b --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/modules/events/LaunchServerNettyFullInitEvent.java @@ -0,0 +1,12 @@ +package pro.gravit.launchserver.modules.events; + +import pro.gravit.launcher.modules.LauncherModule; +import pro.gravit.launchserver.LaunchServer; + +public class LaunchServerNettyFullInitEvent extends LauncherModule.Event { + public final LaunchServer server; + + public LaunchServerNettyFullInitEvent(LaunchServer server) { + this.server = server; + } +} 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 172883ca..555bb696 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java @@ -5,7 +5,6 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.group.ChannelGroup; -import io.netty.channel.group.ChannelMatchers; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -21,7 +20,6 @@ import pro.gravit.launchserver.socket.response.auth.*; import pro.gravit.launchserver.socket.response.management.FeaturesResponse; import pro.gravit.launchserver.socket.response.management.GetPublicKeyResponse; -import pro.gravit.launchserver.socket.response.management.ServerStatusResponse; import pro.gravit.launchserver.socket.response.profile.BatchProfileByUsername; import pro.gravit.launchserver.socket.response.profile.ProfileByUUIDResponse; import pro.gravit.launchserver.socket.response.profile.ProfileByUsername; @@ -33,26 +31,21 @@ import pro.gravit.launchserver.socket.response.update.UpdateListResponse; import pro.gravit.launchserver.socket.response.update.UpdateResponse; import pro.gravit.utils.BiHookSet; +import pro.gravit.utils.HookSet; import pro.gravit.utils.ProviderMap; import pro.gravit.utils.helper.IOHelper; import java.lang.reflect.Type; import java.util.UUID; -import java.util.concurrent.atomic.AtomicLong; import java.util.function.BiConsumer; public class WebSocketService { public static final ProviderMap providers = new ProviderMap<>(); public final ChannelGroup channels; - public final BiHookSet hook = new BiHookSet<>(); - //Statistic data - public final AtomicLong shortRequestLatency = new AtomicLong(); - public final AtomicLong shortRequestCounter = new AtomicLong(); - public final AtomicLong middleRequestLatency = new AtomicLong(); - public final AtomicLong middleRequestCounter = new AtomicLong(); - public final AtomicLong longRequestLatency = new AtomicLong(); - public final AtomicLong longRequestCounter = new AtomicLong(); - public final AtomicLong lastRequestTime = new AtomicLong(); + public final HookSet hookBeforeParsing = new HookSet<>(); + public final HookSet hookBeforeExecute = new HookSet<>(); + public final HookSet hookComplete = new HookSet<>(); + public final BiHookSet hookSend = new BiHookSet<>(); private final LaunchServer server; private final Gson gson; private transient final Logger logger = LogManager.getLogger(); @@ -83,7 +76,6 @@ public static void registerResponses() { providers.register("verifySecureLevelKey", VerifySecureLevelKeyResponse.class); providers.register("securityReport", SecurityReportResponse.class); providers.register("hardwareReport", HardwareReportResponse.class); - providers.register("serverStatus", ServerStatusResponse.class); providers.register("currentUser", CurrentUserResponse.class); providers.register("features", FeaturesResponse.class); providers.register("refreshToken", RefreshTokenResponse.class); @@ -119,55 +111,27 @@ public void forEachActiveChannels(BiConsumer cal } public void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client, String ip) { - long startTimeNanos = System.nanoTime(); String request = frame.text(); + WebSocketRequestContext context = new WebSocketRequestContext(ctx, request, client, ip); + if(hookBeforeParsing.hook(context)) { + return; + } WebSocketServerResponse response = gson.fromJson(request, WebSocketServerResponse.class); + context.response = response; if (response == null) { RequestEvent event = new ErrorRequestEvent("This type of request is not supported"); - sendObject(ctx, event); + hookComplete.hook(context); + sendObject(ctx.channel(), event, WebSocketEvent.class); return; } - process(ctx, response, client, ip); - long executeTime = System.nanoTime() - startTimeNanos; - if (executeTime > 0) { - addRequestTimeToStats(executeTime); - } + process(context, response, client, ip); } - public void addRequestTimeToStats(long nanos) { - if (nanos < 100_000_000L) // < 100 millis - { - shortRequestCounter.getAndIncrement(); - shortRequestLatency.getAndAdd(nanos); - } else if (nanos < 1_000_000_000L) // > 100 millis and < 1 second - { - middleRequestCounter.getAndIncrement(); - middleRequestLatency.getAndAdd(nanos); - } else // > 1 second - { - longRequestCounter.getAndIncrement(); - longRequestLatency.getAndAdd(nanos); - } - long lastTime = lastRequestTime.get(); - long currentTime = System.currentTimeMillis(); - if (currentTime - lastTime > 60 * 1000) //1 minute - { - lastRequestTime.set(currentTime); - shortRequestLatency.set(0); - shortRequestCounter.set(0); - middleRequestCounter.set(0); - middleRequestLatency.set(0); - longRequestCounter.set(0); - longRequestLatency.set(0); - } - - } - - void process(ChannelHandlerContext ctx, WebSocketServerResponse response, Client client, String ip) { - WebSocketRequestContext context = new WebSocketRequestContext(response, client, ip); - if (hook.hook(context, ctx)) { + void process(WebSocketRequestContext context, WebSocketServerResponse response, Client client, String ip) { + if (hookBeforeExecute.hook(context)) { return; } + ChannelHandlerContext ctx = context.context; if (response instanceof SimpleResponse simpleResponse) { simpleResponse.server = server; simpleResponse.service = this; @@ -177,38 +141,27 @@ void process(ChannelHandlerContext ctx, WebSocketServerResponse response, Client } try { response.execute(ctx, client); - } catch (Exception e) { + } catch (Throwable e) { + context.exception = e; logger.error("WebSocket request processing failed", e); RequestEvent event; event = new ErrorRequestEvent("Fatal server error. Contact administrator"); if (response instanceof SimpleResponse) { event.requestUUID = ((SimpleResponse) response).requestUUID; } - sendObject(ctx, event); + sendObject(ctx.channel(), event); } + hookComplete.hook(context); } public void registerClient(Channel channel) { channels.add(channel); } - public void sendObject(ChannelHandlerContext ctx, Object obj) { - String msg = gson.toJson(obj, WebSocketEvent.class); - if (logger.isTraceEnabled()) { - logger.trace("Send to {}: {}", getIPFromContext(ctx), msg); - } - ctx.writeAndFlush(new TextWebSocketFrame(msg), ctx.voidPromise()); - } - - public void sendObject(ChannelHandlerContext ctx, Object obj, Type type) { - String msg = gson.toJson(obj, type); - if (logger.isTraceEnabled()) { - logger.trace("Send to {}: {}", getIPFromContext(ctx), msg); - } - ctx.writeAndFlush(new TextWebSocketFrame(msg), ctx.voidPromise()); - } - public void sendObject(Channel channel, Object obj) { + if(hookSend.hook(channel, obj)) { + return; + } String msg = gson.toJson(obj, WebSocketEvent.class); if (logger.isTraceEnabled()) { logger.trace("Send to channel {}: {}", getIPFromChannel(channel), msg); @@ -217,6 +170,9 @@ public void sendObject(Channel channel, Object obj) { } public void sendObject(Channel channel, Object obj, Type type) { + if(hookSend.hook(channel, obj)) { + return; + } String msg = gson.toJson(obj, type); if (logger.isTraceEnabled()) { logger.trace("Send to channel {}: {}", getIPFromChannel(channel), msg); @@ -224,23 +180,9 @@ public void sendObject(Channel channel, Object obj, Type type) { channel.writeAndFlush(new TextWebSocketFrame(msg), channel.voidPromise()); } - public void sendObjectAll(Object obj) { - String msg = gson.toJson(obj, WebSocketEvent.class); - if (logger.isTraceEnabled()) { - logger.trace("Send to all: {}", msg); - } - for (Channel ch : channels) { - ch.writeAndFlush(new TextWebSocketFrame(msg), ch.voidPromise()); - } - } - public void sendObjectAll(Object obj, Type type) { - String msg = gson.toJson(obj, type); - if (logger.isTraceEnabled()) { - logger.trace("Send to all: {}", msg); - } for (Channel ch : channels) { - ch.writeAndFlush(new TextWebSocketFrame(msg), ch.voidPromise()); + sendObject(ch, obj, type); } } @@ -251,6 +193,9 @@ public void sendObjectToUUID(UUID userUuid, Object obj, Type type) { if (wsHandler == null) continue; Client client = wsHandler.getClient(); if (client == null || !userUuid.equals(client.uuid)) continue; + if(hookSend.hook(ch, obj)) { + continue; + } String msg = gson.toJson(obj, type); if (logger.isTraceEnabled()) { logger.trace("Send to {}({}): {}", getIPFromChannel(ch), userUuid, msg); @@ -319,6 +264,9 @@ public boolean kickByIP(String ip, boolean isClose) { } public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj) { + if(hookSend.hook(ctx.channel(), obj)) { + return; + } String msg = gson.toJson(obj, WebSocketEvent.class); if (logger.isTraceEnabled()) { logger.trace("Send and close {}: {}", getIPFromContext(ctx), msg); @@ -327,6 +275,9 @@ public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj) { } public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj, Type type) { + if(hookSend.hook(ctx.channel(), obj)) { + return; + } String msg = gson.toJson(obj, type); if (logger.isTraceEnabled()) { logger.trace("Send and close {}: {}", getIPFromContext(ctx), msg); @@ -334,22 +285,17 @@ public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj, Type type) ctx.writeAndFlush(new TextWebSocketFrame(msg)).addListener(ChannelFutureListener.CLOSE); } - @Deprecated - public void sendEvent(EventResult obj) { - String msg = gson.toJson(obj, WebSocketEvent.class); - if (logger.isTraceEnabled()) { - logger.trace("Send event: {}", msg); - } - channels.writeAndFlush(new TextWebSocketFrame(msg), ChannelMatchers.all(), true); - } - public static class WebSocketRequestContext { - public final WebSocketServerResponse response; + public final ChannelHandlerContext context; + public final String text; public final Client client; public final String ip; + public WebSocketServerResponse response; + public Throwable exception; - public WebSocketRequestContext(WebSocketServerResponse response, Client client, String ip) { - this.response = response; + public WebSocketRequestContext(ChannelHandlerContext context, String text, Client client, String ip) { + this.context = context; + this.text = text; this.client = client; this.ip = ip; } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyServerSocketHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyServerSocketHandler.java index d01b2e84..09d1ec84 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyServerSocketHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyServerSocketHandler.java @@ -4,6 +4,7 @@ import org.apache.logging.log4j.Logger; import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.config.LaunchServerConfig; +import pro.gravit.launchserver.modules.events.LaunchServerNettyFullInitEvent; import pro.gravit.launchserver.socket.LauncherNettyServer; import javax.net.ssl.SSLServerSocketFactory; @@ -34,5 +35,6 @@ public void run() { for (LaunchServerConfig.NettyBindAddress address : server.config.netty.binds) { nettyServer.bind(new InetSocketAddress(address.address, address.port)); } + server.modulesManager.invokeEvent(new LaunchServerNettyFullInitEvent(server)); } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/SimpleResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/SimpleResponse.java index 50b7b8ce..87e15aed 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/SimpleResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/SimpleResponse.java @@ -17,7 +17,7 @@ public abstract class SimpleResponse implements WebSocketServerResponse { public void sendResult(RequestEvent result) { result.requestUUID = requestUUID; - service.sendObject(ctx, result); + service.sendObject(ctx.channel(), result); } public void sendResultAndClose(RequestEvent result) { @@ -28,6 +28,6 @@ public void sendResultAndClose(RequestEvent result) { public void sendError(String errorMessage) { ErrorRequestEvent event = new ErrorRequestEvent(errorMessage); event.requestUUID = requestUUID; - service.sendObject(ctx, event); + service.sendObject(ctx.channel(), event); } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/ServerStatusResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/ServerStatusResponse.java deleted file mode 100644 index 53108a26..00000000 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/ServerStatusResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package pro.gravit.launchserver.socket.response.management; - -import io.netty.channel.ChannelHandlerContext; -import pro.gravit.launcher.events.request.ServerStatusRequestEvent; -import pro.gravit.launchserver.socket.Client; -import pro.gravit.launchserver.socket.response.SimpleResponse; -import pro.gravit.utils.helper.JVMHelper; - -public class ServerStatusResponse extends SimpleResponse { - @Override - public String getType() { - return "serverStatus"; - } - - @Override - public void execute(ChannelHandlerContext ctx, Client client) { - ServerStatusRequestEvent event = new ServerStatusRequestEvent(server.config.projectName); - event.totalJavaMemory = JVMHelper.RUNTIME.totalMemory(); - event.freeJavaMemory = JVMHelper.RUNTIME.freeMemory(); - event.shortLatency = (service.shortRequestLatency.get() / service.shortRequestCounter.get()) / 1_000_000; - event.middleLatency = (service.middleRequestLatency.get() / service.middleRequestCounter.get()) / 1_000_000; - event.longLatency = (service.longRequestLatency.get() / service.longRequestCounter.get()) / 1_000_000; - event.latency = ((service.shortRequestLatency.get() + service.middleRequestLatency.get() + service.longRequestLatency.get()) / - (service.shortRequestCounter.get() + service.middleRequestCounter.get() + service.longRequestCounter.get())) / 1_000_000; - sendResult(event); - } -} diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/ServerStatusRequestEvent.java b/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/ServerStatusRequestEvent.java deleted file mode 100644 index 47a5a0db..00000000 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/ServerStatusRequestEvent.java +++ /dev/null @@ -1,24 +0,0 @@ -package pro.gravit.launcher.events.request; - -import pro.gravit.launcher.events.RequestEvent; - -public class ServerStatusRequestEvent extends RequestEvent { - public final String projectName; - public long totalJavaMemory; - public long freeJavaMemory; - - //Latency - public long shortLatency; //Millis - public long middleLatency; //Millis - public long longLatency; //Millis - public long latency; - - public ServerStatusRequestEvent(String projectName) { - this.projectName = projectName; - } - - @Override - public String getType() { - return "serverStatus"; - } -} diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/management/ServerStatusRequest.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/management/ServerStatusRequest.java deleted file mode 100644 index e40199ca..00000000 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/management/ServerStatusRequest.java +++ /dev/null @@ -1,11 +0,0 @@ -package pro.gravit.launcher.request.management; - -import pro.gravit.launcher.events.request.ServerStatusRequestEvent; -import pro.gravit.launcher.request.Request; - -public class ServerStatusRequest extends Request { - @Override - public String getType() { - return "serverStatus"; - } -} 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 8b234a4a..9da094b4 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 @@ -102,7 +102,6 @@ public void registerResults() { results.register("verifySecureLevelKey", VerifySecureLevelKeyRequestEvent.class); results.register("securityReport", SecurityReportRequestEvent.class); results.register("hardwareReport", HardwareReportRequestEvent.class); - results.register("serverStatus", ServerStatusRequestEvent.class); results.register("currentUser", CurrentUserRequestEvent.class); results.register("features", FeaturesRequestEvent.class); results.register("refreshToken", RefreshTokenRequestEvent.class); From eff739ce124ba2bad1b1d64e73695ebc2e41e60c Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Mon, 20 Mar 2023 00:25:55 +0700 Subject: [PATCH 12/38] [ANY] Update modules --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index 648a1b06..828d2483 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 648a1b06445a5a48847cd2f3e7077762c170dec4 +Subproject commit 828d2483509744aefde1b6082f5a56dc14b4e1e4 From dc664c7ee2cf6ab4f3f1861450017d11b08ea660 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Wed, 22 Mar 2023 21:18:08 +0700 Subject: [PATCH 13/38] [FIX] Forbidden modification info --- .../gravit/launcher/client/ClientLauncherEntryPoint.java | 7 +++++-- 1 file changed, 5 insertions(+), 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 1d095076..0817567f 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java @@ -33,7 +33,6 @@ import pro.gravit.launcher.utils.DirWatcher; import pro.gravit.utils.helper.*; -import javax.swing.*; import java.io.File; import java.io.IOException; import java.lang.invoke.MethodHandle; @@ -46,6 +45,7 @@ import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.*; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -241,20 +241,23 @@ public static void verifyHDir(Path dir, HashedDir hdir, FileNameMatcher matcher, // Hash directory and compare (ignore update-only matcher entries, it will break offline-mode) HashedDir currentHDir = new HashedDir(dir, matcher, true, digest); HashedDir.Diff diff = hdir.diff(currentHDir, matcher); + AtomicReference latestPath = new AtomicReference<>("unknown"); if (!diff.mismatch.isEmpty() || (checkExtra && !diff.extra.isEmpty())) { diff.extra.walk(File.separator, (e, k, v) -> { if (v.getType().equals(HashedEntry.Type.FILE)) { LogHelper.error("Extra file %s", e); + latestPath.set(e); } else LogHelper.error("Extra %s", e); return HashedDir.WalkAction.CONTINUE; }); diff.mismatch.walk(File.separator, (e, k, v) -> { if (v.getType().equals(HashedEntry.Type.FILE)) { LogHelper.error("Mismatch file %s", e); + latestPath.set(e); } else LogHelper.error("Mismatch %s", e); return HashedDir.WalkAction.CONTINUE; }); - throw new SecurityException(String.format("Forbidden modification: '%s'", IOHelper.getFileName(dir))); + throw new SecurityException(String.format("Forbidden modification: '%s' file '%s'", IOHelper.getFileName(dir), latestPath.get())); } } From fb2883d21562ecc12e064443db44062484b24eb5 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Wed, 22 Mar 2023 21:46:40 +0700 Subject: [PATCH 14/38] [FIX] Possible multithreading issue --- .../java11/pro/gravit/utils/Downloader.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/LauncherCore/src/main/java11/pro/gravit/utils/Downloader.java b/LauncherCore/src/main/java11/pro/gravit/utils/Downloader.java index 7f3445cf..3ca5dcde 100644 --- a/LauncherCore/src/main/java11/pro/gravit/utils/Downloader.java +++ b/LauncherCore/src/main/java11/pro/gravit/utils/Downloader.java @@ -19,6 +19,7 @@ import java.util.Queue; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; public class Downloader { @@ -28,7 +29,7 @@ public class Downloader { private static boolean isNoHttp2; protected final HttpClient client; protected final ExecutorService executor; - protected final LinkedList tasks = new LinkedList<>(); + protected final Queue tasks = new ConcurrentLinkedDeque<>(); protected CompletableFuture future; protected Downloader(HttpClient client, ExecutorService executor) { this.client = client; @@ -128,15 +129,13 @@ protected DownloadTask sendAsync(AsyncDownloader.SizedFile file, URI baseUri, Pa IOHelper.createParentDirs(targetDir.resolve(file.filePath)); ProgressTrackingBodyHandler bodyHandler = makeBodyHandler(targetDir.resolve(file.filePath), callback); CompletableFuture> future = client.sendAsync(makeHttpRequest(baseUri, file.urlPath), bodyHandler); - var ref = new Object() { - DownloadTask task = null; - }; - ref.task = new DownloadTask(bodyHandler, future.thenApply((e) -> { - tasks.remove(ref.task); + AtomicReference task = new AtomicReference<>(null); + task.set(new DownloadTask(bodyHandler, future.thenApply((e) -> { + tasks.remove(task.get()); return e; - })); - tasks.add(ref.task); - return ref.task; + }))); + tasks.add(task.get()); + return task.get(); } protected HttpRequest makeHttpRequest(URI baseUri, String filePath) throws URISyntaxException { From 111d7616d0f8c74e3049eca6ab009e152140d1c4 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Thu, 23 Mar 2023 18:56:23 +0700 Subject: [PATCH 15/38] [FIX] NPE --- .../src/main/java11/pro/gravit/utils/Downloader.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/LauncherCore/src/main/java11/pro/gravit/utils/Downloader.java b/LauncherCore/src/main/java11/pro/gravit/utils/Downloader.java index 3ca5dcde..71dc6c4e 100644 --- a/LauncherCore/src/main/java11/pro/gravit/utils/Downloader.java +++ b/LauncherCore/src/main/java11/pro/gravit/utils/Downloader.java @@ -130,11 +130,12 @@ protected DownloadTask sendAsync(AsyncDownloader.SizedFile file, URI baseUri, Pa ProgressTrackingBodyHandler bodyHandler = makeBodyHandler(targetDir.resolve(file.filePath), callback); CompletableFuture> future = client.sendAsync(makeHttpRequest(baseUri, file.urlPath), bodyHandler); AtomicReference task = new AtomicReference<>(null); - task.set(new DownloadTask(bodyHandler, future.thenApply((e) -> { - tasks.remove(task.get()); - return e; - }))); + task.set(new DownloadTask(bodyHandler, null /* fix NPE (future already completed) */)); tasks.add(task.get()); + task.get().completableFuture = future.thenApply((e) -> { + tasks.remove(task.get()); + return e; + }); return task.get(); } @@ -168,7 +169,7 @@ private static class ConsumerObject { public static class DownloadTask { public final ProgressTrackingBodyHandler bodyHandler; - public final CompletableFuture> completableFuture; + public CompletableFuture> completableFuture; public DownloadTask(ProgressTrackingBodyHandler bodyHandler, CompletableFuture> completableFuture) { this.bodyHandler = bodyHandler; From 55d2fbd57fb00f624a9c2a4beff560a57c489d37 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Thu, 23 Mar 2023 20:28:03 +0700 Subject: [PATCH 16/38] [ANY] Update modules --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index 828d2483..ed433be2 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 828d2483509744aefde1b6082f5a56dc14b4e1e4 +Subproject commit ed433be234a5d6b4336a6af48194add97b0f2874 From 70d102222bd7953d612da7031b18a6472f0ae220 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sat, 25 Mar 2023 23:54:00 +0700 Subject: [PATCH 17/38] [ANY] Upgrade gradle --- gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 61608 bytes gradle/wrapper/gradle-wrapper.properties | 3 ++- gradlew | 12 ++++++++---- gradlew.bat | 1 + 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f090a2944b7473328c07c9755baa3196..ccebba7710deaf9f98673a68957ea02138b60d0a 100644 GIT binary patch delta 39304 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 O;LQ#O9OtPYE&l^NyjRr# delta 38549 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 ltSba#rbH)&uY59oK&k!`i zQCd6QpF5CDEY?ki^7weSN^Iv#?+%_P*hf#@>-ifX2IX8DwyTR;os#GP^|CHs`i%Un+7fyyC?CsGcK; z`7yxeTABjw{(NNRpv?E(BwOI;dA)GQK6wnVu+~-&LzjFQX!twDMn2dZ57(QwA4ZaQ zEIYdI-?NiF38Tc0AXdbEkRY4va}J_hSmcVu-Dmb=uNMqexy z7oT<%k9ZLBq#LiPIGPG<;+;ytmeO}ci>GIetLCMAvkzpbBqa9J*ixOj2MBr%9>Wn} zv>1m!MntP$mw7>s+~M_ubQY%&0fgLg4WX+yhaPs*g1lhQM2QbXfGYzBd$q^p_38u(qv97>8>PCy0lyN_`}Nj}|KEJpWz!P7-j&g+%l{Z_E#YNN*! z!3nC$X}G^aqRp}4fbf98R~t-p$aI)P#IPDm{>iwDV*mHqE2%65sH8}Xd&D0pQj0Va`oOB#XhKJNcH2Iiy%;$@P|tAvhdZVgY;og&-2HT9Vc@UK1U;BojzM3fT6V!#+gf(Il~n>HG)(A z;Dw2h+n^&?&TmF`*lui?u^9MggpR@Of}TdC$d|p#E{Bfwl-p}N@5h`qB>&Gi>__Xj z7$N!DBuL*t2KLhfmk1%Srk%XX*9WfGUln?5E?q+Evni0e;%U|&5JC39E-pfMg#Gd> zhG*N-?#8QI(9Q0KVo*2YIwo{IFT!7v9SCG6a?yATO>Om<{;^%gyEJ5KCv)d4EHon8 zo4s1B57q9C-P*eogzm7OSpOrvVT%uhpq{Z8oX)fx)>l72!3mxn1x#93OIldO_g zgyU44zP94Aw!YZb6!>9a-wg@9);82wh;=#46sG8;b+Fg7FVv;x`}&;$C5zDPxtLbm zBLt?&%F~oc3d`hXXtOi3&8?q+!EF$q#jS`B;X-wBIG=kdn@SMIljUA09P5`(k=#UU|TAw2%_EFZ4ulu znCwPiitFb!XnU{PDXg9$I;OJK>ZTfugf^m|C6SRg(VII?Qic~-#7JtDq0ewJ;dT0ZNS@E_0j)aZOw80q?lS8g0Z6&iepWY>WkPn`fFaEOzo!^jB*vA+y-dP}j*N|(T8dC*=;HQ{6<@H6PaG;O% zA?-J|n?~-I8Xd!IiLSCZqMY#kh?^>DFDRXddzDp(3X1n2LP24Fh8E{*d{;lpu*t(o z4<5a6xQ7{dZTYAe?qPj>`G5-g8U^|v8A`j^UfKUP_SHV%Qd#OwPz7!8b0YkW!n&vb zYb`!tY(*LLMN$8L1NjxC&;FWgbd6mYQ*S8B%tgpBYCn<-cmK0-_*v7ymRCu9!sdX zl(+mZP$7j+Ro-Heb)=PAN()ZDF^!3t@1UN%a)T&#NHdK~_A}D_b9#|tS%`6@qaj1> z+*JTgAax^SPB`H@|K-A|%ob_;q?>|n|5_kE(tgQ4MgHa7$Dw2`L7(MKe#W|>@8w#v zV*?9djy8ah3V>W?crj7#;y4-}CLsNfhcW67t_Ib&YMcgE}uryl&7+x!q931N-^SHGuQE(LoLa}mpkci3t*< zThQu7S!a#s?S{{u#Ydp&B7l6vg3j8Uvqc|0Zo}bQqd7lp1IC8Ts!;%p(ldK{IaXxQ zAP*{OY3nqbWmsG92;=!C-`(tL>NvnW^^vO<^-| z_!hNvA^HK@_Mvs4V<`&?J`#>BS2MlXI$OH-O*Gr(@Ld9r8F_Lsv)%)q-D+^p%qo3i zDC$16$UeOCNqQ5xtI(_}#@!eSY1C#25q=f^}= zLdWnEJa9}ZOQJO$_-4mC2Z~saRF%T%L0Tb6H67?lmMy4RGbgTBA$!V^ba4Q{R1zDB z8RFxqVl{eQJziL_njVBhR&#SEwt4EzsYCuN-l!3@Nt{eMnJwM4(uL>Nj-ql-Hk+VA z4Y`jYt0~kKNg2++hkbqMj>=+W3t}p8BOfXIGZaOIpBZ%?&Dqf;M#1r6j?ssnGZs#$ z0uZ_pek{v+V(NvTWZMj&5RAav8akMY0<)x-wc;L`mz96CFI!E46QL!#>iej=VprVo zjVh%N?3Lr8NCyb7wFN9aIAW9q27O7A1&nS`I&2t)Z-#(KQBE+WntZ=%ju%QdAJ!+G zZWQvK*^jfLe0|L|dDP{?^i`cZkeHEyqIk~TtI`66ZkHqxf#^86S4hC}r?prw=4fq2 z6+zydlR^zdEv*GlwlL*AU^ zLFhf}S_19zGKtq*Mm^!SB2_8p;oA}91={gDx>h}*o_9016T)srei5>+pv!K^2RsG2 z=vW_t$l5>CJ;`NABK`qH{tRt*Zdi!B67}So(LG^!+v9sx(!}3ThsLwMz;|hF$u~a7 zBj1mS^t#to$^Go{0M>dqocVA z{uyQQ{U1~o=meVg$8;S`^?COXtwNLd#5x(TJ<&se!6CzbU-!IxB35N7-1TeR?;=VF>buyi}CEh0(= zD{L&Ej0^xvX=^`MY1%p(qtJUOOHFGc;Gegkl{1P*VxG5ePFDr`UH%&jXx%xUh70mr zQr`*<)(y^4nLy{oBRzUAtR*&oEF}!jljhmQ*#-^McoLUoj@MhP)A75?>EV~ZK}}n3 z9_0ec_k7G5T~5h~J!@hZ@!y=Yur9P2#7_lQ%zFT-G(INXbWf5T(u?+K>ozrKydwJS z_t|kiC!On~iaClc#5btCV<_TNBH18jj9#<}Lw{8dJ-7fC3SGe@v{&{j9U1w#1tgFx zQwZHOjz&V>p;k}LBp%W@15xlAvKb`dv{c8iARPW6!q7-Fm`?sR7&<>Sh`F2nFXzY3 z128}#Prm*ySK?4PXT19jQA(2$3oWR#M>S7-oV+KnMLc1)9S~jn;P1YlF5=dsU*IX=O$D;CVc;M1 zpNkC$ii#?oZJvlz4x@HMr1t}UZw5bpkM{y@^$JMX!nj5Fd9V2etnX)Z0mSWoJRP~y zYjBp4$TbY5^c6iA`2zuaZW)o!QWo#jr#IM#6Xx~%+=92BuyZeYb2r9Uh`V$@3LgHc zle&Kl{Y?`*gE(Bt9iU+hSdW6%=<)adi_+?aZQuu?@cFyJ0&%xJ<~U&fC1oNda2XMB z)Z&~1ABu7~CRqn>|M5*r*oCL;3%lHZ8PiwA5yppYu@1V}^Ozh7os5h3$snmUvBh7c)q+aK9$6r`5 zp6f7c&2>G)mY^5b*cGsUCX2Pl$VPZ0eRfsVm|}cn-&cpJY1KR~LU36L^4PZ6%G?-7Zq%+iMiFGfh;4?_EuvSO~p&Mk=w{`OF zxsI^mkdJff-5;&yr(RjBl%{}a03SFkl1o>wC*@GDI(&F?H^`VT=i8R#VMk-V6{^wq zxgKV3==$>>=ur`s$ng5;hf|ej1u$<*dZ%+YhCDfjU{T1S+0xmUd#-kW%GnUU1h>K- zyiZj=sd6t=2fd&4OrsaGGc3u3_GLU)yyv5wh8PH?VyEZX!SwOn9sq*Xw z_5`Ag{!8d9IGsgtX6+A$TcqW=q<0)eZx7qsinmLHxZ*C3aI^zNx{Dc`R~V7}7q7~# z{kXE2Fo&2;pW}@%wp`@@DeKDPq57gYV~H`0FqjBq5VA!WAzK*PE7`JT&z2=yn1m?1 zQCYK%rVz43T9E8S%Wn!XwhXc*OQHOpDWc||nRnj#o_o%__r1@&cklatYiaC3Z{O%x zr}}i??46Ax6b@y&gqT!|4!!>SsUJ>1$V( zfOQ5yBlnZa&}rF^E+biBj!mEEK;qMlJEFL`(-owHDd(Mu2+;|mChaYnmC+6;%`WnkBIWzga^UH{%04o;0OsvJtjGc@CLZen2-Y#T zI_E9*kDb)bp$-ATT%jX4FqoenZK4O$pkW~4Eppn zc-3?MD}ia1+alIM4CNO>`^jR!%|btsx61u|5vLe^2yV-`Q%KYnuS_+B)jK6Rn&f}fx1Vw|ud|FXZ;w-{n2 zu3&ns&v!CxmA~jjlcuKF^lUmCFxT2H}N=Kl%k_tpl zZ+Uhk6c3i=?f1wb-glW=Xy~ zr=iPz6HuLU-(ahfGKlnEye!PCX&Fgb6%=EK8%u&X#Y$aMQO(6%WIh+oH3`?Mc`3vm zT*R2BqPppSTug$RV>I0Niw7siC~Rh~z|(h)ZHa+RxyvAT!T^=WdFeVm+v{h&Evz5B zVFE%CdZKD`FO*?uJz9~1mKjQQs0NpzsM=AugBHDy4P$;gpYOf3T!?fT zwa9%nTE`^KcVf#%6z%j$6)XaX2qn|2X%~_rAr&_=s(JW=D5W1z>vZs$2)0qlqEFHG zsdi`b@X=68vtDred)`WW;~o@7PeH*AOb`f@CkHTZIWVgjRuX*kj`;WSF*9jecgX&h zD@pDUYP!R?4{4(WjcWH8!~+Fg=XF(r2%dGAE#vhYKipxDjHEfg-t;tf_XF~Ito?rT z&(@vC->w7=DdMmw;U8-A!FN{IXGqG=7Uwx^Xv=9fQ@+H+X=?=PslkRs$2`DSQFzrC z1K-EJ;h1^4k!7fE!#H;^UNSA{Gd7<;9Sl;0gox5RDk3)!iKRBCeD->I>M@iNr^U$THx-;P-y2+*g^Mc=-Ki2sDn7S-v0)&S zSyNpSitc3dqmOr_IJll-#S`gs{ycG54eA{PKN572*mlcfKs!a_8OyDMQwDJY`_}i> ziSEZJr-D&}&glw+6^zP~cJ~W{8|9>Dua7F+ug`sXsi7_DCj+-ZlRHV-`yH-pChdrX zokpT-d`+UI#j%2#oQf*$K{u6|uI#ILTh~W+PE)4_(_E9Y#)3PByv&Yf5K)q*;`nXgi_%{tf62 zH>N_`4`F{{D)NxHy4Ecg^Y=or{zsL=Dvh?7Su_dynKunPfYZb?E$q)Kt4 z>Gf+^h3(q!L4S&OyfB4#I3iOxNrLTzdTssrOMa*llstCg5 zCRNAlJTtq%VquldFSyXgDZ*-AFIRs&Mb0%-b~Yv~qsSR~Q=h&Vld5?0#{B4IvDpK% zIf^Abu(GDlCfp5fCfp}#!10%quNH`wj;#v_%!>TSBwkkhjndjUxm5?I;-KTmP2YXT z=nHb<+Y#2!&t8s4YDpSbNZlVj#MI&n!>BmQEhCV(al(@ckvT_}NsiR}zH#V%6J(tZ zsS^w;e=Fwj=7sLZe13cg_l0!qi#)Er)Agsk<2-)IQf<=Kn|x8U{=uVt-?*?d!{r)G zh&LxH6lwl3L8lBaAD|SPsJWrm%=_gK3^Sp}*=h{O7=JO{&~G7{Y*1~cmY4O!#b8b( zW=YRnZ=(MkB>W|VW=HfQYIqr6Om#UWtumBhCnd5ym5;37TXzuLfNI`vsQ~= z4$P~WoiQ(AA$)u8w)B|pofKZrFkU3Q{N>&1_|pXmQM^}bPG?%O4;dW`d} zrH+9Yb?n5%8(@ux89xzS1sL^emj>&P+E3p1mVz@~>U%0}wAPt=!f0j{mDf$Gi1U5& zZ=ZKo+QdrLxLHI$wvSB@MsUKZ z#Lh|-ShSg`$}l72P#L`w$^T7fB(ps|#j3w#drZA>eMl*f$Kid=Foj}tp*{YauM8{AH8ZenMqaeL zvZCuv7agUGpK6ifJ3E8cDM4uzVIp;J=TECppVDu{8VkOyKbukD*HNYv5BwpLDt7Ti zkeV;I6+C#a;3e!Vk>^S4;a8FD<4imI_RA@B6TftJWG(Lo{cF8N)`Sx+KFi=y38gFY zDb^+WbZ?4XZne+Jzm`zNBVUG=+-s*Ah4534EZl{=KW7qTA37Q<9!Rc#!S{q=LqpzR`@UtM7L9|F11)Xmq&ytN~%tcJ=UkL zy5;a6$EVW#cjIRs6dH-~>DZ;182Tc+^~cWNbaj)s_E?_L}9Ydd^9m{ZB^o-d(4w0McMR>I5z}c{L#@lcBiv(^wSt> zWKC3qmPTRaLBi7D6OhLj+KxD7j##vTszFksjG5l!t{BT~%jR>8tRAP(^hk!&4tksl zO6UOCsR90Inj1_pEZN7OpQBo-?K^OzxsU?pUdX6m$bRhxi-vHFLL&bgyOiP*CpRY3U#a`F=_N{yg@luJW8T`~M_Q)YUXUb#; zaFLCsSxdUDxOcXAu#B3RYgbLi3FH&`Nx6yI|H_X$N?BW5Rss74A>-y z3|4A*Ykjo*FcK8O1Q_7hOT(goAr~+lWyOvNb7Lo2IRF8@U-@nV<_%ITqK07pe0x+k`x&Y%xJy4e7 zHVF8}g8}|aw`jC{JS`k$kLiv z#5fEjAWhzFIgSwgQ|OjdVG&U1OJHf(-e^c{-niDTL$W0x_XO}P0zBpSv@47v2bTK8 zy({pRq8y%*f}#L8AgDd=D6IDQ}Z95F`jSKI;v;)Be z2>mkv{^tDI#^S;~f_H%BpLut+wTDz>+n?N)ZP;%J(@xgBGe}Td(oQ5kEc?!`Fkn}0 zGI>|+j1bU=M8Hs=Mm9h*{}g^~7Pv@elFfdzuw9Ald5L6CA|6>}_pNtII%jtur@z;H zZliGFRE0Ybt~vOwR`#sL+x91y+m8PYVce-HVh#x!d*6I(fn=qi;OgJn`X8G3)Bykh diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8fad3f5a..761b8f08 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-all.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index a69d9cb6..79a61d42 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,10 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' @@ -143,12 +143,16 @@ fi if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac diff --git a/gradlew.bat b/gradlew.bat index f127cfd4..93e3f59f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% From 6a057514b2cf8a485344aa147f37d507a44c2e71 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sun, 26 Mar 2023 23:57:28 +0700 Subject: [PATCH 18/38] [FIX] RequestTextureProvider localPath --- .../launchserver/auth/texture/RequestTextureProvider.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/texture/RequestTextureProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/texture/RequestTextureProvider.java index 3dc394f0..826b00c9 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/texture/RequestTextureProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/texture/RequestTextureProvider.java @@ -60,7 +60,8 @@ public Texture getCloakTexture(UUID uuid, String username, String client) throws if (cloakLocalPath == null) { return getTexture(textureUrl, true); } else { - return getTexture(textureUrl, Paths.get(cloakLocalPath), true); + String path = getTextureURL(cloakLocalPath, uuid, username, client); + return getTexture(textureUrl, Paths.get(path), true); } } @@ -70,7 +71,8 @@ public Texture getSkinTexture(UUID uuid, String username, String client) throws if (skinLocalPath == null) { return getTexture(textureUrl, false); } else { - return getTexture(textureUrl, Paths.get(skinLocalPath), false); + String path = getTextureURL(skinLocalPath, uuid, username, client); + return getTexture(textureUrl, Paths.get(path), false); } } } From e0b3f3d6a51672fbc1301c94c8c468aba419505f Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Wed, 29 Mar 2023 23:46:26 +0700 Subject: [PATCH 19/38] [FEATURE] Launcher build number --- .../pro/gravit/launchserver/binary/tasks/MainBuildTask.java | 3 ++- .../gravit/launchserver/config/LaunchServerRuntimeConfig.java | 2 ++ .../src/main/java/pro/gravit/launcher/LauncherConfig.java | 2 ++ modules | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/MainBuildTask.java b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/MainBuildTask.java index 0b3a87bf..478217ec 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/MainBuildTask.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/MainBuildTask.java @@ -124,7 +124,8 @@ protected void initProps() { properties.put("runtimeconfig.secureCheckSalt", launcherSalt); if (server.runtime.unlockSecret == null) server.runtime.unlockSecret = SecurityHelper.randomStringToken(); properties.put("runtimeconfig.unlockSecret", server.runtime.unlockSecret); - + server.runtime.buildNumber++; + properties.put("runtimeconfig.buildNumber", server.runtime.buildNumber); } public byte[] transformClass(byte[] bytes, String classname, BuildContext context) { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerRuntimeConfig.java b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerRuntimeConfig.java index 0f9c9c53..756fa2cf 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerRuntimeConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerRuntimeConfig.java @@ -11,6 +11,7 @@ public class LaunchServerRuntimeConfig { public String unlockSecret; public String registerApiKey; public String clientCheckSecret; + public long buildNumber; public void verify() { if (passwordEncryptKey == null) logger.error("[RuntimeConfig] passwordEncryptKey must not be null"); @@ -25,5 +26,6 @@ public void reset() { runtimeEncryptKey = SecurityHelper.randomStringAESKey(); registerApiKey = SecurityHelper.randomStringToken(); clientCheckSecret = SecurityHelper.randomStringToken(); + buildNumber = 0; } } diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/LauncherConfig.java b/LauncherAPI/src/main/java/pro/gravit/launcher/LauncherConfig.java index 0d90c99d..0e57587d 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/LauncherConfig.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/LauncherConfig.java @@ -48,6 +48,8 @@ public final class LauncherConfig extends StreamObject { public String unlockSecret; @LauncherInject("launchercore.env") public LauncherEnvironment environment; + @LauncherInject("runtimeconfig.buildNumber") + public long buildNumber; @LauncherInjectionConstructor diff --git a/modules b/modules index ed433be2..b9ec7706 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit ed433be234a5d6b4336a6af48194add97b0f2874 +Subproject commit b9ec7706081097211c4fa9cd7a6669a4dadac6aa From 06e9bc857854a09eb42ef2c12b37c3e4fa6144b5 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Mon, 3 Apr 2023 13:04:12 +0700 Subject: [PATCH 20/38] [ANY] IDEA code inspect --- LaunchServer/build.gradle | 19 +- .../pro/gravit/launchserver/LaunchServer.java | 1 - .../launchserver/LaunchServerStarter.java | 2 - .../launchserver/asm/InjectClassAcceptor.java | 6 +- .../launchserver/auth/AuthException.java | 2 + .../launchserver/auth/AuthProviderPair.java | 12 - .../auth/core/AbstractSQLCoreProvider.java | 16 +- .../auth/core/AuthCoreProvider.java | 4 +- .../auth/core/HttpAuthCoreProvider.java | 26 +-- .../auth/core/MemoryAuthCoreProvider.java | 24 +- .../auth/core/MergeAuthCoreProvider.java | 6 +- .../auth/core/RejectAuthCoreProvider.java | 6 +- .../interfaces/provider/AuthSupportExit.java | 4 +- .../auth/password/JsonPasswordVerifier.java | 2 +- .../auth/protect/AdvancedProtectHandler.java | 21 -- .../auth/protect/NoProtectHandler.java | 4 - .../auth/protect/ProtectHandler.java | 2 - .../auth/protect/StdProtectHandler.java | 8 +- .../auth/texture/JsonTextureProvider.java | 8 +- .../binary/tasks/AttachJarsTask.java | 3 - .../binary/tasks/SignJarTask.java | 2 +- .../command/basic/DebugCommand.java | 2 +- .../command/handler/CommandHandler.java | 1 - .../command/service/SecurityCheckCommand.java | 4 +- .../command/service/SignJarCommand.java | 2 +- .../command/service/TokenCommand.java | 2 +- .../components/ProGuardComponent.java | 4 +- .../components/WhitelistComponent.java | 6 +- .../config/LaunchServerConfig.java | 4 +- .../launchserver/helper/HttpHelper.java | 4 +- .../manangers/FeaturesManager.java | 6 +- .../manangers/KeyAgreementManager.java | 2 +- .../socket/LauncherNettyServer.java | 7 +- .../launchserver/socket/WebSocketService.java | 1 - .../socket/handlers/NettyWebAPIHandler.java | 7 +- .../response/auth/AdditionalDataResponse.java | 3 +- .../socket/response/auth/AuthResponse.java | 2 +- .../response/auth/CurrentUserResponse.java | 4 +- .../auth/FetchClientProfileKeyResponse.java | 2 +- .../response/auth/RefreshTokenResponse.java | 2 +- .../socket/response/auth/RestoreResponse.java | 4 + .../response/auth/RestoreSessionResponse.java | 2 +- .../management/GetPublicKeyResponse.java | 2 +- .../profile/BatchProfileByUsername.java | 2 +- .../profile/ProfileByUUIDResponse.java | 2 +- .../response/profile/ProfileByUsername.java | 2 +- .../response/update/LauncherResponse.java | 2 - .../launchserver/ASMTransformersTest.java | 2 +- .../launchserver/ConfigurationTest.java | 6 + .../impl/TestLaunchServerConfigManager.java | 10 +- Launcher/build.gradle | 8 +- .../launcher/ClientLauncherWrapper.java | 2 - .../pro/gravit/launcher/LauncherEngine.java | 2 - .../launcher/client/ClientClassLoader.java | 4 +- .../client/ClientLauncherProcess.java | 12 +- .../launcher/console/GetPublicKeyCommand.java | 2 +- .../launcher/console/ModulesCommand.java | 2 +- .../test/PrintHardwareInfoCommand.java | 2 +- .../launcher/gui/NoRuntimeProvider.java | 4 +- .../gravit/launcher/gui/RuntimeProvider.java | 4 +- .../pro/gravit/launcher/utils/DirWatcher.java | 4 - .../gravit/launcher/utils/NativeJVMHalt.java | 2 - LauncherAPI/build.gradle | 4 +- .../launcher/modules/LauncherModule.java | 12 +- .../launcher/profiles/ClientProfile.java | 3 +- .../profiles/ClientProfileBuilder.java | 60 ++--- .../optional/triggers/JavaTrigger.java | 3 +- .../pro/gravit/launcher/request/Request.java | 4 +- .../launcher/request/RequestService.java | 2 +- .../request/websockets/ClientJSONPoint.java | 4 +- .../websockets/ClientWebSocketService.java | 16 -- .../websockets/OfflineRequestService.java | 3 +- .../websockets/StdWebSocketService.java | 10 +- .../websockets/VoidRequestService.java | 3 +- .../websockets/WebSocketClientHandler.java | 4 +- LauncherCore/build.gradle | 4 +- .../pro/gravit/launcher/AsyncDownloader.java | 4 +- .../pro/gravit/launcher/hasher/HashedDir.java | 2 +- .../main/java/pro/gravit/utils/BiHookSet.java | 4 +- .../java/pro/gravit/utils/Downloader.java | 2 +- .../main/java/pro/gravit/utils/HookSet.java | 4 +- .../gravit/utils/PublicURLClassLoader.java | 2 - .../gravit/utils/command/CommandHandler.java | 4 +- .../utils/command/JLineCommandHandler.java | 14 -- .../pro/gravit/utils/helper/IOHelper.java | 8 +- .../pro/gravit/utils/helper/JarHelper.java | 4 +- .../pro/gravit/utils/helper/JavaHelper.java | 46 ++-- .../pro/gravit/utils/helper/LogHelper.java | 2 +- .../pro/gravit/utils/helper/UnpackHelper.java | 11 +- .../pro/gravit/utils/helper/VerifyHelper.java | 4 +- .../utils/logging/SimpleLogHelperImpl.java | 3 +- .../java11/pro/gravit/utils/Downloader.java | 1 - ServerWrapper/build.gradle | 4 +- .../gravit/launcher/server/ServerWrapper.java | 4 +- .../server/ServerWrapperGsonManager.java | 1 - .../authlib/DownloadContextModifier.java | 1 - .../server/authlib/InstallAuthlib.java | 4 +- .../server/authlib/LibrariesLstModifier.java | 3 +- .../launcher/server/launch/ModuleLaunch.java | 2 +- .../server/setup/ServerWrapperSetup.java | 2 - build.gradle | 10 +- compat/BungeeCord.patch | 211 ------------------ compat/LaunchWrapper.patch | 17 -- compat/auth/asframework.php | 50 ----- compat/auth/dle.php | 83 ------- compat/auth/dle.sql | 1 - compat/auth/ipb.php | 28 --- compat/auth/ips.php | 22 -- compat/auth/joomla.sql | 1 - .../authcontroller/LauncherAuthController.php | 36 --- compat/auth/laravel/authcontroller/README.MD | 10 - ...020_03_05_151322_add_permission_collum.php | 32 --- .../2020_03_04_172425_create_hwid_table.php | 36 --- ..._03_05_140131_add_auth_handler_collums.php | 36 --- ..._03_05_142041_add_hwid_handler_collums.php | 32 --- compat/auth/laravel/migrations/README.MD | 1 - compat/auth/phpbb.php | 20 -- compat/auth/uuid/ReversibleUUIDs.java | 19 -- compat/auth/uuid/uuidgen.sql | 8 - compat/auth/uuid/uuidgen_offline.sql | 11 - compat/auth/wordpress.php | 15 -- compat/auth/xenforo.php | 47 ---- compat/auth/yii2/MinecraftController.php | 48 ---- compat/authlib/GameProfile-combined.class | Bin 2323 -> 0 bytes .../MinecraftSessionService-combined.class | Bin 1177 -> 0 bytes compat/authlib/README.md | 15 -- compat/authlib/authlib-clean.jar | Bin 23983 -> 0 bytes compat/hibernate.sql | 75 ------- modules | 2 +- 129 files changed, 215 insertions(+), 1244 deletions(-) delete mode 100644 compat/BungeeCord.patch delete mode 100644 compat/LaunchWrapper.patch delete mode 100644 compat/auth/asframework.php delete mode 100644 compat/auth/dle.php delete mode 100644 compat/auth/dle.sql delete mode 100644 compat/auth/ipb.php delete mode 100644 compat/auth/ips.php delete mode 100644 compat/auth/joomla.sql delete mode 100644 compat/auth/laravel/authcontroller/LauncherAuthController.php delete mode 100644 compat/auth/laravel/authcontroller/README.MD delete mode 100644 compat/auth/laravel/authcontroller/migrations/2020_03_05_151322_add_permission_collum.php delete mode 100644 compat/auth/laravel/migrations/2020_03_04_172425_create_hwid_table.php delete mode 100644 compat/auth/laravel/migrations/2020_03_05_140131_add_auth_handler_collums.php delete mode 100644 compat/auth/laravel/migrations/2020_03_05_142041_add_hwid_handler_collums.php delete mode 100644 compat/auth/laravel/migrations/README.MD delete mode 100644 compat/auth/phpbb.php delete mode 100644 compat/auth/uuid/ReversibleUUIDs.java delete mode 100644 compat/auth/uuid/uuidgen.sql delete mode 100644 compat/auth/uuid/uuidgen_offline.sql delete mode 100644 compat/auth/wordpress.php delete mode 100644 compat/auth/xenforo.php delete mode 100644 compat/auth/yii2/MinecraftController.php delete mode 100644 compat/authlib/GameProfile-combined.class delete mode 100644 compat/authlib/MinecraftSessionService-combined.class delete mode 100644 compat/authlib/README.md delete mode 100644 compat/authlib/authlib-clean.jar delete mode 100644 compat/hibernate.sql diff --git a/LaunchServer/build.gradle b/LaunchServer/build.gradle index ce6a9222..db37159c 100644 --- a/LaunchServer/build.gradle +++ b/LaunchServer/build.gradle @@ -50,17 +50,18 @@ } } -task sourcesJar(type: Jar) { +tasks.register('sourcesJar', Jar) { from sourceSets.main.allJava archiveClassifier.set('sources') } -task javadocJar(type: Jar) { +tasks.register('javadocJar', Jar) { from javadoc archiveClassifier.set('javadoc') } -task cleanjar(type: Jar, dependsOn: jar) { +tasks.register('cleanjar', Jar) { + dependsOn jar archiveClassifier.set('clean') manifest.attributes("Main-Class": mainClassName, "Premain-Class": mainAgentName, @@ -117,13 +118,13 @@ pack project(':LauncherAPI') compileOnlyA 'org.apache.logging.log4j:log4j-core:2.14.1' } -task hikari(type: Copy) { +tasks.register('hikari', Copy) { duplicatesStrategy = 'EXCLUDE' into "$buildDir/libs/libraries/hikaricp" from configurations.hikari } -task launch4j(type: Copy) { +tasks.register('launch4j', Copy) { duplicatesStrategy = 'EXCLUDE' into "$buildDir/libs/libraries/launch4j" from(configurations.launch4j.collect { @@ -141,20 +142,20 @@ task launch4j(type: Copy) { } } -task dumpLibs(type: Copy) { +tasks.register('dumpLibs', Copy) { duplicatesStrategy = 'EXCLUDE' dependsOn tasks.hikari, tasks.launch4j into "$buildDir/libs/libraries" from configurations.bundleOnly } -task dumpCompileOnlyLibs(type: Copy) { +tasks.register('dumpCompileOnlyLibs', Copy) { duplicatesStrategy = 'EXCLUDE' into "$buildDir/libs/launcher-libraries-compile" from configurations.compileOnlyA } -task bundle(type: Zip) { +tasks.register('bundle', Zip) { duplicatesStrategy = 'EXCLUDE' dependsOn parent.childProjects.Launcher.tasks.build, tasks.dumpLibs, tasks.dumpCompileOnlyLibs, tasks.jar archiveFileName = 'LaunchServer.zip' @@ -165,7 +166,7 @@ task bundle(type: Zip) { from(parent.childProjects.Launcher.tasks.dumpLibs) { into 'launcher-libraries' } } -task dumpClientLibs(type: Copy) { +tasks.register('dumpClientLibs', Copy) { dependsOn parent.childProjects.Launcher.tasks.build into "$buildDir/libs/launcher-libraries" from parent.childProjects.Launcher.tasks.dumpLibs diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java index 6f25a6e6..e370576a 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java @@ -121,7 +121,6 @@ public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurab // Updates and profiles private volatile Set profilesList; - @SuppressWarnings("deprecation") public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, LaunchServerConfig config, LaunchServerRuntimeConfig runtimeConfig, LaunchServerConfigManager launchServerConfigManager, LaunchServerModulesManager modulesManager, KeyAgreementManager keyAgreementManager, CommandHandler commandHandler, CertificateManager certificateManager) throws IOException { this.dir = directories.dir; this.tmpDir = directories.tmpDir; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServerStarter.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServerStarter.java index ec8d5479..6faec029 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServerStarter.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServerStarter.java @@ -21,7 +21,6 @@ import pro.gravit.launchserver.manangers.LaunchServerGsonManager; import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager; import pro.gravit.launchserver.socket.WebSocketService; -import pro.gravit.utils.Version; import pro.gravit.utils.command.CommandHandler; import pro.gravit.utils.command.JLineCommandHandler; import pro.gravit.utils.command.StdCommandHandler; @@ -202,7 +201,6 @@ public static void initGson(LaunchServerModulesManager modulesManager) { Launcher.gsonManager.initGson(); } - @SuppressWarnings("deprecation") public static void registerAll() { AuthCoreProvider.registerProviders(); PasswordVerifier.registerProviders(); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/asm/InjectClassAcceptor.java b/LaunchServer/src/main/java/pro/gravit/launchserver/asm/InjectClassAcceptor.java index 2beaa2e5..4f698cc5 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/asm/InjectClassAcceptor.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/asm/InjectClassAcceptor.java @@ -65,7 +65,7 @@ private static void visit(ClassNode classNode, Map values) { return newClinitMethod; }); List constructors = classNode.methods.stream().filter(method -> "".equals(method.name)) - .collect(Collectors.toList()); + .toList(); MethodNode initMethod = constructors.stream().filter(method -> method.invisibleAnnotations != null && method.invisibleAnnotations.stream().anyMatch(annotation -> INJECTED_CONSTRUCTOR_DESC.equals(annotation.desc))).findFirst() .orElseGet(() -> constructors.stream().filter(method -> method.desc.equals("()V")).findFirst().orElse(null)); @@ -112,7 +112,7 @@ public void visit(final String name, final Object value) { } List putStaticNodes = Arrays.stream(initMethod.instructions.toArray()) .filter(node -> node instanceof FieldInsnNode && node.getOpcode() == Opcodes.PUTSTATIC).map(p -> (FieldInsnNode) p) - .filter(node -> node.owner.equals(classNode.name) && node.name.equals(field.name) && node.desc.equals(field.desc)).collect(Collectors.toList()); + .filter(node -> node.owner.equals(classNode.name) && node.name.equals(field.name) && node.desc.equals(field.desc)).toList(); InsnList setter = serializeValue(value); if (putStaticNodes.isEmpty()) { setter.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, field.name, field.desc)); @@ -130,7 +130,7 @@ public void visit(final String name, final Object value) { } List putFieldNodes = Arrays.stream(initMethod.instructions.toArray()) .filter(node -> node instanceof FieldInsnNode && node.getOpcode() == Opcodes.PUTFIELD).map(p -> (FieldInsnNode) p) - .filter(node -> node.owner.equals(classNode.name) && node.name.equals(field.name) && node.desc.equals(field.desc)).collect(Collectors.toList()); + .filter(node -> node.owner.equals(classNode.name) && node.name.equals(field.name) && node.desc.equals(field.desc)).toList(); InsnList setter = serializeValue(value); if (putFieldNodes.isEmpty()) { setter.insert(new VarInsnNode(Opcodes.ALOAD, 0)); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/AuthException.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/AuthException.java index 83e81014..0fb5c766 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/AuthException.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/AuthException.java @@ -3,10 +3,12 @@ import pro.gravit.launcher.events.request.AuthRequestEvent; import java.io.IOException; +import java.io.Serial; import java.util.List; import java.util.stream.Collectors; public final class AuthException extends IOException { + @Serial private static final long serialVersionUID = -2586107832847245863L; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/AuthProviderPair.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/AuthProviderPair.java index 4ee003eb..ec5c287f 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/AuthProviderPair.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/AuthProviderPair.java @@ -4,8 +4,6 @@ import org.apache.logging.log4j.Logger; import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.auth.core.AuthCoreProvider; -import pro.gravit.launchserver.auth.core.MySQLCoreProvider; -import pro.gravit.launchserver.auth.core.PostgresSQLCoreProvider; import pro.gravit.launchserver.auth.texture.TextureProvider; import java.io.IOException; @@ -23,7 +21,6 @@ public final class AuthProviderPair { public transient Set features; public String displayName; public boolean visible = true; - private transient boolean warnOAuthShow = false; public AuthProviderPair() { } @@ -56,15 +53,6 @@ public static void getFeatures(Class clazz, Set list) { } } - public void internalShowOAuthWarnMessage() { - if (!warnOAuthShow) { - if (!(core instanceof MySQLCoreProvider) && !(core instanceof PostgresSQLCoreProvider)) { // MySQL and PostgreSQL upgraded later - logger.warn("AuthCoreProvider {} ({}) not supported OAuth. Legacy session system may be removed in next release", name, core.getClass().getName()); - } - warnOAuthShow = true; - } - } - public final T isSupport(Class clazz) { if (core == null) return null; T result = null; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AbstractSQLCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AbstractSQLCoreProvider.java index a389f631..1336c331 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AbstractSQLCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AbstractSQLCoreProvider.java @@ -29,7 +29,7 @@ import java.util.UUID; public abstract class AbstractSQLCoreProvider extends AuthCoreProvider { - public transient Logger logger = LogManager.getLogger(); + public final transient Logger logger = LogManager.getLogger(); public int expireSeconds = 3600; public String uuidColumn; public String usernameColumn; @@ -208,7 +208,7 @@ protected String makeUserCols() { return String.format("%s, %s, %s, %s, %s", uuidColumn, usernameColumn, accessTokenColumn, serverIDColumn, passwordColumn); } - protected boolean updateAuth(User user, String accessToken) throws IOException { + protected void updateAuth(User user, String accessToken) throws IOException { try (Connection c = getSQLConfig().getConnection()) { SQLUser SQLUser = (SQLUser) user; SQLUser.accessToken = accessToken; @@ -216,7 +216,7 @@ protected boolean updateAuth(User user, String accessToken) throws IOException { s.setString(1, accessToken); s.setString(2, user.getUUID().toString()); s.setQueryTimeout(MySQLSourceConfig.TIMEOUT); - return s.executeUpdate() > 0; + s.executeUpdate(); } catch (SQLException e) { throw new IOException(e); } @@ -238,7 +238,7 @@ protected boolean updateServerID(User user, String serverID) throws IOException } @Override - public void close() throws IOException { + public void close() { getSQLConfig().close(); } @@ -299,12 +299,12 @@ private List queryRolesNames(String sql, String value) throws SQLExcepti } public static class SQLUser implements User { - protected UUID uuid; - protected String username; + protected final UUID uuid; + protected final String username; protected String accessToken; protected String serverId; - protected String password; - protected ClientPermissions permissions; + protected final String password; + protected final ClientPermissions permissions; public SQLUser(UUID uuid, String username, String accessToken, String serverId, String password, ClientPermissions permissions) { this.uuid = uuid; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AuthCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AuthCoreProvider.java index cb8860cb..a6c210b0 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AuthCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/AuthCoreProvider.java @@ -140,7 +140,7 @@ public void invoke(String... args) throws Exception { if (instance != null) { map.put("getallusers", new SubCommand("(limit)", "print all users information") { @Override - public void invoke(String... args) throws Exception { + public void invoke(String... args) { int max = Integer.MAX_VALUE; if (args.length > 0) max = Integer.parseInt(args[0]); Iterable users = instance.getAllUsers(); @@ -316,7 +316,7 @@ public T isSupport(Class clazz) { } @Override - public abstract void close() throws IOException; + public abstract void close(); public static class PasswordVerifyReport { public static final PasswordVerifyReport REQUIRED_2FA = new PasswordVerifyReport(-1); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/HttpAuthCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/HttpAuthCoreProvider.java index e929144d..ffb9bfb8 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/HttpAuthCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/HttpAuthCoreProvider.java @@ -1,6 +1,5 @@ package pro.gravit.launchserver.auth.core; -import com.google.gson.reflect.TypeToken; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import pro.gravit.launcher.ClientPermissions; @@ -318,7 +317,7 @@ public void init(LaunchServer server) { } @Override - public void close() throws IOException { + public void close() { } @@ -525,10 +524,6 @@ public class HttpUser implements User, UserSupportTextures, UserSupportPropertie private String serverId; private String accessToken; private ClientPermissions permissions; - @Deprecated - private Texture skin; - @Deprecated - private Texture cloak; private Map assets; private Map properties; private long hwidId; @@ -552,8 +547,6 @@ public HttpUser(String username, UUID uuid, String serverId, String accessToken, this.serverId = serverId; this.accessToken = accessToken; this.permissions = permissions; - this.skin = skin; - this.cloak = cloak; this.hwidId = hwidId; } @@ -563,8 +556,6 @@ public HttpUser(String username, UUID uuid, String serverId, String accessToken, this.serverId = serverId; this.accessToken = accessToken; this.permissions = permissions; - this.skin = skin; - this.cloak = cloak; this.properties = properties; this.hwidId = hwidId; } @@ -607,30 +598,17 @@ public ClientPermissions getPermissions() { @Override public Texture getSkinTexture() { - if (assets == null) { - return skin; - } return assets.get("SKIN"); } @Override public Texture getCloakTexture() { - if (assets == null) { - return cloak; - } return assets.get("CAPE"); } public Map getAssets() { if (assets == null) { - Map map = new HashMap<>(); - if (skin != null) { - map.put("SKIN", skin); - } - if (cloak != null) { - map.put("CAPE", cloak); - } - return map; + return new HashMap<>(); } return assets; } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MemoryAuthCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MemoryAuthCoreProvider.java index f572dce5..62c3391c 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MemoryAuthCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MemoryAuthCoreProvider.java @@ -53,7 +53,7 @@ public User getUserByUUID(UUID uuid) { } @Override - public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws OAuthAccessTokenExpired { + public UserSession getUserSessionByOAuthAccessToken(String accessToken) { synchronized (memory) { for (MemoryUser u : memory) { if (u.accessToken.equals(accessToken)) { @@ -95,14 +95,14 @@ public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext c } @Override - protected boolean updateServerID(User user, String serverID) throws IOException { + protected boolean updateServerID(User user, String serverID) { MemoryUser memoryUser = (MemoryUser) user; memoryUser.serverId = serverID; return true; } @Override - public User checkServer(Client client, String username, String serverID) throws IOException { + public User checkServer(Client client, String username, String serverID) { synchronized (memory) { for (MemoryUser u : memory) { if (u.username.equals(username)) { @@ -116,7 +116,7 @@ public User checkServer(Client client, String username, String serverID) throws } @Override - public boolean joinServer(Client client, String username, String accessToken, String serverID) throws IOException { + public boolean joinServer(Client client, String username, String accessToken, String serverID) { return true; } @@ -126,16 +126,16 @@ public void init(LaunchServer server) { } @Override - public void close() throws IOException { + public void close() { } public static class MemoryUser implements User { - private String username; - private UUID uuid; + private final String username; + private final UUID uuid; private String serverId; - private String accessToken; - private ClientPermissions permissions; + private final String accessToken; + private final ClientPermissions permissions; public MemoryUser(String username) { this.username = username; @@ -188,9 +188,9 @@ public int hashCode() { } public static class MemoryUserSession implements UserSession { - private String id; - private MemoryUser user; - private long expireIn; + private final String id; + private final MemoryUser user; + private final long expireIn; public MemoryUserSession(MemoryUser user) { this.id = SecurityHelper.randomStringToken(); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MergeAuthCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MergeAuthCoreProvider.java index 74498515..1989b942 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MergeAuthCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MergeAuthCoreProvider.java @@ -17,7 +17,7 @@ public class MergeAuthCoreProvider extends AuthCoreProvider { private transient final Logger logger = LogManager.getLogger(MergeAuthCoreProvider.class); public List list = new ArrayList<>(); - private transient List providers = new ArrayList<>(); + private final transient List providers = new ArrayList<>(); @Override public User getUserByUsername(String username) { for(var core : providers) { @@ -67,7 +67,7 @@ public User checkServer(Client client, String username, String serverID) throws } @Override - public boolean joinServer(Client client, String username, String accessToken, String serverID) throws IOException { + public boolean joinServer(Client client, String username, String accessToken, String serverID) { return false; // Authorization not supported } @@ -84,7 +84,7 @@ public void init(LaunchServer server) { } @Override - public void close() throws IOException { + public void close() { // Providers closed automatically } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/RejectAuthCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/RejectAuthCoreProvider.java index 6db40500..69697c7e 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/RejectAuthCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/RejectAuthCoreProvider.java @@ -21,7 +21,7 @@ public User getUserByUUID(UUID uuid) { } @Override - public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws OAuthAccessTokenExpired { + public UserSession getUserSessionByOAuthAccessToken(String accessToken) { return null; } @@ -46,12 +46,12 @@ public void init(LaunchServer server) { } @Override - protected boolean updateServerID(User user, String serverID) throws IOException { + protected boolean updateServerID(User user, String serverID) { return false; } @Override - public void close() throws IOException { + public void close() { } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/interfaces/provider/AuthSupportExit.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/interfaces/provider/AuthSupportExit.java index 4cd58a05..f48aaf1a 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/interfaces/provider/AuthSupportExit.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/interfaces/provider/AuthSupportExit.java @@ -4,7 +4,7 @@ import pro.gravit.launchserver.auth.core.UserSession; public interface AuthSupportExit extends AuthSupport { - boolean deleteSession(UserSession session); + void deleteSession(UserSession session); - boolean exitUser(User user); + void exitUser(User user); } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/JsonPasswordVerifier.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/JsonPasswordVerifier.java index 339b8447..e43ae2a8 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/JsonPasswordVerifier.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/JsonPasswordVerifier.java @@ -14,7 +14,7 @@ import java.time.Duration; public class JsonPasswordVerifier extends PasswordVerifier { - private static transient final Logger logger = LogManager.getLogger(); + private static final Logger logger = LogManager.getLogger(); private transient final HttpClient client = HttpClient.newBuilder().build(); public String url; public String bearerToken; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/AdvancedProtectHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/AdvancedProtectHandler.java index 6b0c7529..d740b7a3 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/AdvancedProtectHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/AdvancedProtectHandler.java @@ -15,7 +15,6 @@ import pro.gravit.launchserver.auth.protect.interfaces.JoinServerProtectHandler; import pro.gravit.launchserver.auth.protect.interfaces.SecureProtectHandler; import pro.gravit.launchserver.socket.Client; -import pro.gravit.launchserver.socket.response.auth.AuthResponse; import pro.gravit.launchserver.socket.response.auth.RestoreResponse; import pro.gravit.launchserver.socket.response.secure.HardwareReportResponse; @@ -27,16 +26,6 @@ public class AdvancedProtectHandler extends StdProtectHandler implements SecureP public boolean enableHardwareFeature; private transient LaunchServer server; - @Override - public boolean allowGetAccessToken(AuthResponse.AuthContext context) { - return (context.authType == AuthResponse.ConnectTypes.CLIENT) && context.client.checkSign; - } - - @Override - public void checkLaunchServerLicense() { - - } - @Override public GetSecureLevelInfoRequestEvent onGetSecureLevelInfo(GetSecureLevelInfoRequestEvent event) { return event; @@ -73,11 +62,9 @@ public void onHardwareReport(HardwareReportResponse response, Client client) { } client.trustLevel.hardwareInfo = hardware.getHardwareInfo(); response.sendResult(new HardwareReportRequestEvent(createHardwareToken(client.username, hardware))); - return; } else { logger.error("AuthCoreProvider not supported hardware"); response.sendError("AuthCoreProvider not supported hardware"); - return; } } } @@ -113,10 +100,6 @@ public void init(LaunchServer server) { this.server = server; } - @Override - public void close() { - } - public String createHardwareToken(String username, UserHardware hardware) { return Jwts.builder() .setIssuer("LaunchServer") @@ -138,12 +121,10 @@ public String createPublicKeyToken(String username, byte[] publicKey) { } public static class HardwareInfoTokenVerifier implements RestoreResponse.ExtendedTokenProvider { - private transient final LaunchServer server; private transient final Logger logger = LogManager.getLogger(); private final JwtParser parser; public HardwareInfoTokenVerifier(LaunchServer server) { - this.server = server; this.parser = Jwts.parserBuilder() .requireIssuer("LaunchServer") .setSigningKey(server.keyAgreementManager.ecdsaPublicKey) @@ -172,12 +153,10 @@ public boolean accept(Client client, AuthProviderPair pair, String extendedToken } public static class PublicKeyTokenVerifier implements RestoreResponse.ExtendedTokenProvider { - private transient final LaunchServer server; private transient final Logger logger = LogManager.getLogger(); private final JwtParser parser; public PublicKeyTokenVerifier(LaunchServer server) { - this.server = server; this.parser = Jwts.parserBuilder() .requireIssuer("LaunchServer") .setSigningKey(server.keyAgreementManager.ecdsaPublicKey) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/NoProtectHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/NoProtectHandler.java index cd80b54b..2cacc3bf 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/NoProtectHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/NoProtectHandler.java @@ -9,8 +9,4 @@ public boolean allowGetAccessToken(AuthResponse.AuthContext context) { return true; } - @Override - public void checkLaunchServerLicense() { - // None - } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/ProtectHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/ProtectHandler.java index bead3fd2..ab3edf69 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/ProtectHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/ProtectHandler.java @@ -20,8 +20,6 @@ public static void registerHandlers() { public abstract boolean allowGetAccessToken(AuthResponse.AuthContext context); - public abstract void checkLaunchServerLicense(); //Выдает SecurityException при ошибке проверки лицензии - public void init(LaunchServer server) { } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/StdProtectHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/StdProtectHandler.java index dd307ddb..008e4dea 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/StdProtectHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/protect/StdProtectHandler.java @@ -20,11 +20,6 @@ public boolean allowGetAccessToken(AuthResponse.AuthContext context) { return (context.authType == AuthResponse.ConnectTypes.CLIENT) && context.client.checkSign; } - @Override - public void checkLaunchServerLicense() { - - } - @Override public void init(LaunchServer server) { if (profileWhitelist != null && profileWhitelist.size() > 0) { @@ -59,7 +54,6 @@ private boolean isWhitelisted(String property, ClientProfile profile, Client cli } } List allowedUsername = profileWhitelist.get(profile.getTitle()); - if (allowedUsername != null && allowedUsername.contains(client.username)) return true; - return false; + return allowedUsername != null && allowedUsername.contains(client.username); } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/texture/JsonTextureProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/texture/JsonTextureProvider.java index 2653a51e..ca27671b 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/texture/JsonTextureProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/texture/JsonTextureProvider.java @@ -15,24 +15,24 @@ import java.util.UUID; public class JsonTextureProvider extends TextureProvider { - private transient static final Type MAP_TYPE = new TypeToken>() { + private static final Type MAP_TYPE = new TypeToken>() { }.getType(); private transient final Logger logger = LogManager.getLogger(); public String url; @Override - public void close() throws IOException { + public void close() { //None } @Override - public Texture getCloakTexture(UUID uuid, String username, String client) throws IOException { + public Texture getCloakTexture(UUID uuid, String username, String client) { logger.warn("Ineffective get cloak texture for {}", username); return getAssets(uuid, username, client).get("CAPE"); } @Override - public Texture getSkinTexture(UUID uuid, String username, String client) throws IOException { + public Texture getSkinTexture(UUID uuid, String username, String client) { logger.warn("Ineffective get skin texture for {}", username); return getAssets(uuid, username, client).get("SKIN"); } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/AttachJarsTask.java b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/AttachJarsTask.java index 998cd516..4904283d 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/AttachJarsTask.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/AttachJarsTask.java @@ -4,12 +4,9 @@ import pro.gravit.utils.helper.IOHelper; import java.io.IOException; -import java.io.InputStream; import java.nio.file.Path; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/SignJarTask.java b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/SignJarTask.java index a2c09d8c..517adc48 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/SignJarTask.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/SignJarTask.java @@ -26,7 +26,7 @@ public class SignJarTask implements LauncherBuildTask { - private transient static final Logger logger = LogManager.getLogger(); + private static final Logger logger = LogManager.getLogger(); private final LaunchServerConfig.JarSignerConf config; private final LaunchServer srv; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/basic/DebugCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/basic/DebugCommand.java index 03a7858c..355f1463 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/basic/DebugCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/basic/DebugCommand.java @@ -10,7 +10,7 @@ import pro.gravit.launchserver.command.Command; public class DebugCommand extends Command { - private transient Logger logger = LogManager.getLogger(); + private final transient Logger logger = LogManager.getLogger(); public DebugCommand(LaunchServer server) { super(server); 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 300b4916..1f3e41ac 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 @@ -12,7 +12,6 @@ import pro.gravit.utils.command.basic.HelpCommand; public abstract class CommandHandler extends pro.gravit.utils.command.CommandHandler { - @SuppressWarnings("deprecation") public static void registerCommands(pro.gravit.utils.command.CommandHandler handler, LaunchServer server) { BaseCommandCategory basic = new BaseCommandCategory(); // Register basic commands 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 30db46a8..114a054b 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 @@ -30,7 +30,7 @@ import java.util.stream.Collectors; public class SecurityCheckCommand extends Command { - private static transient final Logger logger = LogManager.getLogger(); + private static final Logger logger = LogManager.getLogger(); public SecurityCheckCommand(LaunchServer server) { super(server); @@ -110,7 +110,7 @@ public void invoke(String... args) { try { KeyStore keyStore = SignHelper.getStore(new File(config.sign.keyStore).toPath(), config.sign.keyStorePass, config.sign.keyStoreType); Certificate[] certChainPlain = keyStore.getCertificateChain(config.sign.keyAlias); - List certChain = Arrays.stream(certChainPlain).map(e -> (X509Certificate) e).collect(Collectors.toList()); + List certChain = Arrays.stream(certChainPlain).map(e -> (X509Certificate) e).toList(); X509Certificate cert = certChain.get(0); cert.checkValidity(); if (certChain.size() <= 1) { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/SignJarCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/SignJarCommand.java index deef6036..ecdfdf7f 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/SignJarCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/SignJarCommand.java @@ -41,7 +41,7 @@ public void invoke(String... args) throws Exception { Optional task = server.launcherBinary.getTaskByClass(SignJarTask.class); if (task.isEmpty()) throw new IllegalStateException("SignJarTask not found"); task.get().sign(server.config.sign, target, tmpSign); - if (args.length <= 1) { + if (args.length == 1) { logger.info("Move temp jar {} to {}", tmpSign.toString(), target.toString()); Files.deleteIfExists(target); Files.move(tmpSign, target); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/TokenCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/TokenCommand.java index 4e27f048..f6090469 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/TokenCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/TokenCommand.java @@ -25,7 +25,7 @@ public void invoke(String... args) throws Exception { }); this.childCommands.put("server", new SubCommand("[profileName] (authId)", "generate new server token") { @Override - public void invoke(String... args) throws Exception { + public void invoke(String... args) { AuthProviderPair pair = args.length > 1 ? server.config.getAuthProviderPair(args[1]) : server.config.getAuthProviderPair(); ClientProfile profile = null; for (ClientProfile p : server.getProfiles()) { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/components/ProGuardComponent.java b/LaunchServer/src/main/java/pro/gravit/launchserver/components/ProGuardComponent.java index 8951e72e..55c36f06 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/components/ProGuardComponent.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/components/ProGuardComponent.java @@ -28,7 +28,7 @@ import java.util.Map; public class ProGuardComponent extends Component implements AutoCloseable, Reconfigurable { - private transient static final Logger logger = LogManager.getLogger(); + private static final Logger logger = LogManager.getLogger(); public String modeAfter = "MainBuild"; public String dir = "proguard"; public boolean enabled = true; @@ -79,7 +79,7 @@ public void init(LaunchServer launchServer) { } @Override - public void close() throws Exception { + public void close() { if (launchServer != null && buildTask != null) { launchServer.launcherBinary.tasks.remove(buildTask); } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/components/WhitelistComponent.java b/LaunchServer/src/main/java/pro/gravit/launchserver/components/WhitelistComponent.java index 20d69a21..6699a9af 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/components/WhitelistComponent.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/components/WhitelistComponent.java @@ -48,7 +48,7 @@ public boolean hookJoin(JoinServerResponse response, Client client) throws HookE } @Override - public void close() throws Exception { + public void close() { this.server.authHookManager.preHook.unregisterHook(this::hookAuth); this.server.authHookManager.joinServerHook.unregisterHook(this::hookJoin); } @@ -82,14 +82,14 @@ public void invoke(String... args) throws Exception { }); commands.put("disable", new SubCommand() { @Override - public void invoke(String... args) throws Exception { + public void invoke(String... args) { enabled = false; logger.info("Whitelist disabled"); } }); commands.put("enable", new SubCommand() { @Override - public void invoke(String... args) throws Exception { + public void invoke(String... args) { enabled = true; logger.info("Whitelist enabled"); } 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 af766e3c..ee810bd0 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java @@ -106,9 +106,8 @@ public static LaunchServerConfig getDefault(LaunchServer.LaunchServerEnv env) { return newConfig; } - public LaunchServerConfig setLaunchServer(LaunchServer server) { + public void setLaunchServer(LaunchServer server) { this.server = server; - return this; } public AuthProviderPair getAuthProviderPair(String name) { @@ -187,7 +186,6 @@ public void init(LaunchServer.ReloadType type) { if (protectHandler != null) { server.registerObject("protectHandler", protectHandler); protectHandler.init(server); - protectHandler.checkLaunchServerLicense(); } if (components != null) { components.forEach((k, v) -> server.registerObject("component.".concat(k), v)); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/helper/HttpHelper.java b/LaunchServer/src/main/java/pro/gravit/launchserver/helper/HttpHelper.java index 1dc1acc1..6824adbe 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/helper/HttpHelper.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/helper/HttpHelper.java @@ -22,7 +22,7 @@ import java.util.function.Function; public final class HttpHelper { - private static transient final Logger logger = LogManager.getLogger(); + private static final Logger logger = LogManager.getLogger(); private HttpHelper() { throw new UnsupportedOperationException(); @@ -37,7 +37,7 @@ public static HttpOptional send(HttpClient client, HttpRequest requ } } - public static CompletableFuture> sendAsync(HttpClient client, HttpRequest request, HttpErrorHandler handler) throws IOException { + public static CompletableFuture> sendAsync(HttpClient client, HttpRequest request, HttpErrorHandler handler) { return client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()).thenApply(handler::apply); } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/FeaturesManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/FeaturesManager.java index bb750340..5802dfa4 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/FeaturesManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/FeaturesManager.java @@ -7,11 +7,9 @@ import java.util.Map; public class FeaturesManager { - private final transient LaunchServer server; private final Map map; public FeaturesManager(LaunchServer server) { - this.server = server; map = new HashMap<>(); addFeatureInfo("version", Version.getVersion().getVersionString()); addFeatureInfo("projectName", server.config.projectName); @@ -25,8 +23,8 @@ public String getFeatureInfo(String name) { return map.get(name); } - public String addFeatureInfo(String name, String featureInfo) { - return map.put(name, featureInfo); + public void addFeatureInfo(String name, String featureInfo) { + map.put(name, featureInfo); } public String removeFeatureInfo(String name) { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/KeyAgreementManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/KeyAgreementManager.java index 0ee48ecd..4ddee0cc 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/KeyAgreementManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/KeyAgreementManager.java @@ -22,7 +22,6 @@ public class KeyAgreementManager { public final RSAPublicKey rsaPublicKey; public final RSAPrivateKey rsaPrivateKey; public final String legacySalt; - private transient final Logger logger = LogManager.getLogger(); public KeyAgreementManager(ECPublicKey ecdsaPublicKey, ECPrivateKey ecdsaPrivateKey, RSAPublicKey rsaPublicKey, RSAPrivateKey rsaPrivateKey, String legacySalt) { this.ecdsaPublicKey = ecdsaPublicKey; @@ -34,6 +33,7 @@ public KeyAgreementManager(ECPublicKey ecdsaPublicKey, ECPrivateKey ecdsaPrivate public KeyAgreementManager(Path keyDirectory) throws IOException, InvalidKeySpecException { Path ecdsaPublicKeyPath = keyDirectory.resolve("ecdsa_id.pub"), ecdsaPrivateKeyPath = keyDirectory.resolve("ecdsa_id"); + Logger logger = LogManager.getLogger(); if (IOHelper.isFile(ecdsaPublicKeyPath) && IOHelper.isFile(ecdsaPrivateKeyPath)) { logger.info("Reading ECDSA keypair"); ecdsaPublicKey = SecurityHelper.toPublicECDSAKey(IOHelper.read(ecdsaPublicKeyPath)); 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 024951cd..592a79d3 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java @@ -1,7 +1,6 @@ package pro.gravit.launchserver.socket; import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; @@ -34,11 +33,11 @@ public class LauncherNettyServer implements AutoCloseable { public final EventLoopGroup workerGroup; public final WebSocketService service; public final BiHookSet pipelineHook = new BiHookSet<>(); - private transient final Logger logger = LogManager.getLogger(); public LauncherNettyServer(LaunchServer server) { LaunchServerConfig.NettyConfig config = server.config.netty; NettyObjectFactory.setUsingEpoll(config.performance.usingEpoll); + Logger logger = LogManager.getLogger(); if (config.performance.usingEpoll) { logger.debug("Netty: Epoll enabled"); } @@ -74,8 +73,8 @@ public void initChannel(SocketChannel ch) { }); } - public ChannelFuture bind(InetSocketAddress address) { - return serverBootstrap.bind(address); + public void bind(InetSocketAddress address) { + serverBootstrap.bind(address); } @Override 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 555bb696..2cd59b24 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java @@ -56,7 +56,6 @@ public WebSocketService(ChannelGroup channels, LaunchServer server) { this.gson = Launcher.gsonManager.gson; } - @SuppressWarnings("deprecation") public static void registerResponses() { providers.register("auth", AuthResponse.class); providers.register("checkServer", CheckServerResponse.class); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyWebAPIHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyWebAPIHandler.java index b9603131..46fa2fd4 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyWebAPIHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyWebAPIHandler.java @@ -36,10 +36,9 @@ public NettyWebAPIHandler(NettyConnectContext context) { this.context = context; } - public static SeverletPathPair addNewSeverlet(String path, SimpleSeverletHandler callback) { + public static void addNewSeverlet(String path, SimpleSeverletHandler callback) { SeverletPathPair pair = new SeverletPathPair("/webapi/".concat(path), callback); severletList.add(pair); - return pair; } public static SeverletPathPair addUnsafeSeverlet(String path, SimpleSeverletHandler callback) { @@ -53,7 +52,7 @@ public static void removeSeverlet(SeverletPathPair pair) { } @Override - protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception { + protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) { boolean isNext = true; for (SeverletPathPair pair : severletList) { if (msg.uri().startsWith(pair.key)) { @@ -75,7 +74,7 @@ protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) thro @FunctionalInterface public interface SimpleSeverletHandler { - void handle(ChannelHandlerContext ctx, FullHttpRequest msg, NettyConnectContext context) throws Exception; + void handle(ChannelHandlerContext ctx, FullHttpRequest msg, NettyConnectContext context); default Map getParamsFromUri(String uri) { int ind = uri.indexOf("?"); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AdditionalDataResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AdditionalDataResponse.java index 7b99818b..b3a38e6b 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AdditionalDataResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AdditionalDataResponse.java @@ -11,7 +11,6 @@ import java.util.Map; import java.util.UUID; -@SuppressWarnings("deprecation") public class AdditionalDataResponse extends SimpleResponse { public String username; public UUID uuid; @@ -22,7 +21,7 @@ public String getType() { } @Override - public void execute(ChannelHandlerContext ctx, Client client) throws Exception { + public void execute(ChannelHandlerContext ctx, Client client) { if (!client.isAuth) { sendError("Access denied"); return; 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 e947bfaf..58f1ea35 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 @@ -28,7 +28,7 @@ public String getType() { } @Override - public void execute(ChannelHandlerContext ctx, Client clientData) throws Exception { + public void execute(ChannelHandlerContext ctx, Client clientData) { try { AuthRequestEvent result = new AuthRequestEvent(); AuthProviderPair pair; 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 8cfd8455..d1aaa064 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 @@ -6,11 +6,9 @@ import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.response.SimpleResponse; -import java.io.IOException; - public class CurrentUserResponse extends SimpleResponse { - public static CurrentUserRequestEvent.UserInfo collectUserInfoFromClient(LaunchServer server, Client client) throws IOException { + public static CurrentUserRequestEvent.UserInfo collectUserInfoFromClient(LaunchServer server, Client client) { CurrentUserRequestEvent.UserInfo result = new CurrentUserRequestEvent.UserInfo(); if (client.auth != null && client.isAuth && client.username != null) { result.playerProfile = server.authManager.getPlayerProfile(client); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/FetchClientProfileKeyResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/FetchClientProfileKeyResponse.java index 2e1281d9..92f191f5 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/FetchClientProfileKeyResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/FetchClientProfileKeyResponse.java @@ -14,7 +14,7 @@ public String getType() { } @Override - public void execute(ChannelHandlerContext ctx, Client client) throws Exception { + public void execute(ChannelHandlerContext ctx, Client client) { if (!client.isAuth || client.type != AuthResponse.ConnectTypes.CLIENT) { sendError("Permissions denied"); return; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RefreshTokenResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RefreshTokenResponse.java index f6dfada4..892a4e3c 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RefreshTokenResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RefreshTokenResponse.java @@ -18,7 +18,7 @@ public String getType() { } @Override - public void execute(ChannelHandlerContext ctx, Client client) throws Exception { + public void execute(ChannelHandlerContext ctx, Client client) { if (refreshToken == null) { sendError("Invalid request"); return; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RestoreResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RestoreResponse.java index e7a51b3c..fa720e5c 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RestoreResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RestoreResponse.java @@ -76,6 +76,10 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception { return; } User user = session.getUser(); + if(user == null) { + sendError("Internal Auth error: UserSession is broken"); + return; + } client.coreObject = user; client.sessionObject = session; server.authManager.internalAuth(client, client.type == null ? AuthResponse.ConnectTypes.API : client.type, pair, user.getUsername(), user.getUUID(), user.getPermissions(), true); 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 ca314187..e28955df 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 @@ -18,7 +18,7 @@ public String getType() { } @Override - public void execute(ChannelHandlerContext ctx, Client client) throws Exception { + public void execute(ChannelHandlerContext ctx, Client client) { sendError("Legacy session system removed"); } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/GetPublicKeyResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/GetPublicKeyResponse.java index daebed27..398dc3e4 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/GetPublicKeyResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/management/GetPublicKeyResponse.java @@ -12,7 +12,7 @@ public String getType() { } @Override - public void execute(ChannelHandlerContext ctx, Client client) throws Exception { + public void execute(ChannelHandlerContext ctx, Client client) { sendResult(new GetPublicKeyRequestEvent(server.keyAgreementManager.rsaPublicKey, server.keyAgreementManager.ecdsaPublicKey)); } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/profile/BatchProfileByUsername.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/profile/BatchProfileByUsername.java index 513a7ff6..3193d940 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/profile/BatchProfileByUsername.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/profile/BatchProfileByUsername.java @@ -16,7 +16,7 @@ public String getType() { } @Override - public void execute(ChannelHandlerContext ctx, Client client) throws Exception { + public void execute(ChannelHandlerContext ctx, Client client) { BatchProfileByUsernameRequestEvent result = new BatchProfileByUsernameRequestEvent(); if (list == null) { sendError("Invalid request"); 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 50ec6978..90f59088 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 @@ -19,7 +19,7 @@ public String getType() { } @Override - public void execute(ChannelHandlerContext ctx, Client client) throws Exception { + public void execute(ChannelHandlerContext ctx, Client client) { AuthProviderPair pair; if (client.auth == null) { pair = server.config.getAuthProviderPair(); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/profile/ProfileByUsername.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/profile/ProfileByUsername.java index 08ecb794..d19c301a 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/profile/ProfileByUsername.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/profile/ProfileByUsername.java @@ -17,7 +17,7 @@ public String getType() { } @Override - public void execute(ChannelHandlerContext ctx, Client client) throws Exception { + public void execute(ChannelHandlerContext ctx, Client client) { AuthProviderPair pair = client.auth; if (pair == null) pair = server.config.getAuthProviderPair(); PlayerProfile profile = server.authManager.getPlayerProfile(pair, username); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/update/LauncherResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/update/LauncherResponse.java index f011283c..31274399 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/update/LauncherResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/update/LauncherResponse.java @@ -85,12 +85,10 @@ private boolean checkSecure(String hash, String salt) { } public static class LauncherTokenVerifier implements RestoreResponse.ExtendedTokenProvider { - private final LaunchServer server; private final JwtParser parser; private final Logger logger = LogManager.getLogger(); public LauncherTokenVerifier(LaunchServer server) { - this.server = server; parser = Jwts.parserBuilder() .setSigningKey(server.keyAgreementManager.ecdsaPublicKey) .requireIssuer("LaunchServer") diff --git a/LaunchServer/src/test/java/pro/gravit/launchserver/ASMTransformersTest.java b/LaunchServer/src/test/java/pro/gravit/launchserver/ASMTransformersTest.java index dce01ae2..112fbc13 100644 --- a/LaunchServer/src/test/java/pro/gravit/launchserver/ASMTransformersTest.java +++ b/LaunchServer/src/test/java/pro/gravit/launchserver/ASMTransformersTest.java @@ -21,7 +21,7 @@ public class ASMTransformersTest { public static ASMClassLoader classLoader; @BeforeAll - public static void prepare() throws Throwable { + public static void prepare() { classLoader = new ASMClassLoader(ASMTransformersTest.class.getClassLoader()); } diff --git a/LaunchServer/src/test/java/pro/gravit/launchserver/ConfigurationTest.java b/LaunchServer/src/test/java/pro/gravit/launchserver/ConfigurationTest.java index ba8976e7..89ce58eb 100644 --- a/LaunchServer/src/test/java/pro/gravit/launchserver/ConfigurationTest.java +++ b/LaunchServer/src/test/java/pro/gravit/launchserver/ConfigurationTest.java @@ -2,6 +2,7 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import pro.gravit.launcher.Launcher; import pro.gravit.launchserver.config.LaunchServerConfig; @@ -45,4 +46,9 @@ public static void prepare() throws Throwable { .setCommandHandler(new StdCommandHandler(false)); launchServer = builder.build(); } + + @Test + public void test() { + + } } diff --git a/LaunchServer/src/test/java/pro/gravit/launchserver/impl/TestLaunchServerConfigManager.java b/LaunchServer/src/test/java/pro/gravit/launchserver/impl/TestLaunchServerConfigManager.java index 67ff77e5..2d56691d 100644 --- a/LaunchServer/src/test/java/pro/gravit/launchserver/impl/TestLaunchServerConfigManager.java +++ b/LaunchServer/src/test/java/pro/gravit/launchserver/impl/TestLaunchServerConfigManager.java @@ -4,8 +4,6 @@ import pro.gravit.launchserver.config.LaunchServerConfig; import pro.gravit.launchserver.config.LaunchServerRuntimeConfig; -import java.io.IOException; - public class TestLaunchServerConfigManager implements LaunchServer.LaunchServerConfigManager { public LaunchServerConfig config; public LaunchServerRuntimeConfig runtimeConfig; @@ -17,22 +15,22 @@ public TestLaunchServerConfigManager() { } @Override - public LaunchServerConfig readConfig() throws IOException { + public LaunchServerConfig readConfig() { return config; } @Override - public LaunchServerRuntimeConfig readRuntimeConfig() throws IOException { + public LaunchServerRuntimeConfig readRuntimeConfig() { return runtimeConfig; } @Override - public void writeConfig(LaunchServerConfig config) throws IOException { + public void writeConfig(LaunchServerConfig config) { } @Override - public void writeRuntimeConfig(LaunchServerRuntimeConfig config) throws IOException { + public void writeRuntimeConfig(LaunchServerRuntimeConfig config) { } } diff --git a/Launcher/build.gradle b/Launcher/build.gradle index c492bd5c..02cdfb7e 100644 --- a/Launcher/build.gradle +++ b/Launcher/build.gradle @@ -29,12 +29,12 @@ "Multi-Release": "true") } -task sourcesJar(type: Jar) { +tasks.register('sourcesJar', Jar) { from sourceSets.main.allJava archiveClassifier.set('sources') } -task javadocJar(type: Jar) { +tasks.register('javadocJar', Jar) { from javadoc archiveClassifier.set('javadoc') } @@ -53,14 +53,14 @@ pack project(':LauncherAPI') pack group: 'io.netty', name: 'netty-codec-http', version: rootProject['verNetty'] } -task genRuntimeJS(type: Zip) { +tasks.register('genRuntimeJS', Zip) { duplicatesStrategy = 'EXCLUDE' archiveFileName = "runtime.zip" destinationDirectory = file("${buildDir}/tmp") from "runtime/" } -task dumpLibs(type: Copy) { +tasks.register('dumpLibs', Copy) { duplicatesStrategy = 'EXCLUDE' into "$buildDir/libs/libraries" from configurations.bundle diff --git a/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java b/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java index 5b487024..6a0d2f29 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java +++ b/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java @@ -83,8 +83,6 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep } context.executePath = IOHelper.resolveJavaBin(context.javaVersion.jvmDir); - //List args = new LinkedList<>(); - //args.add(javaBin.toString()); String pathLauncher = IOHelper.getCodeSource(LauncherEngine.class).toString(); context.mainClass = LauncherEngine.class.getName(); context.memoryLimit = launcherMemoryLimit; diff --git a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java index 6f22d4f9..74ad4797 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java +++ b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java @@ -130,8 +130,6 @@ public static void main(String... args) throws Throwable { } long endTime = System.currentTimeMillis(); LogHelper.debug("Launcher started in %dms", endTime - startTime); - //Request.service.close(); - //FunctionalBridge.close(); LauncherEngine.exitLauncher(0); } diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java index 192e0741..82e7a38b 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java @@ -12,7 +12,7 @@ public class ClientClassLoader extends URLClassLoader { private static final ClassLoader SYSTEM_CLASS_LOADER = ClassLoader.getSystemClassLoader(); public String nativePath; - private List packages = new ArrayList<>(); + private final List packages = new ArrayList<>(); /** * Constructs a new URLClassLoader for the specified URLs using the @@ -32,7 +32,6 @@ public class ClientClassLoader extends URLClassLoader { * {@code checkCreateClassLoader} method doesn't allow * creation of a class loader. * @throws NullPointerException if {@code urls} is {@code null}. - * @see SecurityManager#checkCreateClassLoader */ public ClientClassLoader(URL[] urls) { super(urls); @@ -59,7 +58,6 @@ public ClientClassLoader(URL[] urls) { * {@code checkCreateClassLoader} method doesn't allow * creation of a class loader. * @throws NullPointerException if {@code urls} is {@code null}. - * @see SecurityManager#checkCreateClassLoader */ public ClientClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); 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 8a9343f6..94abd9e2 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java @@ -186,20 +186,10 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException { } private void applyJava9Params(List processArgs) { - /*jvmModulesPaths.add(javaVersion.jvmDir); - jvmModulesPaths.add(javaVersion.jvmDir.resolve("jre")); - Path openjfxPath = JavaHelper.tryGetOpenJFXPath(javaVersion.jvmDir); - if (openjfxPath != null) { - jvmModulesPaths.add(openjfxPath); - }*/ // TODO: fix runtime in client + // TODO: fix runtime in client StringBuilder modulesPath = new StringBuilder(); StringBuilder modulesAdd = new StringBuilder(); for (String moduleName : jvmModules) { - /*boolean success = JavaHelper.tryAddModule(jvmModulesPaths, moduleName, modulesPath); - if (success) { - if (modulesAdd.length() > 0) modulesAdd.append(","); - modulesAdd.append(moduleName); - }*/ if (modulesAdd.length() > 0) modulesAdd.append(","); modulesAdd.append(moduleName); } diff --git a/Launcher/src/main/java/pro/gravit/launcher/console/GetPublicKeyCommand.java b/Launcher/src/main/java/pro/gravit/launcher/console/GetPublicKeyCommand.java index 49a64eae..e20313fc 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/console/GetPublicKeyCommand.java +++ b/Launcher/src/main/java/pro/gravit/launcher/console/GetPublicKeyCommand.java @@ -24,7 +24,7 @@ public String getUsageDescription() { } @Override - public void invoke(String... args) throws Exception { + public void invoke(String... args) { LogHelper.info("PublicKey: %s", Base64.getEncoder().encodeToString(engine.getClientPublicKey().getEncoded())); } } diff --git a/Launcher/src/main/java/pro/gravit/launcher/console/ModulesCommand.java b/Launcher/src/main/java/pro/gravit/launcher/console/ModulesCommand.java index 69206700..94b03799 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/console/ModulesCommand.java +++ b/Launcher/src/main/java/pro/gravit/launcher/console/ModulesCommand.java @@ -23,7 +23,7 @@ public String getUsageDescription() { } @Override - public void invoke(String... args) throws Exception { + public void invoke(String... args) { for (LauncherModule module : LauncherEngine.modulesManager.getModules()) { LauncherModuleInfo info = module.getModuleInfo(); LauncherTrustManager.CheckClassResult checkStatus = module.getCheckResult(); diff --git a/Launcher/src/main/java/pro/gravit/launcher/console/test/PrintHardwareInfoCommand.java b/Launcher/src/main/java/pro/gravit/launcher/console/test/PrintHardwareInfoCommand.java index 5c3c42a7..93bbe490 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/console/test/PrintHardwareInfoCommand.java +++ b/Launcher/src/main/java/pro/gravit/launcher/console/test/PrintHardwareInfoCommand.java @@ -16,7 +16,7 @@ public String getUsageDescription() { } @Override - public void invoke(String... args) throws Exception { + public void invoke(String... args) { LogHelper.info("Your Hardware ID:"); long startTime = System.currentTimeMillis(); long currentTime; diff --git a/Launcher/src/main/java/pro/gravit/launcher/gui/NoRuntimeProvider.java b/Launcher/src/main/java/pro/gravit/launcher/gui/NoRuntimeProvider.java index 9f3b6af8..0ac704d9 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/gui/NoRuntimeProvider.java +++ b/Launcher/src/main/java/pro/gravit/launcher/gui/NoRuntimeProvider.java @@ -4,12 +4,12 @@ public class NoRuntimeProvider implements RuntimeProvider { @Override - public void run(String[] args) throws Exception { + public void run(String[] args) { JOptionPane.showMessageDialog(null, "GUI часть лаунчера не найдена.\nС 5.1.0 вам необходимо самостоятельно установить модуль, отвечающий за GUI. Рантайм на JS более не поддерживается"); } @Override - public void preLoad() throws Exception { + public void preLoad() { } diff --git a/Launcher/src/main/java/pro/gravit/launcher/gui/RuntimeProvider.java b/Launcher/src/main/java/pro/gravit/launcher/gui/RuntimeProvider.java index 398b0886..bee04f48 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/gui/RuntimeProvider.java +++ b/Launcher/src/main/java/pro/gravit/launcher/gui/RuntimeProvider.java @@ -1,9 +1,9 @@ package pro.gravit.launcher.gui; public interface RuntimeProvider { - void run(String[] args) throws Exception; + void run(String[] args); - void preLoad() throws Exception; + void preLoad(); void init(boolean clientInstance); } diff --git a/Launcher/src/main/java/pro/gravit/launcher/utils/DirWatcher.java b/Launcher/src/main/java/pro/gravit/launcher/utils/DirWatcher.java index 512d0bb1..84107d9b 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/utils/DirWatcher.java +++ b/Launcher/src/main/java/pro/gravit/launcher/utils/DirWatcher.java @@ -115,10 +115,6 @@ private final class RegisterFileVisitor extends SimpleFileVisitor { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { FileVisitResult result = super.preVisitDirectory(dir, attrs); - if (DirWatcher.this.dir.equals(dir)) { - dir.register(service, KINDS); - return result; - } // Maybe it's unnecessary to go deeper //if (matcher != null && !matcher.shouldVerify(path)) { diff --git a/Launcher/src/main/java/pro/gravit/launcher/utils/NativeJVMHalt.java b/Launcher/src/main/java/pro/gravit/launcher/utils/NativeJVMHalt.java index 3d79d20c..34eea24c 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/utils/NativeJVMHalt.java +++ b/Launcher/src/main/java/pro/gravit/launcher/utils/NativeJVMHalt.java @@ -17,7 +17,6 @@ public static void initFunc() { } public static void haltA(int code) { - Throwable[] th = new Throwable[3]; NativeJVMHalt halt = new NativeJVMHalt(code); try { LogHelper.dev("Try invoke Shutdown.exit"); @@ -26,7 +25,6 @@ public static void haltA(int code) { exitMethod.setAccessible(true); exitMethod.invoke(null, code); } catch (Throwable e) { - th[1] = e; if (LogHelper.isDevEnabled()) { LogHelper.error(e); } diff --git a/LauncherAPI/build.gradle b/LauncherAPI/build.gradle index 13feac0d..8a418fc6 100644 --- a/LauncherAPI/build.gradle +++ b/LauncherAPI/build.gradle @@ -37,12 +37,12 @@ java11Implementation files(sourceSets.main.output.classesDirs) { builtBy compile targetCompatibility = 11 } -task sourcesJar(type: Jar) { +tasks.register('sourcesJar', Jar) { from sourceSets.main.allJava archiveClassifier.set('sources') } -task javadocJar(type: Jar) { +tasks.register('javadocJar', Jar) { from javadoc archiveClassifier.set('javadoc') } diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/modules/LauncherModule.java b/LauncherAPI/src/main/java/pro/gravit/launcher/modules/LauncherModule.java index 20e6b883..65ed59a4 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/modules/LauncherModule.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/modules/LauncherModule.java @@ -31,9 +31,8 @@ public InitStatus getInitStatus() { return initStatus; } - public LauncherModule setInitStatus(InitStatus initStatus) { + public void setInitStatus(InitStatus initStatus) { this.initStatus = initStatus; - return this; } /** @@ -71,11 +70,10 @@ public final void setCheckResult(LauncherTrustManager.CheckClassResult result) { this.checkResult = result; } - protected final LauncherModule requireModule(String name, Version minVersion) { + protected final void requireModule(String name, Version minVersion) { if (context == null) throw new IllegalStateException("requireModule must be used in init() phase"); LauncherModule module = context.getModulesManager().getModule(name); requireModule(module, minVersion, name); - return module; } protected final T requireModule(Class clazz, Version minVersion) { @@ -107,13 +105,12 @@ public void preInitAction() { //NOP } - public final LauncherModule preInit() { + public final void preInit() { if (!initStatus.equals(InitStatus.PRE_INIT_WAIT)) throw new IllegalStateException("PreInit not allowed in current state"); initStatus = InitStatus.PRE_INIT; preInitAction(); initStatus = InitStatus.INIT_WAIT; - return this; } /** @@ -225,9 +222,8 @@ public boolean isCancel() { return cancel; } - public Event cancel() { + public void cancel() { this.cancel = true; - return this; } } } 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 c4a1342e..3773e1c2 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java @@ -8,7 +8,6 @@ import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.VerifyHelper; -import java.io.IOException; import java.net.InetSocketAddress; import java.util.*; @@ -510,7 +509,7 @@ public enum CompatibilityFlags { @FunctionalInterface public interface pushOptionalClassPathCallback { - void run(String[] opt) throws IOException; + void run(String[] opt); } public static class ServerProfile { diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileBuilder.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileBuilder.java index fe83469e..78ebfae7 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileBuilder.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileBuilder.java @@ -35,9 +35,8 @@ public class ClientProfileBuilder { private String info; private String mainClass; - public ClientProfileBuilder setUpdate(List update) { + public void setUpdate(List update) { this.update = update; - return this; } public ClientProfileBuilder setUpdateExclusions(List updateExclusions) { @@ -50,34 +49,28 @@ public ClientProfileBuilder setUpdateShared(List updateShared) { return this; } - public ClientProfileBuilder setUpdateVerify(List updateVerify) { + public void setUpdateVerify(List updateVerify) { this.updateVerify = updateVerify; - return this; } - public ClientProfileBuilder setUpdateOptional(Set updateOptional) { + public void setUpdateOptional(Set updateOptional) { this.updateOptional = updateOptional; - return this; } - public ClientProfileBuilder setJvmArgs(List jvmArgs) { + public void setJvmArgs(List jvmArgs) { this.jvmArgs = jvmArgs; - return this; } - public ClientProfileBuilder setClassPath(List classPath) { + public void setClassPath(List classPath) { this.classPath = classPath; - return this; } - public ClientProfileBuilder setAltClassPath(List altClassPath) { + public void setAltClassPath(List altClassPath) { this.altClassPath = altClassPath; - return this; } - public ClientProfileBuilder setClientArgs(List clientArgs) { + public void setClientArgs(List clientArgs) { this.clientArgs = clientArgs; - return this; } public ClientProfileBuilder setCompatClasses(List compatClasses) { @@ -90,39 +83,32 @@ public ClientProfileBuilder setProperties(Map properties) { return this; } - public ClientProfileBuilder setServers(List servers) { + public void setServers(List servers) { this.servers = servers; - return this; } - public ClientProfileBuilder setClassLoaderConfig(ClientProfile.ClassLoaderConfig classLoaderConfig) { + public void setClassLoaderConfig(ClientProfile.ClassLoaderConfig classLoaderConfig) { this.classLoaderConfig = classLoaderConfig; - return this; } - public ClientProfileBuilder setVersion(String version) { + public void setVersion(String version) { this.version = version; - return this; } - public ClientProfileBuilder setAssetIndex(String assetIndex) { + public void setAssetIndex(String assetIndex) { this.assetIndex = assetIndex; - return this; } - public ClientProfileBuilder setDir(String dir) { + public void setDir(String dir) { this.dir = dir; - return this; } - public ClientProfileBuilder setAssetDir(String assetDir) { + public void setAssetDir(String assetDir) { this.assetDir = assetDir; - return this; } - public ClientProfileBuilder setRecommendJavaVersion(int recommendJavaVersion) { + public void setRecommendJavaVersion(int recommendJavaVersion) { this.recommendJavaVersion = recommendJavaVersion; - return this; } public ClientProfileBuilder setModulePath(List modulePath) { @@ -135,14 +121,12 @@ public ClientProfileBuilder setModules(List modules) { return this; } - public ClientProfileBuilder setMinJavaVersion(int minJavaVersion) { + public void setMinJavaVersion(int minJavaVersion) { this.minJavaVersion = minJavaVersion; - return this; } - public ClientProfileBuilder setMaxJavaVersion(int maxJavaVersion) { + public void setMaxJavaVersion(int maxJavaVersion) { this.maxJavaVersion = maxJavaVersion; - return this; } public ClientProfileBuilder setSettings(ClientProfile.ProfileDefaultSettings settings) { @@ -155,24 +139,20 @@ public ClientProfileBuilder setSortIndex(int sortIndex) { return this; } - public ClientProfileBuilder setUuid(UUID uuid) { + public void setUuid(UUID uuid) { this.uuid = uuid; - return this; } - public ClientProfileBuilder setTitle(String title) { + public void setTitle(String title) { this.title = title; - return this; } - public ClientProfileBuilder setInfo(String info) { + public void setInfo(String info) { this.info = info; - return this; } - public ClientProfileBuilder setMainClass(String mainClass) { + public void setMainClass(String mainClass) { this.mainClass = mainClass; - return this; } public ClientProfileBuilder setFlags(List flags) { diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/optional/triggers/JavaTrigger.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/optional/triggers/JavaTrigger.java index d7ffad83..46c08852 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/optional/triggers/JavaTrigger.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/optional/triggers/JavaTrigger.java @@ -31,7 +31,6 @@ public boolean isTriggered(OptionalFile optional, OptionalTriggerContext context JavaHelper.JavaVersion version = context.getJavaVersion(); if (version.version < minVersion) return false; if (version.version > maxVersion) return false; - if (requireJavaFX && !version.enabledJavaFX) return false; - return true; + return !requireJavaFX || version.enabledJavaFX; } } diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/Request.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/Request.java index b3d4df69..0c6f1cc5 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/Request.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/Request.java @@ -116,9 +116,9 @@ public static String getRefreshToken() { return oauth == null ? null : oauth.refreshToken; } - public static RequestRestoreReport reconnect() throws Exception { + public static void reconnect() throws Exception { service.open(); - return restore(); + restore(); } public static RequestRestoreReport restore() throws Exception { diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/RequestService.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/RequestService.java index 39cc2f27..2f8d4bab 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/RequestService.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/RequestService.java @@ -29,7 +29,7 @@ default T requestSync(Request request) throws IOEx boolean isClosed(); @FunctionalInterface - public interface EventHandler { + interface EventHandler { /** * @param event processing event * @param event type diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientJSONPoint.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientJSONPoint.java index d4ce4ec0..255c3267 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientJSONPoint.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientJSONPoint.java @@ -126,9 +126,9 @@ public void openAsync(Runnable onConnect, Consumer onFail) { }); } - public ChannelFuture send(String text) { + public void send(String text) { LogHelper.dev("Send: %s", text); - return ch.writeAndFlush(new TextWebSocketFrame(text), ch.voidPromise()); + ch.writeAndFlush(new TextWebSocketFrame(text), ch.voidPromise()); } abstract void onMessage(String message); 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 9da094b4..04062458 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 @@ -114,33 +114,17 @@ public void registerResults() { } public void waitIfNotConnected() { - /*if(!isOpen() && !isClosed() && !isClosing()) - { - LogHelper.warning("WebSocket not connected. Try wait onConnect object"); - synchronized (onConnect) - { - try { - onConnect.wait(5000); - } catch (InterruptedException e) { - LogHelper.error(e); - } - } - }*/ } public void sendObject(Object obj) throws IOException { waitIfNotConnected(); if (ch == null || !ch.isActive()) reconnectCallback.onReconnect(); - //if(isClosed() && reconnectCallback != null) - // reconnectCallback.onReconnect(); send(gson.toJson(obj, WebSocketRequest.class)); } public void sendObject(Object obj, Type type) throws IOException { waitIfNotConnected(); if (ch == null || !ch.isActive()) reconnectCallback.onReconnect(); - //if(isClosed() && reconnectCallback != null) - // reconnectCallback.onReconnect(); send(gson.toJson(obj, type)); } diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/OfflineRequestService.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/OfflineRequestService.java index 09aee311..bb86a8c2 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/OfflineRequestService.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/OfflineRequestService.java @@ -7,7 +7,6 @@ import pro.gravit.launcher.request.WebSocketEvent; import pro.gravit.utils.helper.LogHelper; -import java.io.IOException; import java.util.HashSet; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -19,7 +18,7 @@ public class OfflineRequestService implements RequestService { @Override @SuppressWarnings("unchecked") - public CompletableFuture request(Request request) throws IOException { + public CompletableFuture request(Request request) { RequestProcessor> processor = (RequestProcessor>) processors.get(request.getClass()); CompletableFuture future = new CompletableFuture<>(); if (processor == null) { diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/StdWebSocketService.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/StdWebSocketService.java index ad6212e1..26515464 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/StdWebSocketService.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/StdWebSocketService.java @@ -27,7 +27,7 @@ public StdWebSocketService(String address) throws SSLException { super(address); } - public static CompletableFuture initWebSockets(String address) throws Exception { + public static CompletableFuture initWebSockets(String address) { StdWebSocketService service; try { service = new StdWebSocketService(address); @@ -41,16 +41,12 @@ public static CompletableFuture initWebSockets(String addre future.complete(service); JVMHelper.RUNTIME.addShutdownHook(new Thread(() -> { try { - //if(service.isOpen()) - // service.closeBlocking(); service.close(); } catch (InterruptedException e) { LogHelper.error(e); } })); - }, (error) -> { - future.completeExceptionally(error); - }); + }, (error) -> future.completeExceptionally(error)); return future; } @@ -74,7 +70,7 @@ public void processEventHandlers(T event) { } } - @SuppressWarnings({"unchecked", "deprecation"}) + @SuppressWarnings({"unchecked"}) public void eventHandle(T webSocketEvent) { if (webSocketEvent instanceof RequestEvent) { RequestEvent event = (RequestEvent) webSocketEvent; diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/VoidRequestService.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/VoidRequestService.java index e08214c2..b45c5dc5 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/VoidRequestService.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/VoidRequestService.java @@ -5,7 +5,6 @@ import pro.gravit.launcher.request.RequestService; import pro.gravit.launcher.request.WebSocketEvent; -import java.io.IOException; import java.util.concurrent.CompletableFuture; public class VoidRequestService implements RequestService { @@ -20,7 +19,7 @@ public VoidRequestService() { } @Override - public CompletableFuture request(Request request) throws IOException { + public CompletableFuture request(Request request) { CompletableFuture future = new CompletableFuture<>(); future.completeExceptionally(ex != null ? ex : new RequestException("Connection fail")); return future; diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/WebSocketClientHandler.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/WebSocketClientHandler.java index 58cd35be..1fa99c11 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/WebSocketClientHandler.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/WebSocketClientHandler.java @@ -29,14 +29,14 @@ public void handlerAdded(final ChannelHandlerContext ctx) { } @Override - public void channelActive(final ChannelHandlerContext ctx) throws Exception { + public void channelActive(final ChannelHandlerContext ctx) { handshaker.handshake(ctx.channel()); clientJSONPoint.onOpen(); ctx.executor().scheduleWithFixedDelay(() -> ctx.channel().writeAndFlush(new PingWebSocketFrame()), 20L, 20L, TimeUnit.SECONDS); } @Override - public void channelInactive(final ChannelHandlerContext ctx) throws Exception { + public void channelInactive(final ChannelHandlerContext ctx) { //System.out.println("WebSocket Client disconnected!"); clientJSONPoint.onDisconnect(); } diff --git a/LauncherCore/build.gradle b/LauncherCore/build.gradle index 9fd20aed..e8401182 100644 --- a/LauncherCore/build.gradle +++ b/LauncherCore/build.gradle @@ -43,12 +43,12 @@ java11Implementation files(sourceSets.main.output.classesDirs) { builtBy compile targetCompatibility = 11 } -task sourcesJar(type: Jar) { +tasks.register('sourcesJar', Jar) { from sourceSets.main.allJava archiveClassifier.set('sources') } -task javadocJar(type: Jar) { +tasks.register('javadocJar', Jar) { from javadoc archiveClassifier.set('javadoc') } diff --git a/LauncherCore/src/main/java/pro/gravit/launcher/AsyncDownloader.java b/LauncherCore/src/main/java/pro/gravit/launcher/AsyncDownloader.java index f7ff77fa..2c495419 100644 --- a/LauncherCore/src/main/java/pro/gravit/launcher/AsyncDownloader.java +++ b/LauncherCore/src/main/java/pro/gravit/launcher/AsyncDownloader.java @@ -101,7 +101,7 @@ public void downloadListInOneThread(List files, String baseURL, Path } } - public void downloadListInOneThreadSimple(List files, String baseURL, Path targetDir) throws URISyntaxException, IOException { + public void downloadListInOneThreadSimple(List files, String baseURL, Path targetDir) throws IOException { for (AsyncDownloader.SizedFile currentFile : files) { downloadFile(new URL(baseURL + currentFile.urlPath), targetDir.resolve(currentFile.filePath), currentFile.size); @@ -157,7 +157,7 @@ public CompletableFuture[] runDownloadListSimple(List> files, St futures[i] = CompletableFuture.runAsync(() -> { try { downloadListInOneThreadSimple(currentTasks, baseURL, targetDir); - } catch (URISyntaxException | IOException e) { + } catch (IOException e) { throw new CompletionException(e); } }, executor); diff --git a/LauncherCore/src/main/java/pro/gravit/launcher/hasher/HashedDir.java b/LauncherCore/src/main/java/pro/gravit/launcher/hasher/HashedDir.java index 71b28e17..38128287 100644 --- a/LauncherCore/src/main/java/pro/gravit/launcher/hasher/HashedDir.java +++ b/LauncherCore/src/main/java/pro/gravit/launcher/hasher/HashedDir.java @@ -288,7 +288,7 @@ public enum WalkAction { @FunctionalInterface public interface WalkCallback { - WalkAction walked(String path, String name, HashedEntry entry) throws IOException; + WalkAction walked(String path, String name, HashedEntry entry); } public static class FindRecursiveResult { diff --git a/LauncherCore/src/main/java/pro/gravit/utils/BiHookSet.java b/LauncherCore/src/main/java/pro/gravit/utils/BiHookSet.java index fd3bf7a4..408934d0 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/BiHookSet.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/BiHookSet.java @@ -10,8 +10,8 @@ public void registerHook(Hook hook) { list.add(hook); } - public boolean unregisterHook(Hook hook) { - return list.remove(hook); + public void unregisterHook(Hook hook) { + list.remove(hook); } /** diff --git a/LauncherCore/src/main/java/pro/gravit/utils/Downloader.java b/LauncherCore/src/main/java/pro/gravit/utils/Downloader.java index b36da07f..39cec8f0 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/Downloader.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/Downloader.java @@ -17,7 +17,7 @@ private Downloader(CompletableFuture future, AsyncDownloader downloader) { this.asyncDownloader = downloader; } - public static Downloader downloadList(List files, String baseURL, Path targetDir, DownloadCallback callback, ExecutorService executor, int threads) throws Exception { + public static Downloader downloadList(List files, String baseURL, Path targetDir, DownloadCallback callback, ExecutorService executor, int threads) { final boolean closeExecutor; LogHelper.info("Download with legacy mode"); if (executor == null) { diff --git a/LauncherCore/src/main/java/pro/gravit/utils/HookSet.java b/LauncherCore/src/main/java/pro/gravit/utils/HookSet.java index b60df1eb..7b8eb36f 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/HookSet.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/HookSet.java @@ -10,8 +10,8 @@ public void registerHook(Hook hook) { list.add(hook); } - public boolean unregisterHook(Hook hook) { - return list.remove(hook); + public void unregisterHook(Hook hook) { + list.remove(hook); } /** diff --git a/LauncherCore/src/main/java/pro/gravit/utils/PublicURLClassLoader.java b/LauncherCore/src/main/java/pro/gravit/utils/PublicURLClassLoader.java index c5082afc..90b73309 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/PublicURLClassLoader.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/PublicURLClassLoader.java @@ -23,7 +23,6 @@ public class PublicURLClassLoader extends URLClassLoader { * {@code checkCreateClassLoader} method doesn't allow * creation of a class loader. * @throws NullPointerException if {@code urls} is {@code null}. - * @see SecurityManager#checkCreateClassLoader */ public PublicURLClassLoader(URL[] urls) { super(urls); @@ -48,7 +47,6 @@ public PublicURLClassLoader(URL[] urls) { * {@code checkCreateClassLoader} method doesn't allow * creation of a class loader. * @throws NullPointerException if {@code urls} is {@code null}. - * @see SecurityManager#checkCreateClassLoader */ public PublicURLClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); diff --git a/LauncherCore/src/main/java/pro/gravit/utils/command/CommandHandler.java b/LauncherCore/src/main/java/pro/gravit/utils/command/CommandHandler.java index 44b538d3..b72e4eec 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/command/CommandHandler.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/command/CommandHandler.java @@ -82,8 +82,8 @@ public void registerCategory(Category category) { categories.add(category); } - public boolean unregisterCategory(Category category) { - return categories.remove(category); + public void unregisterCategory(Category category) { + categories.remove(category); } public Category findCategory(String name) { diff --git a/LauncherCore/src/main/java/pro/gravit/utils/command/JLineCommandHandler.java b/LauncherCore/src/main/java/pro/gravit/utils/command/JLineCommandHandler.java index e8a48d0b..fc10052a 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/command/JLineCommandHandler.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/command/JLineCommandHandler.java @@ -9,18 +9,6 @@ import java.util.List; public class JLineCommandHandler extends CommandHandler { - /*private final class JLineOutput implements Output { - @Override - public void println(String message) { - try { - reader.println(ConsoleReader.RESET_LINE + message); - reader.drawLine(); - reader.flush(); - } catch (IOException ignored) { - // Ignored - } - } - }*/ private final Terminal terminal; private final LineReader reader; @@ -40,8 +28,6 @@ public JLineCommandHandler() throws IOException { //reader.setExpandEvents(false); // Replace writer - //LogHelper.removeStdOutput(); - //LogHelper.addOutput(new JLineOutput(), LogHelper.OutputTypes.JANSI); } @Override diff --git a/LauncherCore/src/main/java/pro/gravit/utils/helper/IOHelper.java b/LauncherCore/src/main/java/pro/gravit/utils/helper/IOHelper.java index 2b1812a6..4151dc98 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/helper/IOHelper.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/helper/IOHelper.java @@ -384,7 +384,7 @@ public static BasicFileAttributes readAttributes(Path path) throws IOException { return Files.readAttributes(path, BasicFileAttributes.class, LINK_OPTIONS); } - public static BufferedImage readTexture(Object input, boolean cloak) throws IOException { + public static void readTexture(Object input, boolean cloak) throws IOException { ImageReader reader = ImageIO.getImageReadersByMIMEType("image/png").next(); try { reader.setInput(ImageIO.createImageInputStream(input), false, false); @@ -396,7 +396,7 @@ public static BufferedImage readTexture(Object input, boolean cloak) throws IOEx throw new IOException(String.format("Invalid texture bounds: %dx%d", width, height)); // Read image - return reader.read(0); + reader.read(0); } finally { reader.dispose(); } @@ -528,8 +528,8 @@ public static long transfer(InputStream input, OutputStream output) throws IOExc return transferred; } - public static long transfer(InputStream input, Path file) throws IOException { - return transfer(input, file, false); + public static void transfer(InputStream input, Path file) throws IOException { + transfer(input, file, false); } public static long transfer(InputStream input, Path file, boolean append) throws IOException { diff --git a/LauncherCore/src/main/java/pro/gravit/utils/helper/JarHelper.java b/LauncherCore/src/main/java/pro/gravit/utils/helper/JarHelper.java index 51288723..1e516138 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/helper/JarHelper.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/helper/JarHelper.java @@ -87,7 +87,7 @@ public static InputStream getClassBytesStream(Class clazz) throws IOException return getClassBytesStream(clazz, clazz.getClassLoader()); } - public static InputStream getClassBytesStream(Class clazz, ClassLoader classLoader) throws IOException { + public static InputStream getClassBytesStream(Class clazz, ClassLoader classLoader) { return classLoader.getResourceAsStream(getClassFile(clazz)); } @@ -107,7 +107,7 @@ public static byte[] getClassFromJar(String name, Path file) throws IOException @FunctionalInterface public interface ZipWalkCallback { - void process(ZipInputStream input, ZipEntry e) throws IOException; + void process(ZipInputStream input, ZipEntry e); } @FunctionalInterface diff --git a/LauncherCore/src/main/java/pro/gravit/utils/helper/JavaHelper.java b/LauncherCore/src/main/java/pro/gravit/utils/helper/JavaHelper.java index a0467b27..8c52aa53 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/helper/JavaHelper.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/helper/JavaHelper.java @@ -63,11 +63,7 @@ public synchronized static List findJava() { } List javaPaths = new ArrayList<>(4); List result = new ArrayList<>(4); - try { - tryAddJava(javaPaths, result, JavaVersion.getCurrentJavaVersion()); - } catch (IOException e) { - LogHelper.error(e); - } + tryAddJava(javaPaths, result, JavaVersion.getCurrentJavaVersion()); String[] path = System.getenv("PATH").split(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE ? ";" : ":"); for (String p : path) { try { @@ -121,25 +117,20 @@ private static JavaVersion tryFindJavaByPath(Path path) { return null; } - public static boolean tryAddJava(List javaPaths, List result, JavaVersion version) throws IOException { - if (version == null) return false; + public static void tryAddJava(List javaPaths, List result, JavaVersion version) { + if (version == null) return; String path = version.jvmDir.toAbsolutePath().toString(); - if (javaPaths.contains(path)) return false; + if (javaPaths.contains(path)) return; javaPaths.add(path); result.add(version); - return true; } public static void trySearchJava(List javaPaths, List result, Path path) throws IOException { if (path == null || !Files.isDirectory(path)) return; Files.list(path).filter(p -> Files.exists(p.resolve("bin").resolve(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE ? "java.exe" : "java"))).forEach(e -> { - try { - tryAddJava(javaPaths, result, JavaVersion.getByPath(e)); - if (Files.exists(e.resolve("jre"))) { - tryAddJava(javaPaths, result, JavaVersion.getByPath(e.resolve("jre"))); - } - } catch (IOException ioException) { - LogHelper.error(ioException); + tryAddJava(javaPaths, result, JavaVersion.getByPath(e)); + if (Files.exists(e.resolve("jre"))) { + tryAddJava(javaPaths, result, JavaVersion.getByPath(e.resolve("jre"))); } }); } @@ -233,7 +224,7 @@ private static boolean isCurrentJavaSupportJavaFX() { } } - public static JavaVersion getByPath(Path jvmDir) throws IOException { + public static JavaVersion getByPath(Path jvmDir) { { JavaVersion version = JavaHelper.tryFindJavaByPath(jvmDir); if (version != null) { @@ -241,18 +232,23 @@ public static JavaVersion getByPath(Path jvmDir) throws IOException { } } Path releaseFile = jvmDir.resolve("release"); - JavaVersionAndBuild versionAndBuild; + JavaVersionAndBuild versionAndBuild = null; JVMHelper.ARCH arch = JVMHelper.ARCH_TYPE; if (IOHelper.isFile(releaseFile)) { - Properties properties = new Properties(); - properties.load(IOHelper.newReader(releaseFile)); - versionAndBuild = getJavaVersion(properties.getProperty("JAVA_VERSION").replaceAll("\"", "")); try { - arch = JVMHelper.getArch(properties.getProperty("OS_ARCH").replaceAll("\"", "")); - } catch (Throwable ignored) { - arch = null; + Properties properties = new Properties(); + properties.load(IOHelper.newReader(releaseFile)); + versionAndBuild = getJavaVersion(properties.getProperty("JAVA_VERSION").replaceAll("\"", "")); + try { + arch = JVMHelper.getArch(properties.getProperty("OS_ARCH").replaceAll("\"", "")); + } catch (Throwable ignored) { + arch = null; + } + } catch (IOException ignored) { + } - } else { + } + if(versionAndBuild == null) { versionAndBuild = new JavaVersionAndBuild(isExistExtJavaLibrary(jvmDir, "rt") ? 8 : 9, 0); } JavaVersion resultJavaVersion = new JavaVersion(jvmDir, versionAndBuild.version, versionAndBuild.build, arch, false); diff --git a/LauncherCore/src/main/java/pro/gravit/utils/helper/LogHelper.java b/LauncherCore/src/main/java/pro/gravit/utils/helper/LogHelper.java index c5f2580a..d63fa7f6 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/helper/LogHelper.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/helper/LogHelper.java @@ -25,7 +25,7 @@ public final class LogHelper { public static final String NO_JANSI_PROPERTY = "launcher.noJAnsi"; public static final String NO_SLF4J_PROPERTY = "launcher.noSlf4j"; private static final Set> EXCEPTIONS_CALLBACKS = Collections.newSetFromMap(new ConcurrentHashMap<>(2)); - private static LogHelperAppender impl; + private static final LogHelperAppender impl; static { boolean useSlf4j = false; diff --git a/LauncherCore/src/main/java/pro/gravit/utils/helper/UnpackHelper.java b/LauncherCore/src/main/java/pro/gravit/utils/helper/UnpackHelper.java index 410e55e8..b967fb03 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/helper/UnpackHelper.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/helper/UnpackHelper.java @@ -11,16 +11,15 @@ import java.util.zip.ZipInputStream; public final class UnpackHelper { - public static boolean unpack(URL resource, Path target) throws IOException { + public static void unpack(URL resource, Path target) throws IOException { if (IOHelper.isFile(target)) { - if (matches(target, resource)) return false; + if (matches(target, resource)) return; } Files.deleteIfExists(target); IOHelper.createParentDirs(target); try (InputStream in = IOHelper.newInput(resource)) { IOHelper.transfer(in, target); } - return true; } private static boolean matches(Path target, URL in) { @@ -48,10 +47,10 @@ public static boolean unpackZipNoCheck(URL resource, Path target) throws IOExcep return true; } - public static boolean unpackZipNoCheck(String resource, Path target) throws IOException { + public static void unpackZipNoCheck(String resource, Path target) throws IOException { try { if (Files.isDirectory(target)) - return false; + return; Files.deleteIfExists(target); Files.createDirectory(target); try (ZipInputStream input = IOHelper.newZipInput(IOHelper.getResourceURL(resource))) { @@ -62,9 +61,7 @@ public static boolean unpackZipNoCheck(String resource, Path target) throws IOEx IOHelper.transfer(input, target.resolve(IOHelper.toPath(entry.getName()))); } } - return true; } catch (NoSuchFileException e) { - return true; } } } diff --git a/LauncherCore/src/main/java/pro/gravit/utils/helper/VerifyHelper.java b/LauncherCore/src/main/java/pro/gravit/utils/helper/VerifyHelper.java index e3c41b65..f43a313b 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/helper/VerifyHelper.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/helper/VerifyHelper.java @@ -67,8 +67,8 @@ public static double verifyDouble(double d, DoublePredicate predicate, String er throw new IllegalArgumentException(error); } - public static String verifyIDName(String name) { - return verify(name, VerifyHelper::isValidIDName, String.format("Invalid name: '%s'", name)); + public static void verifyIDName(String name) { + verify(name, VerifyHelper::isValidIDName, String.format("Invalid name: '%s'", name)); } public static int verifyInt(int i, IntPredicate predicate, String error) { diff --git a/LauncherCore/src/main/java/pro/gravit/utils/logging/SimpleLogHelperImpl.java b/LauncherCore/src/main/java/pro/gravit/utils/logging/SimpleLogHelperImpl.java index c8569e1f..36071e0a 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/logging/SimpleLogHelperImpl.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/logging/SimpleLogHelperImpl.java @@ -31,7 +31,6 @@ public class SimpleLogHelperImpl implements LogHelperAppender { // Output settings private final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss", Locale.US); private final Set OUTPUTS = Collections.newSetFromMap(new ConcurrentHashMap<>(2)); - private final LogHelper.OutputEnity STD_OUTPUT; public SimpleLogHelperImpl() { // Use JAnsi if available @@ -50,7 +49,7 @@ public SimpleLogHelperImpl() { JANSI = jansi; // Add std writer - STD_OUTPUT = new LogHelper.OutputEnity(System.out::println, JANSI ? LogHelper.OutputTypes.JANSI : LogHelper.OutputTypes.PLAIN); + OutputEnity STD_OUTPUT = new OutputEnity(System.out::println, JANSI ? OutputTypes.JANSI : OutputTypes.PLAIN); addOutput(STD_OUTPUT); // Add file log writer diff --git a/LauncherCore/src/main/java11/pro/gravit/utils/Downloader.java b/LauncherCore/src/main/java11/pro/gravit/utils/Downloader.java index 71dc6c4e..daf1dc5e 100644 --- a/LauncherCore/src/main/java11/pro/gravit/utils/Downloader.java +++ b/LauncherCore/src/main/java11/pro/gravit/utils/Downloader.java @@ -14,7 +14,6 @@ import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.concurrent.*; diff --git a/ServerWrapper/build.gradle b/ServerWrapper/build.gradle index b481f010..66520bef 100644 --- a/ServerWrapper/build.gradle +++ b/ServerWrapper/build.gradle @@ -47,12 +47,12 @@ java11Implementation files(sourceSets.main.output.classesDirs) { builtBy compile "Multi-Release": "true") } -task sourcesJar(type: Jar) { +tasks.register('sourcesJar', Jar) { from sourceSets.main.allJava archiveClassifier.set('sources') } -task javadocJar(type: Jar) { +tasks.register('javadocJar', Jar) { from javadoc archiveClassifier.set('javadoc') } 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 fa77103e..0a44b85d 100644 --- a/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java +++ b/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java @@ -70,7 +70,7 @@ public void restore() throws Exception { Request.restore(); } - public ProfilesRequestEvent getProfiles() throws Exception { + public void getProfiles() throws Exception { ProfilesRequestEvent result = new ProfilesRequest().request(); for (ClientProfile p : result.profiles) { LogHelper.debug("Get profile: %s", p.getTitle()); @@ -90,10 +90,8 @@ public ProfilesRequestEvent getProfiles() throws Exception { if (profile == null) { LogHelper.warning("Not connected to ServerProfile. May be serverName incorrect?"); } - return result; } - @SuppressWarnings("ConfusingArgumentToVarargsMethod") public void run(String... args) throws Throwable { initGson(); AuthRequest.registerProviders(); diff --git a/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapperGsonManager.java b/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapperGsonManager.java index 3cbd59c6..bb19fc5f 100644 --- a/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapperGsonManager.java +++ b/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapperGsonManager.java @@ -2,7 +2,6 @@ import com.google.gson.GsonBuilder; import pro.gravit.launcher.managers.GsonManager; -import pro.gravit.launcher.modules.events.PreGsonPhase; import pro.gravit.launcher.request.websockets.ClientWebSocketService; public class ServerWrapperGsonManager extends GsonManager { diff --git a/ServerWrapper/src/main/java/pro/gravit/launcher/server/authlib/DownloadContextModifier.java b/ServerWrapper/src/main/java/pro/gravit/launcher/server/authlib/DownloadContextModifier.java index 7ad939ed..45224f92 100644 --- a/ServerWrapper/src/main/java/pro/gravit/launcher/server/authlib/DownloadContextModifier.java +++ b/ServerWrapper/src/main/java/pro/gravit/launcher/server/authlib/DownloadContextModifier.java @@ -7,7 +7,6 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; public class DownloadContextModifier implements LibrariesHashFileModifier { @Override diff --git a/ServerWrapper/src/main/java/pro/gravit/launcher/server/authlib/InstallAuthlib.java b/ServerWrapper/src/main/java/pro/gravit/launcher/server/authlib/InstallAuthlib.java index c671b706..aa6fdbef 100644 --- a/ServerWrapper/src/main/java/pro/gravit/launcher/server/authlib/InstallAuthlib.java +++ b/ServerWrapper/src/main/java/pro/gravit/launcher/server/authlib/InstallAuthlib.java @@ -14,7 +14,7 @@ import java.util.zip.ZipOutputStream; public class InstallAuthlib { - private static Map modifierMap; + private static final Map modifierMap; static { modifierMap = new HashMap<>(); modifierMap.put("META-INF/libraries.list", new LibrariesLstModifier()); @@ -43,7 +43,7 @@ public void run(String... args) throws Exception { LogHelper.info("Search .jar files in %s", context.workdir.toAbsolutePath()); IOHelper.walk(context.workdir, new SimpleFileVisitor() { @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { if(file.getFileName().toString().endsWith(".jar")) { context.files.add(file); } diff --git a/ServerWrapper/src/main/java/pro/gravit/launcher/server/authlib/LibrariesLstModifier.java b/ServerWrapper/src/main/java/pro/gravit/launcher/server/authlib/LibrariesLstModifier.java index b65f375c..b21c532a 100644 --- a/ServerWrapper/src/main/java/pro/gravit/launcher/server/authlib/LibrariesLstModifier.java +++ b/ServerWrapper/src/main/java/pro/gravit/launcher/server/authlib/LibrariesLstModifier.java @@ -2,13 +2,12 @@ import pro.gravit.utils.helper.SecurityHelper; -import java.io.IOException; import java.nio.charset.StandardCharsets; public class LibrariesLstModifier implements LibrariesHashFileModifier { @Override - public byte[] apply(byte[] data, InstallAuthlib.InstallAuthlibContext context) throws IOException { + public byte[] apply(byte[] data, InstallAuthlib.InstallAuthlibContext context) { String[] lines = new String(data).split("\n"); for(int i=0;iUTF-8 -=================================================================== ---- bootstrap/pom.xml (revision 4c84f37fd23dfd67e4fee5dfd7cb62d67791129f) -+++ bootstrap/pom.xml (revision ) -@@ -50,7 +50,8 @@ - - - -- net.md_5.bungee.Bootstrap -+ net.md_5.bungee.Bootstrap -+ Launcher.jar - ${describe} - ${maven.build.timestamp} - -Index: proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java (revision 4c84f37fd23dfd67e4fee5dfd7cb62d67791129f) -+++ proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java (revision ) -@@ -2,6 +2,7 @@ - - import com.google.common.base.Charsets; - import com.google.common.base.Preconditions; -+import com.google.common.util.concurrent.ThreadFactoryBuilder; - import com.google.gson.Gson; - import java.math.BigInteger; - import java.net.InetAddress; -@@ -10,9 +11,14 @@ - import java.security.MessageDigest; - import java.util.List; - import java.util.UUID; -+import java.util.concurrent.ExecutorService; -+import java.util.concurrent.Executors; - import java.util.concurrent.TimeUnit; - import java.util.logging.Level; - import javax.crypto.SecretKey; -+ -+import com.mojang.authlib.yggdrasil.CompatBridge; -+import com.mojang.authlib.yggdrasil.CompatProfile; - import lombok.Getter; - import lombok.RequiredArgsConstructor; - import net.md_5.bungee.BungeeCord; -@@ -103,6 +109,8 @@ - private boolean legacy; - @Getter - private String extraDataInHandshake = ""; -+ private ExecutorService loginExecutor = Executors.newCachedThreadPool(new ThreadFactoryBuilder(). -+ setNameFormat("Login Thread #%1$d").setDaemon(true).build()); - - @Override - public boolean shouldHandle(PacketWrapper packet) throws Exception -@@ -262,7 +270,7 @@ - this.handshake = handshake; - ch.setVersion( handshake.getProtocolVersion() ); - -- // Starting with FML 1.8, a "\0FML\0" token is appended to the handshake. This interferes -+ // Starting with FML 1.8, a "\0FML\0" token is appended to the handshake. This interferes - // with Bungee's IP forwarding, so we detect it, and remove it from the host string, for now. - // We know FML appends \00FML\00. However, we need to also consider that other systems might - // add their own data to the end of the string. So, we just take everything from the \0 character -@@ -403,37 +411,27 @@ - { - sha.update( bit ); - } -- String encodedHash = URLEncoder.encode( new BigInteger( sha.digest() ).toString( 16 ), "UTF-8" ); - -- String preventProxy = ( ( BungeeCord.getInstance().config.isPreventProxyConnections() ) ? "&ip=" + URLEncoder.encode( getAddress().getAddress().getHostAddress(), "UTF-8" ) : "" ); -- String authURL = "https://sessionserver.mojang.com/session/minecraft/hasJoined?username=" + encName + "&serverId=" + encodedHash + preventProxy; - -- Callback handler = new Callback() -- { -- @Override -- public void done(String result, Throwable error) -- { -- if ( error == null ) -- { -- LoginResult obj = BungeeCord.getInstance().gson.fromJson( result, LoginResult.class ); -- if ( obj != null && obj.getId() != null ) -- { -- loginProfile = obj; -- name = obj.getName(); -- uniqueId = Util.getUUID( obj.getId() ); -- finish(); -- return; -- } -- disconnect( bungee.getTranslation( "offline_mode_player" ) ); -- } else -- { -- disconnect( bungee.getTranslation( "mojang_fail" ) ); -- bungee.getLogger().log( Level.SEVERE, "Error authenticating " + getName() + " with minecraft.net", error ); -+ final String username = InitialHandler.this.getName(); -+ final String serverID = new BigInteger(sha.digest()).toString(16); -+ loginExecutor.submit(() -> { -+ try { -+ CompatProfile properties = CompatBridge.checkServer(username, serverID); -+ if(properties == null) { // Invalid username or serverID -+ disconnect("Bad Login (Serverside)"); -+ return; - } -- } -- }; - -- HttpClient.get( authURL, ch.getHandle().eventLoop(), handler ); -+ // Successful login -+ uniqueId = properties.uuid; -+ loginProfile = new LoginResult(properties); -+ finish(); -+ } catch(Exception e) { -+ disconnect("Authentication failed"); -+ bungee.getLogger().log(Level.SEVERE, "Error authenticating " + username + " with Launcher", e); -+ } -+ }); - } - - private void finish() -Index: bootstrap/src/main/java/net/md_5/bungee/Bootstrap.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- bootstrap/src/main/java/net/md_5/bungee/Bootstrap.java (revision 4c84f37fd23dfd67e4fee5dfd7cb62d67791129f) -+++ bootstrap/src/main/java/net/md_5/bungee/Bootstrap.java (revision ) -@@ -5,9 +5,9 @@ - - public static void main(String[] args) throws Exception - { -- if ( Float.parseFloat( System.getProperty( "java.class.version" ) ) < 51.0 ) -+ if ( Float.parseFloat( System.getProperty( "java.class.version" ) ) < 52.0 ) - { -- System.err.println( "*** ERROR *** BungeeCord requires Java 7 or above to function! Please download and install it!" ); -+ System.err.println( "*** ERROR *** BungeeCord requires Java 8 or above to function! Please download and install it!" ); - System.out.println( "You can check your Java version with the command: java -version" ); - return; - } -Index: proxy/src/main/java/net/md_5/bungee/connection/LoginResult.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- proxy/src/main/java/net/md_5/bungee/connection/LoginResult.java (revision 4c84f37fd23dfd67e4fee5dfd7cb62d67791129f) -+++ proxy/src/main/java/net/md_5/bungee/connection/LoginResult.java (revision ) -@@ -1,5 +1,6 @@ - package net.md_5.bungee.connection; - -+import com.mojang.authlib.yggdrasil.CompatProfile; - import lombok.AllArgsConstructor; - import lombok.Data; - -@@ -12,6 +13,25 @@ - private String name; - private Property[] properties; - -+ public LoginResult(CompatProfile profile) { -+ id = profile.uuidHash; -+ properties = new Property[profile.countProperties()]; -+ -+ int index = 0; -+ if (profile.skinURL != null) { -+ properties[index++] = new Property(CompatProfile.SKIN_URL_PROPERTY, profile.skinURL, ""); -+ } -+ if (profile.skinDigest != null) { -+ properties[index++] = new Property(CompatProfile.SKIN_DIGEST_PROPERTY, profile.skinDigest, ""); -+ } -+ if (profile.cloakURL != null) { -+ properties[index++] = new Property(CompatProfile.CLOAK_URL_PROPERTY, profile.cloakURL, ""); -+ } -+ if (profile.cloakDigest != null) { -+ properties[index++] = new Property(CompatProfile.CLOAK_DIGEST_PROPERTY, profile.cloakDigest, ""); -+ } -+ } -+ - @Data - @AllArgsConstructor - public static class Property -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (revision 4c84f37fd23dfd67e4fee5dfd7cb62d67791129f) -+++ pom.xml (revision ) -@@ -68,8 +68,8 @@ - - unknown - 4.1.17.Final -- 1.7 -- 1.7 -+ 1.8 -+ 1.8 - UTF-8 - - -@@ -97,6 +97,13 @@ - lombok - 1.16.16 - provided -+ -+ -+ launcher -+ clientside -+ 4+ -+ system -+ $HOME$/Launcher/Launcher/build/libs/Launcher.jar - - - diff --git a/compat/LaunchWrapper.patch b/compat/LaunchWrapper.patch deleted file mode 100644 index 81059396..00000000 --- a/compat/LaunchWrapper.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/src/main/java/net/minecraft/launchwrapper/LaunchClassLoader.java b/src/main/java/net/minecraft/launchwrapper/LaunchClassLoader.java -index f4e83af..d3a6d7f 100644 ---- a/src/main/java/net/minecraft/launchwrapper/LaunchClassLoader.java -+++ b/src/main/java/net/minecraft/launchwrapper/LaunchClassLoader.java -@@ -58,6 +58,12 @@ public class LaunchClassLoader extends URLClassLoader { - addClassLoaderExclusion("org.apache.logging."); - addClassLoaderExclusion("net.minecraft.launchwrapper."); - -+ // classloader launcher exclusions -+ addClassLoaderExclusion("pro.gravit.launcher."); -+ addClassLoaderExclusion("com.mojang."); -+ addClassLoaderExclusion("com.google.gson."); -+ addClassLoaderExclusion("org.json."); -+ - // transformer exclusions - addTransformerExclusion("javax."); - addTransformerExclusion("argo."); diff --git a/compat/auth/asframework.php b/compat/auth/asframework.php deleted file mode 100644 index db19fb5f..00000000 --- a/compat/auth/asframework.php +++ /dev/null @@ -1,50 +0,0 @@ -auth($args['login'],$args['pass']); - echo 'OK:'.$acc->login.''; - app::stop(); - } catch (AccountException $e) { - $msg = $e->getMessage(); - if ($msg == AccountException::AuthError) { - echo 'Login or password is incorrect'; - app::stop(); - } - if ($msg == AccountException::NoLoginError) { - echo 'This account is not allowed to sign in'; - app::stop(); - } - if ($msg == AccountException::FatalBanError) { - echo 'You are permanently banned'; - app::stop(); - } - } - } -} diff --git a/compat/auth/dle.php b/compat/auth/dle.php deleted file mode 100644 index bc4a7cec..00000000 --- a/compat/auth/dle.php +++ /dev/null @@ -1,83 +0,0 @@ - false, - - 'login' => filter_input(INPUT_GET, 'login', FILTER_SANITIZE_STRING), - 'password' => filter_input(INPUT_GET, 'password', FILTER_SANITIZE_STRING) - -]; - -if( isset( $auth['login'] ) AND isset( $auth['password'] ) ) { - - define( 'DATALIFEENGINE', true ); - require( __DIR__ . '/engine/classes/mysql.php' ); - require_once( __DIR__ . '/engine/data/dbconfig.php' ); - - $auth['login'] = $db->safesql( $auth['login'] ); - $auth['password'] = $db->safesql( $auth['password'] ); - - if( strlen($auth['password']) > 72 ) $auth['password'] = substr($auth['password'], 0, 72); - - $member_id = $db->super_query( "SELECT name, email, password, hash FROM dle_users WHERE name='{$auth['login']}' OR email='{$auth['login']}'" ); - - if( !$member_id['name'] AND !$member_id['email'] ) { - - exit('Введены неверные данные'); - } - - if( strlen($member_id['password']) == 32 && ctype_xdigit($member_id['password']) ) { - - if( $member_id['password'] == md5(md5($auth['password'])) ) { - $auth['logged'] = true; - } - - } else { - - if( password_verify($auth['password'], $member_id['password']) ) { - $auth['logged'] = true; - } - - } - - if( $auth['logged'] ) { - - session_regenerate_id(); - - if ( password_needs_rehash($member_id['password'], PASSWORD_DEFAULT) ) { - - $member_id['password'] = password_hash($auth['password'], PASSWORD_DEFAULT); - - $new_pass_hash = 'password='.$db->safesql($member_id['password']).', '; - - } else $new_pass_hash = ''; - - if( function_exists('openssl_random_pseudo_bytes') ) { - - $stronghash = md5(openssl_random_pseudo_bytes(15)); - - } else $stronghash = md5(uniqid( mt_rand(), TRUE )); - - $salt = sha1( str_shuffle('abcdefghjkmnpqrstuvwxyz0123456789') . $stronghash ); - $hash = ''; - - for($i = 0; $i < 9; $i ++) { - $hash .= $salt{mt_rand( 0, 39 )}; - } - - $hash = md5( $hash ); - $member_id['hash'] = $hash; - - $db->query( "UPDATE LOW_PRIORITY dle_users SET {$new_pass_hash}hash='{$hash}' WHERE name='{$member_id['name']}'" ); - - exit('OK:'.$member_id['name'].''); - - } else { - - exit('Ошибка при авторизации'); - } -} else { - exit('Введены неверные данные'); -} -?> diff --git a/compat/auth/dle.sql b/compat/auth/dle.sql deleted file mode 100644 index 633b2bc9..00000000 --- a/compat/auth/dle.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT name FROM dle_users WHERE (email=? OR name=?) AND password=MD5(MD5(?)) LIMIT 1 diff --git a/compat/auth/ipb.php b/compat/auth/ipb.php deleted file mode 100644 index 99ea456b..00000000 --- a/compat/auth/ipb.php +++ /dev/null @@ -1,28 +0,0 @@ -init(); - -// Resolve member by login -$member = IPSMember::load(IPSText::parseCleanValue($login), 'all', 'username'); -$member_id = $member['member_id']; -if (!$member_id) { - exit('Введены неверные данные'); -} - -// Try authenticate -$success = IPSMember::authenticateMember($member_id, md5(IPSText::parseCleanValue($password))); -echo($success ? 'OK:' . $member['name'] : 'Ошибка при авторизации'); -?> diff --git a/compat/auth/ips.php b/compat/auth/ips.php deleted file mode 100644 index b454f202..00000000 --- a/compat/auth/ips.php +++ /dev/null @@ -1,22 +0,0 @@ -member_id ) -{ - if ( strcmp( $member->members_pass_hash, $member->encryptedPassword( $_GET['password'] ) ) === 0 ) - { - echo 'OK:' . $member->name; - } - else - { - echo 'Incorrect login or password'; - } -} -else -{ - echo 'Incorrect login or password'; -} diff --git a/compat/auth/joomla.sql b/compat/auth/joomla.sql deleted file mode 100644 index 18feac41..00000000 --- a/compat/auth/joomla.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT username FROM joomla_users WHERE (email=? OR username=?) AND password=CONCAT_WS(':', MD5(CONCAT(?, SUBSTRING_INDEX(SUBSTRING_INDEX(password, ':', 2), ':', -1))), SUBSTRING_INDEX(SUBSTRING_INDEX(password, ':', 2), ':', -1)) LIMIT 1 diff --git a/compat/auth/laravel/authcontroller/LauncherAuthController.php b/compat/auth/laravel/authcontroller/LauncherAuthController.php deleted file mode 100644 index 6c41adc4..00000000 --- a/compat/auth/laravel/authcontroller/LauncherAuthController.php +++ /dev/null @@ -1,36 +0,0 @@ -getContent()); - - if ($data->apiKey !== env('LAUNCHER_APIKEY')) { - return response()->json([ - 'error' => 'Неверный ключ. Обратитесь к администратору', - ]); - } - - if (Auth::attempt(['name' => $data->username, 'password' => $data->password])) { - $perm = DB::table('users') - ->select('launcher_permission') - ->where('name', '=', $data->username) - ->first(); - - return response()->json([ - 'username' => $data->username, - 'permission' => $perm->launcher_permission, - ]); - } else { - return response()->json([ - 'error' => 'Неверный логин или пароль', - ]); - } - } -} diff --git a/compat/auth/laravel/authcontroller/README.MD b/compat/auth/laravel/authcontroller/README.MD deleted file mode 100644 index b6c0a203..00000000 --- a/compat/auth/laravel/authcontroller/README.MD +++ /dev/null @@ -1,10 +0,0 @@ -# Контроллер авторизации методом json - -Route: - -```php -Route::put('launcher/auth', 'LauncherAuthController@json'); -``` - -Добавить в **.env** строку `LAUNCHER_APIKEY=none` -Где `none` ваш apiKey \ No newline at end of file diff --git a/compat/auth/laravel/authcontroller/migrations/2020_03_05_151322_add_permission_collum.php b/compat/auth/laravel/authcontroller/migrations/2020_03_05_151322_add_permission_collum.php deleted file mode 100644 index d82e5eb2..00000000 --- a/compat/auth/laravel/authcontroller/migrations/2020_03_05_151322_add_permission_collum.php +++ /dev/null @@ -1,32 +0,0 @@ -integer('launcher_permission')->default('0'); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::table('users', function (Blueprint $table) { - $table->dropColumn('launcher_permission'); - }); - } -} diff --git a/compat/auth/laravel/migrations/2020_03_04_172425_create_hwid_table.php b/compat/auth/laravel/migrations/2020_03_04_172425_create_hwid_table.php deleted file mode 100644 index db0c8b9f..00000000 --- a/compat/auth/laravel/migrations/2020_03_04_172425_create_hwid_table.php +++ /dev/null @@ -1,36 +0,0 @@ -bigIncrements('id'); - $table->tinyInteger('isBanned')->default('0'); - $table->text('totalMemory'); - $table->text('serialNumber'); - $table->text('HWDiskSerial'); - $table->text('processorID'); - $table->text('macAddr'); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::dropIfExists('users_hwids'); - } -} diff --git a/compat/auth/laravel/migrations/2020_03_05_140131_add_auth_handler_collums.php b/compat/auth/laravel/migrations/2020_03_05_140131_add_auth_handler_collums.php deleted file mode 100644 index 8a456f60..00000000 --- a/compat/auth/laravel/migrations/2020_03_05_140131_add_auth_handler_collums.php +++ /dev/null @@ -1,36 +0,0 @@ -char('uuid', '36')->unique()->nullable(); - $table->char('accessToken', '32')->nullable(); - $table->string('serverID', '41')->nullable(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::table('users', function (Blueprint $table) { - $table->dropColumn('uuid'); - $table->dropColumn('accessToken'); - $table->dropColumn('serverID'); - }); - } -} diff --git a/compat/auth/laravel/migrations/2020_03_05_142041_add_hwid_handler_collums.php b/compat/auth/laravel/migrations/2020_03_05_142041_add_hwid_handler_collums.php deleted file mode 100644 index 5040340b..00000000 --- a/compat/auth/laravel/migrations/2020_03_05_142041_add_hwid_handler_collums.php +++ /dev/null @@ -1,32 +0,0 @@ -bigInteger('hwid')->nullable(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::table('users', function (Blueprint $table) { - $table->dropColumn('hwid'); - }); - } -} diff --git a/compat/auth/laravel/migrations/README.MD b/compat/auth/laravel/migrations/README.MD deleted file mode 100644 index 856151ac..00000000 --- a/compat/auth/laravel/migrations/README.MD +++ /dev/null @@ -1 +0,0 @@ -# Миграции для Laravel \ No newline at end of file diff --git a/compat/auth/phpbb.php b/compat/auth/phpbb.php deleted file mode 100644 index 4f80ad54..00000000 --- a/compat/auth/phpbb.php +++ /dev/null @@ -1,20 +0,0 @@ -login($login, $password, false, false, false); -echo($result['status'] === LOGIN_SUCCESS ? 'OK:' . $result['user_row']['username'] : 'Ошибка при авторизации'); -?> diff --git a/compat/auth/uuid/ReversibleUUIDs.java b/compat/auth/uuid/ReversibleUUIDs.java deleted file mode 100644 index b1f42baa..00000000 --- a/compat/auth/uuid/ReversibleUUIDs.java +++ /dev/null @@ -1,19 +0,0 @@ -public static UUID toUUID(String username){ - ByteBuffer buffer=ByteBuffer.wrap(Arrays.copyOf(username.getBytes(StandardCharsets.US_ASCII),16)); - return new UUID(buffer.getLong(),buffer.getLong()); // MOST, LEAST - } - -public static String toUsername(UUID uuid){ - byte[]bytes=ByteBuffer.allocate(16). - putLong(uuid.getMostSignificantBits()). - putLong(uuid.getLeastSignificantBits()).array(); - - // Find username end - int length=0; - while(lengthuser_login : 'Ошибка при авторизации'); -?> diff --git a/compat/auth/xenforo.php b/compat/auth/xenforo.php deleted file mode 100644 index 97f4ec80..00000000 --- a/compat/auth/xenforo.php +++ /dev/null @@ -1,47 +0,0 @@ -setupAutoloader($libraryDir); -XenForo_Application::initialize($libraryDir, $dir); -XenForo_Application::set('page_start_time', microtime(true)); -$db = XenForo_Application::get('db'); - -// Resolve user_id by login -$result = $db->fetchRow('SELECT user_id, username FROM xf_user WHERE username=' . $db->quote($login) . ' OR email=' . $db->quote($login)); -if(!count($result)) { - exit('Введены неверные данные'); -} -$user_id = $result['user_id']; -$username = $result['username']; - -// Get user data -$result = $db->fetchCol('SELECT data FROM xf_user_authenticate WHERE user_id=' . $db->quote($user_id)); -if(!count($result)) { - exit('Внутренняя ошибка'); // rare! -} -$data = $result[0]; - -// Select authentication core -$auth = NULL; -if(class_exists('XenForo_Authentication_Core12')) { - $auth = new XenForo_Authentication_Core12; -} else if(class_exists('XenForo_Authentication_Core')) { - $auth = new XenForo_Authentication_Core; -} else exit('Внутренняя ошибка'); // rare! - -// Try authenticate -$auth->setData($data); -$success = $auth->authenticate($user_id, $password); -echo($success ? 'OK:' . $username : 'Ошибка при авторизации'); -?> diff --git a/compat/auth/yii2/MinecraftController.php b/compat/auth/yii2/MinecraftController.php deleted file mode 100644 index 883ae454..00000000 --- a/compat/auth/yii2/MinecraftController.php +++ /dev/null @@ -1,48 +0,0 @@ -user->enableSession=false; - } - public $modelClass = 'common\models\User'; - public function behaviors() - { - return [ - 'authenticator' => [ - 'class' => QueryParamAuth::className(), - ], - ]; - } - - public function actionLogin() - { - $this->checkAccess("login"); - \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; - $postarr = json_decode(Yii::$app->getRequest()->getRawBody(), true); - if(!$postarr) return array('status' => 'ERROR','error' => "request incorrect"); - $login = $postarr["login"]; - $pass = $postarr["pass"]; - $model = User::findByUsername($login); - if($model->validatePassword($pass)) - { - if($model->status == User::STATUS_BANNED) return array('status' => 'ERROR','error' => "You Banned"); - return array('status' => 'OK', "username" => $login); - } - else - return array('status' => 'ERROR','error' => "username or password incorrect"); - } - public function checkAccess($action, $model = null, $params = []) - { - if (!\Yii::$app->user->can('checkuser')) - throw new \yii\web\ForbiddenHttpException('You can only MinecraftBot'); - } -} diff --git a/compat/authlib/GameProfile-combined.class b/compat/authlib/GameProfile-combined.class deleted file mode 100644 index edd66a8d74ad677ae0aa0869fbe26b89e64622ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2323 zcmbVNZBrXn6n<_JvSGW>5Z-FjLWSmE_a;0ij zw5qLZHGyQdV3kv4Ynxrvx?M8#e5&n`y65=rE~^zf8Z@+`TG$m38}u=wo4S2d;PTkZ z1pXT~exFD!Seu#*3A%(G8GX<@5kyJGJ#0xJ%Q+NyC(nZ_(3P{*!VX1VRr7`>;gN)I z1g^Nzyq7vHo{anWN+zT)1v-kFogt+nWAT@%3iP!$y@-7J3jv7^vZT&xr73C`?YXiv zC7hu1Zz7_s*A}dD#n5cZkbf+`!6esMh0jP-?c2I)P-6PM*SwqG)(Uo-T_r5bxQMKb zA!G$YCAC&!U7JuDHr-*<9WvRLlXD55%D9eCcvxg@Z}V!NhdFZ7Ygsp|a?Yw(3)-S? z5L|ePZcF#vqOVCVFa;lCRKWsBji6eoXeKGT5qQ zwN$>Y8=G1+wd!)4cfQjKx^b4lmjoW1g6YX{ON{>$B#g`}q^0_tdQ;X4uHiielSnC8 z!ClglN@KxLYm~p<6IIpROiNf*@HukSgL-Ynvgb*Y9f7F#z6&L_nxi7n%z{P<7Z`md zD@X1%YWtdkD;Slqq2K}5iN{veDm!&M>Vmgl2e$>h)h;mXso-PR)!m9Vx2aZat*Ri5 z9t98aHIZj@Cpgjbl6MQ>lqL%|pD0gEf$o#9mI4`P6ok;pv8c38bU+K4(lpYB${740 z8FSTQy{wt`?e7a(#nvrTL6KFK^jcG51q!+tb-URmgc0{#_w}zHH9|X{Q+fhJryTdR zi$IK@ikNC{#xl2J1=TbyJC?WXQY^2<@|<;CqCS-9Z4V&AccxW@1!&I1mS!Kf1kDPF z1A1tT&{qzA`U6sl1N0^i(YJnp{(TH2pQCU583rGt>k#MGBjNyW{gFuS<9uR#AJJdv zh`hz3crM)go_fr6>JG(*bQ*Q4bY!RHsK`k1QIP{;|I9Zh8ch_8+^gO1T(}i zKE@-E5xng}F=s*W9f@CY{wXau(g+22t}^bLd)fRP97yKnGhAk8hpq(QnMH;dc<1%N z)B!HAH*T~QcMS1U%mXcR0!i0ANi(w^WG+YONi;yhPCSMbc!Gd`@0eN#eEqZROAi2z zoSh#iYn&Z5k^C7QfxYAry6OB>l72s-!@rmO6TxK%xR0lC`Ze(Gk2p)0=Z_=yB1`lL z>=32BXaiS|9cZ5%0&NyybV}XgZ(N{+2E|~I3DL9U5_(94d_-u%iP^QW0ZXRdAo4+)Z;bQohMjvMX1!q|mUjP6A diff --git a/compat/authlib/MinecraftSessionService-combined.class b/compat/authlib/MinecraftSessionService-combined.class deleted file mode 100644 index 854101de1634b5bbe00acf95d2bf0884919f8ff3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1177 zcmbVM%TC)s6g?LLE{_%{k3vg#T{N3oLUd6DArJyY1)`GEF1njImoSzyj>Z!NAH+|v z=m+$p5O+cd0a-F+GmmSZd+y`h`G0%!55NXK2UrjAi7=gH+C*$G*b)xE9>-ZbY-fow ztx$E{d8!-Xp=$Flo1N*DYsZPYP+{snN6u=~DzH@lh}-?km^)5qCJ*qDFn6xk5FdQA+){dQa7LIt@=$ zr$(5Hbjv93fpGn52U|roX-lPJtIk|_@^I>RupjG}`c+4|Sc?iU|tB{U*lp3H~%=B zr;UVT_u>LPE$k$LFec9gFi|0lqaybSx%qukECJpOS*CiH>1UQ1%!=i$pvLe{{+Ppj U@4V1k-(yjBk6FSpR(96z0Da?oTmS$7 diff --git a/compat/authlib/README.md b/compat/authlib/README.md deleted file mode 100644 index 0187d027..00000000 --- a/compat/authlib/README.md +++ /dev/null @@ -1,15 +0,0 @@ -com.mojang.authlib-clean.jar ------------------ -Этот JAR - заготовка для сборки LauncherAuthlib. Из неё удалены не используемые клиентом классы, а так же классы, -реализованные в LauncherAuthlib. - -GameProfile-combined.class --------------------------- -Этот класс - результат слияния ASM'ом методов из Authlib 1.7.2 и Authlib 1.7.10+, в нём есть метод как для получения -UUID старого образца (без чёрточек, например `d3730e7436794ba6-8ab2a24ac9e755d4`), так и нового -образца (`d3730e74-3679-4ba6-8ab2-a24ac9e755d4`). Уже включён в `com.mojang.authlib-clean.jar` - -MinecraftSessionService-combined.class --------------------------------------- -Этот класс - результат слияния ASM'ом методов из Authlib 1.10.2 и Authlib 1.11+, в нём есть метод как для авторизации на -сервере с учётом InetAddress, так и без него. Уже включён в `com.mojang.authlib-clean.jar` diff --git a/compat/authlib/authlib-clean.jar b/compat/authlib/authlib-clean.jar deleted file mode 100644 index 0a934fe4b877ed77595ce433e37fe83eb8a2800f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23983 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 Date: Tue, 11 Apr 2023 13:28:31 +0700 Subject: [PATCH 21/38] [FEATURE] LauncherGuard module --- .../launcher/client/ClientLauncherProcess.java | 4 +++- .../pro/gravit/launcher/client/DirBridge.java | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 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 94abd9e2..4136aeb8 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java @@ -31,6 +31,8 @@ import java.util.stream.Collectors; public class ClientLauncherProcess { + + public final List pre = new LinkedList<>(); public final ClientParams params = new ClientParams(); public final List jvmArgs = new LinkedList<>(); public final List jvmModules = new LinkedList<>(); @@ -134,7 +136,7 @@ private void applyClientProfile() { public void start(boolean pipeOutput) throws IOException, InterruptedException { if (isStarted) throw new IllegalStateException("Process already started"); LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderPreLaunchEvent(this)); - List processArgs = new LinkedList<>(); + List processArgs = new LinkedList<>(pre); processArgs.add(executeFile.toString()); processArgs.addAll(jvmArgs); if (javaVersion.version >= 9) { diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/DirBridge.java b/Launcher/src/main/java/pro/gravit/launcher/client/DirBridge.java index 8cd5b337..b26ccd3f 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/DirBridge.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/DirBridge.java @@ -112,6 +112,22 @@ public static Path getGuardDir() { return dir.resolve("guard"); } + public static Path getGuardDir(JVMHelper.ARCH arch, JVMHelper.OS os) { + Path dir = getGuardDir().resolve(makeSpecialGuardDirName(arch, os)); + try { + IOHelper.createParentDirs(dir); + } catch (Throwable e) { + throw new RuntimeException(e); + } + return dir; + } + + + + public static String makeSpecialGuardDirName(JVMHelper.ARCH arch, JVMHelper.OS os) { + return String.format("%s-%s", arch.name, os.name); + } + public static Path getLegacyLauncherDir(String projectname) { return IOHelper.HOME_DIR.resolve(projectname); } From 4ed687087fc3ba42d019fa76264ab422939703f2 Mon Sep 17 00:00:00 2001 From: Gravit'a <12893402+gravit0@users.noreply.github.com> Date: Sat, 15 Apr 2023 13:51:33 +0700 Subject: [PATCH 22/38] [FIX] LauncherGuard default config --- .../main/java/pro/gravit/launcher/client/DirBridge.java | 7 +------ .../src/main/java/pro/gravit/launcher/Launcher.java | 5 +++++ modules | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/DirBridge.java b/Launcher/src/main/java/pro/gravit/launcher/client/DirBridge.java index b26ccd3f..348815e5 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/DirBridge.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/DirBridge.java @@ -113,7 +113,7 @@ public static Path getGuardDir() { } public static Path getGuardDir(JVMHelper.ARCH arch, JVMHelper.OS os) { - Path dir = getGuardDir().resolve(makeSpecialGuardDirName(arch, os)); + Path dir = getGuardDir().resolve(Launcher.makeSpecialGuardDirName(arch, os)); try { IOHelper.createParentDirs(dir); } catch (Throwable e) { @@ -123,11 +123,6 @@ public static Path getGuardDir(JVMHelper.ARCH arch, JVMHelper.OS os) { } - - public static String makeSpecialGuardDirName(JVMHelper.ARCH arch, JVMHelper.OS os) { - return String.format("%s-%s", arch.name, os.name); - } - public static Path getLegacyLauncherDir(String projectname) { return IOHelper.HOME_DIR.resolve(projectname); } diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/Launcher.java b/LauncherAPI/src/main/java/pro/gravit/launcher/Launcher.java index e9471df0..28bb2374 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/Launcher.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/Launcher.java @@ -4,6 +4,7 @@ import pro.gravit.launcher.profiles.ClientProfile; import pro.gravit.launcher.serialize.HInput; import pro.gravit.utils.helper.IOHelper; +import pro.gravit.utils.helper.JVMHelper; import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.SecurityHelper; @@ -122,4 +123,8 @@ public static void applyLauncherEnv(LauncherConfig.LauncherEnvironment env) { break; } } + + public static String makeSpecialGuardDirName(JVMHelper.ARCH arch, JVMHelper.OS os) { + return String.format("%s-%s", arch.name, os.name); + } } diff --git a/modules b/modules index 9be16b2b..29ee5c6d 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 9be16b2bc7047659577f976b5f95a71469d8a735 +Subproject commit 29ee5c6d804282bac17d526a185a41ee40ddd1da From fc7f96d53608c372cb53ebac1af9435d854fe0e8 Mon Sep 17 00:00:00 2001 From: Gravit'a <12893402+gravit0@users.noreply.github.com> Date: Sat, 15 Apr 2023 13:59:32 +0700 Subject: [PATCH 23/38] [FIX] launcher-pack in Windows --- .../pro/gravit/launchserver/binary/tasks/PrepareBuildTask.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/PrepareBuildTask.java b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/PrepareBuildTask.java index 4772615b..c5a63fbf 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/PrepareBuildTask.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/binary/tasks/PrepareBuildTask.java @@ -45,7 +45,7 @@ public Path process(Path inputFile) throws IOException { throw new RuntimeException(ex); } })) { - var map = stream.collect(Collectors.toMap(k -> server.launcherPack.relativize(k).toString(), (v) -> v)); + var map = stream.collect(Collectors.toMap(k -> server.launcherPack.relativize(k).toString().replace("\\", "/"), (v) -> v)); server.launcherBinary.files.putAll(map); } UnpackHelper.unpack(IOHelper.getResourceURL("Launcher.jar"), result); From 76f8b4602c0631a11cc77a87130bbe3b698680af Mon Sep 17 00:00:00 2001 From: Gravit'a <12893402+gravit0@users.noreply.github.com> Date: Sat, 15 Apr 2023 17:40:34 +0700 Subject: [PATCH 24/38] [FIX] JAVA_HOME override --- .../launchermodules/LauncherModuleLoader.java | 11 ----------- .../pro/gravit/launcher/ClientLauncherWrapper.java | 9 +++++++-- modules | 2 +- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/launchermodules/LauncherModuleLoader.java b/LaunchServer/src/main/java/pro/gravit/launchserver/launchermodules/LauncherModuleLoader.java index 7b20a2d9..52580dc4 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/launchermodules/LauncherModuleLoader.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/launchermodules/LauncherModuleLoader.java @@ -119,17 +119,6 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO ModuleEntity entity = new ModuleEntity(); entity.path = file; entity.moduleMainClass = mainClass; - try { - Class mainClazz = (Class) classLoader.loadClass(entity.moduleMainClass); - entity.checkResult = server.modulesManager.checkModuleClass(mainClazz); - } catch (Throwable e) { - if (e instanceof ClassNotFoundException || e instanceof NoClassDefFoundError) { - logger.error("Module-MainClass in module {} incorrect", file.toString()); - } else { - logger.error(e); - } - return super.visitFile(file, attrs); - } entity.moduleConfigClass = attributes.getValue("Module-Config-Class"); if (entity.moduleConfigClass != null) { entity.moduleConfigName = attributes.getValue("Module-Config-Name"); diff --git a/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java b/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java index 6a0d2f29..4e35838e 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java +++ b/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java @@ -141,8 +141,12 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep if (customJvmOptions != null) { args.addAll(customJvmOptions); } - args.add("-cp"); - args.add(String.join(IOHelper.PLATFORM_SEPARATOR, context.classpath)); + if(context.useLegacyClasspathProperty) { + args.add(String.format("-Djava.class.path=%s", String.join(IOHelper.PLATFORM_SEPARATOR, context.classpath))); + } else { + args.add("-cp"); + args.add(String.join(IOHelper.PLATFORM_SEPARATOR, context.classpath)); + } args.add(context.mainClass); args.addAll(context.clientArgs); LogHelper.debug("Commandline: " + args); @@ -170,6 +174,7 @@ public static class ClientLauncherWrapperContext { public Path executePath; public String mainClass; public int memoryLimit; + public boolean useLegacyClasspathProperty; public ProcessBuilder processBuilder; public List args = new ArrayList<>(8); public Map jvmProperties = new HashMap<>(); diff --git a/modules b/modules index 29ee5c6d..8adf9de6 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 29ee5c6d804282bac17d526a185a41ee40ddd1da +Subproject commit 8adf9de6efe47bd820f756184f2a184e1d677dd8 From dcaec54814145e17d1b25ebe6c0b4e35299db403 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Tue, 18 Apr 2023 14:53:35 +0700 Subject: [PATCH 25/38] [ANY] Update modules --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index 8adf9de6..b535714a 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 8adf9de6efe47bd820f756184f2a184e1d677dd8 +Subproject commit b535714a4ee6d9dbf9bdeaab0ee550058afd10d7 From 3bc8040352e9ee70e6974a05bfe6c9758df7c5c3 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Thu, 20 Apr 2023 15:54:02 +0700 Subject: [PATCH 26/38] [FEATURE] MirrorHelper Modrinth support --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index b535714a..27977fe4 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit b535714a4ee6d9dbf9bdeaab0ee550058afd10d7 +Subproject commit 27977fe487fd477f644fa8471b747e87515a61a6 From 48799cf3c2f4766d723429bdd01b6d874dd95faa Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Thu, 20 Apr 2023 19:06:12 +0700 Subject: [PATCH 27/38] [FEATURE] New ClientProfile$Version --- .../gravit/launchserver/command/Command.java | 10 ++ .../command/hash/DownloadClientCommand.java | 7 +- .../command/hash/MakeProfileCommand.java | 4 +- .../command/service/SecurityCheckCommand.java | 2 +- .../helper/MakeProfileHelper.java | 37 ++-- .../manangers/LaunchServerGsonManager.java | 2 + .../client/ClientLauncherEntryPoint.java | 3 +- .../client/ClientLauncherProcess.java | 13 +- .../gravit/launcher/client/ServerPinger.java | 11 +- .../launcher/profiles/ClientProfile.java | 166 ++++++++++-------- .../profiles/ClientProfileBuilder.java | 4 +- .../profiles/ClientProfileVersions.java | 18 ++ .../websockets/ClientWebSocketService.java | 2 + .../pro/gravit/launcher/hasher/HashedDir.java | 2 +- .../gravit/launcher/server/ServerWrapper.java | 2 +- .../server/setup/ServerWrapperSetup.java | 3 +- build.gradle | 2 +- 17 files changed, 166 insertions(+), 122 deletions(-) create mode 100644 LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileVersions.java diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/Command.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/Command.java index e7daa403..e2fdd2cf 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/Command.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/Command.java @@ -4,8 +4,11 @@ import me.tongfei.progressbar.ProgressBarBuilder; import me.tongfei.progressbar.ProgressBarStyle; import pro.gravit.launcher.AsyncDownloader; +import pro.gravit.launcher.Launcher; +import pro.gravit.launcher.profiles.ClientProfile; import pro.gravit.launchserver.LaunchServer; import pro.gravit.utils.Downloader; +import pro.gravit.utils.command.CommandException; import java.io.IOException; import java.nio.file.Path; @@ -29,6 +32,13 @@ public Command(Map childCommands, Laun this.server = server; } + protected ClientProfile.Version parseClientVersion(String arg) throws CommandException { + if(arg.isEmpty()) { + throw new CommandException("ClientVersion can't be empty"); + } + return Launcher.gsonManager.gson.fromJson(arg, ClientProfile.Version.class); + } + protected boolean showApplyDialog(String text) throws IOException { System.out.printf("%s [Y/N]:", text); String response = server.commandHandler.readLine().toLowerCase(Locale.ROOT); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/DownloadClientCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/DownloadClientCommand.java index 942be0c2..09922041 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/DownloadClientCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/DownloadClientCommand.java @@ -5,6 +5,7 @@ import org.apache.logging.log4j.Logger; import pro.gravit.launcher.Launcher; import pro.gravit.launcher.profiles.ClientProfile; +import pro.gravit.launcher.profiles.ClientProfileVersions; import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.command.Command; import pro.gravit.launchserver.helper.MakeProfileHelper; @@ -81,9 +82,9 @@ public void invoke(String... args) throws IOException, CommandException { if (internalVersion.contains("-")) { internalVersion = internalVersion.substring(0, versionName.indexOf('-')); } - ClientProfile.Version version = ClientProfile.Version.byName(internalVersion); - if (version.compareTo(ClientProfile.Version.MC164) <= 0) { - logger.warn("Minecraft 1.6.4 and below not supported. Use at your own risk"); + ClientProfile.Version version = ClientProfile.Version.of(internalVersion); + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_7_10) <= 0) { + logger.warn("Minecraft 1.7.9 and below not supported. Use at your own risk"); } MakeProfileHelper.MakeProfileOption[] options = MakeProfileHelper.getMakeProfileOptionsFromDir(clientDir, version, Files.exists(server.updatesDir.resolve("assets"))); for (MakeProfileHelper.MakeProfileOption option : options) { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/MakeProfileCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/MakeProfileCommand.java index 8d70af88..98997e04 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/MakeProfileCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/MakeProfileCommand.java @@ -32,12 +32,12 @@ public String getUsageDescription() { @Override public void invoke(String... args) throws Exception { verifyArgs(args, 3); - ClientProfile.Version version = ClientProfile.Version.byName(args[1]); + ClientProfile.Version version = parseClientVersion(args[1]); MakeProfileHelper.MakeProfileOption[] options = MakeProfileHelper.getMakeProfileOptionsFromDir(server.updatesDir.resolve(args[2]), version, Files.exists(server.updatesDir.resolve("assets"))); for (MakeProfileHelper.MakeProfileOption option : options) { logger.info("Detected option {}", option); } - ClientProfile profile = MakeProfileHelper.makeProfile(ClientProfile.Version.byName(args[1]), args[0], options); + ClientProfile profile = MakeProfileHelper.makeProfile(version, args[0], options); try (Writer writer = IOHelper.newWriter(server.profilesDir.resolve(args[0].concat(".json")))) { Launcher.gsonManager.configGson.toJson(profile, writer); } 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 114a054b..e9ef4cb4 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 @@ -169,7 +169,7 @@ public void invoke(String... args) { bad = true; } } else { - if (nextToken.equals("memory_repo") || nextToken.equals(profile.getVersion().name)) { + if (nextToken.equals("memory_repo") || nextToken.equals(profile.getVersion().toString())) { printCheckResult(profileModuleName, String.format("updateExclusions %s not safe. Cheats may be injected very easy!", exc), false); bad = true; } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/helper/MakeProfileHelper.java b/LaunchServer/src/main/java/pro/gravit/launchserver/helper/MakeProfileHelper.java index dc270962..bb03de78 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/helper/MakeProfileHelper.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/helper/MakeProfileHelper.java @@ -2,6 +2,7 @@ import pro.gravit.launcher.profiles.ClientProfile; import pro.gravit.launcher.profiles.ClientProfileBuilder; +import pro.gravit.launcher.profiles.ClientProfileVersions; import pro.gravit.launcher.profiles.optional.OptionalFile; import pro.gravit.launcher.profiles.optional.actions.OptionalActionFile; import pro.gravit.launcher.profiles.optional.actions.OptionalActionJvmArgs; @@ -16,14 +17,14 @@ public class MakeProfileHelper { public static ClientProfile makeProfile(ClientProfile.Version version, String title, MakeProfileOption... options) { ClientProfileBuilder builder = new ClientProfileBuilder(); - builder.setVersion(version.name); + builder.setVersion(version); builder.setDir(title); if (findOption(options, MakeProfileOptionGlobalAssets.class).isPresent()) { builder.setAssetDir("assets"); } else { - builder.setAssetDir("asset" + version.name); + builder.setAssetDir("asset" + version.toCleanString()); } - builder.setAssetIndex(version.name); + builder.setAssetIndex(version.toString()); builder.setInfo("Информация о сервере"); builder.setTitle(title); builder.setUuid(UUID.randomUUID()); @@ -35,7 +36,7 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti List classPath = new ArrayList<>(5); classPath.add("libraries"); classPath.add("minecraft.jar"); - if (version.compareTo(ClientProfile.Version.MC1122) <= 0) { + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) <= 0) { findOption(options, MakeProfileOptionForge.class).ifPresent(e -> classPath.add("forge.jar")); findOption(options, MakeProfileOptionLiteLoader.class).ifPresent(e -> classPath.add("liteloader.jar")); } @@ -46,20 +47,20 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti Set optionals = new HashSet<>(); jvmArgs.add("-XX:+DisableAttachMechanism"); // Official Mojang launcher java arguments - if (version.compareTo(ClientProfile.Version.MC112) <= 0) { + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) <= 0) { jvmArgs.add("-XX:+UseConcMarkSweepGC"); jvmArgs.add("-XX:+CMSIncrementalMode"); - } else if (version.compareTo(ClientProfile.Version.MC118) <= 0) { // 1.13 - 1.16.5 + } else if (version.compareTo(ClientProfileVersions.MINECRAFT_1_18) <= 0) { // 1.13 - 1.16.5 jvmArgs.add("-XX:+UseG1GC"); jvmArgs.add("-XX:+UnlockExperimentalVMOptions"); } else { // 1.18+ - jvmArgs.add("-XX:+UseShenandoahGC"); - jvmArgs.add("-XX:+UnlockExperimentalVMOptions"); + //jvmArgs.add("-XX:+UseShenandoahGC"); + //jvmArgs.add("-XX:+UnlockExperimentalVMOptions"); } // ----------- Optional forge = findOption(options, MakeProfileOptionForge.class); Optional fabric = findOption(options, MakeProfileOptionFabric.class); - if (version.compareTo(ClientProfile.Version.MC1122) > 0) { + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) > 0) { jvmArgs.add("-Djava.library.path=natives"); OptionalFile optionalMacOs = new OptionalFile(); optionalMacOs.name = "MacOSArgs"; @@ -112,16 +113,16 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti if (log4jOption.logFile != null) { jvmArgs.add("-Dlog4j.configurationFile=".concat(logFile.get().logFile)); } else if (log4jOption.affected) { - if (version.compareTo(ClientProfile.Version.MC117) >= 0 && version.compareTo(ClientProfile.Version.MC118) < 0) { + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_17) >= 0 && version.compareTo(ClientProfileVersions.MINECRAFT_1_18) < 0) { jvmArgs.add("-Dlog4j2.formatMsgNoLookups=true"); } } } - if (version.compareTo(ClientProfile.Version.MC117) >= 0 && version.compareTo(ClientProfile.Version.MC118) < 0) { + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_17) >= 0 && version.compareTo(ClientProfileVersions.MINECRAFT_1_18) < 0) { builder.setMinJavaVersion(16); builder.setRecommendJavaVersion(16); } - if (version.compareTo(ClientProfile.Version.MC118) >= 0) { + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_18) >= 0) { builder.setMinJavaVersion(17); builder.setRecommendJavaVersion(17); } @@ -137,22 +138,22 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti } if (forge.isPresent()) { clientArgs.add("--tweakClass"); - if (version.compareTo(ClientProfile.Version.MC1710) > 0) { + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_7_10) > 0) { clientArgs.add("net.minecraftforge.fml.common.launcher.FMLTweaker"); } else { clientArgs.add("cpw.mods.fml.common.launcher.FMLTweaker"); } - if (version.compareTo(ClientProfile.Version.MC1122) <= 0) { + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) <= 0) { builder.setMinJavaVersion(8); builder.setRecommendJavaVersion(8); builder.setMaxJavaVersion(8); } } - } else if (version.compareTo(ClientProfile.Version.MC1122) > 0) { + } else if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) > 0) { if (forge.isPresent()) { clientArgs.addAll(forge.get().makeClientArgs()); builder.setClassLoaderConfig(ClientProfile.ClassLoaderConfig.AGENT); - if (version.compareTo(ClientProfile.Version.MC1165) <= 0) { + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_16_5) <= 0) { builder.setMaxJavaVersion(15); } } @@ -171,7 +172,7 @@ public static String getMainClassByVersion(ClientProfile.Version version, MakePr if (findOption(options, MakeProfileOptionLaunchWrapper.class).isPresent()) { return "net.minecraft.launchwrapper.Launch"; } - if (findOption(options, MakeProfileOptionForge.class).isPresent() && version.compareTo(ClientProfile.Version.MC1122) > 0) { + if (findOption(options, MakeProfileOptionForge.class).isPresent() && version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) > 0) { return "cpw.mods.modlauncher.Launcher"; } if (findOption(options, MakeProfileOptionFabric.class).isPresent()) { @@ -206,7 +207,7 @@ public static MakeProfileOption[] getMakeProfileOptionsFromDir(Path dir, ClientP if (Files.exists(dir.resolve("forge.jar"))) { options.add(new MakeProfileOptionForge()); } else if (Files.exists(dir.resolve("libraries/net/minecraftforge/forge"))) { - if (version.compareTo(ClientProfile.Version.MC1122) > 0) { + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) > 0) { options.add(new MakeProfileOptionForge(dir)); } else { options.add(new MakeProfileOptionForge()); 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 430f2819..106abb2d 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/LaunchServerGsonManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/LaunchServerGsonManager.java @@ -5,6 +5,7 @@ import pro.gravit.launcher.events.request.GetAvailabilityAuthRequestEvent; import pro.gravit.launcher.managers.GsonManager; import pro.gravit.launcher.modules.events.PreGsonPhase; +import pro.gravit.launcher.profiles.ClientProfile; import pro.gravit.launcher.profiles.optional.actions.OptionalAction; import pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger; import pro.gravit.launcher.request.JsonResultSerializeAdapter; @@ -35,6 +36,7 @@ public void registerAdapters(GsonBuilder builder) { builder.registerTypeAdapterFactory(RecordTypeAdapterFactory.builder() .allowMissingComponentValues() .create()); + builder.registerTypeAdapter(ClientProfile.Version.class, new ClientProfile.Version.GsonSerializer()); builder.registerTypeAdapter(TextureProvider.class, new UniversalJsonAdapter<>(TextureProvider.providers)); builder.registerTypeAdapter(AuthCoreProvider.class, new UniversalJsonAdapter<>(AuthCoreProvider.providers)); builder.registerTypeAdapter(PasswordVerifier.class, new UniversalJsonAdapter<>(PasswordVerifier.providers)); 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 0817567f..285e94a2 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java @@ -16,6 +16,7 @@ import pro.gravit.launcher.modules.events.OfflineModeEvent; import pro.gravit.launcher.modules.events.PreConfigPhase; import pro.gravit.launcher.profiles.ClientProfile; +import pro.gravit.launcher.profiles.ClientProfileVersions; import pro.gravit.launcher.profiles.optional.actions.OptionalAction; import pro.gravit.launcher.profiles.optional.actions.OptionalActionClassPath; import pro.gravit.launcher.profiles.optional.actions.OptionalActionClientArgs; @@ -290,7 +291,7 @@ public static Stream resolveClassPath(Path clientDir, Set private static void launch(ClientProfile profile, ClientLauncherProcess.ClientParams params) throws Throwable { // Add client args Collection args = new LinkedList<>(); - if (profile.getVersion().compareTo(ClientProfile.Version.MC164) >= 0) + if (profile.getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0) params.addClientArgs(args); else { params.addClientLegacyArgs(args); 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 4136aeb8..c064c471 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java @@ -10,6 +10,7 @@ import pro.gravit.launcher.events.request.AuthRequestEvent; import pro.gravit.launcher.hasher.HashedDir; import pro.gravit.launcher.profiles.ClientProfile; +import pro.gravit.launcher.profiles.ClientProfileVersions; import pro.gravit.launcher.profiles.PlayerProfile; import pro.gravit.launcher.profiles.optional.OptionalView; import pro.gravit.launcher.profiles.optional.actions.OptionalAction; @@ -289,7 +290,7 @@ public static class ClientParams { public transient HashedDir javaHDir; public void addClientArgs(Collection args) { - if (profile.getVersion().compareTo(ClientProfile.Version.MC164) >= 0) + if (profile.getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0) addModernClientArgs(args); else addClientLegacyArgs(args); @@ -300,7 +301,7 @@ public void addClientLegacyArgs(Collection args) { args.add(accessToken); // Add args for tweaker - Collections.addAll(args, "--version", profile.getVersion().name); + Collections.addAll(args, "--version", profile.getVersion().toString()); Collections.addAll(args, "--gameDir", clientDir); Collections.addAll(args, "--assetsDir", assetDir); } @@ -310,12 +311,12 @@ private void addModernClientArgs(Collection args) { // Add version-dependent args ClientProfile.Version version = profile.getVersion(); Collections.addAll(args, "--username", playerProfile.username); - if (version.compareTo(ClientProfile.Version.MC172) >= 0) { + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_7_2) >= 0) { Collections.addAll(args, "--uuid", Launcher.toHash(playerProfile.uuid)); Collections.addAll(args, "--accessToken", accessToken); // Add 1.7.10+ args (user properties, asset index) - if (version.compareTo(ClientProfile.Version.MC1710) >= 0) { + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_7_10) >= 0) { // Add user properties Collections.addAll(args, "--userType", "mojang"); Collections.addAll(args, "--userProperties", "{}"); @@ -327,11 +328,11 @@ private void addModernClientArgs(Collection args) { Collections.addAll(args, "--session", accessToken); // Add version and dirs args - Collections.addAll(args, "--version", profile.getVersion().name); + Collections.addAll(args, "--version", profile.getVersion().toString()); Collections.addAll(args, "--gameDir", clientDir); Collections.addAll(args, "--assetsDir", assetDir); Collections.addAll(args, "--resourcePackDir", resourcePackDir); - if (version.compareTo(ClientProfile.Version.MC194) >= 0) + if (version.compareTo(ClientProfileVersions.MINECRAFT_1_9_4) >= 0) Collections.addAll(args, "--versionType", "Launcher v" + Version.getVersion().getVersionString()); // Add server args diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ServerPinger.java b/Launcher/src/main/java/pro/gravit/launcher/client/ServerPinger.java index 57a86dbe..7de97b99 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ServerPinger.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ServerPinger.java @@ -4,6 +4,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import pro.gravit.launcher.profiles.ClientProfile; +import pro.gravit.launcher.profiles.ClientProfileVersions; import pro.gravit.launcher.serialize.HInput; import pro.gravit.launcher.serialize.HOutput; import pro.gravit.utils.helper.IOHelper; @@ -64,7 +65,7 @@ private Result doPing() throws IOException { socket.connect(IOHelper.resolve(address), IOHelper.SOCKET_TIMEOUT); try (HInput input = new HInput(socket.getInputStream()); HOutput output = new HOutput(socket.getOutputStream())) { - return version.compareTo(ClientProfile.Version.MC172) >= 0 ? modernPing(input, output) : legacyPing(input, output, version.compareTo(ClientProfile.Version.MC164) >= 0); + return version.compareTo(ClientProfileVersions.MINECRAFT_1_7_2) >= 0 ? modernPing(input, output) : legacyPing(input, output, version.compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0); } } } @@ -80,7 +81,7 @@ private Result legacyPing(HInput input, HOutput output, boolean mc16) throws IOE byte[] customPayloadPacket; try (ByteArrayOutputStream packetArray = IOHelper.newByteArrayOutput()) { try (HOutput packetOutput = new HOutput(packetArray)) { - packetOutput.writeUnsignedByte(version.protocol); // Protocol version + packetOutput.writeUnsignedByte(0x4a); // Protocol version writeUTF16String(packetOutput, address.getHostString()); // Server address packetOutput.writeInt(address.getPort()); // Server port } @@ -110,11 +111,7 @@ private Result legacyPing(HInput input, HOutput output, boolean mc16) throws IOE if (!magic.equals(LEGACY_PING_HOST_MAGIC)) throw new IOException("Magic file mismatch: " + magic); int protocol = Integer.parseInt(splitted[1]); - if (protocol != version.protocol) - throw new IOException("Protocol mismatch: " + protocol); String clientVersion = splitted[2]; - if (!clientVersion.equals(version.name)) - throw new IOException(String.format("Version mismatch: '%s'", clientVersion)); int onlinePlayers = VerifyHelper.verifyInt(Integer.parseInt(splitted[4]), VerifyHelper.NOT_NEGATIVE, "onlinePlayers can't be < 0"); int maxPlayers = VerifyHelper.verifyInt(Integer.parseInt(splitted[5]), @@ -130,7 +127,7 @@ private Result modernPing(HInput input, HOutput output) throws IOException { try (ByteArrayOutputStream packetArray = IOHelper.newByteArrayOutput()) { try (HOutput packetOutput = new HOutput(packetArray)) { packetOutput.writeVarInt(0x0); // Handshake packet ID - packetOutput.writeVarInt(version.protocol); // Protocol version + packetOutput.writeVarInt(0x4); // Protocol version packetOutput.writeString(address.getHostString(), 0); // Server address packetOutput.writeShort((short) address.getPort()); // Server port packetOutput.writeVarInt(0x1); // Next state - status 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 3773e1c2..69f2037b 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java @@ -1,5 +1,6 @@ package pro.gravit.launcher.profiles; +import com.google.gson.*; import pro.gravit.launcher.LauncherNetworkAPI; import pro.gravit.launcher.hasher.FileNameMatcher; import pro.gravit.launcher.profiles.optional.OptionalDepend; @@ -8,6 +9,7 @@ import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.VerifyHelper; +import java.lang.reflect.Type; import java.net.InetSocketAddress; import java.util.*; @@ -20,7 +22,7 @@ public final class ClientProfile implements Comparable { @LauncherNetworkAPI private UUID uuid; @LauncherNetworkAPI - private String version; + private Version version; @LauncherNetworkAPI private String info; @LauncherNetworkAPI @@ -97,7 +99,7 @@ public ClientProfile() { flags = new ArrayList<>(); } - public ClientProfile(List update, List updateExclusions, List updateShared, List updateVerify, Set updateOptional, List jvmArgs, List classPath, List modulePath, List modules, List altClassPath, List clientArgs, List compatClasses, Map properties, List servers, ClassLoaderConfig classLoaderConfig, List flags, String version, String assetIndex, String dir, String assetDir, int recommendJavaVersion, int minJavaVersion, int maxJavaVersion, ProfileDefaultSettings settings, int sortIndex, UUID uuid, String title, String info, String mainClass) { + public ClientProfile(List update, List updateExclusions, List updateShared, List updateVerify, Set updateOptional, List jvmArgs, List classPath, List modulePath, List modules, List altClassPath, List clientArgs, List compatClasses, Map properties, List servers, ClassLoaderConfig classLoaderConfig, List flags, Version version, String assetIndex, String dir, String assetDir, int recommendJavaVersion, int minJavaVersion, int maxJavaVersion, ProfileDefaultSettings settings, int sortIndex, UUID uuid, String title, String info, String mainClass) { this.update = update; this.updateExclusions = updateExclusions; this.updateShared = updateShared; @@ -146,7 +148,7 @@ public String getAssetIndex() { } public FileNameMatcher getAssetUpdateMatcher() { - return getVersion().compareTo(Version.MC1710) >= 0 ? ASSET_MATCHER : null; + return getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_7_10) >= 0 ? ASSET_MATCHER : null; } public String[] getClassPath() { @@ -291,11 +293,11 @@ public void setInfo(String info) { } public Version getVersion() { - return Version.byName(version); + return version; } public void setVersion(Version version) { - this.version = version.name; + this.version = version; } @Deprecated @@ -429,76 +431,6 @@ public List getFlags() { return flags; } - public enum Version { - MC125("1.2.5", 29), - MC147("1.4.7", 51), - MC152("1.5.2", 61), - MC164("1.6.4", 78), - MC172("1.7.2", 4), - MC1710("1.7.10", 5), - MC189("1.8.9", 47), - MC19("1.9", 107), - MC192("1.9.2", 109), - MC194("1.9.4", 110), - MC1102("1.10.2", 210), - MC111("1.11", 315), - MC1112("1.11.2", 316), - MC112("1.12", 335), - MC1121("1.12.1", 338), - MC1122("1.12.2", 340), - MC113("1.13", 393), - MC1131("1.13.1", 401), - MC1132("1.13.2", 402), - MC114("1.14", 477), - MC1141("1.14.1", 480), - MC1142("1.14.2", 485), - MC1143("1.14.3", 490), - MC1144("1.14.4", 498), - MC115("1.15", 573), - MC1151("1.15.1", 575), - MC1152("1.15.2", 578), - MC1161("1.16.1", 736), - MC1162("1.16.2", 751), - MC1163("1.16.3", 753), - MC1164("1.16.4", 754), - MC1165("1.16.5", 754), - MC117("1.17", 755), - MC1171("1.17.1", 756), - MC118("1.18", 757), - MC1181("1.18.1", 757), - MC1182("1.18.2", 758), - MC119("1.19", 759), - MC1191("1.19.1", 760), - MC1192("1.19.2", 760), - MC1193("1.19.3", 761), - MC1194("1.19.4", 762); - private static final Map VERSIONS; - - static { - Version[] versionsValues = values(); - VERSIONS = new HashMap<>(versionsValues.length); - for (Version version : versionsValues) - VERSIONS.put(version.name, version); - } - - public final String name; - public final int protocol; - - Version(String name, int protocol) { - this.name = name; - this.protocol = protocol; - } - - public static Version byName(String name) { - return VerifyHelper.getMapValue(VERSIONS, name, String.format("Unknown client version: '%s'", name)); - } - - @Override - public String toString() { - return "Minecraft " + name; - } - } - public enum ClassLoaderConfig { AGENT, LAUNCHER, MODULE, SYSTEM_ARGS } @@ -507,9 +439,87 @@ public enum CompatibilityFlags { LEGACY_NATIVES_DIR } - @FunctionalInterface - public interface pushOptionalClassPathCallback { - void run(String[] opt); + public static class Version implements Comparable { + private final long[] data; + private final String original; + private final boolean isObjectSerialized; + + public static Version of(String string) { + String tmp = string.replaceAll("[^.0-9]", "."); // Replace any non-digit character to . + String[] list = tmp.split("\\."); + return new Version(Arrays.stream(list) + .filter(e -> !e.isEmpty()) // Filter ".." + .mapToLong(Long::parseLong).toArray(), string); + } + + private Version(long[] data, String str) { + this.data = data; + this.original = str; + this.isObjectSerialized = false; + } + + public Version(long[] data, String original, boolean isObjectSerialized) { + this.data = data; + this.original = original; + this.isObjectSerialized = isObjectSerialized; + } + + @Override + public int compareTo(Version some) { + int result = 0; + for (int i = 0; i < data.length; ++i) { + if (i > some.data.length) break; + result = Long.compare(data[i], some.data[i]); + if (result != 0) return result; + } + return result; + } + + public String toCleanString() { + return join(data); + } + + private static String join(long[] data) { + return String.join(".", Arrays.stream(data).mapToObj(String::valueOf).toArray(String[]::new)); + } + + @Override + public String toString() { + return original; + } + + public static class GsonSerializer implements JsonSerializer, JsonDeserializer { + + @Override + public Version deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + if(json.isJsonObject()) { + JsonObject object = json.getAsJsonObject(); + String name = object.get("name").getAsString(); + long[] list = context.deserialize(object.get("data"), long[].class); + return new Version(list, name, true); + } else if(json.isJsonArray()) { + long[] list = context.deserialize(json, long[].class); + return new Version(list, join(list), false); + } else { + return Version.of(json.getAsString()); + } + } + + @Override + public JsonElement serialize(Version src, Type typeOfSrc, JsonSerializationContext context) { + if(src.isObjectSerialized) { + JsonObject object = new JsonObject(); + object.add("name", new JsonPrimitive(src.original)); + JsonArray array = new JsonArray(); + for(long l : src.data) { + array.add(l); + } + object.add("data", array); + return object; + } + return new JsonPrimitive(src.toString()); + } + } } public static class ServerProfile { diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileBuilder.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileBuilder.java index 78ebfae7..5e6a09d6 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileBuilder.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileBuilder.java @@ -21,7 +21,7 @@ public class ClientProfileBuilder { private List servers = new ArrayList<>(); private ClientProfile.ClassLoaderConfig classLoaderConfig = ClientProfile.ClassLoaderConfig.LAUNCHER; private List flags = new ArrayList<>(); - private String version; + private ClientProfile.Version version; private String assetIndex; private String dir; private String assetDir; @@ -91,7 +91,7 @@ public void setClassLoaderConfig(ClientProfile.ClassLoaderConfig classLoaderConf this.classLoaderConfig = classLoaderConfig; } - public void setVersion(String version) { + public void setVersion(ClientProfile.Version version) { this.version = version; } diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileVersions.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileVersions.java new file mode 100644 index 00000000..0af1185c --- /dev/null +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfileVersions.java @@ -0,0 +1,18 @@ +package pro.gravit.launcher.profiles; + +public class ClientProfileVersions { + private ClientProfileVersions() { + throw new UnsupportedOperationException(); + } + public static final ClientProfile.Version MINECRAFT_1_6_4 = ClientProfile.Version.of("1.6.4"); + public static final ClientProfile.Version MINECRAFT_1_7_2 = ClientProfile.Version.of("1.7.2"); + public static final ClientProfile.Version MINECRAFT_1_7_10 = ClientProfile.Version.of("1.7.10"); + public static final ClientProfile.Version MINECRAFT_1_9_4 = ClientProfile.Version.of("1.9.4"); + public static final ClientProfile.Version MINECRAFT_1_12_2 = ClientProfile.Version.of("1.12.2"); + + public static final ClientProfile.Version MINECRAFT_1_13 = ClientProfile.Version.of("1.13"); + public static final ClientProfile.Version MINECRAFT_1_16_5 = ClientProfile.Version.of("1.16.5"); + public static final ClientProfile.Version MINECRAFT_1_17 = ClientProfile.Version.of("1.17"); + public static final ClientProfile.Version MINECRAFT_1_18 = ClientProfile.Version.of("1.18"); + public static final ClientProfile.Version MINECRAFT_1_19 = ClientProfile.Version.of("1.19"); +} 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 04062458..4296684b 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 @@ -7,6 +7,7 @@ import pro.gravit.launcher.events.request.*; import pro.gravit.launcher.hasher.HashedEntry; import pro.gravit.launcher.hasher.HashedEntryAdapter; +import pro.gravit.launcher.profiles.ClientProfile; import pro.gravit.launcher.profiles.optional.actions.OptionalAction; import pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger; import pro.gravit.launcher.request.WebSocketEvent; @@ -40,6 +41,7 @@ public ClientWebSocketService(String address) throws SSLException { public static void appendTypeAdapters(GsonBuilder builder) { builder.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter()); + builder.registerTypeAdapter(ClientProfile.Version.class, new ClientProfile.Version.GsonSerializer()); builder.registerTypeAdapter(WebSocketEvent.class, new UniversalJsonAdapter<>(ClientWebSocketService.results)); builder.registerTypeAdapter(WebSocketRequest.class, new UniversalJsonAdapter<>(ClientWebSocketService.requests)); builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers)); diff --git a/LauncherCore/src/main/java/pro/gravit/launcher/hasher/HashedDir.java b/LauncherCore/src/main/java/pro/gravit/launcher/hasher/HashedDir.java index 38128287..71b28e17 100644 --- a/LauncherCore/src/main/java/pro/gravit/launcher/hasher/HashedDir.java +++ b/LauncherCore/src/main/java/pro/gravit/launcher/hasher/HashedDir.java @@ -288,7 +288,7 @@ public enum WalkAction { @FunctionalInterface public interface WalkCallback { - WalkAction walked(String path, String name, HashedEntry entry); + WalkAction walked(String path, String name, HashedEntry entry) throws IOException; } public static class FindRecursiveResult { 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 0a44b85d..61fa66a9 100644 --- a/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java +++ b/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java @@ -157,7 +157,7 @@ public void run(String... args) throws Throwable { ServerAgent.loadLibraries(librariesDir); } LogHelper.info("ServerWrapper: LaunchServer address: %s. Title: %s", 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("Minecraft Version (for profile): %s", wrapper.profile == null ? "unknown" : wrapper.profile.getVersion().toString()); String[] real_args; if(config.args != null && config.args.size() > 0) { real_args = config.args.toArray(new String[0]); 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 6aece315..fdd1fa0d 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 @@ -2,6 +2,7 @@ import pro.gravit.launcher.events.request.GetPublicKeyRequestEvent; import pro.gravit.launcher.profiles.ClientProfile; +import pro.gravit.launcher.profiles.ClientProfileVersions; import pro.gravit.launcher.request.Request; import pro.gravit.launcher.request.auth.GetPublicKeyRequest; import pro.gravit.launcher.request.websockets.StdWebSocketService; @@ -90,7 +91,7 @@ public void run() throws Exception { } } } - if(wrapper.profile != null && wrapper.profile.getVersion().compareTo(ClientProfile.Version.MC118) >= 0) { + if(wrapper.profile != null && wrapper.profile.getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_18) >= 0) { LogHelper.info("Switch to alternative start mode (1.18)"); wrapper.config.classpath.add(jarName); wrapper.config.classLoaderConfig = ClientProfile.ClassLoaderConfig.LAUNCHER; diff --git a/build.gradle b/build.gradle index fe664078..f4e239bc 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ id 'org.openjfx.javafxplugin' version '0.0.10' apply false } group = 'pro.gravit.launcher' -version = '5.3.6' +version = '5.4.0-SNAPSHOT' apply from: 'props.gradle' From 26c017a2778355c3888ed49b3e131fb4649a3ec1 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Thu, 20 Apr 2023 21:48:52 +0700 Subject: [PATCH 28/38] [ANY] Update modules --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index 27977fe4..06e98102 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 27977fe487fd477f644fa8471b747e87515a61a6 +Subproject commit 06e98102578275e84ba8d3b7aed65228ecbfc30e From 6caa34e255689b574455aab6aa3776a1510066a4 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Fri, 21 Apr 2023 15:34:42 +0700 Subject: [PATCH 29/38] [FEATURE] MirrorHelper Quilt support --- .../helper/MakeProfileHelper.java | 16 +++++++++- .../launcher/profiles/ClientProfile.java | 25 +++++++++++++--- .../gravit/launcher/ClientVersionTest.java | 29 +++++++++++++++++++ modules | 2 +- 4 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 LauncherAPI/src/test/java/pro/gravit/launcher/ClientVersionTest.java diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/helper/MakeProfileHelper.java b/LaunchServer/src/main/java/pro/gravit/launchserver/helper/MakeProfileHelper.java index bb03de78..f5fe8bc9 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/helper/MakeProfileHelper.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/helper/MakeProfileHelper.java @@ -60,6 +60,7 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti // ----------- Optional forge = findOption(options, MakeProfileOptionForge.class); Optional fabric = findOption(options, MakeProfileOptionFabric.class); + Optional quilt = findOption(options, MakeProfilesOptionsQuilt.class); if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) > 0) { jvmArgs.add("-Djava.library.path=natives"); OptionalFile optionalMacOs = new OptionalFile(); @@ -73,6 +74,9 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti if (fabric.isPresent()) { builder.setAltClassPath(fabric.orElseThrow().getAltClassPath()); } + if(quilt.isPresent()) { + builder.setClassLoaderConfig(ClientProfile.ClassLoaderConfig.SYSTEM_ARGS); + } if (findOption(options, MakeProfileOptionLwjgl.class).isPresent()) { OptionalFile optionalMac = new OptionalFile(); optionalMac.name = "MacLwjgl"; @@ -152,7 +156,7 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti } else if (version.compareTo(ClientProfileVersions.MINECRAFT_1_12_2) > 0) { if (forge.isPresent()) { clientArgs.addAll(forge.get().makeClientArgs()); - builder.setClassLoaderConfig(ClientProfile.ClassLoaderConfig.AGENT); + builder.setClassLoaderConfig(ClientProfile.ClassLoaderConfig.SYSTEM_ARGS); if (version.compareTo(ClientProfileVersions.MINECRAFT_1_16_5) <= 0) { builder.setMaxJavaVersion(15); } @@ -178,6 +182,9 @@ public static String getMainClassByVersion(ClientProfile.Version version, MakePr if (findOption(options, MakeProfileOptionFabric.class).isPresent()) { return "net.fabricmc.loader.launch.knot.KnotClient"; } + if(findOption(options, MakeProfilesOptionsQuilt.class).isPresent()) { + return "org.quiltmc.loader.impl.launch.knot.KnotClient"; + } return "net.minecraft.client.main.Main"; } @@ -216,6 +223,9 @@ public static MakeProfileOption[] getMakeProfileOptionsFromDir(Path dir, ClientP if (Files.exists(dir.resolve("libraries/net/fabricmc/fabric-loader"))) { options.add(new MakeProfileOptionFabric(dir)); } + if (Files.exists(dir.resolve("libraries/org/quiltmc/quilt-loader"))) { + options.add(new MakeProfilesOptionsQuilt()); + } { String log4jVersion = getLog4jVersion(dir); if (log4jVersion != null) { @@ -344,6 +354,10 @@ public List getAltClassPath() { } } + public static class MakeProfilesOptionsQuilt implements MakeProfileOption { + + } + public static class MakeProfileOptionLiteLoader implements MakeProfileOption { } 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 69f2037b..a5475723 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java @@ -467,10 +467,27 @@ public Version(long[] data, String original, boolean isObjectSerialized) { @Override public int compareTo(Version some) { int result = 0; - for (int i = 0; i < data.length; ++i) { - if (i > some.data.length) break; - result = Long.compare(data[i], some.data[i]); - if (result != 0) return result; + if(data.length == some.data.length) { + for (int i = 0; i < data.length; ++i) { + result = Long.compare(data[i], some.data[i]); + if (result != 0) return result; + } + } else if(data.length < some.data.length) { + for (int i = 0; i < data.length; ++i) { + result = Long.compare(data[i], some.data[i]); + if (result != 0) return result; + } + for(int i = data.length; i < some.data.length;++i) { + if(some.data[i] > 0) return -1; + } + } else { + for (int i = 0; i < some.data.length; ++i) { + result = Long.compare(data[i], some.data[i]); + if (result != 0) return result; + } + for(int i = some.data.length; i < data.length;++i) { + if(data[i] > 0) return 1; + } } return result; } diff --git a/LauncherAPI/src/test/java/pro/gravit/launcher/ClientVersionTest.java b/LauncherAPI/src/test/java/pro/gravit/launcher/ClientVersionTest.java new file mode 100644 index 00000000..b676e662 --- /dev/null +++ b/LauncherAPI/src/test/java/pro/gravit/launcher/ClientVersionTest.java @@ -0,0 +1,29 @@ +package pro.gravit.launcher; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import pro.gravit.launcher.profiles.ClientProfile; + +public class ClientVersionTest { + @Test + public void parseTest() { + Assertions.assertEquals(ClientProfile.Version.of("1.0.0").toCleanString(), "1.0.0"); + Assertions.assertEquals(ClientProfile.Version.of("1.0.0-1").toCleanString(), "1.0.0.1"); + Assertions.assertEquals(ClientProfile.Version.of("-----1.0.0").toCleanString(), "1.0.0"); + } + + @Test + public void compareTest() { + Assertions.assertTrue(ClientProfile.Version.of("1.0.0").compareTo(ClientProfile.Version.of("1.0.0")) == 0); + Assertions.assertTrue(ClientProfile.Version.of("1.1.0").compareTo(ClientProfile.Version.of("1.0.0")) > 0); + Assertions.assertTrue(ClientProfile.Version.of("2.0.0").compareTo(ClientProfile.Version.of("1.0.0")) > 0); + Assertions.assertTrue(ClientProfile.Version.of("1.0.0").compareTo(ClientProfile.Version.of("1.0.1")) < 0); + Assertions.assertTrue(ClientProfile.Version.of("1.1.0").compareTo(ClientProfile.Version.of("1.0.0")) > 0); + Assertions.assertTrue(ClientProfile.Version.of("1.0.0").compareTo(ClientProfile.Version.of("1.1.0")) < 0); + Assertions.assertTrue(ClientProfile.Version.of("1.0").compareTo(ClientProfile.Version.of("1.0.0")) == 0); + Assertions.assertTrue(ClientProfile.Version.of("1.0.0").compareTo(ClientProfile.Version.of("1.0")) == 0); + Assertions.assertTrue(ClientProfile.Version.of("1.0.1").compareTo(ClientProfile.Version.of("1.0")) > 0); + Assertions.assertTrue(ClientProfile.Version.of("1.0").compareTo(ClientProfile.Version.of("1.0.1")) < 0); + Assertions.assertTrue(ClientProfile.Version.of("1.0").compareTo(ClientProfile.Version.of("1.0.1")) < 0); + } +} diff --git a/modules b/modules index 06e98102..19e9cf3d 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 06e98102578275e84ba8d3b7aed65228ecbfc30e +Subproject commit 19e9cf3d6ce7148db4374e3736862d52b5854638 From 50b463b439ff9c634b0e0c3e9bc0b8197dae5ac4 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Fri, 21 Apr 2023 16:14:33 +0700 Subject: [PATCH 30/38] [FEATURE] Support custom protocol --- .../java/pro/gravit/launcher/client/ServerPinger.java | 8 +++++--- .../java/pro/gravit/launcher/profiles/ClientProfile.java | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ServerPinger.java b/Launcher/src/main/java/pro/gravit/launcher/client/ServerPinger.java index 7de97b99..07d9a1d9 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ServerPinger.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ServerPinger.java @@ -30,6 +30,7 @@ public final class ServerPinger { private static final int PACKET_LENGTH = 65535; // Instance private final InetSocketAddress address; + private final int protocol; private final ClientProfile.Version version; // Cache private final Object cacheLock = new Object(); @@ -47,6 +48,7 @@ public ServerPinger(ClientProfile.ServerProfile profile, ClientProfile.Version v } this.address = profile.toSocketAddress(); this.version = Objects.requireNonNull(version, "version"); + this.protocol = profile.protocol; } private static String readUTF16String(HInput input) throws IOException { @@ -65,7 +67,7 @@ private Result doPing() throws IOException { socket.connect(IOHelper.resolve(address), IOHelper.SOCKET_TIMEOUT); try (HInput input = new HInput(socket.getInputStream()); HOutput output = new HOutput(socket.getOutputStream())) { - return version.compareTo(ClientProfileVersions.MINECRAFT_1_7_2) >= 0 ? modernPing(input, output) : legacyPing(input, output, version.compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0); + return version.compareTo(ClientProfileVersions.MINECRAFT_1_7_2) >= 0 ? modernPing(input, output, protocol) : legacyPing(input, output, version.compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0); } } } @@ -121,13 +123,13 @@ private Result legacyPing(HInput input, HOutput output, boolean mc16) throws IOE return new Result(onlinePlayers, maxPlayers, response); } - private Result modernPing(HInput input, HOutput output) throws IOException { + private Result modernPing(HInput input, HOutput output, int protocol) throws IOException { // Prepare handshake packet byte[] handshakePacket; try (ByteArrayOutputStream packetArray = IOHelper.newByteArrayOutput()) { try (HOutput packetOutput = new HOutput(packetArray)) { packetOutput.writeVarInt(0x0); // Handshake packet ID - packetOutput.writeVarInt(0x4); // Protocol version + packetOutput.writeVarInt(protocol > 0 ? protocol : 0x4); // Protocol version packetOutput.writeString(address.getHostString(), 0); // Server address packetOutput.writeShort((short) address.getPort()); // Server port packetOutput.writeVarInt(0x1); // Next state - status 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 a5475723..b0265d08 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java @@ -544,6 +544,7 @@ public static class ServerProfile { public String serverAddress; public int serverPort; public boolean isDefault = true; + public int protocol = -1; public boolean socketPing = true; public ServerProfile() { From bfa6966ec60a2ada34ee26a946b4ce3d3fa1f475 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sat, 22 Apr 2023 20:17:02 +0700 Subject: [PATCH 31/38] [ANY] Update mirror link --- .../java/pro/gravit/launchserver/config/LaunchServerConfig.java | 2 +- 1 file changed, 1 insertion(+), 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 ee810bd0..3e759cc3 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java @@ -45,7 +45,7 @@ public final class LaunchServerConfig { public static LaunchServerConfig getDefault(LaunchServer.LaunchServerEnv env) { LaunchServerConfig newConfig = new LaunchServerConfig(); - newConfig.mirrors = new String[]{"https://mirror.gravitlauncher.com/5.3.x/", "https://gravit-launcher-mirror.storage.googleapis.com/"}; + newConfig.mirrors = new String[]{"https://mirror.gravitlauncher.com/5.4.x/", "https://gravit-launcher-mirror.storage.googleapis.com/"}; newConfig.launch4j = new LaunchServerConfig.ExeConf(); newConfig.launch4j.enabled = false; newConfig.launch4j.copyright = "© GravitLauncher Team"; From e05aa4b2040348c81c74825d37da35b84d243ac2 Mon Sep 17 00:00:00 2001 From: microwin7 Date: Tue, 25 Apr 2023 16:28:14 +0300 Subject: [PATCH 32/38] [FIX] DownloadAssetCommand.java command ArrayIndexOutOfBoundsException --- .../gravit/launchserver/command/hash/DownloadAssetCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/DownloadAssetCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/DownloadAssetCommand.java index a1f79553..206bdef0 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/DownloadAssetCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/hash/DownloadAssetCommand.java @@ -43,7 +43,7 @@ public void invoke(String... args) throws Exception { verifyArgs(args, 1); //Version version = Version.byName(args[0]); String versionName = args[0]; - String dirName = IOHelper.verifyFileName(args[1] != null ? args[1] : "assets"); + String dirName = IOHelper.verifyFileName(args.length > 1 ? args[1] : "assets"); String type = args.length > 2 ? args[2] : "mojang"; Path assetDir = server.updatesDir.resolve(dirName); From b10535042f7dae01aa64c0a6f9bbcc129f1405b2 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Thu, 27 Apr 2023 21:02:18 +0700 Subject: [PATCH 33/38] [FIX] FileAuthSystem slim support --- .../auth/texture/RequestTextureProvider.java | 4 ++-- .../main/java/pro/gravit/launcher/profiles/Texture.java | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/texture/RequestTextureProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/texture/RequestTextureProvider.java index 826b00c9..4d8885b2 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/texture/RequestTextureProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/texture/RequestTextureProvider.java @@ -29,7 +29,7 @@ public RequestTextureProvider(String skinURL, String cloakURL) { private static Texture getTexture(String url, boolean cloak) throws IOException { try { - return new Texture(url, cloak); + return new Texture(url, cloak, null); } catch (FileNotFoundException ignored) { return null; // Simply not found } @@ -37,7 +37,7 @@ private static Texture getTexture(String url, boolean cloak) throws IOException private static Texture getTexture(String url, Path local, boolean cloak) throws IOException { try { - return new Texture(url, local, cloak); + return new Texture(url, local, cloak, null); } catch (FileNotFoundException ignored) { return null; // Simply not found } diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/Texture.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/Texture.java index 83ae980f..2b8d26bc 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/Texture.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/Texture.java @@ -24,7 +24,7 @@ public final class Texture extends StreamObject { public final Map metadata; - public Texture(String url, boolean cloak) throws IOException { + public Texture(String url, boolean cloak, Map metadata) throws IOException { this.url = IOHelper.verifyURL(url); // Fetch texture @@ -38,19 +38,20 @@ public Texture(String url, boolean cloak) throws IOException { // Get digest of texture digest = SecurityHelper.digest(DIGEST_ALGO, new URL(url)); - metadata = null; // May be auto-detect? + this.metadata = metadata; // May be auto-detect? } - public Texture(String url, Path local, boolean cloak) throws IOException { + public Texture(String url, Path local, boolean cloak, Map metadata) throws IOException { this.url = IOHelper.verifyURL(url); try (InputStream input = IOHelper.newInput(local)) { IOHelper.readTexture(input, cloak); // Verify texture } this.digest = SecurityHelper.digest(DIGEST_ALGO, local); - this.metadata = null; + this.metadata = metadata; } + @Deprecated public Texture(String url, byte[] digest) { this.url = IOHelper.verifyURL(url); this.digest = digest == null ? new byte[0] : digest; From 5aa4fe8d473f943702f857ba0a15d38576eb2f37 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Thu, 27 Apr 2023 21:03:21 +0700 Subject: [PATCH 34/38] [ANY] Update modules --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index 19e9cf3d..fc263e19 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 19e9cf3d6ce7148db4374e3736862d52b5854638 +Subproject commit fc263e19bc73cc7cb0f64c4e78c092c363b6769a From 5436b2a2d63052c94aa47dc84c4bb2f6d421df80 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Thu, 27 Apr 2023 21:12:21 +0700 Subject: [PATCH 35/38] [FIX] Double read textures --- .../main/java/pro/gravit/launcher/profiles/Texture.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/Texture.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/Texture.java index 2b8d26bc..f4a070d9 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/Texture.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/Texture.java @@ -37,16 +37,20 @@ public Texture(String url, boolean cloak, Map metadata) throws I } // Get digest of texture - digest = SecurityHelper.digest(DIGEST_ALGO, new URL(url)); + digest = SecurityHelper.digest(DIGEST_ALGO, texture); this.metadata = metadata; // May be auto-detect? } public Texture(String url, Path local, boolean cloak, Map metadata) throws IOException { this.url = IOHelper.verifyURL(url); + byte[] texture; try (InputStream input = IOHelper.newInput(local)) { + texture = IOHelper.read(input); + } + try (ByteArrayInputStream input = new ByteArrayInputStream(texture)) { IOHelper.readTexture(input, cloak); // Verify texture } - this.digest = SecurityHelper.digest(DIGEST_ALGO, local); + this.digest = SecurityHelper.digest(DIGEST_ALGO, texture); this.metadata = metadata; } From d97b856ad6ebfe19c02e328004742bc702dbf051 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Fri, 28 Apr 2023 00:08:31 +0700 Subject: [PATCH 36/38] [FIX] Update mysql connector --- props.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/props.gradle b/props.gradle index f74b6a75..3fba03e4 100644 --- a/props.gradle +++ b/props.gradle @@ -12,7 +12,7 @@ verBcpkix = '1.70' verSlf4j = '1.7.36' verLog4j = '2.19.0' - verMySQLConn = '8.0.32' + verMySQLConn = '8.0.33' verPostgreSQLConn = '42.5.1' verProguard = '7.3.1' verLaunch4j = '3.50' From 74af58bc7acc7e477d3aef3713ad5ce92611811d Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Fri, 28 Apr 2023 01:02:40 +0700 Subject: [PATCH 37/38] [ANY] Remove deprecated flag --- .../src/main/java/pro/gravit/utils/helper/JVMHelper.java | 3 --- .../src/main/java11/pro/gravit/utils/helper/JVMHelper.java | 3 --- 2 files changed, 6 deletions(-) diff --git a/LauncherCore/src/main/java/pro/gravit/utils/helper/JVMHelper.java b/LauncherCore/src/main/java/pro/gravit/utils/helper/JVMHelper.java index ec0c26e1..1ec88240 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/helper/JVMHelper.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/helper/JVMHelper.java @@ -20,7 +20,6 @@ public final class JVMHelper { public static final OperatingSystemMXBean OPERATING_SYSTEM_MXBEAN = ManagementFactory.getOperatingSystemMXBean(); public static final OS OS_TYPE = OS.byName(OPERATING_SYSTEM_MXBEAN.getName()); - @Deprecated public static final int OS_BITS = getCorrectOSArch(); // System properties public static final String OS_VERSION = OPERATING_SYSTEM_MXBEAN.getVersion(); @@ -138,7 +137,6 @@ public static void checkStackTrace(Class mainClass) { } } - @Deprecated private static int getCorrectOSArch() { // As always, mustdie must die if (OS_TYPE == OS.MUSTDIE) @@ -152,7 +150,6 @@ public static String getEnvPropertyCaseSensitive(String name) { return System.getenv().get(name); } - @Deprecated public static boolean isJVMMatchesSystemArch() { return JVM_BITS == OS_BITS; } diff --git a/LauncherCore/src/main/java11/pro/gravit/utils/helper/JVMHelper.java b/LauncherCore/src/main/java11/pro/gravit/utils/helper/JVMHelper.java index 756e7fc3..e96e532c 100644 --- a/LauncherCore/src/main/java11/pro/gravit/utils/helper/JVMHelper.java +++ b/LauncherCore/src/main/java11/pro/gravit/utils/helper/JVMHelper.java @@ -23,7 +23,6 @@ public final class JVMHelper { // System properties public static final String OS_VERSION = OPERATING_SYSTEM_MXBEAN.getVersion(); - @Deprecated public static final int OS_BITS = getCorrectOSArch(); public static final ARCH ARCH_TYPE = getArch(System.getProperty("os.arch")); @@ -131,7 +130,6 @@ public static void checkStackTrace(Class mainClass) { } } - @Deprecated private static int getCorrectOSArch() { // As always, mustdie must die if (OS_TYPE == OS.MUSTDIE) @@ -147,7 +145,6 @@ public static String getEnvPropertyCaseSensitive(String name) { } - @Deprecated public static boolean isJVMMatchesSystemArch() { return JVM_BITS == OS_BITS; } From dec86c9a9124d21ebe70f23714a7c9abeadc5601 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Fri, 28 Apr 2023 20:41:48 +0700 Subject: [PATCH 38/38] [ANY] 5.4.0 stable --- LaunchServer/src/main/resources/experimental-build.json | 2 +- LauncherCore/src/main/java/pro/gravit/utils/Version.java | 2 +- build.gradle | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LaunchServer/src/main/resources/experimental-build.json b/LaunchServer/src/main/resources/experimental-build.json index e5bb4564..ab148d00 100644 --- a/LaunchServer/src/main/resources/experimental-build.json +++ b/LaunchServer/src/main/resources/experimental-build.json @@ -1,4 +1,4 @@ { - "features": ["profiles-rework"], + "features": [], "info": [] } \ No newline at end of file diff --git a/LauncherCore/src/main/java/pro/gravit/utils/Version.java b/LauncherCore/src/main/java/pro/gravit/utils/Version.java index 694800ac..d74be01d 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 implements Comparable { public static final int MINOR = 4; public static final int PATCH = 0; public static final int BUILD = 1; - public static final Version.Type RELEASE = Type.EXPERIMENTAL; + 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 f4e239bc..d2e54bea 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ id 'org.openjfx.javafxplugin' version '0.0.10' apply false } group = 'pro.gravit.launcher' -version = '5.4.0-SNAPSHOT' +version = '5.4.0' apply from: 'props.gradle'