clientloader: use fallback config if gamepack fails to load
This commit is contained in:
@@ -49,12 +49,13 @@ import java.security.cert.CertificateException;
|
|||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.jar.JarInputStream;
|
import java.util.jar.JarInputStream;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
@@ -66,9 +67,9 @@ import static net.runelite.client.rs.ClientUpdateCheckMode.VANILLA;
|
|||||||
import net.runelite.client.ui.FatalErrorDialog;
|
import net.runelite.client.ui.FatalErrorDialog;
|
||||||
import net.runelite.client.ui.SplashScreen;
|
import net.runelite.client.ui.SplashScreen;
|
||||||
import net.runelite.client.util.CountingInputStream;
|
import net.runelite.client.util.CountingInputStream;
|
||||||
|
import net.runelite.client.util.VerificationException;
|
||||||
import net.runelite.http.api.RuneLiteAPI;
|
import net.runelite.http.api.RuneLiteAPI;
|
||||||
import net.runelite.http.api.worlds.World;
|
import net.runelite.http.api.worlds.World;
|
||||||
import net.runelite.client.util.VerificationException;
|
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
@@ -86,7 +87,6 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
private Object client = null;
|
private Object client = null;
|
||||||
|
|
||||||
private WorldSupplier worldSupplier = new WorldSupplier();
|
private WorldSupplier worldSupplier = new WorldSupplier();
|
||||||
private RSConfig config;
|
|
||||||
|
|
||||||
public ClientLoader(ClientUpdateCheckMode updateCheckMode)
|
public ClientLoader(ClientUpdateCheckMode updateCheckMode)
|
||||||
{
|
{
|
||||||
@@ -118,7 +118,7 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
SplashScreen.stage(0, null, "Fetching applet viewer config");
|
SplashScreen.stage(0, null, "Fetching applet viewer config");
|
||||||
downloadConfig();
|
RSConfig config = downloadConfig();
|
||||||
|
|
||||||
SplashScreen.stage(.05, null, "Waiting for other clients to start");
|
SplashScreen.stage(.05, null, "Waiting for other clients to start");
|
||||||
|
|
||||||
@@ -129,7 +129,24 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
FileLock flock = lockfile.lock())
|
FileLock flock = lockfile.lock())
|
||||||
{
|
{
|
||||||
SplashScreen.stage(.05, null, "Downloading Old School RuneScape");
|
SplashScreen.stage(.05, null, "Downloading Old School RuneScape");
|
||||||
updateVanilla();
|
try
|
||||||
|
{
|
||||||
|
updateVanilla(config);
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
// try again with the fallback config and gamepack
|
||||||
|
if (!config.isFallback())
|
||||||
|
{
|
||||||
|
log.warn("Unable to download game client, attempting to use fallback config", ex);
|
||||||
|
config = downloadFallbackConfig();
|
||||||
|
updateVanilla(config);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (updateCheckMode == AUTO)
|
if (updateCheckMode == AUTO)
|
||||||
{
|
{
|
||||||
@@ -146,7 +163,7 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
|
|
||||||
SplashScreen.stage(.465, "Starting", "Starting Old School RuneScape");
|
SplashScreen.stage(.465, "Starting", "Starting Old School RuneScape");
|
||||||
|
|
||||||
Applet rs = loadClient(classLoader);
|
Applet rs = loadClient(config, classLoader);
|
||||||
|
|
||||||
SplashScreen.stage(.5, null, "Starting core classes");
|
SplashScreen.stage(.5, null, "Starting core classes");
|
||||||
|
|
||||||
@@ -162,7 +179,7 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downloadConfig() throws IOException
|
private RSConfig downloadConfig() throws IOException
|
||||||
{
|
{
|
||||||
HttpUrl url = HttpUrl.parse(RuneLiteProperties.getJavConfig());
|
HttpUrl url = HttpUrl.parse(RuneLiteProperties.getJavConfig());
|
||||||
IOException err = null;
|
IOException err = null;
|
||||||
@@ -170,14 +187,14 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
config = ClientConfigLoader.fetch(url);
|
RSConfig config = ClientConfigLoader.fetch(url);
|
||||||
|
|
||||||
if (Strings.isNullOrEmpty(config.getCodeBase()) || Strings.isNullOrEmpty(config.getInitialJar()) || Strings.isNullOrEmpty(config.getInitialClass()))
|
if (Strings.isNullOrEmpty(config.getCodeBase()) || Strings.isNullOrEmpty(config.getInitialJar()) || Strings.isNullOrEmpty(config.getInitialClass()))
|
||||||
{
|
{
|
||||||
throw new IOException("Invalid or missing jav_config");
|
throw new IOException("Invalid or missing jav_config");
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return config;
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
@@ -192,35 +209,42 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RSConfig backupConfig = ClientConfigLoader.fetch(HttpUrl.parse(RuneLiteProperties.getJavConfigBackup()));
|
return downloadFallbackConfig();
|
||||||
|
|
||||||
if (Strings.isNullOrEmpty(backupConfig.getCodeBase()) || Strings.isNullOrEmpty(backupConfig.getInitialJar()) || Strings.isNullOrEmpty(backupConfig.getInitialClass()))
|
|
||||||
{
|
|
||||||
throw new IOException("Invalid or missing jav_config");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Strings.isNullOrEmpty(backupConfig.getRuneLiteGamepack()) || Strings.isNullOrEmpty(backupConfig.getRuneLiteWorldParam()))
|
|
||||||
{
|
|
||||||
throw new IOException("Backup config does not have RuneLite gamepack url");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Randomize the codebase
|
|
||||||
World world = worldSupplier.get();
|
|
||||||
backupConfig.setCodebase("http://" + world.getAddress() + "/");
|
|
||||||
|
|
||||||
// Update the world applet parameter
|
|
||||||
Map<String, String> appletProperties = backupConfig.getAppletProperties();
|
|
||||||
appletProperties.put(backupConfig.getRuneLiteWorldParam(), Integer.toString(world.getId()));
|
|
||||||
|
|
||||||
config = backupConfig;
|
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
|
log.debug("error downloading backup config", ex);
|
||||||
throw err; // use error from Jagex's servers
|
throw err; // use error from Jagex's servers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateVanilla() throws IOException, VerificationException
|
@Nonnull
|
||||||
|
private RSConfig downloadFallbackConfig() throws IOException
|
||||||
|
{
|
||||||
|
RSConfig backupConfig = ClientConfigLoader.fetch(HttpUrl.parse(RuneLiteProperties.getJavConfigBackup()));
|
||||||
|
|
||||||
|
if (Strings.isNullOrEmpty(backupConfig.getCodeBase()) || Strings.isNullOrEmpty(backupConfig.getInitialJar()) || Strings.isNullOrEmpty(backupConfig.getInitialClass()))
|
||||||
|
{
|
||||||
|
throw new IOException("Invalid or missing jav_config");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Strings.isNullOrEmpty(backupConfig.getRuneLiteGamepack()) || Strings.isNullOrEmpty(backupConfig.getRuneLiteWorldParam()))
|
||||||
|
{
|
||||||
|
throw new IOException("Backup config does not have RuneLite gamepack url");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Randomize the codebase
|
||||||
|
World world = worldSupplier.get();
|
||||||
|
backupConfig.setCodebase("http://" + world.getAddress() + "/");
|
||||||
|
|
||||||
|
// Update the world applet parameter
|
||||||
|
Map<String, String> appletProperties = backupConfig.getAppletProperties();
|
||||||
|
appletProperties.put(backupConfig.getRuneLiteWorldParam(), Integer.toString(world.getId()));
|
||||||
|
|
||||||
|
return backupConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateVanilla(RSConfig config) throws IOException, VerificationException
|
||||||
{
|
{
|
||||||
Certificate[] jagexCertificateChain = getJagexCertificateChain();
|
Certificate[] jagexCertificateChain = getJagexCertificateChain();
|
||||||
|
|
||||||
@@ -256,7 +280,7 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
|
|
||||||
// Start downloading the vanilla client
|
// Start downloading the vanilla client
|
||||||
HttpUrl url;
|
HttpUrl url;
|
||||||
if (config.getRuneLiteGamepack() != null)
|
if (config.isFallback())
|
||||||
{
|
{
|
||||||
// If we are using the backup config, use our own gamepack and ignore the codebase
|
// If we are using the backup config, use our own gamepack and ignore the codebase
|
||||||
url = HttpUrl.parse(config.getRuneLiteGamepack());
|
url = HttpUrl.parse(config.getRuneLiteGamepack());
|
||||||
@@ -503,7 +527,7 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Applet loadClient(ClassLoader classLoader) throws ClassNotFoundException, IllegalAccessException, InstantiationException
|
private Applet loadClient(RSConfig config, ClassLoader classLoader) throws ClassNotFoundException, IllegalAccessException, InstantiationException
|
||||||
{
|
{
|
||||||
String initialClass = config.getInitialClass();
|
String initialClass = config.getInitialClass();
|
||||||
Class<?> clientClass = classLoader.loadClass(initialClass);
|
Class<?> clientClass = classLoader.loadClass(initialClass);
|
||||||
|
|||||||
@@ -55,6 +55,11 @@ class RSConfig
|
|||||||
return classLoaderProperties.get("initial_class").replace(".class", "");
|
return classLoaderProperties.get("initial_class").replace(".class", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isFallback()
|
||||||
|
{
|
||||||
|
return getRuneLiteGamepack() != null;
|
||||||
|
}
|
||||||
|
|
||||||
String getRuneLiteGamepack()
|
String getRuneLiteGamepack()
|
||||||
{
|
{
|
||||||
return classLoaderProperties.get("runelite.gamepack");
|
return classLoaderProperties.get("runelite.gamepack");
|
||||||
|
|||||||
Reference in New Issue
Block a user