diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 3b0335af5c..177861af22 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -33,12 +33,15 @@ import com.google.inject.Injector; import java.io.File; import java.lang.management.ManagementFactory; import java.lang.management.RuntimeMXBean; +import java.net.Authenticator; +import java.net.PasswordAuthentication; import java.nio.file.Paths; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.Locale; +import java.util.Optional; import javax.annotation.Nullable; import javax.inject.Provider; import javax.inject.Singleton; @@ -62,6 +65,7 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.discord.DiscordService; import net.runelite.client.eventbus.EventBus; import net.runelite.client.externalplugins.ExternalPluginManager; +import net.runelite.client.game.WorldService; import net.runelite.client.plugins.OPRSExternalPluginManager; import net.runelite.client.rs.ClientLoader; import net.runelite.client.rs.ClientUpdateCheckMode; @@ -73,7 +77,10 @@ import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.WidgetOverlay; import net.runelite.client.ui.overlay.tooltip.TooltipOverlay; import net.runelite.client.ui.overlay.worldmap.WorldMapOverlay; +import net.runelite.client.util.WorldUtil; import net.runelite.http.api.RuneLiteAPI; +import net.runelite.http.api.worlds.World; +import net.runelite.http.api.worlds.WorldResult; import okhttp3.Cache; import okhttp3.OkHttpClient; import org.slf4j.LoggerFactory; @@ -132,6 +139,9 @@ public class RuneLite @Inject private Provider worldMapOverlay; + @Inject + private WorldService worldService; + @Inject @Nullable private Client client; @@ -151,6 +161,14 @@ public class RuneLite .withValuesConvertedBy(new ConfigFileConverter()) .defaultsTo(DEFAULT_SESSION_FILE); + final ArgumentAcceptingOptionSpec proxyInfo = parser + .accepts("proxy") + .withRequiredArg().ofType(String.class); + + final ArgumentAcceptingOptionSpec worldInfo = parser + .accepts("world") + .withRequiredArg().ofType(Integer.class); + final ArgumentAcceptingOptionSpec configfile = parser.accepts("config", "Use a specified config file") .withRequiredArg() .withValuesConvertedBy(new ConfigFileConverter()) @@ -185,6 +203,42 @@ public class RuneLite logger.setLevel(Level.DEBUG); } + if (options.has("proxy")) + { + String[] proxy = options.valueOf(proxyInfo).split(":"); + + if (proxy.length >= 2) + { + System.setProperty("socksProxyHost", proxy[0]); + System.setProperty("socksProxyPort", proxy[1]); + } + + if (proxy.length >= 4) + { + System.setProperty("java.net.socks.username", proxy[2]); + System.setProperty("java.net.socks.password", proxy[3]); + + final String user = proxy[2]; + final char[] pass = proxy[3].toCharArray(); + + Authenticator.setDefault(new Authenticator() + { + private final PasswordAuthentication auth = new PasswordAuthentication(user, pass); + + protected PasswordAuthentication getPasswordAuthentication() + { + return auth; + } + }); + } + } + + if (options.has("world")) + { + int world = options.valueOf(worldInfo); + System.setProperty("cli.world", String.valueOf(world)); + } + Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { log.error("Uncaught exception:", throwable); @@ -336,6 +390,10 @@ public class RuneLite SplashScreen.stop(); clientUI.show(); + + //Set the world if specified via CLI args - will not work until clientUI.init is called + Optional worldArg = Optional.ofNullable(System.getProperty("cli.world")).map(Integer::parseInt); + worldArg.ifPresent(this::setWorld); } @VisibleForTesting @@ -383,6 +441,44 @@ public class RuneLite } } + private void setWorld(int cliWorld) + { + int correctedWorld = cliWorld < 300 ? cliWorld + 300 : cliWorld; + + if (correctedWorld <= 300 || client.getWorld() == correctedWorld) + { + return; + } + + final WorldResult worldResult = worldService.getWorlds(); + + if (worldResult == null) + { + log.warn("Failed to lookup worlds."); + return; + } + + final World world = worldResult.findWorld(correctedWorld); + + if (world != null) + { + final net.runelite.api.World rsWorld = client.createWorld(); + rsWorld.setActivity(world.getActivity()); + rsWorld.setAddress(world.getAddress()); + rsWorld.setId(world.getId()); + rsWorld.setPlayerCount(world.getPlayers()); + rsWorld.setLocation(world.getLocation()); + rsWorld.setTypes(WorldUtil.toWorldTypes(world.getTypes())); + + client.changeWorld(rsWorld); + log.debug("Applied new world {}", correctedWorld); + } + else + { + log.warn("World {} not found.", correctedWorld); + } + } + private static void setupInsecureTrustManager(OkHttpClient.Builder okHttpClientBuilder) { try diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java b/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java index 2be480f85e..c15287a263 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java @@ -34,6 +34,7 @@ import okhttp3.HttpUrl; public class RuneLiteProperties { + private static final String RUNELITE_TITLE = "runelite.title"; private static final String RUNELITE_VERSION = "runelite.version"; private static final String DISCORD_INVITE = "runelite.discord.invite"; private static final String LAUNCHER_VERSION_PROPERTY = "runelite.launcher.version"; @@ -61,6 +62,17 @@ public class RuneLiteProperties } } + public static String getTitle() + { + final StringBuilder sb = new StringBuilder(properties.getProperty(RUNELITE_TITLE)); + String proxy; + if ((proxy = System.getProperty("socksProxyHost")) != null) + { + sb.append(String.format(" (%s)", proxy)); + } + return sb.toString(); + } + public static String getVersion() { return properties.getProperty(RUNELITE_VERSION); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java index 9010f9a8d0..210ee8b935 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/defaultworld/DefaultWorldPlugin.java @@ -152,6 +152,11 @@ public class DefaultWorldPlugin extends Plugin log.debug("Stored old world {}", worldCache); } + if (System.getProperty("cli.world") != null) + { + return; + } + final int newWorld = !config.useLastWorld() ? config.getWorld() : config.lastWorld(); changeWorld(newWorld); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index a33c6c4757..4a631166c4 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -71,6 +71,7 @@ import net.runelite.api.Point; import net.runelite.api.events.GameStateChanged; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.RuneLiteProperties; import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ExpandResizeType; @@ -121,7 +122,6 @@ public class ClientUI private final Provider clientThreadProvider; private final EventBus eventBus; private final boolean safeMode; - private final String title; private final CardLayout cardLayout = new CardLayout(); private final Rectangle sidebarButtonPosition = new Rectangle(); @@ -153,8 +153,7 @@ public class ClientUI ConfigManager configManager, Provider clientThreadProvider, EventBus eventBus, - @Named("safeMode") boolean safeMode, - @Named("runelite.title") String title + @Named("safeMode") boolean safeMode ) { this.config = config; @@ -165,7 +164,6 @@ public class ClientUI this.clientThreadProvider = clientThreadProvider; this.eventBus = eventBus; this.safeMode = safeMode; - this.title = title; } @Subscribe @@ -298,7 +296,7 @@ public class ClientUI return false; } - frame.setTitle(title + " - " + name); + frame.setTitle(RuneLiteProperties.getTitle() + " - " + name); return true; }); } @@ -325,7 +323,7 @@ public class ClientUI // Try to enable fullscreen on OSX OSXUtil.tryEnableFullscreen(frame); - frame.setTitle(title); + frame.setTitle(RuneLiteProperties.getTitle()); frame.setIconImage(ICON); frame.getLayeredPane().setCursor(Cursor.getDefaultCursor()); // Prevent substance from using a resize cursor for pointing frame.setLocationRelativeTo(frame.getOwner()); @@ -511,7 +509,7 @@ public class ClientUI frame.revalidateMinimumSize(); // Create tray icon (needs to be created after frame is packed) - trayIcon = SwingUtil.createTrayIcon(ICON, title, frame); + trayIcon = SwingUtil.createTrayIcon(ICON, RuneLiteProperties.getTitle(), frame); // Move frame around (needs to be done after frame is packed) if (config.rememberScreenBounds() && !safeMode) @@ -1038,12 +1036,12 @@ public class ClientUI if (player != null && player.getName() != null) { - frame.setTitle(title + " - " + player.getName()); + frame.setTitle(RuneLiteProperties.getTitle() + " - " + player.getName()); } } else { - frame.setTitle(title); + frame.setTitle(RuneLiteProperties.getTitle()); } if (frame.isAlwaysOnTopSupported())