diff --git a/LaunchServer/src/main/resources/experimental-build.json b/LaunchServer/src/main/resources/experimental-build.json index ab148d00..b87fec33 100644 --- a/LaunchServer/src/main/resources/experimental-build.json +++ b/LaunchServer/src/main/resources/experimental-build.json @@ -1,4 +1,4 @@ { - "features": [], + "features": ["separate"], "info": [] } \ No newline at end of file diff --git a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/proguard.cfg b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/proguard.cfg index 23797bd8..fb73c174 100644 --- a/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/proguard.cfg +++ b/LaunchServer/src/main/resources/pro/gravit/launchserver/defaults/proguard.cfg @@ -17,7 +17,7 @@ -keeppackagenames com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,pro.gravit.repackage.**,org.fusesource.**, pro.gravit.launcher.api.**, pro.gravit.utils.**, pro.gravit.launcher.request.**, pro.gravit.launcher.events.**, pro.gravit.launcher.profiles.** --keep class com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,pro.gravit.repackage.**,org.fusesource.**, pro.gravit.launcher.api.**, pro.gravit.utils.**, pro.gravit.launcher.request.**, pro.gravit.launcher.events.**, pro.gravit.launcher.profiles.** { +-keep class com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,pro.gravit.repackage.**,org.fusesource.**, pro.gravit.launcher.api.**, pro.gravit.utils.**, pro.gravit.launcher.request.**, pro.gravit.launcher.events.**, pro.gravit.launcher.profiles.**, pro.gravit.launcher.LauncherEngineWrapper { *; } diff --git a/Launcher/build.gradle b/Launcher/build.gradle index 02cdfb7e..03cfe7ae 100644 --- a/Launcher/build.gradle +++ b/Launcher/build.gradle @@ -49,6 +49,8 @@ dependencies { pack project(':LauncherAPI') + pack project(':LauncherClient') + pack project(':LauncherStart') bundle group: 'com.github.oshi', name: 'oshi-core', version: rootProject['verOshiCore'] pack group: 'io.netty', name: 'netty-codec-http', version: rootProject['verNetty'] } diff --git a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java index 74ad4797..87d829f6 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java +++ b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngine.java @@ -10,7 +10,7 @@ import pro.gravit.launcher.events.request.*; import pro.gravit.launcher.gui.NoRuntimeProvider; import pro.gravit.launcher.gui.RuntimeProvider; -import pro.gravit.launcher.managers.ClientGsonManager; +import pro.gravit.launcher.client.RuntimeGsonManager; import pro.gravit.launcher.managers.ConsoleManager; import pro.gravit.launcher.modules.events.OfflineModeEvent; import pro.gravit.launcher.modules.events.PreConfigPhase; @@ -45,8 +45,8 @@ import java.util.concurrent.atomic.AtomicBoolean; public class LauncherEngine { - public static ClientLauncherProcess.ClientParams clientParams; - public static ClientModuleManager modulesManager; + public static ClientParams clientParams; + public static RuntimeModuleManager modulesManager; public final boolean clientInstance; // Instance private final AtomicBoolean started = new AtomicBoolean(false); @@ -102,18 +102,19 @@ public static void exitLauncher(int code) { } public static void main(String... args) throws Throwable { - JVMHelper.checkStackTrace(LauncherEngine.class); + JVMHelper.checkStackTrace(LauncherEngineWrapper.class); JVMHelper.verifySystemProperties(Launcher.class, true); EnvHelper.checkDangerousParams(); //if(!LauncherAgent.isStarted()) throw new SecurityException("JavaAgent not set"); verifyNoAgent(); LogHelper.printVersion("Launcher"); LogHelper.printLicense("Launcher"); + LauncherEngine.checkClass(LauncherEngineWrapper.class); LauncherEngine.checkClass(LauncherEngine.class); LauncherEngine.checkClass(LauncherAgent.class); LauncherEngine.checkClass(ClientLauncherEntryPoint.class); - LauncherEngine.modulesManager = new ClientModuleManager(); - LauncherEngine.modulesManager.loadModule(new ClientLauncherCoreModule()); + LauncherEngine.modulesManager = new RuntimeModuleManager(); + LauncherEngine.modulesManager.loadModule(new RuntimeLauncherCoreModule()); LauncherConfig.initModules(LauncherEngine.modulesManager); LauncherEngine.modulesManager.initModules(null); // Start Launcher @@ -133,12 +134,12 @@ public static void main(String... args) throws Throwable { LauncherEngine.exitLauncher(0); } - public static void initGson(ClientModuleManager modulesManager) { + public static void initGson(RuntimeModuleManager modulesManager) { AuthRequest.registerProviders(); GetAvailabilityAuthRequest.registerProviders(); OptionalAction.registerProviders(); OptionalTrigger.registerProviders(); - Launcher.gsonManager = new ClientGsonManager(modulesManager); + Launcher.gsonManager = new RuntimeGsonManager(modulesManager); Launcher.gsonManager.initGson(); } @@ -149,37 +150,12 @@ public static void verifyNoAgent() { public static RequestService initOffline() { OfflineRequestService service = new OfflineRequestService(); - applyBasicOfflineProcessors(service); + ClientLauncherMethods.applyBasicOfflineProcessors(service); OfflineModeEvent event = new OfflineModeEvent(service); modulesManager.invokeEvent(event); return event.service; } - public static void applyBasicOfflineProcessors(OfflineRequestService service) { - service.registerRequestProcessor(LauncherRequest.class, (r) -> new LauncherRequestEvent(false, (String) null)); - service.registerRequestProcessor(CheckServerRequest.class, (r) -> { - throw new RequestException("CheckServer disabled in offline mode"); - }); - service.registerRequestProcessor(GetAvailabilityAuthRequest.class, (r) -> { - List details = new ArrayList<>(); - details.add(new AuthLoginOnlyDetails()); - GetAvailabilityAuthRequestEvent.AuthAvailability authAvailability = new GetAvailabilityAuthRequestEvent.AuthAvailability("offline", "Offline Mode", true, details); - List list = new ArrayList<>(1); - list.add(authAvailability); - return new GetAvailabilityAuthRequestEvent(list); - }); - service.registerRequestProcessor(JoinServerRequest.class, (r) -> new JoinServerRequestEvent(false)); - service.registerRequestProcessor(ExitRequest.class, (r) -> new ExitRequestEvent(ExitRequestEvent.ExitReason.CLIENT)); - service.registerRequestProcessor(SetProfileRequest.class, (r) -> new SetProfileRequestEvent(null)); - service.registerRequestProcessor(FeaturesRequest.class, (r) -> new FeaturesRequestEvent()); - service.registerRequestProcessor(GetSecureLevelInfoRequest.class, (r) -> new GetSecureLevelInfoRequestEvent(null, false)); - service.registerRequestProcessor(SecurityReportRequest.class, (r) -> new SecurityReportRequestEvent(SecurityReportRequestEvent.ReportAction.NONE)); - } - - public static LauncherEngine clientInstance() { - return new LauncherEngine(true); - } - public static LauncherEngine newInstance(boolean clientInstance) { return new LauncherEngine(clientInstance); } diff --git a/Launcher/src/main/java/pro/gravit/launcher/LauncherEngineWrapper.java b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngineWrapper.java new file mode 100644 index 00000000..25906d97 --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/LauncherEngineWrapper.java @@ -0,0 +1,8 @@ +package pro.gravit.launcher; + +@LauncherNetworkAPI +public class LauncherEngineWrapper { + public static void main(String[] args) throws Throwable { + LauncherEngine.main(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 c064c471..a224e176 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java @@ -7,18 +7,14 @@ import pro.gravit.launcher.client.events.client.ClientProcessBuilderLaunchedEvent; import pro.gravit.launcher.client.events.client.ClientProcessBuilderParamsWrittedEvent; import pro.gravit.launcher.client.events.client.ClientProcessBuilderPreLaunchEvent; -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; -import pro.gravit.launcher.profiles.optional.actions.OptionalActionClientArgs; import pro.gravit.launcher.profiles.optional.actions.OptionalActionJvmArgs; import pro.gravit.launcher.request.Request; import pro.gravit.launcher.serialize.HOutput; -import pro.gravit.utils.Version; import pro.gravit.utils.helper.*; import java.io.File; @@ -238,120 +234,4 @@ public Process getProcess() { return process; } - public static class ClientParams { - public String assetDir; - - public String clientDir; - - public String resourcePackDir; - - public String nativesDir; - - // Client params - - public PlayerProfile playerProfile; - - public ClientProfile profile; - - public String accessToken; - - //==Minecraft params== - - public boolean autoEnter; - - public boolean fullScreen; - - public int ram; - - public int width; - - public int height; - - public Set actions = new HashSet<>(); - - //======== - - public UUID session; - - public AuthRequestEvent.OAuthRequestEvent oauth; - - public String authId; - - public long oauthExpiredTime; - - public Map extendedTokens; - - public boolean offlineMode; - - public transient HashedDir assetHDir; - - public transient HashedDir clientHDir; - - public transient HashedDir javaHDir; - - public void addClientArgs(Collection args) { - if (profile.getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0) - addModernClientArgs(args); - else - addClientLegacyArgs(args); - } - - public void addClientLegacyArgs(Collection args) { - args.add(playerProfile.username); - args.add(accessToken); - - // Add args for tweaker - Collections.addAll(args, "--version", profile.getVersion().toString()); - Collections.addAll(args, "--gameDir", clientDir); - Collections.addAll(args, "--assetsDir", assetDir); - } - - private void addModernClientArgs(Collection args) { - - // Add version-dependent args - ClientProfile.Version version = profile.getVersion(); - Collections.addAll(args, "--username", playerProfile.username); - 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(ClientProfileVersions.MINECRAFT_1_7_10) >= 0) { - // Add user properties - Collections.addAll(args, "--userType", "mojang"); - Collections.addAll(args, "--userProperties", "{}"); - - // Add asset index - Collections.addAll(args, "--assetIndex", profile.getAssetIndex()); - } - } else - Collections.addAll(args, "--session", accessToken); - - // Add version and dirs args - 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(ClientProfileVersions.MINECRAFT_1_9_4) >= 0) - Collections.addAll(args, "--versionType", "Launcher v" + Version.getVersion().getVersionString()); - - // Add server args - if (autoEnter) { - Collections.addAll(args, "--server", profile.getServerAddress()); - Collections.addAll(args, "--port", Integer.toString(profile.getServerPort())); - } - for (OptionalAction a : actions) { - if (a instanceof OptionalActionClientArgs) { - args.addAll(((OptionalActionClientArgs) a).args); - } - } - // Add window size args - if (fullScreen) - Collections.addAll(args, "--fullscreen", Boolean.toString(true)); - if (width > 0 && height > 0) { - Collections.addAll(args, "--width", Integer.toString(width)); - Collections.addAll(args, "--height", Integer.toString(height)); - } - } - } } diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/RuntimeGsonManager.java b/Launcher/src/main/java/pro/gravit/launcher/client/RuntimeGsonManager.java new file mode 100644 index 00000000..b8789cf4 --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/client/RuntimeGsonManager.java @@ -0,0 +1,23 @@ +package pro.gravit.launcher.client; + +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; +import pro.gravit.utils.UniversalJsonAdapter; + +public class RuntimeGsonManager extends GsonManager { + private final RuntimeModuleManager moduleManager; + + public RuntimeGsonManager(RuntimeModuleManager moduleManager) { + this.moduleManager = moduleManager; + } + + @Override + public void registerAdapters(GsonBuilder builder) { + super.registerAdapters(builder); + builder.registerTypeAdapter(UserSettings.class, new UniversalJsonAdapter<>(UserSettings.providers)); + ClientWebSocketService.appendTypeAdapters(builder); + moduleManager.invokeEvent(new PreGsonPhase(builder)); + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/RuntimeLauncherCoreModule.java b/Launcher/src/main/java/pro/gravit/launcher/client/RuntimeLauncherCoreModule.java new file mode 100644 index 00000000..76b85182 --- /dev/null +++ b/Launcher/src/main/java/pro/gravit/launcher/client/RuntimeLauncherCoreModule.java @@ -0,0 +1,17 @@ +package pro.gravit.launcher.client; + +import pro.gravit.launcher.modules.LauncherInitContext; +import pro.gravit.launcher.modules.LauncherModule; +import pro.gravit.launcher.modules.LauncherModuleInfo; +import pro.gravit.utils.Version; + +public class RuntimeLauncherCoreModule extends LauncherModule { + public RuntimeLauncherCoreModule() { + super(new LauncherModuleInfo("ClientLauncherCore", Version.getVersion())); + } + + @Override + public void init(LauncherInitContext initContext) { + + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessInitPhase.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessInitPhase.java deleted file mode 100644 index 69378d97..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessInitPhase.java +++ /dev/null @@ -1,15 +0,0 @@ -package pro.gravit.launcher.client.events.client; - -import pro.gravit.launcher.LauncherEngine; -import pro.gravit.launcher.client.ClientLauncherProcess; -import pro.gravit.launcher.modules.events.InitPhase; - -public class ClientProcessInitPhase extends InitPhase { - public final LauncherEngine clientInstance; - public final ClientLauncherProcess.ClientParams params; - - public ClientProcessInitPhase(LauncherEngine clientInstance, ClientLauncherProcess.ClientParams params) { - this.clientInstance = clientInstance; - this.params = params; - } -} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessLaunchEvent.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessLaunchEvent.java deleted file mode 100644 index 5e66f7f6..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessLaunchEvent.java +++ /dev/null @@ -1,15 +0,0 @@ -package pro.gravit.launcher.client.events.client; - -import pro.gravit.launcher.LauncherEngine; -import pro.gravit.launcher.client.ClientLauncherProcess; -import pro.gravit.launcher.modules.LauncherModule; - -public class ClientProcessLaunchEvent extends LauncherModule.Event { - public final LauncherEngine clientInstance; - public final ClientLauncherProcess.ClientParams params; - - public ClientProcessLaunchEvent(LauncherEngine clientInstance, ClientLauncherProcess.ClientParams params) { - this.clientInstance = clientInstance; - this.params = params; - } -} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessReadyEvent.java b/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessReadyEvent.java deleted file mode 100644 index d16961e4..00000000 --- a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessReadyEvent.java +++ /dev/null @@ -1,15 +0,0 @@ -package pro.gravit.launcher.client.events.client; - -import pro.gravit.launcher.LauncherEngine; -import pro.gravit.launcher.client.ClientLauncherProcess; -import pro.gravit.launcher.modules.events.PostInitPhase; - -public class ClientProcessReadyEvent extends PostInitPhase { - public final LauncherEngine clientInstance; - public final ClientLauncherProcess.ClientParams params; - - public ClientProcessReadyEvent(LauncherEngine clientInstance, ClientLauncherProcess.ClientParams params) { - this.clientInstance = clientInstance; - this.params = params; - } -} diff --git a/Launcher/src/main/java/pro/gravit/launcher/debug/DebugMain.java b/Launcher/src/main/java/pro/gravit/launcher/debug/DebugMain.java index c5559229..ab345cd1 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/debug/DebugMain.java +++ b/Launcher/src/main/java/pro/gravit/launcher/debug/DebugMain.java @@ -1,10 +1,11 @@ package pro.gravit.launcher.debug; +import pro.gravit.launcher.ClientLauncherMethods; import pro.gravit.launcher.Launcher; import pro.gravit.launcher.LauncherConfig; import pro.gravit.launcher.LauncherEngine; -import pro.gravit.launcher.client.ClientLauncherCoreModule; -import pro.gravit.launcher.client.ClientModuleManager; +import pro.gravit.launcher.client.RuntimeLauncherCoreModule; +import pro.gravit.launcher.client.RuntimeModuleManager; import pro.gravit.launcher.managers.ConsoleManager; import pro.gravit.launcher.modules.LauncherModule; import pro.gravit.launcher.modules.events.OfflineModeEvent; @@ -42,8 +43,8 @@ public static void main(String[] args) throws Throwable { config.unlockSecret = unlockSecret; Launcher.setConfig(config); Launcher.applyLauncherEnv(environment); - LauncherEngine.modulesManager = new ClientModuleManager(); - LauncherEngine.modulesManager.loadModule(new ClientLauncherCoreModule()); + LauncherEngine.modulesManager = new RuntimeModuleManager(); + LauncherEngine.modulesManager.loadModule(new RuntimeLauncherCoreModule()); for (String moduleClassName : moduleClasses) { if (moduleClassName.isEmpty()) continue; LauncherEngine.modulesManager.loadModule(newModule(moduleClassName)); @@ -59,7 +60,7 @@ public static void main(String[] args) throws Throwable { RequestService service; if (offlineMode) { OfflineRequestService offlineRequestService = new OfflineRequestService(); - LauncherEngine.applyBasicOfflineProcessors(offlineRequestService); + ClientLauncherMethods.applyBasicOfflineProcessors(offlineRequestService); OfflineModeEvent event = new OfflineModeEvent(offlineRequestService); LauncherEngine.modulesManager.invokeEvent(event); service = event.service; diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/Launcher.java b/LauncherAPI/src/main/java/pro/gravit/launcher/Launcher.java index 27457da0..9b673b61 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/Launcher.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/Launcher.java @@ -22,23 +22,9 @@ public final class Launcher { // Authlib constants - public static final String SKIN_URL_PROPERTY = "skinURL"; - - public static final String SKIN_DIGEST_PROPERTY = "skinDigest"; - - public static final String SKIN_METADATA_PROPERTY = "skinMetadata"; - - public static final String CLOAK_URL_PROPERTY = "cloakURL"; - - public static final String CLOAK_DIGEST_PROPERTY = "cloakDigest"; - - public static final String CLOAK_METADATA_PROPERTY = "cloakMetadata"; - // Used to determine from clientside is launched from launcher public static final AtomicBoolean LAUNCHED = new AtomicBoolean(false); - public static final int PROTOCOL_MAGIC_LEGACY = 0x724724_00 + 24; - public static final int PROTOCOL_MAGIC = 0xA205B064; // e = 2.718281828 public static final String RUNTIME_DIR = "runtime"; // Constants diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/SecurityReportRequestEvent.java b/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/SecurityReportRequestEvent.java index 7266ea4b..2c9af856 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/SecurityReportRequestEvent.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/SecurityReportRequestEvent.java @@ -31,6 +31,7 @@ public enum ReportAction { LOGOUT, TOKEN_EXPIRED, EXIT, + @Deprecated CRASH, OTHER } diff --git a/LauncherClient/build.gradle b/LauncherClient/build.gradle new file mode 100644 index 00000000..c930c7da --- /dev/null +++ b/LauncherClient/build.gradle @@ -0,0 +1,79 @@ +apply plugin: 'org.openjfx.javafxplugin' + +String mainClassName = "pro.gravit.launcher.ClientLauncherWrapper" +String mainAgentName = "pro.gravit.launcher.LauncherAgent" + +repositories { + maven { + url "https://repo.spring.io/plugins-release/" + } +} +sourceCompatibility = '1.8' +targetCompatibility = '1.8' + +jar { + archiveClassifier.set('clean') + manifest.attributes("Main-Class": mainClassName, + "Premain-Class": mainAgentName, + "Multi-Release": "true") +} + +tasks.register('sourcesJar', Jar) { + from sourceSets.main.allJava + archiveClassifier.set('sources') +} + +tasks.register('javadocJar', Jar) { + from javadoc + archiveClassifier.set('javadoc') +} + +dependencies { + implementation project(':LauncherAPI') +} + +publishing { + publications { + launcherclientstarter(MavenPublication) { + artifactId = 'launcher-client-starter-api' + artifact(jar) { + classifier "" + } + artifact sourcesJar + artifact javadocJar + pom { + name = 'GravitLauncher Client API' + description = 'GravitLauncher Client Module API' + url = 'https://gravitlauncher.com' + licenses { + license { + name = 'GNU General Public License, Version 3.0' + url = 'https://www.gnu.org/licenses/gpl-3.0.html' + } + } + developers { + developer { + id = 'gravita' + name = 'Gravita' + email = 'gravita@gravit.pro' + } + developer { + id = 'zaxar163' + name = 'Zaxar163' + email = 'zahar.vcherachny@yandex.ru' + } + } + scm { + connection = 'scm:git:https://github.com/GravitLauncher/Launcher.git' + developerConnection = 'scm:git:ssh://git@github.com:GravitLauncher/Launcher.git' + url = 'https://gravitlauncher.com/' + } + } + } + } +} + + +signing { + sign publishing.publications.launcherclientapi +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/BasicLauncherEventHandler.java b/LauncherClient/src/main/java/pro/gravit/launcher/BasicLauncherEventHandler.java similarity index 90% rename from Launcher/src/main/java/pro/gravit/launcher/BasicLauncherEventHandler.java rename to LauncherClient/src/main/java/pro/gravit/launcher/BasicLauncherEventHandler.java index c02deec7..872ce399 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/BasicLauncherEventHandler.java +++ b/LauncherClient/src/main/java/pro/gravit/launcher/BasicLauncherEventHandler.java @@ -15,9 +15,7 @@ public class BasicLauncherEventHandler implements RequestService.EventHandler { public boolean eventHandle(T event) { if (event instanceof SecurityReportRequestEvent) { SecurityReportRequestEvent event1 = (SecurityReportRequestEvent) event; - if (event1.action == SecurityReportRequestEvent.ReportAction.CRASH) { - LauncherEngine.exitLauncher(80); - } else if (event1.action == SecurityReportRequestEvent.ReportAction.TOKEN_EXPIRED) { + if (event1.action == SecurityReportRequestEvent.ReportAction.TOKEN_EXPIRED) { try { Request.restore(); } catch (Exception e) { diff --git a/LauncherClient/src/main/java/pro/gravit/launcher/ClientLauncherMethods.java b/LauncherClient/src/main/java/pro/gravit/launcher/ClientLauncherMethods.java new file mode 100644 index 00000000..9210a1d5 --- /dev/null +++ b/LauncherClient/src/main/java/pro/gravit/launcher/ClientLauncherMethods.java @@ -0,0 +1,138 @@ +package pro.gravit.launcher; + +import pro.gravit.launcher.client.ClientGsonManager; +import pro.gravit.launcher.client.ClientLauncherEntryPoint; +import pro.gravit.launcher.client.ClientModuleManager; +import pro.gravit.launcher.client.ClientParams; +import pro.gravit.launcher.client.events.ClientExitPhase; +import pro.gravit.launcher.events.request.*; +import pro.gravit.launcher.modules.LauncherModulesManager; +import pro.gravit.launcher.modules.events.OfflineModeEvent; +import pro.gravit.launcher.profiles.optional.actions.OptionalAction; +import pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger; +import pro.gravit.launcher.request.RequestException; +import pro.gravit.launcher.request.RequestService; +import pro.gravit.launcher.request.auth.*; +import pro.gravit.launcher.request.auth.details.AuthLoginOnlyDetails; +import pro.gravit.launcher.request.management.FeaturesRequest; +import pro.gravit.launcher.request.secure.GetSecureLevelInfoRequest; +import pro.gravit.launcher.request.secure.SecurityReportRequest; +import pro.gravit.launcher.request.update.LauncherRequest; +import pro.gravit.launcher.request.uuid.ProfileByUUIDRequest; +import pro.gravit.launcher.request.uuid.ProfileByUsernameRequest; +import pro.gravit.launcher.request.websockets.OfflineRequestService; +import pro.gravit.launcher.utils.NativeJVMHalt; +import pro.gravit.utils.helper.JVMHelper; + +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ClientLauncherMethods { + + public static void verifyNoAgent() { + if (JVMHelper.RUNTIME_MXBEAN.getInputArguments().stream().filter(e -> e != null && !e.isEmpty()).anyMatch(e -> e.contains("javaagent"))) + throw new SecurityException("JavaAgent found"); + } + + //JVMHelper.getCertificates + public static X509Certificate[] getCertificates(Class clazz) { + Object[] signers = clazz.getSigners(); + if (signers == null) return null; + return Arrays.stream(signers).filter((c) -> c instanceof X509Certificate).map((c) -> (X509Certificate) c).toArray(X509Certificate[]::new); + } + + + + public static void beforeExit(int code) { + try { + ClientLauncherEntryPoint.modulesManager.invokeEvent(new ClientExitPhase(code)); + } catch (Throwable ignored) { + } + } + + public static void forceExit(int code) { + try { + System.exit(code); + } catch (Throwable e) //Forge Security Manager? + { + NativeJVMHalt.haltA(code); + } + } + + public static void exitLauncher(int code) { + beforeExit(code); + forceExit(code); + } + + public static void checkClass(Class clazz) throws SecurityException { + LauncherTrustManager trustManager = Launcher.getConfig().trustManager; + if (trustManager == null) return; + X509Certificate[] certificates = getCertificates(clazz); + if (certificates == null) { + throw new SecurityException(String.format("Class %s not signed", clazz.getName())); + } + try { + trustManager.checkCertificatesSuccess(certificates, trustManager::stdCertificateChecker); + } catch (Exception e) { + throw new SecurityException(e); + } + } + + public static void initGson(ClientModuleManager moduleManager) { + AuthRequest.registerProviders(); + GetAvailabilityAuthRequest.registerProviders(); + OptionalAction.registerProviders(); + OptionalTrigger.registerProviders(); + Launcher.gsonManager = new ClientGsonManager(moduleManager); + Launcher.gsonManager.initGson(); + } + + public static RequestService initOffline(LauncherModulesManager modulesManager, ClientParams params) { + OfflineRequestService service = new OfflineRequestService(); + applyBasicOfflineProcessors(service); + applyClientOfflineProcessors(service, params); + OfflineModeEvent event = new OfflineModeEvent(service); + modulesManager.invokeEvent(event); + return event.service; + } + + public static void applyClientOfflineProcessors(OfflineRequestService service, ClientParams params) { + service.registerRequestProcessor(ProfileByUsernameRequest.class, (r) -> { + if (params.playerProfile.username.equals(r.username)) { + return new ProfileByUsernameRequestEvent(params.playerProfile); + } + throw new RequestException("User not found"); + }); + service.registerRequestProcessor(ProfileByUUIDRequest.class, (r) -> { + if (params.playerProfile.uuid.equals(r.uuid)) { + return new ProfileByUUIDRequestEvent(params.playerProfile); + } + throw new RequestException("User not found"); + }); + } + + + + public static void applyBasicOfflineProcessors(OfflineRequestService service) { + service.registerRequestProcessor(LauncherRequest.class, (r) -> new LauncherRequestEvent(false, (String) null)); + service.registerRequestProcessor(CheckServerRequest.class, (r) -> { + throw new RequestException("CheckServer disabled in offline mode"); + }); + service.registerRequestProcessor(GetAvailabilityAuthRequest.class, (r) -> { + List details = new ArrayList<>(); + details.add(new AuthLoginOnlyDetails()); + GetAvailabilityAuthRequestEvent.AuthAvailability authAvailability = new GetAvailabilityAuthRequestEvent.AuthAvailability("offline", "Offline Mode", true, details); + List list = new ArrayList<>(1); + list.add(authAvailability); + return new GetAvailabilityAuthRequestEvent(list); + }); + service.registerRequestProcessor(JoinServerRequest.class, (r) -> new JoinServerRequestEvent(false)); + service.registerRequestProcessor(ExitRequest.class, (r) -> new ExitRequestEvent(ExitRequestEvent.ExitReason.CLIENT)); + service.registerRequestProcessor(SetProfileRequest.class, (r) -> new SetProfileRequestEvent(null)); + service.registerRequestProcessor(FeaturesRequest.class, (r) -> new FeaturesRequestEvent()); + service.registerRequestProcessor(GetSecureLevelInfoRequest.class, (r) -> new GetSecureLevelInfoRequestEvent(null, false)); + service.registerRequestProcessor(SecurityReportRequest.class, (r) -> new SecurityReportRequestEvent(SecurityReportRequestEvent.ReportAction.NONE)); + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/LauncherAgent.java b/LauncherClient/src/main/java/pro/gravit/launcher/LauncherAgent.java similarity index 100% rename from Launcher/src/main/java/pro/gravit/launcher/LauncherAgent.java rename to LauncherClient/src/main/java/pro/gravit/launcher/LauncherAgent.java diff --git a/Launcher/src/main/java/pro/gravit/launcher/api/AuthService.java b/LauncherClient/src/main/java/pro/gravit/launcher/api/AuthService.java similarity index 100% rename from Launcher/src/main/java/pro/gravit/launcher/api/AuthService.java rename to LauncherClient/src/main/java/pro/gravit/launcher/api/AuthService.java diff --git a/Launcher/src/main/java/pro/gravit/launcher/api/CertificateService.java b/LauncherClient/src/main/java/pro/gravit/launcher/api/CertificateService.java similarity index 92% rename from Launcher/src/main/java/pro/gravit/launcher/api/CertificateService.java rename to LauncherClient/src/main/java/pro/gravit/launcher/api/CertificateService.java index 4bf651fd..2b2f0b5c 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/api/CertificateService.java +++ b/LauncherClient/src/main/java/pro/gravit/launcher/api/CertificateService.java @@ -1,19 +1,19 @@ package pro.gravit.launcher.api; +import pro.gravit.launcher.ClientLauncherMethods; import pro.gravit.launcher.LauncherTrustManager; +import pro.gravit.launcher.client.ClientLauncherEntryPoint; import pro.gravit.launcher.utils.ApiBridgeService; import java.security.cert.X509Certificate; -import static pro.gravit.launcher.LauncherEngine.getCertificates; - public class CertificateService { private CertificateService() { throw new UnsupportedOperationException(); } public static CheckClassResultApi checkClass(Class clazz) throws SecurityException { - X509Certificate[] certificates = getCertificates(clazz); + X509Certificate[] certificates = ClientLauncherMethods.getCertificates(clazz); if (certificates == null) { return new CheckClassResultApi(CheckClassResultTypeApi.NOT_SIGNED, null, null); } @@ -25,7 +25,7 @@ public static CheckClassResultApi checkClass(Class clazz) throws SecurityExce } public static void checkClassSuccess(Class clazz) { - X509Certificate[] certificates = getCertificates(clazz); + X509Certificate[] certificates = ClientLauncherMethods.getCertificates(clazz); if (certificates == null) { throw new SecurityException(String.format("Class %s not signed", clazz.getName())); } diff --git a/Launcher/src/main/java/pro/gravit/launcher/api/ClientService.java b/LauncherClient/src/main/java/pro/gravit/launcher/api/ClientService.java similarity index 100% rename from Launcher/src/main/java/pro/gravit/launcher/api/ClientService.java rename to LauncherClient/src/main/java/pro/gravit/launcher/api/ClientService.java diff --git a/Launcher/src/main/java/pro/gravit/launcher/api/DialogService.java b/LauncherClient/src/main/java/pro/gravit/launcher/api/DialogService.java similarity index 100% rename from Launcher/src/main/java/pro/gravit/launcher/api/DialogService.java rename to LauncherClient/src/main/java/pro/gravit/launcher/api/DialogService.java diff --git a/Launcher/src/main/java/pro/gravit/launcher/api/SystemService.java b/LauncherClient/src/main/java/pro/gravit/launcher/api/SystemService.java similarity index 66% rename from Launcher/src/main/java/pro/gravit/launcher/api/SystemService.java rename to LauncherClient/src/main/java/pro/gravit/launcher/api/SystemService.java index dfdd74b3..9d8aed49 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/api/SystemService.java +++ b/LauncherClient/src/main/java/pro/gravit/launcher/api/SystemService.java @@ -1,6 +1,6 @@ package pro.gravit.launcher.api; -import pro.gravit.launcher.LauncherEngine; +import pro.gravit.launcher.ClientLauncherMethods; public class SystemService { private SystemService() { @@ -8,6 +8,6 @@ private SystemService() { } public static void exit(int code) { - LauncherEngine.exitLauncher(code); + ClientLauncherMethods.exitLauncher(code); } } diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java similarity index 100% rename from Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java rename to LauncherClient/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java diff --git a/Launcher/src/main/java/pro/gravit/launcher/managers/ClientGsonManager.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientGsonManager.java similarity index 68% rename from Launcher/src/main/java/pro/gravit/launcher/managers/ClientGsonManager.java rename to LauncherClient/src/main/java/pro/gravit/launcher/client/ClientGsonManager.java index ef917aae..bcd99ccc 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/managers/ClientGsonManager.java +++ b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientGsonManager.java @@ -1,11 +1,9 @@ -package pro.gravit.launcher.managers; +package pro.gravit.launcher.client; import com.google.gson.GsonBuilder; -import pro.gravit.launcher.client.ClientModuleManager; -import pro.gravit.launcher.client.UserSettings; +import pro.gravit.launcher.managers.GsonManager; import pro.gravit.launcher.modules.events.PreGsonPhase; import pro.gravit.launcher.request.websockets.ClientWebSocketService; -import pro.gravit.utils.UniversalJsonAdapter; public class ClientGsonManager extends GsonManager { private final ClientModuleManager moduleManager; @@ -17,7 +15,6 @@ public ClientGsonManager(ClientModuleManager moduleManager) { @Override public void registerAdapters(GsonBuilder builder) { super.registerAdapters(builder); - builder.registerTypeAdapter(UserSettings.class, new UniversalJsonAdapter<>(UserSettings.providers)); ClientWebSocketService.appendTypeAdapters(builder); moduleManager.invokeEvent(new PreGsonPhase(builder)); } diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherCoreModule.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherCoreModule.java similarity index 100% rename from Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherCoreModule.java rename to LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherCoreModule.java diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java similarity index 79% rename from Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java rename to LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java index 285e94a2..997e1495 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java +++ b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java @@ -4,14 +4,13 @@ import pro.gravit.launcher.api.AuthService; import pro.gravit.launcher.api.ClientService; import pro.gravit.launcher.api.KeyService; +import pro.gravit.launcher.client.events.ClientExitPhase; import pro.gravit.launcher.client.events.client.*; import pro.gravit.launcher.events.request.ProfileByUUIDRequestEvent; import pro.gravit.launcher.events.request.ProfileByUsernameRequestEvent; import pro.gravit.launcher.hasher.FileNameMatcher; import pro.gravit.launcher.hasher.HashedDir; import pro.gravit.launcher.hasher.HashedEntry; -import pro.gravit.launcher.managers.ClientGsonManager; -import pro.gravit.launcher.managers.ConsoleManager; import pro.gravit.launcher.modules.LauncherModulesManager; import pro.gravit.launcher.modules.events.OfflineModeEvent; import pro.gravit.launcher.modules.events.PreConfigPhase; @@ -32,6 +31,7 @@ import pro.gravit.launcher.request.websockets.StdWebSocketService; import pro.gravit.launcher.serialize.HInput; import pro.gravit.launcher.utils.DirWatcher; +import pro.gravit.launcher.utils.NativeJVMHalt; import pro.gravit.utils.helper.*; import java.io.File; @@ -45,6 +45,7 @@ import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; +import java.security.cert.X509Certificate; import java.util.*; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -52,13 +53,15 @@ public class ClientLauncherEntryPoint { private static ClassLoader classLoader; + public static ClientModuleManager modulesManager; + public static ClientParams clientParams; - private static ClientLauncherProcess.ClientParams readParams(SocketAddress address) throws IOException { + private static ClientParams readParams(SocketAddress address) throws IOException { try (Socket socket = IOHelper.newSocket()) { socket.connect(address); try (HInput input = new HInput(socket.getInputStream())) { byte[] serialized = input.readByteArray(0); - ClientLauncherProcess.ClientParams params = Launcher.gsonManager.gson.fromJson(IOHelper.decode(serialized), ClientLauncherProcess.ClientParams.class); + ClientParams params = Launcher.gsonManager.gson.fromJson(IOHelper.decode(serialized), ClientParams.class); params.clientHDir = new HashedDir(input); params.assetHDir = new HashedDir(input); boolean isNeedReadJavaDir = input.readBoolean(); @@ -70,31 +73,26 @@ private static ClientLauncherProcess.ClientParams readParams(SocketAddress addre } public static void main(String[] args) throws Throwable { - LauncherEngine engine = LauncherEngine.clientInstance(); JVMHelper.verifySystemProperties(ClientLauncherEntryPoint.class, true); EnvHelper.checkDangerousParams(); JVMHelper.checkStackTrace(ClientLauncherEntryPoint.class); LogHelper.printVersion("Client Launcher"); - LauncherEngine.checkClass(LauncherEngine.class); - LauncherEngine.checkClass(LauncherAgent.class); - LauncherEngine.checkClass(ClientLauncherEntryPoint.class); - LauncherEngine.modulesManager = new ClientModuleManager(); - LauncherEngine.modulesManager.loadModule(new ClientLauncherCoreModule()); - LauncherConfig.initModules(LauncherEngine.modulesManager); //INIT - LauncherEngine.modulesManager.initModules(null); - initGson(LauncherEngine.modulesManager); - ConsoleManager.initConsole(); - LauncherEngine.modulesManager.invokeEvent(new PreConfigPhase()); - engine.readKeys(); + ClientLauncherMethods.checkClass(ClientLauncherEntryPoint.class); + modulesManager = new ClientModuleManager(); + modulesManager.loadModule(new ClientLauncherCoreModule()); + LauncherConfig.initModules(modulesManager); //INIT + modulesManager.initModules(null); + ClientLauncherMethods.initGson(modulesManager); + modulesManager.invokeEvent(new PreConfigPhase()); LogHelper.debug("Reading ClientLauncher params"); - ClientLauncherProcess.ClientParams params = readParams(new InetSocketAddress("127.0.0.1", Launcher.getConfig().clientPort)); + ClientParams params = readParams(new InetSocketAddress("127.0.0.1", Launcher.getConfig().clientPort)); if (params.profile.getClassLoaderConfig() != ClientProfile.ClassLoaderConfig.AGENT) { - LauncherEngine.verifyNoAgent(); + ClientLauncherMethods.verifyNoAgent(); } ClientProfile profile = params.profile; Launcher.profile = profile; AuthService.profile = profile; - LauncherEngine.clientParams = params; + clientParams = params; if (params.oauth != null) { LogHelper.info("Using OAuth"); if (params.oauthExpiredTime != 0) { @@ -108,7 +106,7 @@ public static void main(String[] args) throws Throwable { } else if (params.session != null) { throw new UnsupportedOperationException("Legacy session not supported"); } - LauncherEngine.modulesManager.invokeEvent(new ClientProcessInitPhase(engine, params)); + modulesManager.invokeEvent(new ClientProcessInitPhase(params)); Path clientDir = Paths.get(params.clientDir); Path assetDir = Paths.get(params.assetDir); @@ -122,7 +120,7 @@ public static void main(String[] args) throws Throwable { // Start client with WatchService monitoring RequestService service; if (params.offlineMode) { - service = initOffline(LauncherEngine.modulesManager, params); + service = ClientLauncherMethods.initOffline(modulesManager, params); Request.setRequestService(service); } else { service = StdWebSocketService.initWebSockets(Launcher.getConfig().address).get(); @@ -149,7 +147,7 @@ public static void main(String[] args) throws Throwable { ClientLauncherEntryPoint.classLoader = classLoader; Thread.currentThread().setContextClassLoader(classLoader); classLoader.nativePath = params.nativesDir; - LauncherEngine.modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(engine, classLoader, profile)); + modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(classLoader, profile)); ClientService.classLoader = classLoader; ClientService.nativePath = classLoader.nativePath; classLoader.addURL(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL()); @@ -162,7 +160,7 @@ public static void main(String[] args) throws Throwable { } ClientService.instrumentation = LauncherAgent.inst; ClientService.nativePath = params.nativesDir; - LauncherEngine.modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(engine, classLoader, profile)); + modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(classLoader, profile)); ClientService.classLoader = classLoader; ClientService.baseURLs = classpathURLs.toArray(new URL[0]); } else if (classLoaderConfig == ClientProfile.ClassLoaderConfig.SYSTEM_ARGS) { @@ -174,7 +172,7 @@ public static void main(String[] args) throws Throwable { AuthService.username = params.playerProfile.username; AuthService.uuid = params.playerProfile.uuid; KeyService.serverRsaPublicKey = Launcher.getConfig().rsaPublicKey; - LauncherEngine.modulesManager.invokeEvent(new ClientProcessReadyEvent(engine, params)); + modulesManager.invokeEvent(new ClientProcessReadyEvent(params)); LogHelper.debug("Starting JVM and client WatchService"); FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher(); FileNameMatcher clientMatcher = profile.getClientUpdateMatcher(); @@ -197,44 +195,11 @@ public static void main(String[] args) throws Throwable { verifyHDir(clientDir, params.clientHDir, clientMatcher, false, true); if (javaWatcher != null) verifyHDir(javaDir, params.javaHDir, null, false, true); - LauncherEngine.modulesManager.invokeEvent(new ClientProcessLaunchEvent(engine, params)); + modulesManager.invokeEvent(new ClientProcessLaunchEvent(params)); launch(profile, params); } } - private static void initGson(ClientModuleManager moduleManager) { - AuthRequest.registerProviders(); - GetAvailabilityAuthRequest.registerProviders(); - OptionalAction.registerProviders(); - OptionalTrigger.registerProviders(); - Launcher.gsonManager = new ClientGsonManager(moduleManager); - Launcher.gsonManager.initGson(); - } - - public static RequestService initOffline(LauncherModulesManager modulesManager, ClientLauncherProcess.ClientParams params) { - OfflineRequestService service = new OfflineRequestService(); - LauncherEngine.applyBasicOfflineProcessors(service); - applyClientOfflineProcessors(service, params); - OfflineModeEvent event = new OfflineModeEvent(service); - modulesManager.invokeEvent(event); - return event.service; - } - - public static void applyClientOfflineProcessors(OfflineRequestService service, ClientLauncherProcess.ClientParams params) { - service.registerRequestProcessor(ProfileByUsernameRequest.class, (r) -> { - if (params.playerProfile.username.equals(r.username)) { - return new ProfileByUsernameRequestEvent(params.playerProfile); - } - throw new RequestException("User not found"); - }); - service.registerRequestProcessor(ProfileByUUIDRequest.class, (r) -> { - if (params.playerProfile.uuid.equals(r.uuid)) { - return new ProfileByUUIDRequestEvent(params.playerProfile); - } - throw new RequestException("User not found"); - }); - } - public static void verifyHDir(Path dir, HashedDir hdir, FileNameMatcher matcher, boolean digest, boolean checkExtra) throws IOException { //if (matcher != null) // matcher = matcher.verifyOnly(); @@ -288,7 +253,7 @@ public static Stream resolveClassPath(Path clientDir, Set return result; } - private static void launch(ClientProfile profile, ClientLauncherProcess.ClientParams params) throws Throwable { + private static void launch(ClientProfile profile, ClientParams params) throws Throwable { // Add client args Collection args = new LinkedList<>(); if (profile.getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0) @@ -318,7 +283,7 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa LogHelper.dev("ClassLoader URL: %s", u.toString()); } } - LauncherEngine.modulesManager.invokeEvent(new ClientProcessPreInvokeMainClassEvent(params, profile, args)); + modulesManager.invokeEvent(new ClientProcessPreInvokeMainClassEvent(params, profile, args)); // Invoke main method try { { @@ -338,7 +303,7 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa LogHelper.error(e); throw e; } finally { - LauncherEngine.exitLauncher(0); + ClientLauncherMethods.exitLauncher(0); } } diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientModuleManager.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientModuleManager.java similarity index 76% rename from Launcher/src/main/java/pro/gravit/launcher/client/ClientModuleManager.java rename to LauncherClient/src/main/java/pro/gravit/launcher/client/ClientModuleManager.java index 62df10ca..648685e7 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientModuleManager.java +++ b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientModuleManager.java @@ -1,6 +1,5 @@ package pro.gravit.launcher.client; -import pro.gravit.launcher.ClientLauncherWrapper; import pro.gravit.launcher.Launcher; import pro.gravit.launcher.LauncherTrustManager; import pro.gravit.launcher.modules.LauncherModule; @@ -38,12 +37,4 @@ public List getModules() { public final boolean verifyClassCheckResult(LauncherTrustManager.CheckClassResult result) { return result.type == LauncherTrustManager.CheckClassResultType.SUCCESS; } - - public void callWrapper(ClientLauncherWrapper.ClientLauncherWrapperContext context) { - for (LauncherModule module : modules) { - if (module instanceof ClientWrapperModule) { - ((ClientWrapperModule) module).wrapperPhase(context); - } - } - } } diff --git a/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientParams.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientParams.java new file mode 100644 index 00000000..89876c7b --- /dev/null +++ b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientParams.java @@ -0,0 +1,130 @@ +package pro.gravit.launcher.client; + +import pro.gravit.launcher.Launcher; +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.actions.OptionalAction; +import pro.gravit.launcher.profiles.optional.actions.OptionalActionClientArgs; +import pro.gravit.utils.Version; + +import java.util.*; + +public class ClientParams { + public String assetDir; + + public String clientDir; + + public String resourcePackDir; + + public String nativesDir; + + // Client params + + public PlayerProfile playerProfile; + + public ClientProfile profile; + + public String accessToken; + + //==Minecraft params== + + public boolean autoEnter; + + public boolean fullScreen; + + public int ram; + + public int width; + + public int height; + + public Set actions = new HashSet<>(); + + //======== + + public UUID session; + + public AuthRequestEvent.OAuthRequestEvent oauth; + + public String authId; + + public long oauthExpiredTime; + + public Map extendedTokens; + + public boolean offlineMode; + + public transient HashedDir assetHDir; + + public transient HashedDir clientHDir; + + public transient HashedDir javaHDir; + + public void addClientArgs(Collection args) { + if (profile.getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0) + addModernClientArgs(args); + else + addClientLegacyArgs(args); + } + + public void addClientLegacyArgs(Collection args) { + args.add(playerProfile.username); + args.add(accessToken); + + // Add args for tweaker + Collections.addAll(args, "--version", profile.getVersion().toString()); + Collections.addAll(args, "--gameDir", clientDir); + Collections.addAll(args, "--assetsDir", assetDir); + } + + private void addModernClientArgs(Collection args) { + + // Add version-dependent args + ClientProfile.Version version = profile.getVersion(); + Collections.addAll(args, "--username", playerProfile.username); + 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(ClientProfileVersions.MINECRAFT_1_7_10) >= 0) { + // Add user properties + Collections.addAll(args, "--userType", "mojang"); + Collections.addAll(args, "--userProperties", "{}"); + + // Add asset index + Collections.addAll(args, "--assetIndex", profile.getAssetIndex()); + } + } else + Collections.addAll(args, "--session", accessToken); + + // Add version and dirs args + 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(ClientProfileVersions.MINECRAFT_1_9_4) >= 0) + Collections.addAll(args, "--versionType", "Launcher v" + Version.getVersion().getVersionString()); + + // Add server args + if (autoEnter) { + Collections.addAll(args, "--server", profile.getServerAddress()); + Collections.addAll(args, "--port", Integer.toString(profile.getServerPort())); + } + for (OptionalAction a : actions) { + if (a instanceof OptionalActionClientArgs) { + args.addAll(((OptionalActionClientArgs) a).args); + } + } + // Add window size args + if (fullScreen) + Collections.addAll(args, "--fullscreen", Boolean.toString(true)); + if (width > 0 && height > 0) { + Collections.addAll(args, "--width", Integer.toString(width)); + Collections.addAll(args, "--height", Integer.toString(height)); + } + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/DirBridge.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/DirBridge.java similarity index 100% rename from Launcher/src/main/java/pro/gravit/launcher/client/DirBridge.java rename to LauncherClient/src/main/java/pro/gravit/launcher/client/DirBridge.java diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/ClientExitPhase.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/events/ClientExitPhase.java similarity index 100% rename from Launcher/src/main/java/pro/gravit/launcher/client/events/ClientExitPhase.java rename to LauncherClient/src/main/java/pro/gravit/launcher/client/events/ClientExitPhase.java diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessClassLoaderEvent.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessClassLoaderEvent.java similarity index 60% rename from Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessClassLoaderEvent.java rename to LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessClassLoaderEvent.java index 3cffc0aa..9a97c1e7 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessClassLoaderEvent.java +++ b/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessClassLoaderEvent.java @@ -1,16 +1,13 @@ package pro.gravit.launcher.client.events.client; -import pro.gravit.launcher.LauncherEngine; import pro.gravit.launcher.modules.LauncherModule; import pro.gravit.launcher.profiles.ClientProfile; public class ClientProcessClassLoaderEvent extends LauncherModule.Event { - public final LauncherEngine clientInstance; public final ClassLoader clientClassLoader; public final ClientProfile profile; - public ClientProcessClassLoaderEvent(LauncherEngine clientInstance, ClassLoader clientClassLoader, ClientProfile profile) { - this.clientInstance = clientInstance; + public ClientProcessClassLoaderEvent(ClassLoader clientClassLoader, ClientProfile profile) { this.clientClassLoader = clientClassLoader; this.profile = profile; } diff --git a/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessInitPhase.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessInitPhase.java new file mode 100644 index 00000000..613d696f --- /dev/null +++ b/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessInitPhase.java @@ -0,0 +1,12 @@ +package pro.gravit.launcher.client.events.client; + +import pro.gravit.launcher.client.ClientParams; +import pro.gravit.launcher.modules.events.InitPhase; + +public class ClientProcessInitPhase extends InitPhase { + public final ClientParams params; + + public ClientProcessInitPhase(ClientParams params) { + this.params = params; + } +} diff --git a/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessLaunchEvent.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessLaunchEvent.java new file mode 100644 index 00000000..c43a9c5c --- /dev/null +++ b/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessLaunchEvent.java @@ -0,0 +1,12 @@ +package pro.gravit.launcher.client.events.client; + +import pro.gravit.launcher.client.ClientParams; +import pro.gravit.launcher.modules.LauncherModule; + +public class ClientProcessLaunchEvent extends LauncherModule.Event { + public final ClientParams params; + + public ClientProcessLaunchEvent(ClientParams params) { + this.params = params; + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessPreInvokeMainClassEvent.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessPreInvokeMainClassEvent.java similarity index 63% rename from Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessPreInvokeMainClassEvent.java rename to LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessPreInvokeMainClassEvent.java index 0ac25094..731f2c84 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessPreInvokeMainClassEvent.java +++ b/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessPreInvokeMainClassEvent.java @@ -1,17 +1,17 @@ package pro.gravit.launcher.client.events.client; -import pro.gravit.launcher.client.ClientLauncherProcess; +import pro.gravit.launcher.client.ClientParams; import pro.gravit.launcher.modules.LauncherModule; import pro.gravit.launcher.profiles.ClientProfile; import java.util.Collection; public class ClientProcessPreInvokeMainClassEvent extends LauncherModule.Event { - public final ClientLauncherProcess.ClientParams params; + public final ClientParams params; public final ClientProfile profile; public final Collection args; - public ClientProcessPreInvokeMainClassEvent(ClientLauncherProcess.ClientParams params, ClientProfile profile, Collection args) { + public ClientProcessPreInvokeMainClassEvent(ClientParams params, ClientProfile profile, Collection args) { this.params = params; this.profile = profile; this.args = args; diff --git a/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessReadyEvent.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessReadyEvent.java new file mode 100644 index 00000000..574814a6 --- /dev/null +++ b/LauncherClient/src/main/java/pro/gravit/launcher/client/events/client/ClientProcessReadyEvent.java @@ -0,0 +1,12 @@ +package pro.gravit.launcher.client.events.client; + +import pro.gravit.launcher.client.ClientParams; +import pro.gravit.launcher.modules.events.PostInitPhase; + +public class ClientProcessReadyEvent extends PostInitPhase { + public final ClientParams params; + + public ClientProcessReadyEvent(ClientParams params) { + this.params = params; + } +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/utils/ApiBridgeService.java b/LauncherClient/src/main/java/pro/gravit/launcher/utils/ApiBridgeService.java similarity index 100% rename from Launcher/src/main/java/pro/gravit/launcher/utils/ApiBridgeService.java rename to LauncherClient/src/main/java/pro/gravit/launcher/utils/ApiBridgeService.java diff --git a/Launcher/src/main/java/pro/gravit/launcher/utils/DirWatcher.java b/LauncherClient/src/main/java/pro/gravit/launcher/utils/DirWatcher.java similarity index 96% rename from Launcher/src/main/java/pro/gravit/launcher/utils/DirWatcher.java rename to LauncherClient/src/main/java/pro/gravit/launcher/utils/DirWatcher.java index 84107d9b..8469d64e 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/utils/DirWatcher.java +++ b/LauncherClient/src/main/java/pro/gravit/launcher/utils/DirWatcher.java @@ -1,6 +1,7 @@ package pro.gravit.launcher.utils; -import pro.gravit.launcher.LauncherEngine; +import pro.gravit.launcher.ClientLauncherMethods; +import pro.gravit.launcher.client.ClientLauncherEntryPoint; import pro.gravit.launcher.hasher.FileNameMatcher; import pro.gravit.launcher.hasher.HashedDir; import pro.gravit.launcher.hasher.HashedEntry; @@ -47,7 +48,7 @@ public DirWatcher(Path dir, HashedDir hdir, FileNameMatcher matcher, boolean dig private static void handleError(Throwable e) { LogHelper.error(e); - LauncherEngine.exitLauncher(-123); + ClientLauncherMethods.exitLauncher(-123); } private static Deque toPath(Iterable path) { diff --git a/Launcher/src/main/java/pro/gravit/launcher/utils/NativeJVMHalt.java b/LauncherClient/src/main/java/pro/gravit/launcher/utils/NativeJVMHalt.java similarity index 100% rename from Launcher/src/main/java/pro/gravit/launcher/utils/NativeJVMHalt.java rename to LauncherClient/src/main/java/pro/gravit/launcher/utils/NativeJVMHalt.java diff --git a/LauncherCore/src/main/java/pro/gravit/utils/Version.java b/LauncherCore/src/main/java/pro/gravit/utils/Version.java index 9251cf19..712f06ee 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 = 4; - public static final int PATCH = 4; + public static final int MINOR = 5; + public static final int PATCH = 0; public static final int BUILD = 1; - public static final Version.Type RELEASE = Type.STABLE; + public static final Version.Type RELEASE = Type.EXPERIMENTAL; public final int major; public final int minor; public final int patch; diff --git a/LauncherStart/build.gradle b/LauncherStart/build.gradle new file mode 100644 index 00000000..511567d1 --- /dev/null +++ b/LauncherStart/build.gradle @@ -0,0 +1,80 @@ +apply plugin: 'org.openjfx.javafxplugin' + +String mainClassName = "pro.gravit.launcher.ClientLauncherWrapper" +String mainAgentName = "pro.gravit.launcher.LauncherAgent" + +repositories { + maven { + url "https://repo.spring.io/plugins-release/" + } +} +sourceCompatibility = '1.8' +targetCompatibility = '1.8' + +jar { + archiveClassifier.set('clean') + manifest.attributes("Main-Class": mainClassName, + "Premain-Class": mainAgentName, + "Multi-Release": "true") +} + +tasks.register('sourcesJar', Jar) { + from sourceSets.main.allJava + archiveClassifier.set('sources') +} + +tasks.register('javadocJar', Jar) { + from javadoc + archiveClassifier.set('javadoc') +} + +dependencies { + implementation project(':LauncherAPI') + implementation project(':LauncherClient') +} + +publishing { + publications { + launcherclientstart(MavenPublication) { + artifactId = 'launcher-client-start-api' + artifact(jar) { + classifier "" + } + artifact sourcesJar + artifact javadocJar + pom { + name = 'GravitLauncher Client API' + description = 'GravitLauncher Client Module API' + url = 'https://gravitlauncher.com' + licenses { + license { + name = 'GNU General Public License, Version 3.0' + url = 'https://www.gnu.org/licenses/gpl-3.0.html' + } + } + developers { + developer { + id = 'gravita' + name = 'Gravita' + email = 'gravita@gravit.pro' + } + developer { + id = 'zaxar163' + name = 'Zaxar163' + email = 'zahar.vcherachny@yandex.ru' + } + } + scm { + connection = 'scm:git:https://github.com/GravitLauncher/Launcher.git' + developerConnection = 'scm:git:ssh://git@github.com:GravitLauncher/Launcher.git' + url = 'https://gravitlauncher.com/' + } + } + } + } +} + + +signing { + sign publishing.publications.launcherclientapi +} diff --git a/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java b/LauncherStart/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java similarity index 95% rename from Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java rename to LauncherStart/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java index 4e35838e..e9f4fe78 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java +++ b/LauncherStart/src/main/java/pro/gravit/launcher/ClientLauncherWrapper.java @@ -1,6 +1,6 @@ package pro.gravit.launcher; -import pro.gravit.launcher.client.ClientModuleManager; +import pro.gravit.launcher.client.RuntimeModuleManager; import pro.gravit.launcher.client.DirBridge; import pro.gravit.launcher.utils.DirWatcher; import pro.gravit.utils.helper.*; @@ -22,6 +22,7 @@ public class ClientLauncherWrapper { public static int launcherMemoryLimit; @LauncherInject("launcher.customJvmOptions") public static List customJvmOptions; + public static RuntimeModuleManager modulesManager; public static void main(String[] arguments) throws IOException, InterruptedException { LogHelper.printVersion("Launcher"); @@ -30,8 +31,8 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep JVMHelper.verifySystemProperties(Launcher.class, true); EnvHelper.checkDangerousParams(); LauncherConfig config = Launcher.getConfig(); - LauncherEngine.modulesManager = new ClientModuleManager(); - LauncherConfig.initModules(LauncherEngine.modulesManager); + modulesManager = new RuntimeModuleManager(); + LauncherConfig.initModules(modulesManager); LogHelper.info("Launcher for project %s", config.projectName); if (config.environment.equals(LauncherConfig.LauncherEnvironment.PROD)) { @@ -83,8 +84,8 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep } context.executePath = IOHelper.resolveJavaBin(context.javaVersion.jvmDir); - String pathLauncher = IOHelper.getCodeSource(LauncherEngine.class).toString(); - context.mainClass = LauncherEngine.class.getName(); + String pathLauncher = IOHelper.getCodeSource(ClientLauncherWrapper.class).toString(); + context.mainClass = "pro.gravit.launcher.LauncherEngineWrapper"; context.memoryLimit = launcherMemoryLimit; context.classpath.add(pathLauncher); context.jvmProperties.put(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())); @@ -104,7 +105,7 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep context.args.add(MAGIC_ARG); context.args.add("-XX:+DisableAttachMechanism"); EnvHelper.addEnv(context.processBuilder); - LauncherEngine.modulesManager.callWrapper(context); + modulesManager.callWrapper(context); // --------- List args = new ArrayList<>(16); args.add(context.executePath.toAbsolutePath().toString()); diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientWrapperModule.java b/LauncherStart/src/main/java/pro/gravit/launcher/ClientWrapperModule.java similarity index 83% rename from Launcher/src/main/java/pro/gravit/launcher/client/ClientWrapperModule.java rename to LauncherStart/src/main/java/pro/gravit/launcher/ClientWrapperModule.java index 73e726d6..6c4feafb 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientWrapperModule.java +++ b/LauncherStart/src/main/java/pro/gravit/launcher/ClientWrapperModule.java @@ -1,4 +1,4 @@ -package pro.gravit.launcher.client; +package pro.gravit.launcher; import pro.gravit.launcher.ClientLauncherWrapper; diff --git a/LauncherStart/src/main/java/pro/gravit/launcher/client/RuntimeModuleManager.java b/LauncherStart/src/main/java/pro/gravit/launcher/client/RuntimeModuleManager.java new file mode 100644 index 00000000..c3f92075 --- /dev/null +++ b/LauncherStart/src/main/java/pro/gravit/launcher/client/RuntimeModuleManager.java @@ -0,0 +1,50 @@ +package pro.gravit.launcher.client; + +import pro.gravit.launcher.ClientLauncherWrapper; +import pro.gravit.launcher.ClientWrapperModule; +import pro.gravit.launcher.Launcher; +import pro.gravit.launcher.LauncherTrustManager; +import pro.gravit.launcher.modules.LauncherModule; +import pro.gravit.launcher.modules.impl.SimpleModuleManager; + +import java.nio.file.Path; +import java.util.Collections; +import java.util.List; + +public final class RuntimeModuleManager extends SimpleModuleManager { + public RuntimeModuleManager() { + super(null, null, Launcher.getConfig().trustManager); + } + + @Override + public void autoload() { + throw new UnsupportedOperationException(); + } + + @Override + public void autoload(Path dir) { + throw new UnsupportedOperationException(); + } + + @Override + public LauncherModule loadModule(LauncherModule module) { + return super.loadModule(module); + } + + public List getModules() { + return Collections.unmodifiableList(modules); + } + + @Override + public final boolean verifyClassCheckResult(LauncherTrustManager.CheckClassResult result) { + return result.type == LauncherTrustManager.CheckClassResultType.SUCCESS; + } + + public void callWrapper(ClientLauncherWrapper.ClientLauncherWrapperContext context) { + for (LauncherModule module : modules) { + if (module instanceof ClientWrapperModule) { + ((ClientWrapperModule) module).wrapperPhase(context); + } + } + } +} diff --git a/build.gradle b/build.gradle index 9b320def..049b56d2 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.4' +version = '5.5.0-SNAPSHOT' apply from: 'props.gradle' diff --git a/settings.gradle b/settings.gradle index 49181b91..dfdf4434 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,6 +3,8 @@ include 'Launcher' include 'LauncherCore' include 'LauncherAPI' +include 'LauncherClient' +include 'LauncherStart' include 'ServerWrapper' include 'LaunchServer' include 'modules'