diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java index 55956b16..a8c6b48b 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientClassLoader.java @@ -1,13 +1,19 @@ package pro.gravit.launcher.client; +import pro.gravit.launcher.profiles.ClientProfile; import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.JVMHelper; import java.net.URL; 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 String nativePath; + public Path clientPath; + private ClientProfile profile; /** * Constructs a new URLClassLoader for the specified URLs using the @@ -54,13 +60,25 @@ public class ClientClassLoader extends URLClassLoader { * @throws NullPointerException if {@code urls} is {@code null}. * @see SecurityManager#checkCreateClassLoader */ - public ClientClassLoader(URL[] urls, ClassLoader parent) { + public ClientClassLoader(URL[] urls, ClientProfile profile, ClassLoader 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 public String findLibrary(String name) { - return nativePath.concat(IOHelper.PLATFORM_SEPARATOR).concat(getNativePrefix()).concat(name).concat(getNativeEx()); + return resolveLibrary(name).toString(); } public String getNativeEx() { diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java index 0c92003e..499ee8ee 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java @@ -45,10 +45,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.net.*; -import java.nio.file.FileVisitResult; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; +import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.*; import java.util.stream.Collectors; @@ -56,6 +53,48 @@ import java.util.stream.Stream; public class ClientLauncherEntryPoint { private static ClassLoader classLoader; + private static List 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 { LauncherEngine engine = LauncherEngine.clientInstance(); @@ -85,6 +124,7 @@ public class ClientLauncherEntryPoint { Launcher.profile = profile; AuthService.profile = profile; LauncherEngine.clientParams = params; + zones = params.zones; if (params.oauth != null) { LogHelper.info("Using OAuth"); if (params.oauthExpiredTime != 0) { @@ -133,13 +173,13 @@ public class ClientLauncherEntryPoint { } ClientProfile.ClassLoaderConfig classLoaderConfig = profile.getClassLoaderConfig(); 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; Thread.currentThread().setContextClassLoader(classLoader); - classLoader.nativePath = clientDir.resolve("natives").toString(); + classLoader.clientPath = clientDir; LauncherEngine.modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(engine, classLoader, profile)); ClientService.classLoader = classLoader; - ClientService.nativePath = classLoader.nativePath; + ClientService.nativePath = clientDir.resolve("natives").toString(); classLoader.addURL(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toUri().toURL()); ClientService.baseURLs = classLoader.getURLs(); } else if (classLoaderConfig == ClientProfile.ClassLoaderConfig.AGENT) { diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java index 714b85a7..dcfb873f 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java @@ -10,6 +10,7 @@ import pro.gravit.utils.helper.VerifyHelper; import java.io.IOException; import java.net.InetSocketAddress; +import java.nio.file.Path; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -138,6 +139,10 @@ public final class ClientProfile implements Comparable { this.type = LibraryType.CLASSPATH; } + public boolean isDefaultZone() { + return zone == null || zone.isEmpty() || zone.equals("@"); + } + public static String convertMavenPathToName(String path) { Matcher matcher = MAVEN_PATTERN.matcher(path); if(matcher.matches()) {