mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-22 08:31:07 +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": []
|
||||
}
|
|
@ -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 {
|
||||
*;
|
||||
}
|
||||
|
||||
|
|
|
@ -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']
|
||||
}
|
||||
|
|
|
@ -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<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) {
|
||||
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.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<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;
|
||||
|
||||
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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -31,6 +31,7 @@ public enum ReportAction {
|
|||
LOGOUT,
|
||||
TOKEN_EXPIRED,
|
||||
EXIT,
|
||||
@Deprecated
|
||||
CRASH,
|
||||
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) {
|
||||
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) {
|
|
@ -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;
|
||||
|
||||
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()));
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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<Path> resolveClassPath(Path clientDir, Set<OptionalAction>
|
|||
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<String> 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<LauncherModule> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
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<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.profile = profile;
|
||||
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;
|
||||
|
||||
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<String> toPath(Iterable<Path> path) {
|
|
@ -5,10 +5,10 @@
|
|||
public final class Version implements Comparable<Version> {
|
||||
|
||||
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;
|
||||
|
|
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;
|
||||
|
||||
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<String> 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<String> args = new ArrayList<>(16);
|
||||
args.add(context.executePath.toAbsolutePath().toString());
|
|
@ -1,4 +1,4 @@
|
|||
package pro.gravit.launcher.client;
|
||||
package pro.gravit.launcher;
|
||||
|
||||
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
|
||||
}
|
||||
group = 'pro.gravit.launcher'
|
||||
version = '5.4.4'
|
||||
version = '5.5.0-SNAPSHOT'
|
||||
|
||||
apply from: 'props.gradle'
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
include 'Launcher'
|
||||
include 'LauncherCore'
|
||||
include 'LauncherAPI'
|
||||
include 'LauncherClient'
|
||||
include 'LauncherStart'
|
||||
include 'ServerWrapper'
|
||||
include 'LaunchServer'
|
||||
include 'modules'
|
||||
|
|
Loading…
Reference in a new issue