[Feature] Zoned natives

This commit is contained in:
Gravita 2021-11-26 18:57:18 +07:00
parent 64defdcc58
commit f9a55ca357
3 changed files with 73 additions and 10 deletions

View file

@ -1,13 +1,19 @@
package pro.gravit.launcher.client; package pro.gravit.launcher.client;
import pro.gravit.launcher.profiles.ClientProfile;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.JVMHelper; import pro.gravit.utils.helper.JVMHelper;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class ClientClassLoader extends URLClassLoader { public class ClientClassLoader extends URLClassLoader {
public String nativePath; public Path clientPath;
private ClientProfile profile;
/** /**
* Constructs a new URLClassLoader for the specified URLs using the * Constructs a new URLClassLoader for the specified URLs using the
@ -54,13 +60,25 @@ public ClientClassLoader(URL[] urls) {
* @throws NullPointerException if {@code urls} is {@code null}. * @throws NullPointerException if {@code urls} is {@code null}.
* @see SecurityManager#checkCreateClassLoader * @see SecurityManager#checkCreateClassLoader
*/ */
public ClientClassLoader(URL[] urls, ClassLoader parent) { public ClientClassLoader(URL[] urls, ClientProfile profile, ClassLoader parent) {
super(urls, parent); super(urls, parent);
this.profile = profile;
}
public Path resolveLibrary(String name) {
for(ClientProfile.ClientProfileLibrary library : profile.getLibraries()) {
if(library.type == ClientProfile.ClientProfileLibrary.LibraryType.NATIVE) {
if(library.name.equals(name)) {
return ClientLauncherEntryPoint.getLibraryPath(library);
}
}
}
return clientPath.resolve("natives").resolve(getNativePrefix().concat(name).concat(getNativeEx()));
} }
@Override @Override
public String findLibrary(String name) { public String findLibrary(String name) {
return nativePath.concat(IOHelper.PLATFORM_SEPARATOR).concat(getNativePrefix()).concat(name).concat(getNativeEx()); return resolveLibrary(name).toString();
} }
public String getNativeEx() { public String getNativeEx() {

View file

@ -45,10 +45,7 @@
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType; import java.lang.invoke.MethodType;
import java.net.*; import java.net.*;
import java.nio.file.FileVisitResult; import java.nio.file.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -56,6 +53,48 @@
public class ClientLauncherEntryPoint { public class ClientLauncherEntryPoint {
private static ClassLoader classLoader; private static ClassLoader classLoader;
private static List<ClientLauncherProcess.ClientParams.ClientZoneInfo> zones;
public static Path getLibraryPath(ClientProfile.ClientProfileLibrary library) {
Path basePath = IOHelper.WORKING_DIR;
if(!library.isDefaultZone()) {
for(ClientLauncherProcess.ClientParams.ClientZoneInfo zoneInfo : zones) {
if(library.zone.equals(zoneInfo.name)) {
basePath = Paths.get(zoneInfo.path);
break;
}
}
}
if(library.type == ClientProfile.ClientProfileLibrary.LibraryType.CLASSPATH || library.type == ClientProfile.ClientProfileLibrary.LibraryType.MODULEPATH || library.type == ClientProfile.ClientProfileLibrary.LibraryType.RUNTIME) {
return basePath.resolve("libraries").resolve(library.path);
} else if(library.type == ClientProfile.ClientProfileLibrary.LibraryType.NATIVE) {
Path path = basePath.resolve("natives").resolve(library.path);
if(Files.isDirectory(path)) {
path = path.resolve(getNativePrefix().concat(library.name).concat(getNativeEx()));
}
return path;
} else {
return basePath.resolve(library.path);
}
}
public static String getNativeEx() {
if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE)
return ".dll";
else if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX)
return ".so";
else if (JVMHelper.OS_TYPE == JVMHelper.OS.MACOSX)
return ".dylib";
return "";
}
public static String getNativePrefix() {
if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX)
return "lib";
else if (JVMHelper.OS_TYPE == JVMHelper.OS.MACOSX)
return "lib";
return "";
}
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
LauncherEngine engine = LauncherEngine.clientInstance(); LauncherEngine engine = LauncherEngine.clientInstance();
@ -85,6 +124,7 @@ public static void main(String[] args) throws Throwable {
Launcher.profile = profile; Launcher.profile = profile;
AuthService.profile = profile; AuthService.profile = profile;
LauncherEngine.clientParams = params; LauncherEngine.clientParams = params;
zones = params.zones;
if (params.oauth != null) { if (params.oauth != null) {
LogHelper.info("Using OAuth"); LogHelper.info("Using OAuth");
if (params.oauthExpiredTime != 0) { if (params.oauthExpiredTime != 0) {
@ -133,13 +173,13 @@ public static void main(String[] args) throws Throwable {
} }
ClientProfile.ClassLoaderConfig classLoaderConfig = profile.getClassLoaderConfig(); ClientProfile.ClassLoaderConfig classLoaderConfig = profile.getClassLoaderConfig();
if (classLoaderConfig == ClientProfile.ClassLoaderConfig.LAUNCHER) { if (classLoaderConfig == ClientProfile.ClassLoaderConfig.LAUNCHER) {
ClientClassLoader classLoader = new ClientClassLoader(classpath.toArray(new URL[0]), ClassLoader.getSystemClassLoader()); ClientClassLoader classLoader = new ClientClassLoader(classpath.toArray(new URL[0]), profile, ClassLoader.getSystemClassLoader());
ClientLauncherEntryPoint.classLoader = classLoader; ClientLauncherEntryPoint.classLoader = classLoader;
Thread.currentThread().setContextClassLoader(classLoader); Thread.currentThread().setContextClassLoader(classLoader);
classLoader.nativePath = clientDir.resolve("natives").toString(); classLoader.clientPath = clientDir;
LauncherEngine.modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(engine, classLoader, profile)); LauncherEngine.modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(engine, classLoader, profile));
ClientService.classLoader = classLoader; ClientService.classLoader = classLoader;
ClientService.nativePath = classLoader.nativePath; ClientService.nativePath = clientDir.resolve("natives").toString();
classLoader.addURL(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL()); classLoader.addURL(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL());
ClientService.baseURLs = classLoader.getURLs(); ClientService.baseURLs = classLoader.getURLs();
} else if (classLoaderConfig == ClientProfile.ClassLoaderConfig.AGENT) { } else if (classLoaderConfig == ClientProfile.ClassLoaderConfig.AGENT) {

View file

@ -10,6 +10,7 @@
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -138,6 +139,10 @@ public ClientProfileLibrary(String name) {
this.type = LibraryType.CLASSPATH; this.type = LibraryType.CLASSPATH;
} }
public boolean isDefaultZone() {
return zone == null || zone.isEmpty() || zone.equals("@");
}
public static String convertMavenPathToName(String path) { public static String convertMavenPathToName(String path) {
Matcher matcher = MAVEN_PATTERN.matcher(path); Matcher matcher = MAVEN_PATTERN.matcher(path);
if(matcher.matches()) { if(matcher.matches()) {