diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/components/ProGuardComponent.java b/LaunchServer/src/main/java/pro/gravit/launchserver/components/ProGuardComponent.java index 520a80f4..ee92b7e0 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/components/ProGuardComponent.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/components/ProGuardComponent.java @@ -9,21 +9,23 @@ import pro.gravit.utils.command.SubCommand; import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.JVMHelper; +import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.SecurityHelper; import pro.gravit.utils.helper.UnpackHelper; -import proguard.Configuration; -import proguard.ConfigurationParser; -import proguard.ProGuard; import java.io.*; +import java.nio.file.FileVisitOption; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.SecureRandom; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; @@ -32,6 +34,7 @@ public class ProGuardComponent extends Component implements AutoCloseable, Recon private static final Logger logger = LogManager.getLogger(); public String modeAfter = "MainBuild"; public String dir = "proguard"; + public List jvmArgs = new ArrayList<>(); public boolean enabled = true; public boolean mappings = true; public transient ProguardConf proguardConf; @@ -39,6 +42,10 @@ public class ProGuardComponent extends Component implements AutoCloseable, Recon private transient ProGuardBuildTask buildTask; private transient ProGuardMultiReleaseFixer fixerTask; + public ProGuardComponent() { + this.jvmArgs.add("-Xmx512M"); + } + public static boolean checkFXJMods(Path path) { if (!IOHelper.exists(path.resolve("javafx.base.jmod"))) return false; @@ -191,7 +198,6 @@ public String getName() { public Path process(Path inputFile) throws IOException { Path outputJar = server.launcherBinary.nextLowerPath(this); if (component.enabled) { - Configuration proguard_cfg = new Configuration(); if (!checkJMods(IOHelper.JVM_DIR.resolve("jmods"))) { throw new RuntimeException("Java path: %s is not JDK! Please install JDK".formatted(IOHelper.JVM_DIR)); } @@ -204,12 +210,35 @@ public Path process(Path inputFile) throws IOException { } else { throw new RuntimeException("JavaFX jmods not found. May be install OpenJFX?"); } - ConfigurationParser parser = new ConfigurationParser(proguardConf.buildConfig(inputFile, outputJar, jfxPath == null ? new Path[0] : new Path[]{jfxPath}), - proguardConf.proguard.toFile(), System.getProperties()); try { - parser.parse(proguard_cfg); - ProGuard proGuard = new ProGuard(proguard_cfg); - proGuard.execute(); + List args = new ArrayList<>(); + args.add(IOHelper.resolveJavaBin(IOHelper.JVM_DIR).toAbsolutePath().toString()); + args.addAll(component.jvmArgs); + args.add("-cp"); + try(Stream files = Files.walk(Path.of("libraries"), FileVisitOption.FOLLOW_LINKS)) { + args.add(files + .filter(e -> e.getFileName().toString().endsWith(".jar")) + .map(path -> path.toAbsolutePath().toString()) + .collect(Collectors.joining(File.pathSeparator)) + ); + } + args.add("proguard.ProGuard"); + proguardConf.buildConfig(args, inputFile, outputJar, jfxPath == null ? new Path[0] : new Path[]{jfxPath}); + + Process process = new ProcessBuilder() + .command(args) + .inheritIO() + .directory(proguardConf.proguard.toFile()) + .start(); + + try { + process.waitFor(); + } catch (InterruptedException ignored) { + + } + if (process.exitValue() != 0) { + throw new RuntimeException("ProGuard process return %d".formatted(process.exitValue())); + } } catch (Exception e) { logger.error(e); } @@ -256,8 +285,7 @@ private static String generateString(SecureRandom rand, String lowString, String return sb.toString(); } - public String[] buildConfig(Path inputJar, Path outputJar, Path[] jfxPath) { - List confStrs = new ArrayList<>(); + public void buildConfig(List confStrs, Path inputJar, Path outputJar, Path[] jfxPath) { prepare(false); if (component.mappings) confStrs.add("-printmapping '" + mappings.toFile().getName() + "'"); @@ -279,7 +307,6 @@ public String[] buildConfig(Path inputJar, Path outputJar, Path[] jfxPath) { .forEach(confStrs::add); confStrs.add("-classobfuscationdictionary '" + words.toFile().getName() + "'"); confStrs.add("@".concat(config.toFile().getName())); - return confStrs.toArray(new String[0]); } private void genConfig(boolean force) throws IOException { diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java index a224e176..7352126b 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/ClientLauncherProcess.java @@ -171,6 +171,14 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException { LogHelper.debug("Commandline: %s", Arrays.toString(processArgs.toArray())); ProcessBuilder processBuilder = new ProcessBuilder(processArgs); EnvHelper.addEnv(processBuilder); + if(JVMHelper.OS_TYPE == JVMHelper.OS.LINUX){ + var env = processBuilder.environment(); + // https://github.com/Admicos/minecraft-wayland/issues/55 + env.put("__GL_THREADED_OPTIMIZATIONS", "0"); + if(params.lwjglGlfwWayland) { + env.remove("DISPLAY"); // No X11 + } + } processBuilder.environment().put("JAVA_HOME", javaVersion.jvmDir.toAbsolutePath().toString()); processBuilder.environment().putAll(systemEnv); processBuilder.directory(workDir.toFile()); diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/api/AuthService.java b/LauncherAPI/src/main/java/pro/gravit/launcher/api/AuthService.java index 0020d954..e96152a3 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/api/AuthService.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/api/AuthService.java @@ -7,6 +7,7 @@ import java.util.UUID; public class AuthService { + public static String projectName; public static String username; public static ClientPermissions permissions = new ClientPermissions(); public static UUID uuid; 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 70d9dd2a..681ba5b4 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java @@ -60,6 +60,8 @@ public final class ClientProfile implements Comparable { @LauncherNetworkAPI private List compatClasses; @LauncherNetworkAPI + private List loadNatives; + @LauncherNetworkAPI private Map properties; @LauncherNetworkAPI private List servers; @@ -253,6 +255,10 @@ public ProfileDefaultSettings getSettings() { return settings; } + public List getLoadNatives() { + return loadNatives; + } + public void updateOptionalGraph() { for (OptionalFile file : updateOptional) { if (file.dependenciesFile != null) { @@ -460,7 +466,7 @@ public enum ClassLoaderConfig { } public enum CompatibilityFlags { - LEGACY_NATIVES_DIR, CLASS_CONTROL_API, ENABLE_HACKS + LEGACY_NATIVES_DIR, CLASS_CONTROL_API, ENABLE_HACKS, WAYLAND_USE_CUSTOM_GLFW } public static class Version implements Comparable { diff --git a/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java index 15436bd5..b90f7958 100644 --- a/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java +++ b/LauncherClient/src/main/java/pro/gravit/launcher/client/ClientLauncherEntryPoint.java @@ -142,6 +142,12 @@ private static void realMain(String[] args) throws Throwable { LaunchOptions options = new LaunchOptions(); options.enableHacks = profile.hasFlag(ClientProfile.CompatibilityFlags.ENABLE_HACKS); options.moduleConf = profile.getModuleConf(); + ClientService.nativePath = params.nativesDir; + if(profile.getLoadNatives() != null) { + for(String e : profile.getLoadNatives()) { + System.load(Paths.get(params.nativesDir).resolve(ClientService.findLibrary(e)).toAbsolutePath().toString()); + } + } if (classLoaderConfig == ClientProfile.ClassLoaderConfig.LAUNCHER) { if(JVMHelper.JVM_VERSION <= 11) { launch = new LegacyLaunch(); @@ -151,7 +157,6 @@ private static void realMain(String[] args) throws Throwable { classLoaderControl = launch.init(classpath, params.nativesDir, options); System.setProperty("java.class.path", classpath.stream().map(Path::toString).collect(Collectors.joining(File.pathSeparator))); modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(launch, classLoaderControl, profile)); - ClientService.nativePath = params.nativesDir; ClientService.baseURLs = classLoaderControl.getURLs(); } else if (classLoaderConfig == ClientProfile.ClassLoaderConfig.AGENT) { launch = new BasicLaunch(LauncherAgent.inst); @@ -161,22 +166,21 @@ private static void realMain(String[] args) throws Throwable { LauncherAgent.addJVMClassPath(Paths.get(url.toURI())); } ClientService.instrumentation = LauncherAgent.inst; - ClientService.nativePath = params.nativesDir; modulesManager.invokeEvent(new ClientProcessClassLoaderEvent(launch, null, profile)); ClientService.baseURLs = classpathURLs.toArray(new URL[0]); } else if (classLoaderConfig == ClientProfile.ClassLoaderConfig.SYSTEM_ARGS) { launch = new BasicLaunch(); classLoaderControl = launch.init(classpath, params.nativesDir, options); ClientService.baseURLs = classpathURLs.toArray(new URL[0]); - ClientService.nativePath = params.nativesDir; } if(profile.hasFlag(ClientProfile.CompatibilityFlags.CLASS_CONTROL_API)) { ClientService.classLoaderControl = classLoaderControl; } - if(params.lwjglGlfwWayland) { - String glfwPath = ClientService.findLibrary("glfw_wayland"); - System.setProperty("org.lwjgl.glfw.libname", glfwPath); + if(params.lwjglGlfwWayland && profile.hasFlag(ClientProfile.CompatibilityFlags.WAYLAND_USE_CUSTOM_GLFW)) { + String glfwName = ClientService.findLibrary("glfw_wayland"); + System.setProperty("org.lwjgl.glfw.libname", glfwName); } + AuthService.projectName = Launcher.getConfig().projectName; AuthService.username = params.playerProfile.username; AuthService.uuid = params.playerProfile.uuid; KeyService.serverRsaPublicKey = Launcher.getConfig().rsaPublicKey; diff --git a/LauncherCore/src/main/java/pro/gravit/utils/Version.java b/LauncherCore/src/main/java/pro/gravit/utils/Version.java index d42ebb45..801c763c 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/Version.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/Version.java @@ -6,7 +6,7 @@ public final class Version implements Comparable { public static final int MAJOR = 5; public static final int MINOR = 5; - public static final int PATCH = 3; + public static final int PATCH = 4; public static final int BUILD = 1; public static final Version.Type RELEASE = Type.STABLE; public final int major; diff --git a/LauncherCore/src/main/java/pro/gravit/utils/helper/JVMHelper.java b/LauncherCore/src/main/java/pro/gravit/utils/helper/JVMHelper.java index e691aacb..bc029287 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/helper/JVMHelper.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/helper/JVMHelper.java @@ -46,7 +46,7 @@ private JVMHelper() { public static ARCH getArch(String arch) { if (arch.equals("amd64") || arch.equals("x86-64") || arch.equals("x86_64")) return ARCH.X86_64; - if (arch.equals("i386") || arch.equals("i686") || arch.equals("x86")) return ARCH.X86; + if (arch.equals("i386") || arch.equals("i586") || arch.equals("i686") || arch.equals("x86")) return ARCH.X86; if (arch.startsWith("armv8") || arch.startsWith("aarch64")) return ARCH.ARM64; if (arch.startsWith("arm") || arch.startsWith("aarch32")) return ARCH.ARM32; throw new InternalError(String.format("Unsupported arch '%s'", arch)); diff --git a/LauncherCore/src/main/java/pro/gravit/utils/helper/JavaHelper.java b/LauncherCore/src/main/java/pro/gravit/utils/helper/JavaHelper.java index a4d1f58f..96c54a79 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/helper/JavaHelper.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/helper/JavaHelper.java @@ -265,7 +265,6 @@ public static JavaVersion getByPath(Path jvmDir) { arch = JVMHelper.getArch(archProperty); } } catch (Throwable ignored) { - arch = null; } String modulesProperty = getProperty(properties, "MODULES"); if(modulesProperty != null) { diff --git a/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java b/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java index 4b82b2a3..42e85eec 100644 --- a/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java +++ b/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java @@ -27,6 +27,7 @@ import pro.gravit.utils.helper.SecurityHelper; import pro.gravit.utils.launch.*; +import java.io.File; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; @@ -183,12 +184,21 @@ public void run(String... args) throws Throwable { System.arraycopy(args, 1, real_args, 0, args.length - 1); } else real_args = args; Launch launch; + ClientService.nativePath = config.nativesDir; + ConfigService.serverName = config.serverName; + if(config.loadNatives != null) { + for(String e : config.loadNatives) { + System.load(Paths.get(config.nativesDir).resolve(ClientService.findLibrary(e)).toAbsolutePath().toString()); + } + } switch (config.classLoaderConfig) { case LAUNCHER: launch = new LegacyLaunch(); + System.setProperty("java.class.path", String.join(File.pathSeparator, config.classpath)); break; case MODULE: launch = new ModuleLaunch(); + System.setProperty("java.class.path", String.join(File.pathSeparator, config.classpath)); break; default: if(ServerAgent.isAgentStarted()) { @@ -207,13 +217,10 @@ public void run(String... args) throws Throwable { } ClientService.classLoaderControl = classLoaderControl; ClientService.baseURLs = classLoaderControl.getURLs(); - ClientService.nativePath = config.nativesDir; - ConfigService.serverName = config.serverName; if(config.configServiceSettings != null) { config.configServiceSettings.apply(); } LogHelper.info("Start Minecraft Server"); - LogHelper.debug("Invoke main method %s with %s", classname, launch.getClass().getName()); try { if(config.compatClasses != null) { for (String e : config.compatClasses) { @@ -222,6 +229,7 @@ public void run(String... args) throws Throwable { runMethod.invoke(classLoaderControl); } } + LogHelper.debug("Invoke main method %s with %s", classname, launch.getClass().getName()); launch.launch(config.mainclass, config.mainmodule, Arrays.asList(real_args)); } catch (Throwable e) { LogHelper.error(e); @@ -274,6 +282,7 @@ public static final class Config { public String nativesDir = "natives"; public List args; public List compatClasses; + public List loadNatives; public String authId; public AuthRequestEvent.OAuthRequestEvent oauth; public long oauthExpireTime; diff --git a/build.gradle b/build.gradle index 30340061..6c18cc21 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ id 'org.openjfx.javafxplugin' version '0.0.10' apply false } group = 'pro.gravit.launcher' -version = '5.5.3' +version = '5.5.4' apply from: 'props.gradle' diff --git a/props.gradle b/props.gradle index d8072da7..30ea7931 100644 --- a/props.gradle +++ b/props.gradle @@ -1,19 +1,19 @@ project.ext { verAsm = '9.6' verNetty = '4.1.99.Final' - verOshiCore = '6.4.6' + verOshiCore = '6.4.11' verJunit = '5.9.3' verGuavaC = '30.1.1-jre' - verJansi = '2.4.0' - verJline = '3.23.0' + verJansi = '2.4.1' + verJline = '3.25.0' verJwt = '0.11.5' verBcprov = '1.70' verGson = '2.10.1' verBcpkix = '1.70' verSlf4j = '1.7.36' verLog4j = '2.20.0' - verMySQLConn = '8.1.0' - verPostgreSQLConn = '42.6.0' - verProguard = '7.4.0' + verMySQLConn = '8.3.0' + verPostgreSQLConn = '42.7.1' + verProguard = '7.4.1' verLaunch4j = '3.50' }