From ca86fd49423853fb78f09c18d35839eadc5d63cb Mon Sep 17 00:00:00 2001 From: Owain van Brakel Date: Thu, 5 Dec 2019 12:37:16 +0100 Subject: [PATCH] client: connecting... --- .../java/net/runelite/client/RuneLite.java | 2 - .../client/rs/ClientConfigLoader.java | 121 ++++++++---------- .../net/runelite/client/rs/ClientLoader.java | 64 ++++++++- .../java/net/runelite/client/rs/RSConfig.java | 5 + .../client/ui/components/MessagePanel.java | 2 +- 5 files changed, 115 insertions(+), 79 deletions(-) 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 3ba63b48fa..1b5a09d14e 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -294,8 +294,6 @@ public class RuneLite RuneLiteSplashScreen.setError("Error while loading!", "Please check your internet connection and your DNS settings."); }); - RuneLiteSplashScreen.stage(0, "Starting OpenOSRS injector"); - PROFILES_DIR.mkdirs(); final long start = System.currentTimeMillis(); diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientConfigLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientConfigLoader.java index c43a981f3e..391d2c4a81 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientConfigLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientConfigLoader.java @@ -25,12 +25,12 @@ */ package net.runelite.client.rs; -import io.reactivex.Single; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import net.runelite.http.api.RuneLiteAPI; +import java.util.concurrent.TimeUnit; import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; @@ -38,80 +38,59 @@ class ClientConfigLoader { private ClientConfigLoader() { - throw new RuntimeException(); } - private static final String CONFIG_URL = "http://oldschool.runescape.com/jav_config.ws"; - private static final int MAX_ATTEMPTS = 100; - - static Single fetch() + static RSConfig fetch(HttpUrl url) throws IOException { - return Single.create(obs -> + final Request request = new Request.Builder() + .url(url) + .build(); + + final RSConfig config = new RSConfig(); + + OkHttpClient okHttpClient = new OkHttpClient.Builder() + .connectTimeout(2000, TimeUnit.MILLISECONDS) + .build(); + + try (final Response response = okHttpClient.newCall(request).execute()) { - int attempt = 0; - - HostSupplier supplier = null; - HttpUrl url = HttpUrl.parse(CONFIG_URL); - - final RSConfig config = new RSConfig(); - - while (attempt++ < MAX_ATTEMPTS) + if (!response.isSuccessful()) { - final Request request = new Request.Builder() - .url(url) - .build(); - - try (final Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) - { - if (!response.isSuccessful()) - { - if (supplier == null) - { - supplier = new HostSupplier(); - } - - String host = supplier.get(); - url = url.newBuilder().host(host).build(); - continue; - } - - String str; - final BufferedReader in = new BufferedReader(new InputStreamReader(response.body().byteStream())); - while ((str = in.readLine()) != null) - { - int idx = str.indexOf('='); - - if (idx == -1) - { - continue; - } - - String s = str.substring(0, idx); - - switch (s) - { - case "param": - str = str.substring(idx + 1); - idx = str.indexOf('='); - s = str.substring(0, idx); - - config.getAppletProperties().put(s, str.substring(idx + 1)); - break; - case "msg": - // ignore - break; - default: - config.getClassLoaderProperties().put(s, str.substring(idx + 1)); - break; - } - } - - obs.onSuccess(config); - return; - } + throw new IOException("Unsuccessful response: " + response.message()); } - obs.onError(new IOException("Too many attempts")); - }); + String str; + final BufferedReader in = new BufferedReader(new InputStreamReader(response.body().byteStream())); + while ((str = in.readLine()) != null) + { + int idx = str.indexOf('='); + + if (idx == -1) + { + continue; + } + + String s = str.substring(0, idx); + + switch (s) + { + case "param": + str = str.substring(idx + 1); + idx = str.indexOf('='); + s = str.substring(0, idx); + + config.getAppletProperties().put(s, str.substring(idx + 1)); + break; + case "msg": + // ignore + break; + default: + config.getClassLoaderProperties().put(s, str.substring(idx + 1)); + break; + } + } + } + + return config; } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java index bd5705c6c3..78e540f859 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java @@ -26,6 +26,7 @@ */ package net.runelite.client.rs; +import com.google.common.base.Strings; import com.google.common.io.ByteStreams; import java.applet.Applet; import java.io.IOException; @@ -36,13 +37,21 @@ import java.util.function.Supplier; import lombok.extern.slf4j.Slf4j; import net.runelite.client.RuneLite; import net.runelite.client.ui.RuneLiteSplashScreen; +import okhttp3.HttpUrl; @Slf4j public class ClientLoader implements Supplier { + private static final String CONFIG_URL = "http://oldschool.runescape.com/jav_config.ws"; + private static final String BACKUP_CONFIG_URL = "https://raw.githubusercontent.com/open-osrs/hosting/master/jav_config.ws"; + + private static final int NUM_ATTEMPTS = 6; private final ClientUpdateCheckMode updateCheckMode; private Object client = null; + private HostSupplier hostSupplier = new HostSupplier(); + private RSConfig config; + public ClientLoader(ClientUpdateCheckMode updateCheckMode) { this.updateCheckMode = updateCheckMode; @@ -67,11 +76,7 @@ public class ClientLoader implements Supplier { try { - RuneLiteSplashScreen.stage(.2, "Fetching applet viewer config"); - - final RSConfig config = ClientConfigLoader.fetch() - .retry(50) - .blockingGet(); + downloadConfig(); switch (updateCheckMode) { @@ -103,6 +108,55 @@ public class ClientLoader implements Supplier } } + private void downloadConfig() throws IOException + { + HttpUrl url = HttpUrl.parse(CONFIG_URL); + IOException err = null; + for (int attempt = 0; attempt < NUM_ATTEMPTS; attempt++) + { + RuneLiteSplashScreen.stage(.0, "Connecting with gameserver (try " + (attempt + 1) + "/" + NUM_ATTEMPTS + ")"); + try + { + config = ClientConfigLoader.fetch(url); + + if (Strings.isNullOrEmpty(config.getCodeBase()) || Strings.isNullOrEmpty(config.getInitialJar()) || Strings.isNullOrEmpty(config.getInitialClass())) + { + throw new IOException("Invalid or missing jav_config"); + } + + return; + } + catch (IOException e) + { + log.info("Failed to get jav_config from host \"{}\" ({})", url.host(), e.getMessage()); + String host = hostSupplier.get(); + url = url.newBuilder().host(host).build(); + err = e; + } + } + + log.info("Falling back to backup client config"); + + try + { + RSConfig backupConfig = ClientConfigLoader.fetch(HttpUrl.parse(BACKUP_CONFIG_URL)); + + if (Strings.isNullOrEmpty(backupConfig.getCodeBase()) || Strings.isNullOrEmpty(backupConfig.getInitialJar()) || Strings.isNullOrEmpty(backupConfig.getInitialClass())) + { + throw new IOException("Invalid or missing jav_config"); + } + + // Randomize the codebase + String codebase = hostSupplier.get(); + backupConfig.setCodebase("http://" + codebase + "/"); + config = backupConfig; + } + catch (IOException ex) + { + throw err; // use error from Jagex's servers + } + } + private static Applet loadRLPlus(final RSConfig config) throws ClassNotFoundException, InstantiationException, IllegalAccessException { diff --git a/runelite-client/src/main/java/net/runelite/client/rs/RSConfig.java b/runelite-client/src/main/java/net/runelite/client/rs/RSConfig.java index e0c5539323..df6de027ff 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/RSConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/RSConfig.java @@ -40,6 +40,11 @@ class RSConfig return classLoaderProperties.get("codebase"); } + void setCodebase(String codebase) + { + classLoaderProperties.put("codebase", codebase); + } + String getInitialJar() { return classLoaderProperties.get("initial_jar"); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/MessagePanel.java b/runelite-client/src/main/java/net/runelite/client/ui/components/MessagePanel.java index 3f125d0f60..e1f9d4d56c 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/MessagePanel.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/MessagePanel.java @@ -52,7 +52,7 @@ public class MessagePanel extends JPanel private final JLabel titleLabel = new JLabel("Welcome to OpenOSRS"); private final JLabel messageArea; - private final JLabel barLabel = new JLabel("Loading..."); + private final JLabel barLabel = new JLabel("Connecting with gameserver (try 1/6)"); private final JProgressBar bar = new JProgressBar(0, 100); @Getter(AccessLevel.NONE)