[FIX] New trigger system

This commit is contained in:
Gravita 2021-06-18 11:34:32 +07:00
parent 661fb94594
commit b09cd5c456
16 changed files with 401 additions and 227 deletions

View file

@ -7,6 +7,7 @@
import pro.gravit.launcher.LauncherTrustManager; import pro.gravit.launcher.LauncherTrustManager;
import pro.gravit.launcher.modules.events.PreConfigPhase; import pro.gravit.launcher.modules.events.PreConfigPhase;
import pro.gravit.launcher.profiles.optional.actions.OptionalAction; import pro.gravit.launcher.profiles.optional.actions.OptionalAction;
import pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger;
import pro.gravit.launcher.request.auth.AuthRequest; import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest; import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest;
import pro.gravit.launchserver.auth.core.AuthCoreProvider; import pro.gravit.launchserver.auth.core.AuthCoreProvider;
@ -211,6 +212,7 @@ public static void registerAll() {
GetAvailabilityAuthRequest.registerProviders(); GetAvailabilityAuthRequest.registerProviders();
HWIDProvider.registerProviders(); HWIDProvider.registerProviders();
OptionalAction.registerProviders(); OptionalAction.registerProviders();
OptionalTrigger.registerProviders();
SessionStorage.registerProviders(); SessionStorage.registerProviders();
} }

View file

