From 079e27c840170b0a8636eaf46b4af42c25bc3f9f Mon Sep 17 00:00:00 2001 From: RaphiMC <50594595+RaphiMC@users.noreply.github.com> Date: Wed, 3 Jul 2024 11:38:34 +0200 Subject: [PATCH] Fixed CWD issues on Windows Fixes issues where ViaProxy wouldn't run when double-clicking the jar file --- .../java/net/raphimc/viaproxy/ViaProxy.java | 53 +++++++++++++++---- .../viaproxy/plugins/PluginManager.java | 2 +- .../ProtocolTranslator.java | 2 +- .../impl/ViaProxyViaVersionPlatformImpl.java | 2 +- .../raphimc/viaproxy/saves/SaveManager.java | 3 +- .../viaproxy/tasks/UpdateCheckTask.java | 10 ++-- .../viaproxy/ui/impl/UISettingsTab.java | 10 ++-- .../util/ClassLoaderPriorityUtil.java | 3 +- .../net/raphimc/viaproxy/util/JarUtil.java | 40 ++++++++++++++ src/main/resources/log4j2.xml | 4 +- 10 files changed, 101 insertions(+), 28 deletions(-) create mode 100644 src/main/java/net/raphimc/viaproxy/util/JarUtil.java diff --git a/src/main/java/net/raphimc/viaproxy/ViaProxy.java b/src/main/java/net/raphimc/viaproxy/ViaProxy.java index db4967c..06aac05 100644 --- a/src/main/java/net/raphimc/viaproxy/ViaProxy.java +++ b/src/main/java/net/raphimc/viaproxy/ViaProxy.java @@ -53,6 +53,7 @@ import net.raphimc.viaproxy.ui.SplashScreen; import net.raphimc.viaproxy.ui.ViaProxyWindow; import net.raphimc.viaproxy.util.AddressUtil; import net.raphimc.viaproxy.util.ClassLoaderPriorityUtil; +import net.raphimc.viaproxy.util.JarUtil; import net.raphimc.viaproxy.util.logging.Logger; import javax.swing.*; @@ -61,6 +62,9 @@ import java.io.File; import java.io.IOException; import java.lang.instrument.Instrumentation; import java.lang.reflect.InvocationTargetException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; @@ -70,6 +74,7 @@ public class ViaProxy { public static final String IMPL_VERSION = "${impl_version}"; public static final LambdaManager EVENT_MANAGER = LambdaManager.threadSafe(new LambdaMetaFactoryGenerator(JavaBypass.TRUSTED_LOOKUP)); + private static /*final*/ File CWD; private static /*final*/ PluginManager PLUGIN_MANAGER; private static /*final*/ SaveManager SAVE_MANAGER; private static /*final*/ ViaProxyConfig CONFIG; @@ -107,17 +112,37 @@ public class ViaProxy { } public static void injectedMain(final String injectionMethod, final String[] args) throws InterruptedException, IOException, InvocationTargetException { - Logger.setup(); - final boolean useUI = args.length == 0 && !GraphicsEnvironment.isHeadless(); final boolean useConfig = args.length == 2 && args[0].equals("config"); final boolean useCLI = args.length > 0 && args[0].equals("cli"); - if (!useUI && !useConfig && !useCLI) { - String fileName = "ViaProxy.jar"; - try { - fileName = new File(ViaProxy.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getName(); - } catch (Throwable ignored) { + + final List potentialCwds = new ArrayList<>(); + potentialCwds.add(new File(System.getProperty("user.dir"))); + potentialCwds.add(new File(".")); + JarUtil.getJarFile().map(File::getParentFile).ifPresent(potentialCwds::add); + + final List failedCwds = new ArrayList<>(); + for (File potentialCwd : potentialCwds) { + if (potentialCwd.isDirectory()) { + if (Files.isWritable(potentialCwd.toPath())) { + CWD = potentialCwd; + break; + } } + failedCwds.add(potentialCwd); + } + if (CWD != null) { + System.setProperty("user.dir", CWD.getAbsolutePath()); + } else if (useUI) { + JOptionPane.showMessageDialog(null, "Could not find a suitable directory to use as working directory. Make sure that the current folder is writeable.", "ViaProxy", JOptionPane.ERROR_MESSAGE); + System.exit(1); + } else { + throw new IllegalStateException("Could not find a suitable directory to use as working directory. Make sure that the current folder is writeable."); + } + + Logger.setup(); + if (!useUI && !useConfig && !useCLI) { + final String fileName = JarUtil.getJarFile().map(File::getName).orElse("ViaProxy.jar"); Logger.LOGGER.info("Usage: java -jar " + fileName + " | Starts ViaProxy in graphical mode if available"); Logger.LOGGER.info("Usage: java -jar " + fileName + " config | Starts ViaProxy with the specified config file"); Logger.LOGGER.info("Usage: java -jar " + fileName + " cli --help | Starts ViaProxy in CLI mode"); @@ -127,7 +152,13 @@ public class ViaProxy { Logger.LOGGER.info("Initializing ViaProxy {} v{} ({}) (Injected using {})...", useUI ? "GUI" : "CLI", VERSION, IMPL_VERSION, injectionMethod); Logger.LOGGER.info("Using java version: " + System.getProperty("java.vm.name") + " " + System.getProperty("java.version") + " (" + System.getProperty("java.vendor") + ") on " + System.getProperty("os.name")); Logger.LOGGER.info("Available memory (bytes): " + Runtime.getRuntime().maxMemory()); - Logger.LOGGER.info("Working directory: " + System.getProperty("user.dir")); + Logger.LOGGER.info("Working directory: " + CWD.getAbsolutePath()); + if (!failedCwds.isEmpty()) { + Logger.LOGGER.warn("Failed to use the following directories as working directory:"); + for (File failedCwd : failedCwds) { + Logger.LOGGER.warn("\t- " + failedCwd.getAbsolutePath()); + } + } if (System.getProperty("ignoreSystemRequirements") == null) { if ("32".equals(System.getProperty("sun.arch.data.model")) && Runtime.getRuntime().maxMemory() < 256 * 1024 * 1024) { Logger.LOGGER.fatal("ViaProxy is not able to run on 32bit Java."); @@ -179,7 +210,7 @@ public class ViaProxy { if (useConfig) { viaProxyConfigFile = new File(args[1]); } else { - viaProxyConfigFile = new File("viaproxy.yml"); + viaProxyConfigFile = new File(ViaProxy.getCwd(), "viaproxy.yml"); } final boolean firstStart = !viaProxyConfigFile.exists(); @@ -275,6 +306,10 @@ public class ViaProxy { CLIENT_CHANNELS = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); } + public static File getCwd() { + return CWD; + } + public static PluginManager getPluginManager() { return PLUGIN_MANAGER; } diff --git a/src/main/java/net/raphimc/viaproxy/plugins/PluginManager.java b/src/main/java/net/raphimc/viaproxy/plugins/PluginManager.java index 4c91ab8..0285141 100644 --- a/src/main/java/net/raphimc/viaproxy/plugins/PluginManager.java +++ b/src/main/java/net/raphimc/viaproxy/plugins/PluginManager.java @@ -41,7 +41,7 @@ import java.util.Map; public class PluginManager { - public static final File PLUGINS_DIR = new File("plugins"); + public static final File PLUGINS_DIR = new File(ViaProxy.getCwd(), "plugins"); private final Yaml yaml = new Yaml(); private final IClassProvider rootClassProvider = new GuavaClassPathProvider(); diff --git a/src/main/java/net/raphimc/viaproxy/protocoltranslator/ProtocolTranslator.java b/src/main/java/net/raphimc/viaproxy/protocoltranslator/ProtocolTranslator.java index 7716cd8..8b30aed 100644 --- a/src/main/java/net/raphimc/viaproxy/protocoltranslator/ProtocolTranslator.java +++ b/src/main/java/net/raphimc/viaproxy/protocoltranslator/ProtocolTranslator.java @@ -69,7 +69,7 @@ public class ProtocolTranslator { } private static void patchConfigs() { - final File configFolder = new File("ViaLoader"); + final File configFolder = new File(ViaProxy.getCwd(), "ViaLoader"); configFolder.mkdirs(); try { diff --git a/src/main/java/net/raphimc/viaproxy/protocoltranslator/impl/ViaProxyViaVersionPlatformImpl.java b/src/main/java/net/raphimc/viaproxy/protocoltranslator/impl/ViaProxyViaVersionPlatformImpl.java index c80f2b8..194289b 100644 --- a/src/main/java/net/raphimc/viaproxy/protocoltranslator/impl/ViaProxyViaVersionPlatformImpl.java +++ b/src/main/java/net/raphimc/viaproxy/protocoltranslator/impl/ViaProxyViaVersionPlatformImpl.java @@ -29,7 +29,7 @@ import java.util.UUID; public class ViaProxyViaVersionPlatformImpl extends ViaVersionPlatformImpl { public ViaProxyViaVersionPlatformImpl() { - super(null); + super(ViaProxy.getCwd()); } @Override diff --git a/src/main/java/net/raphimc/viaproxy/saves/SaveManager.java b/src/main/java/net/raphimc/viaproxy/saves/SaveManager.java index f8f84f1..619fa43 100644 --- a/src/main/java/net/raphimc/viaproxy/saves/SaveManager.java +++ b/src/main/java/net/raphimc/viaproxy/saves/SaveManager.java @@ -21,6 +21,7 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.lenni0451.reflect.stream.RStream; +import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.saves.impl.AccountsSaveV3; import net.raphimc.viaproxy.saves.impl.UISave; import net.raphimc.viaproxy.util.logging.Logger; @@ -31,7 +32,7 @@ import java.io.FileWriter; public class SaveManager { - private static final File SAVE_FILE = new File("saves.json"); + private static final File SAVE_FILE = new File(ViaProxy.getCwd(), "saves.json"); private static final Gson GSON = new Gson(); public final AccountsSaveV3 accountsSave = new AccountsSaveV3(); diff --git a/src/main/java/net/raphimc/viaproxy/tasks/UpdateCheckTask.java b/src/main/java/net/raphimc/viaproxy/tasks/UpdateCheckTask.java index 29fd6f0..30f0b4e 100644 --- a/src/main/java/net/raphimc/viaproxy/tasks/UpdateCheckTask.java +++ b/src/main/java/net/raphimc/viaproxy/tasks/UpdateCheckTask.java @@ -26,11 +26,11 @@ import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ui.I18n; import net.raphimc.viaproxy.ui.ViaProxyWindow; import net.raphimc.viaproxy.ui.popups.DownloadPopup; +import net.raphimc.viaproxy.util.JarUtil; import net.raphimc.viaproxy.util.logging.Logger; import javax.swing.*; import java.io.File; -import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; @@ -77,7 +77,7 @@ public class UpdateCheckTask implements Runnable { } if (updateAvailable) { Logger.LOGGER.warn("You are running an outdated version of ViaProxy! Latest version: " + latestVersion); - if (this.hasUI) { + if (this.hasUI && JarUtil.getJarFile().isPresent()) { final boolean runsJava8 = System.getProperty("java.version").startsWith("1.8"); JsonArray assets = object.getAsJsonArray("assets"); boolean found = false; @@ -103,13 +103,13 @@ public class UpdateCheckTask implements Runnable { private void showUpdateQuestion(final String name, final String downloadUrl, final String latestVersion) { int chosen = JOptionPane.showConfirmDialog(ViaProxy.getForegroundWindow(), I18n.get("popup.update.info", VERSION, latestVersion) + "\n\n" + I18n.get("popup.update.question"), "ViaProxy", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (chosen == JOptionPane.YES_OPTION) { - File f = new File(name); + final File f = new File(JarUtil.getJarFile().map(File::getParentFile).orElseThrow(), name); new DownloadPopup(ViaProxy.getForegroundWindow(), downloadUrl, f, () -> SwingUtilities.invokeLater(() -> { JOptionPane.showMessageDialog(ViaProxy.getForegroundWindow(), I18n.get("popup.update.success"), "ViaProxy", JOptionPane.INFORMATION_MESSAGE); try { - Runtime.getRuntime().exec(new String[]{System.getProperty("java.home") + "/bin/java", "-jar", f.getAbsolutePath()}); + JarUtil.launch(f); System.exit(0); - } catch (IOException e) { + } catch (Throwable e) { Logger.LOGGER.error("Could not start the new ViaProxy jar", e); ViaProxyWindow.showException(e); } diff --git a/src/main/java/net/raphimc/viaproxy/ui/impl/UISettingsTab.java b/src/main/java/net/raphimc/viaproxy/ui/impl/UISettingsTab.java index a7824f0..2ac69e7 100644 --- a/src/main/java/net/raphimc/viaproxy/ui/impl/UISettingsTab.java +++ b/src/main/java/net/raphimc/viaproxy/ui/impl/UISettingsTab.java @@ -18,17 +18,14 @@ package net.raphimc.viaproxy.ui.impl; import net.lenni0451.commons.swing.GBC; -import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ui.I18n; import net.raphimc.viaproxy.ui.UITab; import net.raphimc.viaproxy.ui.ViaProxyWindow; +import net.raphimc.viaproxy.util.JarUtil; import net.raphimc.viaproxy.util.logging.Logger; import javax.swing.*; import java.awt.*; -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; import static net.raphimc.viaproxy.ui.ViaProxyWindow.BORDER_PADDING; @@ -65,10 +62,9 @@ public class UISettingsTab extends UITab { I18n.setLocale(locale); ViaProxyWindow.showInfo(I18n.get("tab.ui_settings.language.success", I18n.get("language.name"), locale)); try { - final File f = new File(ViaProxy.class.getProtectionDomain().getCodeSource().getLocation().toURI()); - Runtime.getRuntime().exec(new String[]{System.getProperty("java.home") + "/bin/java", "-jar", f.getAbsolutePath()}); + JarUtil.launch(JarUtil.getJarFile().orElseThrow()); System.exit(0); - } catch (URISyntaxException | IOException e) { + } catch (Throwable e) { Logger.LOGGER.error("Could not start the ViaProxy jar", e); ViaProxyWindow.showException(e); System.exit(1); diff --git a/src/main/java/net/raphimc/viaproxy/util/ClassLoaderPriorityUtil.java b/src/main/java/net/raphimc/viaproxy/util/ClassLoaderPriorityUtil.java index a045024..5484cfa 100644 --- a/src/main/java/net/raphimc/viaproxy/util/ClassLoaderPriorityUtil.java +++ b/src/main/java/net/raphimc/viaproxy/util/ClassLoaderPriorityUtil.java @@ -18,6 +18,7 @@ package net.raphimc.viaproxy.util; import net.lenni0451.reflect.ClassLoaders; +import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.util.logging.Logger; import java.io.File; @@ -25,7 +26,7 @@ import java.io.File; public class ClassLoaderPriorityUtil { public static void loadOverridingJars() { - final File jarsFolder = new File("jars"); + final File jarsFolder = new File(ViaProxy.getCwd(), "jars"); if (!jarsFolder.exists()) { jarsFolder.mkdir(); return; diff --git a/src/main/java/net/raphimc/viaproxy/util/JarUtil.java b/src/main/java/net/raphimc/viaproxy/util/JarUtil.java new file mode 100644 index 0000000..73a52dc --- /dev/null +++ b/src/main/java/net/raphimc/viaproxy/util/JarUtil.java @@ -0,0 +1,40 @@ +/* + * This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy + * Copyright (C) 2021-2024 RK_01/RaphiMC and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.raphimc.viaproxy.util; + +import net.raphimc.viaproxy.ViaProxy; + +import java.io.File; +import java.io.IOException; +import java.util.Optional; + +public class JarUtil { + + public static Optional getJarFile() { + try { + return Optional.of(new File(ViaProxy.class.getProtectionDomain().getCodeSource().getLocation().toURI())); + } catch (Throwable ignored) { + return Optional.empty(); + } + } + + public static void launch(final File jarFile) throws IOException { + new ProcessBuilder(System.getProperty("java.home") + "/bin/java", "-jar", jarFile.getAbsolutePath()).directory(ViaProxy.getCwd()).start(); + } + +} diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 8bbff14..47b2bc3 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -7,7 +7,7 @@ - + @@ -16,7 +16,7 @@ - +