mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 03:31:15 +03:00
[FEATURE][EXPERIMENTAL] separate branch
This commit is contained in:
parent
4d1fd23e84
commit
9de81095b1
46 changed files with 638 additions and 324 deletions
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"features": [],
|
"features": ["separate"],
|
||||||
"info": []
|
"info": []
|
||||||
}
|
}
|
|
@ -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.**
|
-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 {
|
||||||
*;
|
*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,8 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
pack project(':LauncherAPI')
|
pack project(':LauncherAPI')
|
||||||
|
pack project(':LauncherClient')
|
||||||
|
pack project(':LauncherStart')
|
||||||
bundle group: 'com.github.oshi', name: 'oshi-core', version: rootProject['verOshiCore']
|
bundle group: 'com.github.oshi', name: 'oshi-core', version: rootProject['verOshiCore']
|
||||||
pack group: 'io.netty', name: 'netty-codec-http', version: rootProject['verNetty']
|
pack group: 'io.netty', name: 'netty-codec-http', version: rootProject['verNetty']
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
import pro.gravit.launcher.events.request.*;
|
import pro.gravit.launcher.events.request.*;
|
||||||
import pro.gravit.launcher.gui.NoRuntimeProvider;
|
import pro.gravit.launcher.gui.NoRuntimeProvider;
|
||||||
import pro.gravit.launcher.gui.RuntimeProvider;
|
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.managers.ConsoleManager;
|
||||||
import pro.gravit.launcher.modules.events.OfflineModeEvent;
|
import pro.gravit.launcher.modules.events.OfflineModeEvent;
|
||||||
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
||||||
|
@ -45,8 +45,8 @@
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class LauncherEngine {
|
public class LauncherEngine {
|
||||||
public static ClientLauncherProcess.ClientParams clientParams;
|
public static ClientParams clientParams;
|
||||||
public static ClientModuleManager modulesManager;
|
public static RuntimeModuleManager modulesManager;
|
||||||
public final boolean clientInstance;
|
public final boolean clientInstance;
|
||||||
// Instance
|
// Instance
|
||||||
private final AtomicBoolean started = new AtomicBoolean(false);
|
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 {
|
public static void main(String... args) throws Throwable {
|
||||||
JVMHelper.checkStackTrace(LauncherEngine.class);
|
JVMHelper.checkStackTrace(LauncherEngineWrapper.class);
|
||||||
JVMHelper.verifySystemProperties(Launcher.class, true);
|
JVMHelper.verifySystemProperties(Launcher.class, true);
|
||||||
EnvHelper.checkDangerousParams();
|
EnvHelper.checkDangerousParams();
|
||||||
//if(!LauncherAgent.isStarted()) throw new SecurityException("JavaAgent not set");
|
//if(!LauncherAgent.isStarted()) throw new SecurityException("JavaAgent not set");
|
||||||
verifyNoAgent();
|
verifyNoAgent();
|
||||||
LogHelper.printVersion("Launcher");
|
LogHelper.printVersion("Launcher");
|
||||||
LogHelper.printLicense("Launcher");
|
LogHelper.printLicense("Launcher");
|
||||||
|
LauncherEngine.checkClass(LauncherEngineWrapper.class);
|
||||||
LauncherEngine.checkClass(LauncherEngine.class);
|
LauncherEngine.checkClass(LauncherEngine.class);
|
||||||
LauncherEngine.checkClass(LauncherAgent.class);
|
LauncherEngine.checkClass(LauncherAgent.class);
|
||||||
LauncherEngine.checkClass(ClientLauncherEntryPoint.class);
|
LauncherEngine.checkClass(ClientLauncherEntryPoint.class);
|
||||||
LauncherEngine.modulesManager = new ClientModuleManager();
|
LauncherEngine.modulesManager = new RuntimeModuleManager();
|
||||||
LauncherEngine.modulesManager.loadModule(new ClientLauncherCoreModule());
|
LauncherEngine.modulesManager.loadModule(new RuntimeLauncherCoreModule());
|
||||||
LauncherConfig.initModules(LauncherEngine.modulesManager);
|
LauncherConfig.initModules(LauncherEngine.modulesManager);
|
||||||
LauncherEngine.modulesManager.initModules(null);
|
LauncherEngine.modulesManager.initModules(null);
|
||||||
// Start Launcher
|
// Start Launcher
|
||||||
|
@ -133,12 +134,12 @@ public static void main(String... args) throws Throwable {
|
||||||
LauncherEngine.exitLauncher(0);
|
LauncherEngine.exitLauncher(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initGson(ClientModuleManager modulesManager) {
|
public static void initGson(RuntimeModuleManager modulesManager) {
|
||||||
AuthRequest.registerProviders();
|
AuthRequest.registerProviders();
|
||||||
GetAvailabilityAuthRequest.registerProviders();
|
GetAvailabilityAuthRequest.registerProviders();
|
||||||
OptionalAction.registerProviders();
|
OptionalAction.registerProviders();
|
||||||
OptionalTrigger.registerProviders();
|
OptionalTrigger.registerProviders();
|
||||||
Launcher.gsonManager = new ClientGsonManager(modulesManager);
|
Launcher.gsonManager = new RuntimeGsonManager(modulesManager);
|
||||||
Launcher.gsonManager.initGson();
|
Launcher.gsonManager.initGson();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,37 +150,12 @@ public static void verifyNoAgent() {
|
||||||
|
|
||||||
public static RequestService initOffline() {
|
public static RequestService initOffline() {
|
||||||
OfflineRequestService service = new OfflineRequestService();
|
OfflineRequestService service = new OfflineRequestService();
|
||||||
applyBasicOfflineProcessors(service);
|
ClientLauncherMethods.applyBasicOfflineProcessors(service);
|
||||||
OfflineModeEvent event = new OfflineModeEvent(service);
|
OfflineModeEvent event = new OfflineModeEvent(service);
|
||||||
modulesManager.invokeEvent(event);
|
modulesManager.invokeEvent(event);
|
||||||
return event.service;
|
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<GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails> details = new ArrayList<>();
|
|
||||||
details.add(new AuthLoginOnlyDetails());
|
|
||||||
GetAvailabilityAuthRequestEvent.AuthAvailability authAvailability = new GetAvailabilityAuthRequestEvent.AuthAvailability("offline", "Offline Mode", true, details);
|
|
||||||
List<GetAvailabilityAuthRequestEvent.AuthAvailability> 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) {
|
public static LauncherEngine newInstance(boolean clientInstance) {
|
||||||
return new LauncherEngine(clientInstance);
|
return new LauncherEngine(clientInstance);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package pro.gravit.launcher;
|
||||||
|
|
||||||
|
@LauncherNetworkAPI
|
||||||
|
public class LauncherEngineWrapper {
|
||||||
|
public static void main(String[] args) throws Throwable {
|
||||||
|
LauncherEngine.main(args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,18 +7,14 @@
|
||||||
import pro.gravit.launcher.client.events.client.ClientProcessBuilderLaunchedEvent;
|
import pro.gravit.launcher.client.events.client.ClientProcessBuilderLaunchedEvent;
|
||||||
import pro.gravit.launcher.client.events.client.ClientProcessBuilderParamsWrittedEvent;
|
import pro.gravit.launcher.client.events.client.ClientProcessBuilderParamsWrittedEvent;
|
||||||
import pro.gravit.launcher.client.events.client.ClientProcessBuilderPreLaunchEvent;
|
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.hasher.HashedDir;
|
||||||
import pro.gravit.launcher.profiles.ClientProfile;
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
import pro.gravit.launcher.profiles.ClientProfileVersions;
|
|
||||||
import pro.gravit.launcher.profiles.PlayerProfile;
|
import pro.gravit.launcher.profiles.PlayerProfile;
|
||||||
import pro.gravit.launcher.profiles.optional.OptionalView;
|
import pro.gravit.launcher.profiles.optional.OptionalView;
|
||||||
import pro.gravit.launcher.profiles.optional.actions.OptionalAction;
|
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.profiles.optional.actions.OptionalActionJvmArgs;
|
||||||
import pro.gravit.launcher.request.Request;
|
import pro.gravit.launcher.request.Request;
|
||||||
import pro.gravit.launcher.serialize.HOutput;
|
import pro.gravit.launcher.serialize.HOutput;
|
||||||
import pro.gravit.utils.Version;
|
|
||||||
import pro.gravit.utils.helper.*;
|
import pro.gravit.utils.helper.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -238,120 +234,4 @@ public Process getProcess() {
|
||||||
return process;
|
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<OptionalAction> actions = new HashSet<>();
|
|
||||||
|
|
||||||
//========
|
|
||||||
|
|
||||||
public UUID session;
|
|
||||||
|
|
||||||
public AuthRequestEvent.OAuthRequestEvent oauth;
|
|
||||||
|
|
||||||
public String authId;
|
|
||||||
|
|
||||||
public long oauthExpiredTime;
|
|
||||||
|
|
||||||
public Map<String, String> extendedTokens;
|
|
||||||
|
|
||||||
public boolean offlineMode;
|
|
||||||
|
|
||||||
public transient HashedDir assetHDir;
|
|
||||||
|
|
||||||
public transient HashedDir clientHDir;
|
|
||||||
|
|
||||||
public transient HashedDir javaHDir;
|
|
||||||
|
|
||||||
public void addClientArgs(Collection<String> args) {
|
|
||||||
if (profile.getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0)
|
|
||||||
addModernClientArgs(args);
|
|
||||||
else
|
|
||||||
addClientLegacyArgs(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addClientLegacyArgs(Collection<String> 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<String> 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +1,11 @@
|
||||||
package pro.gravit.launcher.debug;
|
package pro.gravit.launcher.debug;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.ClientLauncherMethods;
|
||||||
import pro.gravit.launcher.Launcher;
|
import pro.gravit.launcher.Launcher;
|
||||||
import pro.gravit.launcher.LauncherConfig;
|
import pro.gravit.launcher.LauncherConfig;
|
||||||
import pro.gravit.launcher.LauncherEngine;
|
import pro.gravit.launcher.LauncherEngine;
|
||||||
import pro.gravit.launcher.client.ClientLauncherCoreModule;
|
import pro.gravit.launcher.client.RuntimeLauncherCoreModule;
|
||||||
import pro.gravit.launcher.client.ClientModuleManager;
|
import pro.gravit.launcher.client.RuntimeModuleManager;
|
||||||
import pro.gravit.launcher.managers.ConsoleManager;
|
import pro.gravit.launcher.managers.ConsoleManager;
|
||||||
import pro.gravit.launcher.modules.LauncherModule;
|
import pro.gravit.launcher.modules.LauncherModule;
|
||||||
import pro.gravit.launcher.modules.events.OfflineModeEvent;
|
import pro.gravit.launcher.modules.events.OfflineModeEvent;
|
||||||
|
@ -42,8 +43,8 @@ public static void main(String[] args) throws Throwable {
|
||||||
config.unlockSecret = unlockSecret;
|
config.unlockSecret = unlockSecret;
|
||||||
Launcher.setConfig(config);
|
Launcher.setConfig(config);
|
||||||
Launcher.applyLauncherEnv(environment);
|
Launcher.applyLauncherEnv(environment);
|
||||||
LauncherEngine.modulesManager = new ClientModuleManager();
|
LauncherEngine.modulesManager = new RuntimeModuleManager();
|
||||||
LauncherEngine.modulesManager.loadModule(new ClientLauncherCoreModule());
|
LauncherEngine.modulesManager.loadModule(new RuntimeLauncherCoreModule());
|
||||||
for (String moduleClassName : moduleClasses) {
|
for (String moduleClassName : moduleClasses) {
|
||||||
if (moduleClassName.isEmpty()) continue;
|
if (moduleClassName.isEmpty()) continue;
|
||||||
LauncherEngine.modulesManager.loadModule(newModule(moduleClassName));
|
LauncherEngine.modulesManager.loadModule(newModule(moduleClassName));
|
||||||
|
@ -59,7 +60,7 @@ public static void main(String[] args) throws Throwable {
|
||||||
RequestService service;
|
RequestService service;
|
||||||
if (offlineMode) {
|
if (offlineMode) {
|
||||||
OfflineRequestService offlineRequestService = new OfflineRequestService();
|
OfflineRequestService offlineRequestService = new OfflineRequestService();
|
||||||
LauncherEngine.applyBasicOfflineProcessors(offlineRequestService);
|
ClientLauncherMethods.applyBasicOfflineProcessors(offlineRequestService);
|
||||||
OfflineModeEvent event = new OfflineModeEvent(offlineRequestService);
|
OfflineModeEvent event = new OfflineModeEvent(offlineRequestService);
|
||||||
LauncherEngine.modulesManager.invokeEvent(event);
|
LauncherEngine.modulesManager.invokeEvent(event);
|
||||||
service = event.service;
|
service = event.service;
|
||||||
|
|
|
@ -22,23 +22,9 @@ public final class Launcher {
|
||||||
|
|
||||||
// Authlib constants
|
// 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
|
// Used to determine from clientside is launched from launcher
|
||||||
public static final AtomicBoolean LAUNCHED = new AtomicBoolean(false);
|
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";
|
public static final String RUNTIME_DIR = "runtime";
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
|
|
|
@ -31,6 +31,7 @@ public enum ReportAction {
|
||||||
LOGOUT,
|
LOGOUT,
|
||||||
TOKEN_EXPIRED,
|
TOKEN_EXPIRED,
|
||||||
EXIT,
|
EXIT,
|
||||||
|
@Deprecated
|
||||||
CRASH,
|
CRASH,
|
||||||
OTHER
|
OTHER
|
||||||
}
|
}
|
||||||
|
|
79
LauncherClient/build.gradle
Normal file
79
LauncherClient/build.gradle
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -15,9 +15,7 @@ public class BasicLauncherEventHandler implements RequestService.EventHandler {
|
||||||
public <T extends WebSocketEvent> boolean eventHandle(T event) {
|
public <T extends WebSocketEvent> boolean eventHandle(T event) {
|
||||||
if (event instanceof SecurityReportRequestEvent) {
|
if (event instanceof SecurityReportRequestEvent) {
|
||||||
SecurityReportRequestEvent event1 = (SecurityReportRequestEvent) event;
|
SecurityReportRequestEvent event1 = (SecurityReportRequestEvent) event;
|
||||||
if (event1.action == SecurityReportRequestEvent.ReportAction.CRASH) {
|
if (event1.action == SecurityReportRequestEvent.ReportAction.TOKEN_EXPIRED) {
|
||||||
LauncherEngine.exitLauncher(80);
|
|
||||||
} else if (event1.action == SecurityReportRequestEvent.ReportAction.TOKEN_EXPIRED) {
|
|
||||||
try {
|
try {
|
||||||
Request.restore();
|
Request.restore();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
|
@ -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<GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails> details = new ArrayList<>();
|
||||||
|
details.add(new AuthLoginOnlyDetails());
|
||||||
|
GetAvailabilityAuthRequestEvent.AuthAvailability authAvailability = new GetAvailabilityAuthRequestEvent.AuthAvailability("offline", "Offline Mode", true, details);
|
||||||
|
List<GetAvailabilityAuthRequestEvent.AuthAvailability> 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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +1,19 @@
|
||||||
package pro.gravit.launcher.api;
|
package pro.gravit.launcher.api;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.ClientLauncherMethods;
|
||||||
import pro.gravit.launcher.LauncherTrustManager;
|
import pro.gravit.launcher.LauncherTrustManager;
|
||||||
|
import pro.gravit.launcher.client.ClientLauncherEntryPoint;
|
||||||
import pro.gravit.launcher.utils.ApiBridgeService;
|
import pro.gravit.launcher.utils.ApiBridgeService;
|
||||||
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
import static pro.gravit.launcher.LauncherEngine.getCertificates;
|
|
||||||
|
|
||||||
public class CertificateService {
|
public class CertificateService {
|
||||||
private CertificateService() {
|
private CertificateService() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CheckClassResultApi checkClass(Class<?> clazz) throws SecurityException {
|
public static CheckClassResultApi checkClass(Class<?> clazz) throws SecurityException {
|
||||||
X509Certificate[] certificates = getCertificates(clazz);
|
X509Certificate[] certificates = ClientLauncherMethods.getCertificates(clazz);
|
||||||
if (certificates == null) {
|
if (certificates == null) {
|
||||||
return new CheckClassResultApi(CheckClassResultTypeApi.NOT_SIGNED, null, 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) {
|
public static void checkClassSuccess(Class<?> clazz) {
|
||||||
X509Certificate[] certificates = getCertificates(clazz);
|
X509Certificate[] certificates = ClientLauncherMethods.getCertificates(clazz);
|
||||||
if (certificates == null) {
|
if (certificates == null) {
|
||||||
throw new SecurityException(String.format("Class %s not signed", clazz.getName()));
|
throw new SecurityException(String.format("Class %s not signed", clazz.getName()));
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package pro.gravit.launcher.api;
|
package pro.gravit.launcher.api;
|
||||||
|
|
||||||
import pro.gravit.launcher.LauncherEngine;
|
import pro.gravit.launcher.ClientLauncherMethods;
|
||||||
|
|
||||||
public class SystemService {
|
public class SystemService {
|
||||||
private SystemService() {
|
private SystemService() {
|
||||||
|
@ -8,6 +8,6 @@ private SystemService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void exit(int code) {
|
public static void exit(int code) {
|
||||||
LauncherEngine.exitLauncher(code);
|
ClientLauncherMethods.exitLauncher(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,11 +1,9 @@
|
||||||
package pro.gravit.launcher.managers;
|
package pro.gravit.launcher.client;
|
||||||
|
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import pro.gravit.launcher.client.ClientModuleManager;
|
import pro.gravit.launcher.managers.GsonManager;
|
||||||
import pro.gravit.launcher.client.UserSettings;
|
|
||||||
import pro.gravit.launcher.modules.events.PreGsonPhase;
|
import pro.gravit.launcher.modules.events.PreGsonPhase;
|
||||||
import pro.gravit.launcher.request.websockets.ClientWebSocketService;
|
import pro.gravit.launcher.request.websockets.ClientWebSocketService;
|
||||||
import pro.gravit.utils.UniversalJsonAdapter;
|
|
||||||
|
|
||||||
public class ClientGsonManager extends GsonManager {
|
public class ClientGsonManager extends GsonManager {
|
||||||
private final ClientModuleManager moduleManager;
|
private final ClientModuleManager moduleManager;
|
||||||
|
@ -17,7 +15,6 @@ public ClientGsonManager(ClientModuleManager moduleManager) {
|
||||||
@Override
|
@Override
|
||||||
public void registerAdapters(GsonBuilder builder) {
|
public void registerAdapters(GsonBuilder builder) {
|
||||||
super.registerAdapters(builder);
|
super.registerAdapters(builder);
|
||||||
builder.registerTypeAdapter(UserSettings.class, new UniversalJsonAdapter<>(UserSettings.providers));
|
|
||||||
ClientWebSocketService.appendTypeAdapters(builder);
|
ClientWebSocketService.appendTypeAdapters(builder);
|
||||||
moduleManager.invokeEvent(new PreGsonPhase(builder));
|
moduleManager.invokeEvent(new PreGsonPhase(builder));
|
||||||
}
|
}
|
|
@ -4,14 +4,13 @@
|
||||||
import pro.gravit.launcher.api.AuthService;
|
import pro.gravit.launcher.api.AuthService;
|
||||||
import pro.gravit.launcher.api.ClientService;
|
import pro.gravit.launcher.api.ClientService;
|
||||||
import pro.gravit.launcher.api.KeyService;
|
import pro.gravit.launcher.api.KeyService;
|
||||||
|
import pro.gravit.launcher.client.events.ClientExitPhase;
|
||||||
import pro.gravit.launcher.client.events.client.*;
|
import pro.gravit.launcher.client.events.client.*;
|
||||||
import pro.gravit.launcher.events.request.ProfileByUUIDRequestEvent;
|
import pro.gravit.launcher.events.request.ProfileByUUIDRequestEvent;
|
||||||
import pro.gravit.launcher.events.request.ProfileByUsernameRequestEvent;
|
import pro.gravit.launcher.events.request.ProfileByUsernameRequestEvent;
|
||||||
import pro.gravit.launcher.hasher.FileNameMatcher;
|
import pro.gravit.launcher.hasher.FileNameMatcher;
|
||||||
import pro.gravit.launcher.hasher.HashedDir;
|
import pro.gravit.launcher.hasher.HashedDir;
|
||||||
import pro.gravit.launcher.hasher.HashedEntry;
|
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.LauncherModulesManager;
|
||||||
import pro.gravit.launcher.modules.events.OfflineModeEvent;
|
import pro.gravit.launcher.modules.events.OfflineModeEvent;
|
||||||
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
||||||
|
@ -32,6 +31,7 @@
|
||||||
import pro.gravit.launcher.request.websockets.StdWebSocketService;
|
import pro.gravit.launcher.request.websockets.StdWebSocketService;
|
||||||
import pro.gravit.launcher.serialize.HInput;
|
import pro.gravit.launcher.serialize.HInput;
|
||||||
import pro.gravit.launcher.utils.DirWatcher;
|
import pro.gravit.launcher.utils.DirWatcher;
|
||||||
|
import pro.gravit.launcher.utils.NativeJVMHalt;
|
||||||
import pro.gravit.utils.helper.*;
|
import pro.gravit.utils.helper.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -45,6 +45,7 @@
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.SimpleFileVisitor;
|
import java.nio.file.SimpleFileVisitor;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -52,13 +53,15 @@
|
||||||
|
|
||||||
public class ClientLauncherEntryPoint {
|
public class ClientLauncherEntryPoint {
|
||||||
private static ClassLoader classLoader;
|
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()) {
|
try (Socket socket = IOHelper.newSocket()) {
|
||||||
socket.connect(address);
|
socket.connect(address);
|
||||||
try (HInput input = new HInput(socket.getInputStream())) {
|
try (HInput input = new HInput(socket.getInputStream())) {
|
||||||
byte[] serialized = input.readByteArray(0);
|
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.clientHDir = new HashedDir(input);
|
||||||
params.assetHDir = new HashedDir(input);
|
params.assetHDir = new HashedDir(input);
|
||||||
boolean isNeedReadJavaDir = input.readBoolean();
|
boolean isNeedReadJavaDir = input.readBoolean();
|
||||||
|
@ -70,31 +73,26 @@ private static ClientLauncherProcess.ClientParams readParams(SocketAddress addre
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Throwable {
|
public static void main(String[] args) throws Throwable {
|
||||||
LauncherEngine engine = LauncherEngine.clientInstance();
|
|
||||||
JVMHelper.verifySystemProperties(ClientLauncherEntryPoint.class, true);
|
JVMHelper.verifySystemProperties(ClientLauncherEntryPoint.class, true);
|
||||||
EnvHelper.checkDangerousParams();
|
EnvHelper.checkDangerousParams();
|
||||||
JVMHelper.checkStackTrace(ClientLauncherEntryPoint.class);
|
JVMHelper.checkStackTrace(ClientLauncherEntryPoint.class);
|
||||||
LogHelper.printVersion("Client Launcher");
|
LogHelper.printVersion("Client Launcher");
|
||||||
LauncherEngine.checkClass(LauncherEngine.class);
|
ClientLauncherMethods.checkClass(ClientLauncherEntryPoint.class);
|
||||||
LauncherEngine.checkClass(LauncherAgent.class);
|
modulesManager = new ClientModuleManager();
|
||||||
LauncherEngine.checkClass(ClientLauncherEntryPoint.class);
|
modulesManager.loadModule(new ClientLauncherCoreModule());
|
||||||
LauncherEngine.modulesManager = new ClientModuleManager();
|
LauncherConfig.initModules(modulesManager); //INIT
|
||||||
LauncherEngine.modulesManager.loadModule(new ClientLauncherCoreModule());
|
modulesManager.initModules(null);
|
||||||
LauncherConfig.initModules(LauncherEngine.modulesManager); //INIT
|
ClientLauncherMethods.initGson(modulesManager);
|
||||||
LauncherEngine.modulesManager.initModules(null);
|
modulesManager.invokeEvent(new PreConfigPhase());
|
||||||
initGson(LauncherEngine.modulesManager);
|
|
||||||
ConsoleManager.initConsole();
|
|
||||||
LauncherEngine.modulesManager.invokeEvent(new PreConfigPhase());
|
|
||||||
engine.readKeys();
|
|
||||||
LogHelper.debug("Reading ClientLauncher params");
|
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) {
|
if (params.profile.getClassLoaderConfig() != ClientProfile.ClassLoaderConfig.AGENT) {
|
||||||
LauncherEngine.verifyNoAgent();
|
ClientLauncherMethods.verifyNoAgent();
|
||||||
}
|
}
|
||||||
ClientProfile profile = params.profile;
|
ClientProfile profile = params.profile;
|
||||||
Launcher.profile = profile;
|
Launcher.profile = profile;
|
||||||
AuthService.profile = profile;
|
AuthService.profile = profile;
|
||||||
LauncherEngine.clientParams = params;
|
clientParams = params;
|
||||||
if (params.oauth != null) {
|
if (params.oauth != null) {
|
||||||
LogHelper.info("Using OAuth");
|
LogHelper.info("Using OAuth");
|
||||||
if (params.oauthExpiredTime != 0) {
|
if (params.oauthExpiredTime != 0) {
|
||||||
|
@ -108,7 +106,7 @@ public static void main(String[] args) throws Throwable {
|
||||||
} else if (params.session != null) {
|
} else if (params.session != null) {
|
||||||
throw new UnsupportedOperationException("Legacy session not supported");
|
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 clientDir = Paths.get(params.clientDir);
|
||||||
Path assetDir = Paths.get(params.assetDir);
|
Path assetDir = Paths.get(params.assetDir);
|
||||||
|
@ -122,7 +120,7 @@ public static void main(String[] args) throws Throwable {
|
||||||
// Start client with WatchService monitoring
|
// Start client with WatchService monitoring
|
||||||
RequestService service;
|
RequestService service;
|
||||||
if (params.offlineMode) {
|
if (params.offlineMode) {
|
||||||
service = initOffline(LauncherEngine.modulesManager, params);
|
service = ClientLauncherMethods.initOffline(modulesManager, params);
|
||||||
Request.setRequestService(service);
|
Request.setRequestService(service);
|
||||||
} else {
|
} else {
|
||||||
service = StdWebSocketService.initWebSockets(Launcher.getConfig().address).get();
|
service = StdWebSocketService.initWebSockets(Launcher.getConfig().address).get();
|
||||||
|
@ -149,7 +147,7 @@ public static void main(String[] args) throws Throwable {
|
||||||
ClientLauncherEntryPoint.classLoader = classLoader;
|
ClientLauncherEntryPoint.classLoader = classLoader;
|
||||||
Thread.currentThread().setContextClassLoader(classLoader);
|
Thread.currentThread().setContextClassLoader(classLoader);
|
||||||
classLoader.nativePath = params.nativesDir;
|
classLoader.nativePath = params.nativesDir;
|
||||||
LauncherEngine.modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(engine, classLoader, profile));
|
modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(classLoader, profile));
|
||||||
ClientService.classLoader = classLoader;
|
ClientService.classLoader = classLoader;
|
||||||
ClientService.nativePath = classLoader.nativePath;
|
ClientService.nativePath = classLoader.nativePath;
|
||||||
classLoader.addURL(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL());
|
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.instrumentation = LauncherAgent.inst;
|
||||||
ClientService.nativePath = params.nativesDir;
|
ClientService.nativePath = params.nativesDir;
|
||||||
LauncherEngine.modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(engine, classLoader, profile));
|
modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(classLoader, profile));
|
||||||
ClientService.classLoader = classLoader;
|
ClientService.classLoader = classLoader;
|
||||||
ClientService.baseURLs = classpathURLs.toArray(new URL[0]);
|
ClientService.baseURLs = classpathURLs.toArray(new URL[0]);
|
||||||
} else if (classLoaderConfig == ClientProfile.ClassLoaderConfig.SYSTEM_ARGS) {
|
} 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.username = params.playerProfile.username;
|
||||||
AuthService.uuid = params.playerProfile.uuid;
|
AuthService.uuid = params.playerProfile.uuid;
|
||||||
KeyService.serverRsaPublicKey = Launcher.getConfig().rsaPublicKey;
|
KeyService.serverRsaPublicKey = Launcher.getConfig().rsaPublicKey;
|
||||||
LauncherEngine.modulesManager.invokeEvent(new ClientProcessReadyEvent(engine, params));
|
modulesManager.invokeEvent(new ClientProcessReadyEvent(params));
|
||||||
LogHelper.debug("Starting JVM and client WatchService");
|
LogHelper.debug("Starting JVM and client WatchService");
|
||||||
FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher();
|
FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher();
|
||||||
FileNameMatcher clientMatcher = profile.getClientUpdateMatcher();
|
FileNameMatcher clientMatcher = profile.getClientUpdateMatcher();
|
||||||
|
@ -197,44 +195,11 @@ public static void main(String[] args) throws Throwable {
|
||||||
verifyHDir(clientDir, params.clientHDir, clientMatcher, false, true);
|
verifyHDir(clientDir, params.clientHDir, clientMatcher, false, true);
|
||||||
if (javaWatcher != null)
|
if (javaWatcher != null)
|
||||||
verifyHDir(javaDir, params.javaHDir, null, false, true);
|
verifyHDir(javaDir, params.javaHDir, null, false, true);
|
||||||
LauncherEngine.modulesManager.invokeEvent(new ClientProcessLaunchEvent(engine, params));
|
modulesManager.invokeEvent(new ClientProcessLaunchEvent(params));
|
||||||
launch(profile, 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 {
|
public static void verifyHDir(Path dir, HashedDir hdir, FileNameMatcher matcher, boolean digest, boolean checkExtra) throws IOException {
|
||||||
//if (matcher != null)
|
//if (matcher != null)
|
||||||
// matcher = matcher.verifyOnly();
|
// matcher = matcher.verifyOnly();
|
||||||
|
@ -288,7 +253,7 @@ public static Stream<Path> resolveClassPath(Path clientDir, Set<OptionalAction>
|
||||||
return result;
|
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
|
// Add client args
|
||||||
Collection<String> args = new LinkedList<>();
|
Collection<String> args = new LinkedList<>();
|
||||||
if (profile.getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0)
|
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());
|
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
|
// Invoke main method
|
||||||
try {
|
try {
|
||||||
{
|
{
|
||||||
|
@ -338,7 +303,7 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
LauncherEngine.exitLauncher(0);
|
ClientLauncherMethods.exitLauncher(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package pro.gravit.launcher.client;
|
package pro.gravit.launcher.client;
|
||||||
|
|
||||||
import pro.gravit.launcher.ClientLauncherWrapper;
|
|
||||||
import pro.gravit.launcher.Launcher;
|
import pro.gravit.launcher.Launcher;
|
||||||
import pro.gravit.launcher.LauncherTrustManager;
|
import pro.gravit.launcher.LauncherTrustManager;
|
||||||
import pro.gravit.launcher.modules.LauncherModule;
|
import pro.gravit.launcher.modules.LauncherModule;
|
||||||
|
@ -38,12 +37,4 @@ public List<LauncherModule> getModules() {
|
||||||
public final boolean verifyClassCheckResult(LauncherTrustManager.CheckClassResult result) {
|
public final boolean verifyClassCheckResult(LauncherTrustManager.CheckClassResult result) {
|
||||||
return result.type == LauncherTrustManager.CheckClassResultType.SUCCESS;
|
return result.type == LauncherTrustManager.CheckClassResultType.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void callWrapper(ClientLauncherWrapper.ClientLauncherWrapperContext context) {
|
|
||||||
for (LauncherModule module : modules) {
|
|
||||||
if (module instanceof ClientWrapperModule) {
|
|
||||||
((ClientWrapperModule) module).wrapperPhase(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -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<OptionalAction> actions = new HashSet<>();
|
||||||
|
|
||||||
|
//========
|
||||||
|
|
||||||
|
public UUID session;
|
||||||
|
|
||||||
|
public AuthRequestEvent.OAuthRequestEvent oauth;
|
||||||
|
|
||||||
|
public String authId;
|
||||||
|
|
||||||
|
public long oauthExpiredTime;
|
||||||
|
|
||||||
|
public Map<String, String> extendedTokens;
|
||||||
|
|
||||||
|
public boolean offlineMode;
|
||||||
|
|
||||||
|
public transient HashedDir assetHDir;
|
||||||
|
|
||||||
|
public transient HashedDir clientHDir;
|
||||||
|
|
||||||
|
public transient HashedDir javaHDir;
|
||||||
|
|
||||||
|
public void addClientArgs(Collection<String> args) {
|
||||||
|
if (profile.getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_6_4) >= 0)
|
||||||
|
addModernClientArgs(args);
|
||||||
|
else
|
||||||
|
addClientLegacyArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addClientLegacyArgs(Collection<String> 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<String> 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +1,13 @@
|
||||||
package pro.gravit.launcher.client.events.client;
|
package pro.gravit.launcher.client.events.client;
|
||||||
|
|
||||||
import pro.gravit.launcher.LauncherEngine;
|
|
||||||
import pro.gravit.launcher.modules.LauncherModule;
|
import pro.gravit.launcher.modules.LauncherModule;
|
||||||
import pro.gravit.launcher.profiles.ClientProfile;
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
|
|
||||||
public class ClientProcessClassLoaderEvent extends LauncherModule.Event {
|
public class ClientProcessClassLoaderEvent extends LauncherModule.Event {
|
||||||
public final LauncherEngine clientInstance;
|
|
||||||
public final ClassLoader clientClassLoader;
|
public final ClassLoader clientClassLoader;
|
||||||
public final ClientProfile profile;
|
public final ClientProfile profile;
|
||||||
|
|
||||||
public ClientProcessClassLoaderEvent(LauncherEngine clientInstance, ClassLoader clientClassLoader, ClientProfile profile) {
|
public ClientProcessClassLoaderEvent(ClassLoader clientClassLoader, ClientProfile profile) {
|
||||||
this.clientInstance = clientInstance;
|
|
||||||
this.clientClassLoader = clientClassLoader;
|
this.clientClassLoader = clientClassLoader;
|
||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,17 @@
|
||||||
package pro.gravit.launcher.client.events.client;
|
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.modules.LauncherModule;
|
||||||
import pro.gravit.launcher.profiles.ClientProfile;
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public class ClientProcessPreInvokeMainClassEvent extends LauncherModule.Event {
|
public class ClientProcessPreInvokeMainClassEvent extends LauncherModule.Event {
|
||||||
public final ClientLauncherProcess.ClientParams params;
|
public final ClientParams params;
|
||||||
public final ClientProfile profile;
|
public final ClientProfile profile;
|
||||||
public final Collection<String> args;
|
public final Collection<String> args;
|
||||||
|
|
||||||
public ClientProcessPreInvokeMainClassEvent(ClientLauncherProcess.ClientParams params, ClientProfile profile, Collection<String> args) {
|
public ClientProcessPreInvokeMainClassEvent(ClientParams params, ClientProfile profile, Collection<String> args) {
|
||||||
this.params = params;
|
this.params = params;
|
||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
this.args = args;
|
this.args = args;
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package pro.gravit.launcher.utils;
|
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.FileNameMatcher;
|
||||||
import pro.gravit.launcher.hasher.HashedDir;
|
import pro.gravit.launcher.hasher.HashedDir;
|
||||||
import pro.gravit.launcher.hasher.HashedEntry;
|
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) {
|
private static void handleError(Throwable e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
LauncherEngine.exitLauncher(-123);
|
ClientLauncherMethods.exitLauncher(-123);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Deque<String> toPath(Iterable<Path> path) {
|
private static Deque<String> toPath(Iterable<Path> path) {
|
|
@ -5,10 +5,10 @@
|
||||||
public final class Version implements Comparable<Version> {
|
public final class Version implements Comparable<Version> {
|
||||||
|
|
||||||
public static final int MAJOR = 5;
|
public static final int MAJOR = 5;
|
||||||
public static final int MINOR = 4;
|
public static final int MINOR = 5;
|
||||||
public static final int PATCH = 4;
|
public static final int PATCH = 0;
|
||||||
public static final int BUILD = 1;
|
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 major;
|
||||||
public final int minor;
|
public final int minor;
|
||||||
public final int patch;
|
public final int patch;
|
||||||
|
|
80
LauncherStart/build.gradle
Normal file
80
LauncherStart/build.gradle
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package pro.gravit.launcher;
|
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.client.DirBridge;
|
||||||
import pro.gravit.launcher.utils.DirWatcher;
|
import pro.gravit.launcher.utils.DirWatcher;
|
||||||
import pro.gravit.utils.helper.*;
|
import pro.gravit.utils.helper.*;
|
||||||
|
@ -22,6 +22,7 @@ public class ClientLauncherWrapper {
|
||||||
public static int launcherMemoryLimit;
|
public static int launcherMemoryLimit;
|
||||||
@LauncherInject("launcher.customJvmOptions")
|
@LauncherInject("launcher.customJvmOptions")
|
||||||
public static List<String> customJvmOptions;
|
public static List<String> customJvmOptions;
|
||||||
|
public static RuntimeModuleManager modulesManager;
|
||||||
|
|
||||||
public static void main(String[] arguments) throws IOException, InterruptedException {
|
public static void main(String[] arguments) throws IOException, InterruptedException {
|
||||||
LogHelper.printVersion("Launcher");
|
LogHelper.printVersion("Launcher");
|
||||||
|
@ -30,8 +31,8 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
|
||||||
JVMHelper.verifySystemProperties(Launcher.class, true);
|
JVMHelper.verifySystemProperties(Launcher.class, true);
|
||||||
EnvHelper.checkDangerousParams();
|
EnvHelper.checkDangerousParams();
|
||||||
LauncherConfig config = Launcher.getConfig();
|
LauncherConfig config = Launcher.getConfig();
|
||||||
LauncherEngine.modulesManager = new ClientModuleManager();
|
modulesManager = new RuntimeModuleManager();
|
||||||
LauncherConfig.initModules(LauncherEngine.modulesManager);
|
LauncherConfig.initModules(modulesManager);
|
||||||
|
|
||||||
LogHelper.info("Launcher for project %s", config.projectName);
|
LogHelper.info("Launcher for project %s", config.projectName);
|
||||||
if (config.environment.equals(LauncherConfig.LauncherEnvironment.PROD)) {
|
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);
|
context.executePath = IOHelper.resolveJavaBin(context.javaVersion.jvmDir);
|
||||||
String pathLauncher = IOHelper.getCodeSource(LauncherEngine.class).toString();
|
String pathLauncher = IOHelper.getCodeSource(ClientLauncherWrapper.class).toString();
|
||||||
context.mainClass = LauncherEngine.class.getName();
|
context.mainClass = "pro.gravit.launcher.LauncherEngineWrapper";
|
||||||
context.memoryLimit = launcherMemoryLimit;
|
context.memoryLimit = launcherMemoryLimit;
|
||||||
context.classpath.add(pathLauncher);
|
context.classpath.add(pathLauncher);
|
||||||
context.jvmProperties.put(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled()));
|
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(MAGIC_ARG);
|
||||||
context.args.add("-XX:+DisableAttachMechanism");
|
context.args.add("-XX:+DisableAttachMechanism");
|
||||||
EnvHelper.addEnv(context.processBuilder);
|
EnvHelper.addEnv(context.processBuilder);
|
||||||
LauncherEngine.modulesManager.callWrapper(context);
|
modulesManager.callWrapper(context);
|
||||||
// ---------
|
// ---------
|
||||||
List<String> args = new ArrayList<>(16);
|
List<String> args = new ArrayList<>(16);
|
||||||
args.add(context.executePath.toAbsolutePath().toString());
|
args.add(context.executePath.toAbsolutePath().toString());
|
|
@ -1,4 +1,4 @@
|
||||||
package pro.gravit.launcher.client;
|
package pro.gravit.launcher;
|
||||||
|
|
||||||
import pro.gravit.launcher.ClientLauncherWrapper;
|
import pro.gravit.launcher.ClientLauncherWrapper;
|
||||||
|
|
|
@ -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<LauncherModule> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
id 'org.openjfx.javafxplugin' version '0.0.10' apply false
|
id 'org.openjfx.javafxplugin' version '0.0.10' apply false
|
||||||
}
|
}
|
||||||
group = 'pro.gravit.launcher'
|
group = 'pro.gravit.launcher'
|
||||||
version = '5.4.4'
|
version = '5.5.0-SNAPSHOT'
|
||||||
|
|
||||||
apply from: 'props.gradle'
|
apply from: 'props.gradle'
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
include 'Launcher'
|
include 'Launcher'
|
||||||
include 'LauncherCore'
|
include 'LauncherCore'
|
||||||
include 'LauncherAPI'
|
include 'LauncherAPI'
|
||||||
|
include 'LauncherClient'
|
||||||
|
include 'LauncherStart'
|
||||||
include 'ServerWrapper'
|
include 'ServerWrapper'
|
||||||
include 'LaunchServer'
|
include 'LaunchServer'
|
||||||
include 'modules'
|
include 'modules'
|
||||||
|
|
Loading…
Reference in a new issue