@ -8,9 +8,11 @@
import pro.gravit.launcher.profiles.optional.OptionalFile; import pro.gravit.launcher.profiles.optional.OptionalFile;
import pro.gravit.launcher.profiles.optional.OptionalTrigger; import pro.gravit.launcher.profiles.optional.OptionalTrigger;
import pro.gravit.launcher.profiles.optional.actions.*; import pro.gravit.launcher.profiles.optional.actions.*;
import pro.gravit.launcher.profiles.optional.triggers.OSTrigger;
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.command.Command; import pro.gravit.launchserver.command.Command;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.JVMHelper;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
@ -61,7 +63,7 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
optionalMacOs.visible = false; optionalMacOs.visible = false;
optionalMacOs.actions = new ArrayList<>(1); optionalMacOs.actions = new ArrayList<>(1);
optionalMacOs.actions.add(new OptionalActionJvmArgs(List.of("-XstartOnFirstThread"))); optionalMacOs.actions.add(new OptionalActionJvmArgs(List.of("-XstartOnFirstThread")));
optionalMacOs.triggers = new OptionalTrigger[]{new OptionalTrigger(OptionalTrigger.TriggerType.OS_TYPE, 2)}; optionalMacOs.triggersList = List.of(new OSTrigger(JVMHelper.OS.MACOSX));
optionals.add(optionalMacOs); optionals.add(optionalMacOs);
} }
if (optionContains(options, MakeProfileOption.LWJGLMAC)) { if (optionContains(options, MakeProfileOption.LWJGLMAC)) {
@ -77,7 +79,7 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
"libraries/libraries/org/lwjgl/lwjgl-opengl/3.2.1", "", "libraries/libraries/org/lwjgl/lwjgl-opengl/3.2.1", "",
"libraries/libraries/org/lwjgl/lwjgl-jemalloc/3.2.1", "" "libraries/libraries/org/lwjgl/lwjgl-jemalloc/3.2.1", ""
))); )));
optionalMac.triggers = new OptionalTrigger[]{new OptionalTrigger(OptionalTrigger.TriggerType.OS_TYPE, true, 2, 0)}; optionalMac.triggersList = List.of(new OSTrigger(JVMHelper.OS.MACOSX));
optionals.add(optionalMac); optionals.add(optionalMac);
OptionalFile optionalOther = new OptionalFile(); OptionalFile optionalOther = new OptionalFile();
optionalOther.name = "NonMacLwjgl"; optionalOther.name = "NonMacLwjgl";
@ -91,7 +93,9 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
"libraries/libraries/org/lwjgl/lwjgl-opengl/3.2.2", "", "libraries/libraries/org/lwjgl/lwjgl-opengl/3.2.2", "",
"libraries/libraries/org/lwjgl/lwjgl-jemalloc/3.2.2", "" "libraries/libraries/org/lwjgl/lwjgl-jemalloc/3.2.2", ""
))); )));
optionalOther.triggers = new OptionalTrigger[]{new OptionalTrigger(OptionalTrigger.TriggerType.OS_TYPE, true, 2, 0)}; OSTrigger nonMacTrigger = new OSTrigger(JVMHelper.OS.MACOSX);
nonMacTrigger.inverted = true;
optionalOther.triggersList = List.of(nonMacTrigger);
optionals.add(optionalOther); optionals.add(optionalOther);
} }
if (version.compareTo(ClientProfile.Version.MC117) >= 0) { if (version.compareTo(ClientProfile.Version.MC117) >= 0) {
@ -192,6 +196,14 @@ public static void saveProfile(ClientProfile profile, Path path) throws IOExcept
} }
file.actions.add(action); file.actions.add(action);
} }
if (file.triggers != null) {
file.triggersList = new ArrayList<>(file.triggers.length);
for (OptionalTrigger trigger : file.triggers) {
pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger newTrigger = trigger.toTrigger();
if (newTrigger != null) file.triggersList.add(newTrigger);
}
file.triggers = null;
}
} }
try (Writer w = IOHelper.newWriter(path)) { try (Writer w = IOHelper.newWriter(path)) {
Launcher.gsonManager.configGson.toJson(profile, w); Launcher.gsonManager.configGson.toJson(profile, w);

View file

@ -5,6 +5,7 @@
import pro.gravit.launcher.managers.GsonManager; import pro.gravit.launcher.managers.GsonManager;
import pro.gravit.launcher.modules.events.PreGsonPhase; import pro.gravit.launcher.modules.events.PreGsonPhase;
import pro.gravit.launcher.profiles.optional.actions.OptionalAction; import pro.gravit.launcher.profiles.optional.actions.OptionalAction;
import pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger;
import pro.gravit.launcher.request.JsonResultSerializeAdapter; import pro.gravit.launcher.request.JsonResultSerializeAdapter;
import pro.gravit.launcher.request.WebSocketEvent; import pro.gravit.launcher.request.WebSocketEvent;
import pro.gravit.launcher.request.auth.AuthRequest; import pro.gravit.launcher.request.auth.AuthRequest;
@ -50,6 +51,7 @@ public void registerAdapters(GsonBuilder builder) {
builder.registerTypeAdapter(GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails.class, new UniversalJsonAdapter<>(GetAvailabilityAuthRequest.providers)); builder.registerTypeAdapter(GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails.class, new UniversalJsonAdapter<>(GetAvailabilityAuthRequest.providers));
builder.registerTypeAdapter(HWIDProvider.class, new UniversalJsonAdapter<>(HWIDProvider.providers)); builder.registerTypeAdapter(HWIDProvider.class, new UniversalJsonAdapter<>(HWIDProvider.providers));
builder.registerTypeAdapter(OptionalAction.class, new UniversalJsonAdapter<>(OptionalAction.providers)); builder.registerTypeAdapter(OptionalAction.class, new UniversalJsonAdapter<>(OptionalAction.providers));
builder.registerTypeAdapter(OptionalTrigger.class, new UniversalJsonAdapter<>(OptionalTrigger.providers));
builder.registerTypeAdapter(SessionStorage.class, new UniversalJsonAdapter<>(SessionStorage.providers)); builder.registerTypeAdapter(SessionStorage.class, new UniversalJsonAdapter<>(SessionStorage.providers));
modulesManager.invokeEvent(new PreGsonPhase(builder)); modulesManager.invokeEvent(new PreGsonPhase(builder));
//ClientWebSocketService.appendTypeAdapters(builder); //ClientWebSocketService.appendTypeAdapters(builder);

View file

@ -3,17 +3,14 @@
import pro.gravit.launcher.client.ClientModuleManager; import pro.gravit.launcher.client.ClientModuleManager;
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.EnvHelper; import pro.gravit.utils.helper.*;
import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.JVMHelper;
import pro.gravit.utils.helper.LogHelper;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.util.ArrayList;
import java.util.*; import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ClientLauncherWrapper { public class ClientLauncherWrapper {
public static final String MAGIC_ARG = "-Djdk.attach.allowAttachSelf"; public static final String MAGIC_ARG = "-Djdk.attach.allowAttachSelf";
@ -56,8 +53,8 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
context.javaVersion = null; context.javaVersion = null;
try { try {
if (!noJavaCheck) { if (!noJavaCheck) {
List<JavaVersion> javaVersions = findJava(); List<JavaHelper.JavaVersion> javaVersions = JavaHelper.findJava();
for (JavaVersion version : javaVersions) { for (JavaHelper.JavaVersion version : javaVersions) {
LogHelper.debug("Found Java %d b%d in %s javafx %s", version.version, version.build, version.jvmDir.toString(), version.enabledJavaFX ? "supported" : "not supported"); LogHelper.debug("Found Java %d b%d in %s javafx %s", version.version, version.build, version.jvmDir.toString(), version.enabledJavaFX ? "supported" : "not supported");
if (context.javaVersion == null) { if (context.javaVersion == null) {
context.javaVersion = version; context.javaVersion = version;
@ -80,7 +77,7 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
LogHelper.error(e); LogHelper.error(e);
} }
if (context.javaVersion == null) { if (context.javaVersion == null) {
context.javaVersion = JavaVersion.getCurrentJavaVersion(); context.javaVersion = JavaHelper.JavaVersion.getCurrentJavaVersion();
} }
context.executePath = IOHelper.resolveJavaBin(context.javaVersion.jvmDir); context.executePath = IOHelper.resolveJavaBin(context.javaVersion.jvmDir);
@ -116,14 +113,14 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
if (context.javaVersion.version >= 9) { if (context.javaVersion.version >= 9) {
context.javaFXPaths.add(context.javaVersion.jvmDir); context.javaFXPaths.add(context.javaVersion.jvmDir);
context.javaFXPaths.add(context.javaVersion.jvmDir.resolve("jre")); context.javaFXPaths.add(context.javaVersion.jvmDir.resolve("jre"));
Path openjfxPath = tryGetOpenJFXPath(context.javaVersion.jvmDir); Path openjfxPath = JavaHelper.tryGetOpenJFXPath(context.javaVersion.jvmDir);
if (openjfxPath != null) { if (openjfxPath != null) {
context.javaFXPaths.add(openjfxPath); context.javaFXPaths.add(openjfxPath);
} }
StringBuilder modulesPath = new StringBuilder(); StringBuilder modulesPath = new StringBuilder();
StringBuilder modulesAdd = new StringBuilder(); StringBuilder modulesAdd = new StringBuilder();
for (String moduleName : context.jvmModules) { for (String moduleName : context.jvmModules) {
boolean success = tryAddModule(context.javaFXPaths, moduleName, modulesPath); boolean success = JavaHelper.tryAddModule(context.javaFXPaths, moduleName, modulesPath);
if (success) { if (success) {
if (modulesAdd.length() > 0) modulesAdd.append(","); if (modulesAdd.length() > 0) modulesAdd.append(",");
modulesAdd.append(moduleName); modulesAdd.append(moduleName);
@ -164,213 +161,9 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
} }
} }
public static Path tryGetOpenJFXPath(Path jvmDir) {
String dirName = jvmDir.getFileName().toString();
Path parent = jvmDir.getParent();
if (parent == null) return null;
Path archJFXPath = parent.resolve(dirName.replace("openjdk", "openjfx"));
if (Files.isDirectory(archJFXPath)) {
return archJFXPath;
}
Path arch2JFXPath = parent.resolve(dirName.replace("jdk", "openjfx"));
if (Files.isDirectory(arch2JFXPath)) {
return arch2JFXPath;
}
if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX) {
Path debianJfxPath = Paths.get("/usr/share/openjfx");
if (Files.isDirectory(debianJfxPath)) {
return debianJfxPath;
}
}
return null;
}
public static Path tryFindModule(Path path, String moduleName) {
Path result = path.resolve(moduleName.concat(".jar"));
if (!IOHelper.isFile(result))
result = path.resolve("lib").resolve(moduleName.concat(".jar"));
else return result;
if (!IOHelper.isFile(result))
return null;
else return result;
}
public static boolean tryAddModule(List<Path> paths, String moduleName, StringBuilder args) {
for (Path path : paths) {
if (path == null) continue;
Path result = tryFindModule(path, moduleName);
if (result != null) {
if (args.length() != 0) args.append(File.pathSeparatorChar);
args.append(result.toAbsolutePath().toString());
return true;
}
}
return false;
}
public static List<JavaVersion> findJava() {
List<String> javaPaths = new ArrayList<>(4);
List<JavaVersion> result = new ArrayList<>(4);
try {
tryAddJava(javaPaths, result, ClientLauncherWrapper.JavaVersion.getCurrentJavaVersion());
} catch (IOException e) {
LogHelper.error(e);
}
String[] path = System.getenv("PATH").split(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE ? ";" : ":");
for (String p : path) {
try {
Path p1 = Paths.get(p);
Path javaExecPath = JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE ? p1.resolve("java.exe") : p1.resolve("java");
if (Files.exists(javaExecPath)) {
if (Files.isSymbolicLink(javaExecPath)) {
javaExecPath = javaExecPath.toRealPath();
}
p1 = javaExecPath.getParent().getParent();
tryAddJava(javaPaths, result, ClientLauncherWrapper.JavaVersion.getByPath(p1));
trySearchJava(javaPaths, result, p1.getParent());
}
} catch (IOException e) {
LogHelper.error(e);
}
}
if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) {
Path rootDrive = Paths.get(System.getProperty("java.home"));
try {
trySearchJava(javaPaths, result, rootDrive.resolve("Program Files").resolve("Java"));
trySearchJava(javaPaths, result, rootDrive.resolve("Program Files").resolve("AdoptOpenJDK"));
} catch (IOException e) {
LogHelper.error(e);
}
} else if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX) {
try {
trySearchJava(javaPaths, result, Paths.get("/usr/lib/jvm"));
} catch (IOException e) {
LogHelper.error(e);
}
}
return result;
}
public static boolean tryAddJava(List<String> javaPaths, List<JavaVersion> result, ClientLauncherWrapper.JavaVersion version) throws IOException {
if (version == null) return false;
String path = version.jvmDir.toAbsolutePath().toString();
if (javaPaths.contains(path)) return false;
javaPaths.add(path);
result.add(version);
return true;
}
public static void trySearchJava(List<String> javaPaths, List<JavaVersion> result, Path path) throws IOException {
if (!Files.isDirectory(path)) return;
Files.list(path).filter(p -> Files.exists(p.resolve("bin").resolve(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE ? "java.exe" : "java"))).forEach(e -> {
try {
tryAddJava(javaPaths, result, JavaVersion.getByPath(e));
if (Files.exists(e.resolve("jre"))) {
tryAddJava(javaPaths, result, JavaVersion.getByPath(e.resolve("jre")));
}
} catch (IOException ioException) {
LogHelper.error(ioException);
}
});
}
public static class JavaVersionAndBuild {
public int version;
public int build;
public JavaVersionAndBuild(int version, int build) {
this.version = version;
this.build = build;
}
public JavaVersionAndBuild() {
}
}
public static JavaVersionAndBuild getJavaVersion(String version) {
JavaVersionAndBuild result = new JavaVersionAndBuild();
if (version.startsWith("1.")) {
result.version = Integer.parseInt(version.substring(2, 3));
result.build = Integer.parseInt(version.substring(version.indexOf('_') + 1));
} else {
int dot = version.indexOf(".");
if (dot != -1) {
result.version = Integer.parseInt(version.substring(0, dot));
dot = version.lastIndexOf(".");
result.build = Integer.parseInt(version.substring(dot + 1));
}
}
return result;
}
public static class JavaVersion {
public final Path jvmDir;
public final int version;
public final int build;
public boolean enabledJavaFX;
public JavaVersion(Path jvmDir, int version) {
this.jvmDir = jvmDir;
this.version = version;
this.build = 0;
this.enabledJavaFX = true;
}
public JavaVersion(Path jvmDir, int version, int build, boolean enabledJavaFX) {
this.jvmDir = jvmDir;
this.version = version;
this.build = build;
this.enabledJavaFX = enabledJavaFX;
}
public static JavaVersion getCurrentJavaVersion() {
return new JavaVersion(Paths.get(System.getProperty("java.home")), JVMHelper.getVersion(), 0, isCurrentJavaSupportJavaFX());
}
private static boolean isCurrentJavaSupportJavaFX() {
try {
Class.forName("javafx.application.Application");
return true;
} catch (ClassNotFoundException e) {
if (JVMHelper.getVersion() > 8) {
Path jvmDir = Paths.get(System.getProperty("java.home"));
return tryFindModule(jvmDir, "javafx.base") != null;
}
return false;
}
}
public static JavaVersion getByPath(Path jvmDir) throws IOException {
Path releaseFile = jvmDir.resolve("release");
JavaVersionAndBuild versionAndBuild;
if (IOHelper.isFile(releaseFile)) {
Properties properties = new Properties();
properties.load(IOHelper.newReader(releaseFile));
versionAndBuild = getJavaVersion(properties.getProperty("JAVA_VERSION").replaceAll("\"", ""));
} else {
versionAndBuild = new JavaVersionAndBuild(isExistExtJavaLibrary(jvmDir, "jfxrt") ? 8 : 9, 0);
}
JavaVersion resultJavaVersion = new JavaVersion(jvmDir, versionAndBuild.version, versionAndBuild.build, false);
if (versionAndBuild.version <= 8) {
resultJavaVersion.enabledJavaFX = isExistExtJavaLibrary(jvmDir, "jfxrt");
} else {
resultJavaVersion.enabledJavaFX = tryFindModule(jvmDir, "javafx.base") != null;
if (!resultJavaVersion.enabledJavaFX)
resultJavaVersion.enabledJavaFX = tryFindModule(jvmDir.resolve("jre"), "javafx.base") != null;
}
return resultJavaVersion;
}
public static boolean isExistExtJavaLibrary(Path jvmDir, String name) {
Path jrePath = jvmDir.resolve("lib").resolve("ext").resolve(name.concat(".jar"));
Path jdkPath = jvmDir.resolve("jre").resolve("lib").resolve("ext").resolve(name.concat(".jar"));
return IOHelper.isFile(jrePath) || IOHelper.isFile(jdkPath);
}
}
public static class ClientLauncherWrapperContext { public static class ClientLauncherWrapperContext {
public JavaVersion javaVersion; public JavaHelper.JavaVersion javaVersion;
public Path executePath; public Path executePath;
public String mainClass; public String mainClass;
public int memoryLimit; public int memoryLimit;

View file

@ -14,6 +14,7 @@
import pro.gravit.launcher.managers.ConsoleManager; import pro.gravit.launcher.managers.ConsoleManager;
import pro.gravit.launcher.modules.events.PreConfigPhase; import pro.gravit.launcher.modules.events.PreConfigPhase;
import pro.gravit.launcher.profiles.optional.actions.OptionalAction; import pro.gravit.launcher.profiles.optional.actions.OptionalAction;
import pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger;
import pro.gravit.launcher.request.Request; import pro.gravit.launcher.request.Request;
import pro.gravit.launcher.request.RequestException; import pro.gravit.launcher.request.RequestException;
import pro.gravit.launcher.request.auth.AuthRequest; import pro.gravit.launcher.request.auth.AuthRequest;
@ -120,6 +121,7 @@ public static void initGson(ClientModuleManager modulesManager) {
AuthRequest.registerProviders(); AuthRequest.registerProviders();
GetAvailabilityAuthRequest.registerProviders(); GetAvailabilityAuthRequest.registerProviders();
OptionalAction.registerProviders(); OptionalAction.registerProviders();
OptionalTrigger.registerProviders();
Launcher.gsonManager = new ClientGsonManager(modulesManager); Launcher.gsonManager = new ClientGsonManager(modulesManager);
Launcher.gsonManager.initGson(); Launcher.gsonManager.initGson();
} }

View file

@ -16,6 +16,7 @@
import pro.gravit.launcher.profiles.optional.actions.OptionalAction; import pro.gravit.launcher.profiles.optional.actions.OptionalAction;
import pro.gravit.launcher.profiles.optional.actions.OptionalActionClassPath; import pro.gravit.launcher.profiles.optional.actions.OptionalActionClassPath;
import pro.gravit.launcher.profiles.optional.actions.OptionalActionClientArgs; import pro.gravit.launcher.profiles.optional.actions.OptionalActionClientArgs;
import pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger;
import pro.gravit.launcher.request.Request; import pro.gravit.launcher.request.Request;
import pro.gravit.launcher.request.RequestException; import pro.gravit.launcher.request.RequestException;
import pro.gravit.launcher.request.auth.AuthRequest; import pro.gravit.launcher.request.auth.AuthRequest;
@ -198,6 +199,7 @@ private static void initGson(ClientModuleManager moduleManager) {
AuthRequest.registerProviders(); AuthRequest.registerProviders();
GetAvailabilityAuthRequest.registerProviders(); GetAvailabilityAuthRequest.registerProviders();
OptionalAction.registerProviders(); OptionalAction.registerProviders();
OptionalTrigger.registerProviders();
Launcher.gsonManager = new ClientGsonManager(moduleManager); Launcher.gsonManager = new ClientGsonManager(moduleManager);
Launcher.gsonManager.initGson(); Launcher.gsonManager.initGson();
} }

View file

@ -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.LauncherEngine; import pro.gravit.launcher.LauncherEngine;
import pro.gravit.launcher.LauncherNetworkAPI; import pro.gravit.launcher.LauncherNetworkAPI;
@ -45,7 +44,7 @@ public class ClientLauncherProcess {
public int bits; public int bits;
public boolean useLegacyJavaClassPathProperty; public boolean useLegacyJavaClassPathProperty;
public boolean isStarted; public boolean isStarted;
public ClientLauncherWrapper.JavaVersion javaVersion; public JavaHelper.JavaVersion javaVersion;
private transient Process process; private transient Process process;
public ClientLauncherProcess(Path executeFile, Path workDir, Path javaDir, String mainClass) { public ClientLauncherProcess(Path executeFile, Path workDir, Path javaDir, String mainClass) {
@ -87,13 +86,13 @@ public ClientLauncherProcess(Path clientDir, Path assetDir, Path javaDir, Path r
this.params.actions = view.getEnabledActions(); this.params.actions = view.getEnabledActions();
} }
try { try {
javaVersion = ClientLauncherWrapper.JavaVersion.getByPath(javaDir); javaVersion = JavaHelper.JavaVersion.getByPath(javaDir);
} catch (IOException e) { } catch (IOException e) {
LogHelper.error(e); LogHelper.error(e);
javaVersion = null; javaVersion = null;
} }
if (javaVersion == null) { if (javaVersion == null) {
javaVersion = ClientLauncherWrapper.JavaVersion.getCurrentJavaVersion(); javaVersion = JavaHelper.JavaVersion.getCurrentJavaVersion();
} }
this.bits = JVMHelper.JVM_BITS; this.bits = JVMHelper.JVM_BITS;
applyClientProfile(); applyClientProfile();
@ -187,14 +186,14 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException {
private void applyJava9Params(List<String> processArgs) { private void applyJava9Params(List<String> processArgs) {
jvmModulesPaths.add(javaVersion.jvmDir); jvmModulesPaths.add(javaVersion.jvmDir);
jvmModulesPaths.add(javaVersion.jvmDir.resolve("jre")); jvmModulesPaths.add(javaVersion.jvmDir.resolve("jre"));
Path openjfxPath = ClientLauncherWrapper.tryGetOpenJFXPath(javaVersion.jvmDir); Path openjfxPath = JavaHelper.tryGetOpenJFXPath(javaVersion.jvmDir);
if (openjfxPath != null) { if (openjfxPath != null) {
jvmModulesPaths.add(openjfxPath); jvmModulesPaths.add(openjfxPath);
} }
StringBuilder modulesPath = new StringBuilder(); StringBuilder modulesPath = new StringBuilder();
StringBuilder modulesAdd = new StringBuilder(); StringBuilder modulesAdd = new StringBuilder();
for (String moduleName : jvmModules) { for (String moduleName : jvmModules) {
boolean success = ClientLauncherWrapper.tryAddModule(jvmModulesPaths, moduleName, modulesPath); boolean success = JavaHelper.tryAddModule(jvmModulesPaths, moduleName, modulesPath);
if (success) { if (success) {
if (modulesAdd.length() > 0) modulesAdd.append(","); if (modulesAdd.length() > 0) modulesAdd.append(",");
modulesAdd.append(moduleName); modulesAdd.append(moduleName);

View file

@ -16,6 +16,7 @@
public class OptionalFile { public class OptionalFile {
@LauncherNetworkAPI @LauncherNetworkAPI
@Deprecated
public long permissions = 0L; public long permissions = 0L;
@LauncherNetworkAPI @LauncherNetworkAPI
@Deprecated @Deprecated
@ -34,6 +35,9 @@ public class OptionalFile {
@LauncherNetworkAPI @LauncherNetworkAPI
public String info; public String info;
@LauncherNetworkAPI @LauncherNetworkAPI
public List<pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger> triggersList;
@LauncherNetworkAPI
@Deprecated
public OptionalTrigger[] triggers; public OptionalTrigger[] triggers;
@LauncherNetworkAPI @LauncherNetworkAPI
public OptionalDepend[] dependenciesFile; public OptionalDepend[] dependenciesFile;
@ -106,6 +110,7 @@ public boolean isMark() {
return mark; return mark;
} }
@Deprecated
public long getPermissions() { public long getPermissions() {
return permissions; return permissions;
} }

View file

@ -1,7 +1,10 @@
package pro.gravit.launcher.profiles.optional; package pro.gravit.launcher.profiles.optional;
import pro.gravit.launcher.profiles.optional.triggers.JavaTrigger;
import pro.gravit.launcher.profiles.optional.triggers.OSTrigger;
import pro.gravit.utils.helper.JVMHelper; import pro.gravit.utils.helper.JVMHelper;
@Deprecated
public class OptionalTrigger { public class OptionalTrigger {
public TriggerType type; public TriggerType type;
public boolean need = true; public boolean need = true;
@ -60,6 +63,36 @@ public boolean isTriggered() {
else return test > value; else return test > value;
} }
public pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger toTrigger() {
switch (type) {
case JAVA_VERSION: {
JavaTrigger trigger = new JavaTrigger((int) value, (int) value);
trigger.required = need;
if (compareMode > 0) {
trigger.maxVersion = 999;
} else if (compareMode < 0) {
trigger.minVersion = 0;
}
return trigger;
}
case JAVA_BITS:
case OS_BITS:
return null;
case OS_TYPE: {
JVMHelper.OS os;
if (value == 0) os = JVMHelper.OS.MUSTDIE;
else if (value == 1) os = JVMHelper.OS.LINUX;
else if (value == 2) os = JVMHelper.OS.MUSTDIE;
else throw new IllegalArgumentException(String.format("Os version %d unknown", value));
OSTrigger trigger = new OSTrigger(os);
trigger.required = need;
if (compareMode != 0) trigger.inverted = true;
return trigger;
}
}
return null;
}
public enum TriggerType { public enum TriggerType {
JAVA_VERSION, JAVA_BITS, OS_BITS, OS_TYPE JAVA_VERSION, JAVA_BITS, OS_BITS, OS_TYPE
} }

View file

@ -0,0 +1,37 @@
package pro.gravit.launcher.profiles.optional.triggers;
import pro.gravit.launcher.profiles.optional.OptionalFile;
import pro.gravit.utils.helper.JavaHelper;
public class JavaTrigger extends OptionalTrigger {
public int minVersion;
public int maxVersion;
public boolean requireJavaFX;
public JavaTrigger(int minVersion, int maxVersion, boolean requireJavaFX) {
this.minVersion = minVersion;
this.maxVersion = maxVersion;
this.requireJavaFX = requireJavaFX;
}
public JavaTrigger(int minVersion, int maxVersion) {
this.minVersion = minVersion;
this.maxVersion = maxVersion;
this.requireJavaFX = false;
}
public JavaTrigger() {
this.minVersion = 8;
this.maxVersion = 999;
this.requireJavaFX = false;
}
@Override
public boolean isTriggered(OptionalFile optional, OptionalTriggerContext context) {
JavaHelper.JavaVersion version = context.getJavaVersion();
if (version.version < minVersion) return false;
if (version.version > maxVersion) return false;
if (requireJavaFX && !version.enabledJavaFX) return false;
return true;
}
}

View file

@ -0,0 +1,17 @@
package pro.gravit.launcher.profiles.optional.triggers;
import pro.gravit.launcher.profiles.optional.OptionalFile;
import pro.gravit.utils.helper.JVMHelper;
public class OSTrigger extends OptionalTrigger {
public JVMHelper.OS os;
public OSTrigger(JVMHelper.OS os) {
this.os = os;
}
@Override
public boolean isTriggered(OptionalFile optional, OptionalTriggerContext context) {
return JVMHelper.OS_TYPE == os;
}
}

View file

@ -0,0 +1,28 @@
package pro.gravit.launcher.profiles.optional.triggers;
import pro.gravit.launcher.profiles.optional.OptionalFile;
import pro.gravit.utils.ProviderMap;
public abstract class OptionalTrigger {
public static ProviderMap<OptionalTrigger> providers = new ProviderMap<>("OptionalTriggers");
private static boolean isRegisteredProviders = false;
public static void registerProviders() {
if (!isRegisteredProviders) {
providers.register("java", JavaTrigger.class);
providers.register("os", OSTrigger.class);
isRegisteredProviders = true;
}
}
public boolean required;
public boolean inverted;
protected abstract boolean isTriggered(OptionalFile optional, OptionalTriggerContext context);
public boolean check(OptionalFile optional, OptionalTriggerContext context) {
boolean result = isTriggered(optional, context);
if (inverted) result = !result;
return result;
}
}

View file

@ -0,0 +1,22 @@
package pro.gravit.launcher.profiles.optional.triggers;
import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launcher.profiles.ClientProfile;
import pro.gravit.launcher.profiles.PlayerProfile;
import pro.gravit.utils.helper.JavaHelper;
public interface OptionalTriggerContext {
ClientProfile getProfile();
String getUsername();
JavaHelper.JavaVersion getJavaVersion();
default ClientPermissions getPermissions() {
return ClientPermissions.DEFAULT;
}
default PlayerProfile getPlayerProfile() {
return null;
}
}

View file

@ -10,6 +10,7 @@
import pro.gravit.launcher.hasher.HashedEntry; import pro.gravit.launcher.hasher.HashedEntry;
import pro.gravit.launcher.hasher.HashedEntryAdapter; import pro.gravit.launcher.hasher.HashedEntryAdapter;
import pro.gravit.launcher.profiles.optional.actions.OptionalAction; import pro.gravit.launcher.profiles.optional.actions.OptionalAction;
import pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger;
import pro.gravit.launcher.request.WebSocketEvent; import pro.gravit.launcher.request.WebSocketEvent;
import pro.gravit.launcher.request.auth.AuthRequest; import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest; import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest;
@ -44,6 +45,7 @@ public static void appendTypeAdapters(GsonBuilder builder) {
builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers)); builder.registerTypeAdapter(AuthRequest.AuthPasswordInterface.class, new UniversalJsonAdapter<>(AuthRequest.providers));
builder.registerTypeAdapter(GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails.class, new UniversalJsonAdapter<>(GetAvailabilityAuthRequest.providers)); builder.registerTypeAdapter(GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails.class, new UniversalJsonAdapter<>(GetAvailabilityAuthRequest.providers));
builder.registerTypeAdapter(OptionalAction.class, new UniversalJsonAdapter<>(OptionalAction.providers)); builder.registerTypeAdapter(OptionalAction.class, new UniversalJsonAdapter<>(OptionalAction.providers));
builder.registerTypeAdapter(OptionalTrigger.class, new UniversalJsonAdapter<>(OptionalTrigger.providers));
} }
private static URI createURL(String address) { private static URI createURL(String address) {

View file

@ -0,0 +1,216 @@
package pro.gravit.utils.helper;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class JavaHelper {
public static Path tryGetOpenJFXPath(Path jvmDir) {
String dirName = jvmDir.getFileName().toString();
Path parent = jvmDir.getParent();
if (parent == null) return null;
Path archJFXPath = parent.resolve(dirName.replace("openjdk", "openjfx"));
if (Files.isDirectory(archJFXPath)) {
return archJFXPath;
}
Path arch2JFXPath = parent.resolve(dirName.replace("jdk", "openjfx"));
if (Files.isDirectory(arch2JFXPath)) {
return arch2JFXPath;
}
if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX) {
Path debianJfxPath = Paths.get("/usr/share/openjfx");
if (Files.isDirectory(debianJfxPath)) {
return debianJfxPath;
}
}
return null;
}
public static Path tryFindModule(Path path, String moduleName) {
Path result = path.resolve(moduleName.concat(".jar"));
if (!IOHelper.isFile(result))
result = path.resolve("lib").resolve(moduleName.concat(".jar"));
else return result;
if (!IOHelper.isFile(result))
return null;
else return result;
}
public static boolean tryAddModule(List<Path> paths, String moduleName, StringBuilder args) {
for (Path path : paths) {
if (path == null) continue;
Path result = tryFindModule(path, moduleName);
if (result != null) {
if (args.length() != 0) args.append(File.pathSeparatorChar);
args.append(result.toAbsolutePath().toString());
return true;
}
}
return false;
}
public static List<JavaVersion> findJava() {
List<String> javaPaths = new ArrayList<>(4);
List<JavaVersion> result = new ArrayList<>(4);
try {
tryAddJava(javaPaths, result, JavaVersion.getCurrentJavaVersion());
} catch (IOException e) {
LogHelper.error(e);
}
String[] path = System.getenv("PATH").split(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE ? ";" : ":");
for (String p : path) {
try {
Path p1 = Paths.get(p);
Path javaExecPath = JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE ? p1.resolve("java.exe") : p1.resolve("java");
if (Files.exists(javaExecPath)) {
if (Files.isSymbolicLink(javaExecPath)) {
javaExecPath = javaExecPath.toRealPath();
}
p1 = javaExecPath.getParent().getParent();
tryAddJava(javaPaths, result, JavaVersion.getByPath(p1));
trySearchJava(javaPaths, result, p1.getParent());
}
} catch (IOException e) {
LogHelper.error(e);
}
}
if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) {
Path rootDrive = Paths.get(System.getProperty("java.home"));
try {
trySearchJava(javaPaths, result, rootDrive.resolve("Program Files").resolve("Java"));
trySearchJava(javaPaths, result, rootDrive.resolve("Program Files").resolve("AdoptOpenJDK"));
} catch (IOException e) {
LogHelper.error(e);
}
} else if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX) {
try {
trySearchJava(javaPaths, result, Paths.get("/usr/lib/jvm"));
} catch (IOException e) {
LogHelper.error(e);
}
}
return result;
}
public static boolean tryAddJava(List<String> javaPaths, List<JavaVersion> result, JavaVersion version) throws IOException {
if (version == null) return false;
String path = version.jvmDir.toAbsolutePath().toString();
if (javaPaths.contains(path)) return false;
javaPaths.add(path);
result.add(version);
return true;
}
public static void trySearchJava(List<String> javaPaths, List<JavaVersion> result, Path path) throws IOException {
if (!Files.isDirectory(path)) return;
Files.list(path).filter(p -> Files.exists(p.resolve("bin").resolve(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE ? "java.exe" : "java"))).forEach(e -> {
try {
tryAddJava(javaPaths, result, JavaVersion.getByPath(e));
if (Files.exists(e.resolve("jre"))) {
tryAddJava(javaPaths, result, JavaVersion.getByPath(e.resolve("jre")));
}
} catch (IOException ioException) {
LogHelper.error(ioException);
}
});
}
public static JavaVersionAndBuild getJavaVersion(String version) {
JavaVersionAndBuild result = new JavaVersionAndBuild();
if (version.startsWith("1.")) {
result.version = Integer.parseInt(version.substring(2, 3));
result.build = Integer.parseInt(version.substring(version.indexOf('_') + 1));
} else {
int dot = version.indexOf(".");
if (dot != -1) {
result.version = Integer.parseInt(version.substring(0, dot));
dot = version.lastIndexOf(".");
result.build = Integer.parseInt(version.substring(dot + 1));
}
}
return result;
}
public static class JavaVersionAndBuild {
public int version;
public int build;
public JavaVersionAndBuild(int version, int build) {
this.version = version;
this.build = build;
}
public JavaVersionAndBuild() {
}
}
public static class JavaVersion {
public final Path jvmDir;
public final int version;
public final int build;
public boolean enabledJavaFX;
public JavaVersion(Path jvmDir, int version) {
this.jvmDir = jvmDir;
this.version = version;
this.build = 0;
this.enabledJavaFX = true;
}
public JavaVersion(Path jvmDir, int version, int build, boolean enabledJavaFX) {
this.jvmDir = jvmDir;
this.version = version;
this.build = build;
this.enabledJavaFX = enabledJavaFX;
}
public static JavaVersion getCurrentJavaVersion() {
return new JavaVersion(Paths.get(System.getProperty("java.home")), JVMHelper.getVersion(), 0, isCurrentJavaSupportJavaFX());
}
private static boolean isCurrentJavaSupportJavaFX() {
try {
Class.forName("javafx.application.Application");
return true;
} catch (ClassNotFoundException e) {
if (JVMHelper.getVersion() > 8) {
Path jvmDir = Paths.get(System.getProperty("java.home"));
return tryFindModule(jvmDir, "javafx.base") != null;
}
return false;
}
}
public static JavaVersion getByPath(Path jvmDir) throws IOException {
Path releaseFile = jvmDir.resolve("release");
JavaVersionAndBuild versionAndBuild;
if (IOHelper.isFile(releaseFile)) {
Properties properties = new Properties();
properties.load(IOHelper.newReader(releaseFile));
versionAndBuild = getJavaVersion(properties.getProperty("JAVA_VERSION").replaceAll("\"", ""));
} else {
versionAndBuild = new JavaVersionAndBuild(isExistExtJavaLibrary(jvmDir, "jfxrt") ? 8 : 9, 0);
}
JavaVersion resultJavaVersion = new JavaVersion(jvmDir, versionAndBuild.version, versionAndBuild.build, false);
if (versionAndBuild.version <= 8) {
resultJavaVersion.enabledJavaFX = isExistExtJavaLibrary(jvmDir, "jfxrt");
} else {
resultJavaVersion.enabledJavaFX = tryFindModule(jvmDir, "javafx.base") != null;
if (!resultJavaVersion.enabledJavaFX)
resultJavaVersion.enabledJavaFX = tryFindModule(jvmDir.resolve("jre"), "javafx.base") != null;
}
return resultJavaVersion;
}
public static boolean isExistExtJavaLibrary(Path jvmDir, String name) {
Path jrePath = jvmDir.resolve("lib").resolve("ext").resolve(name.concat(".jar"));
Path jdkPath = jvmDir.resolve("jre").resolve("lib").resolve("ext").resolve(name.concat(".jar"));
return IOHelper.isFile(jrePath) || IOHelper.isFile(jdkPath);
}
}
}

View file

@ -11,6 +11,7 @@
import pro.gravit.launcher.profiles.ClientProfile; import pro.gravit.launcher.profiles.ClientProfile;
import pro.gravit.launcher.profiles.PlayerProfile; import pro.gravit.launcher.profiles.PlayerProfile;
import pro.gravit.launcher.profiles.optional.actions.OptionalAction; import pro.gravit.launcher.profiles.optional.actions.OptionalAction;
import pro.gravit.launcher.profiles.optional.triggers.OptionalTrigger;
import pro.gravit.launcher.request.Request; import pro.gravit.launcher.request.Request;
import pro.gravit.launcher.request.auth.AuthRequest; import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest; import pro.gravit.launcher.request.auth.GetAvailabilityAuthRequest;
@ -124,6 +125,7 @@ public void run(String... args) throws Throwable {
AuthRequest.registerProviders(); AuthRequest.registerProviders();
GetAvailabilityAuthRequest.registerProviders(); GetAvailabilityAuthRequest.registerProviders();
OptionalAction.registerProviders(); OptionalAction.registerProviders();
OptionalTrigger.registerProviders();
if (args.length > 0 && args[0].equals("setup") && !disableSetup) { if (args.length > 0 && args[0].equals("setup") && !disableSetup) {
LogHelper.debug("Read ServerWrapperConfig.json"); LogHelper.debug("Read ServerWrapperConfig.json");
loadConfig(); loadConfig();