diff --git a/params.txt b/params.txt
new file mode 100644
index 0000000000..f6a66a22f3
--- /dev/null
+++ b/params.txt
@@ -0,0 +1,24 @@
+Created at Thu Jul 18 15:08:02 CDT 2019
+
+codebase=http://oldschool14.runescape.com/
+mainclass=client.class
+
+param=1=1
+param=2=https://payments.jagex.com/operator/v1/
+param=3=true
+param=4=59193
+param=5=1
+param=6=0
+param=7=0
+param=8=true
+param=9=ElZAIrq5NpKN6D3mDdihco3oPeYN2KFy2DCquj7JMmECPmLrDP3Bnw
+param=10=5
+param=11=https://auth.jagex.com/
+param=12=314
+param=13=.runescape.com
+param=14=0
+param=15=0
+param=16=false
+param=17=http://www.runescape.com/g=oldscape/slr.ws?order=LPWM
+param=18=
+param=19=196515767263-1oo20deqm6edn7ujlihl6rpadk9drhva.apps.googleusercontent.com
diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml
index 2313bd41fc..1363d27664 100644
--- a/runelite-client/pom.xml
+++ b/runelite-client/pom.xml
@@ -199,12 +199,6 @@
${project.version}
runtime
-
- net.runelite
- injected-client
- ${project.version}
- runtime
-
net.runelite
http-api
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 250b90f877..73ac63fd1d 100644
--- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java
+++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java
@@ -181,6 +181,7 @@ public class RuneLite
parser.accepts("debug", "Show extra debugging output");
parser.accepts("no-splash", "Do not show the splash screen");
parser.accepts("local-injected", "Use local injected-client");
+ parser.accepts("private-server", "Use a non official server to play");
final ArgumentAcceptingOptionSpec proxyInfo = parser
.accepts("proxy")
@@ -251,6 +252,13 @@ public class RuneLite
}
}
+ final boolean privateServer = options.has("private-server");
+
+ if (privateServer)
+ {
+ ClientLoader.usePrivateServer = true;
+ }
+
PROFILES_DIR.mkdirs();
if (options.has("debug"))
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 e39b76716d..4a92c7c0cd 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,22 +26,31 @@
*/
package net.runelite.client.rs;
-import java.net.URLClassLoader;
import java.applet.Applet;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
+import net.runelite.client.RuneLite;
+import net.runelite.http.api.RuneLiteAPI;
@Slf4j
@Singleton
public class ClientLoader
{
+ public static boolean useLocalInjected = false;
+ public static boolean usePrivateServer = false;
private final ClientConfigLoader clientConfigLoader;
private final ClientUpdateCheckMode updateCheckMode;
- public static boolean useLocalInjected = false;
@Inject
private ClientLoader(
@@ -52,6 +61,120 @@ public class ClientLoader
this.clientConfigLoader = clientConfigLoader;
}
+ private static Applet loadRLPlus(final RSConfig config) throws ClassNotFoundException, InstantiationException, IllegalAccessException
+ {
+ if (useLocalInjected)
+ {
+ try
+ {
+ URL localInjected = new File("./injected-client/target/injected-client-" + RuneLiteAPI.getVersion() + ".jar").toURI().toURL();
+ log.info("Using local injected-client");
+ URLClassLoader classLoader = new URLClassLoader(new URL[]{localInjected});
+ Class> clientClass = classLoader.loadClass("client");
+ return loadFromClass(config, clientClass);
+ }
+ catch (MalformedURLException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ try
+ {
+ File cachedInjected = new File(RuneLite.RUNELITE_DIR + "/injected-client-" + RuneLiteAPI.getVersion() + ".jar");
+ URL remoteInjected = new URL("https://github.com/runelite-extended/maven-repo/raw/master/live/injected-client-" + RuneLiteAPI.getVersion() + ".jar");
+ int remoteSize = getFileSize(remoteInjected);
+ URL cachedInjectedURL = cachedInjected.toURI().toURL();
+ int cachedSize = 0;
+ if (cachedInjected.exists())
+ {
+ cachedSize = getFileSize(cachedInjectedURL);
+ }
+
+ if (remoteSize != cachedSize)
+ {
+ log.info("Injected-client size mismatch, updating.");
+ try (BufferedInputStream in = new BufferedInputStream(remoteInjected.openStream()))
+ {
+ FileOutputStream fileOutputStream = new FileOutputStream(cachedInjected);
+ byte[] dataBuffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1)
+ {
+ fileOutputStream.write(dataBuffer, 0, bytesRead);
+ }
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+ URLClassLoader classLoader = new URLClassLoader(new URL[]{cachedInjectedURL});
+ Class> clientClass = classLoader.loadClass("client");
+ return loadFromClass(config, clientClass);
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+
+ log.error("Failed to load injected-client!");
+ return null;
+ }
+
+ private static Applet loadVanilla(final RSConfig config) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException
+ {
+ final String codebase = config.getCodeBase();
+ final String initialJar = config.getInitialJar();
+ final String initialClass = config.getInitialClass();
+ final URL url = new URL(codebase + initialJar);
+
+ // Must set parent classloader to null, or it will pull from
+ // this class's classloader first
+ final URLClassLoader classloader = new URLClassLoader(new URL[]{url}, null);
+ final Class> clientClass = classloader.loadClass(initialClass);
+ return loadFromClass(config, clientClass);
+ }
+
+ private static Applet loadFromClass(final RSConfig config, final Class> clientClass) throws IllegalAccessException, InstantiationException
+ {
+ final Applet rs = (Applet) clientClass.newInstance();
+ if (usePrivateServer)
+ {
+ rs.setStub(new PrivateRSAppletStub());
+ return rs;
+ }
+ rs.setStub(new RSAppletStub(config));
+ return rs;
+ }
+
+ private static int getFileSize(URL url)
+ {
+ URLConnection conn = null;
+ try
+ {
+ conn = url.openConnection();
+ if (conn instanceof HttpURLConnection)
+ {
+ ((HttpURLConnection) conn).setRequestMethod("HEAD");
+ }
+ conn.getInputStream();
+ return conn.getContentLength();
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ finally
+ {
+ if (conn instanceof HttpURLConnection)
+ {
+ ((HttpURLConnection) conn).disconnect();
+ }
+ }
+ }
+
public Applet load()
{
try
@@ -84,32 +207,4 @@ public class ClientLoader
return null;
}
}
-
- private static Applet loadRLPlus(final RSConfig config) throws ClassNotFoundException, InstantiationException, IllegalAccessException
- {
- // the injected client is a runtime scoped dependency
- final Class> clientClass = ClientLoader.class.getClassLoader().loadClass(config.getInitialClass());
- return loadFromClass(config, clientClass);
- }
-
- private static Applet loadVanilla(final RSConfig config) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException
- {
- final String codebase = config.getCodeBase();
- final String initialJar = config.getInitialJar();
- final String initialClass = config.getInitialClass();
- final URL url = new URL(codebase + initialJar);
-
- // Must set parent classloader to null, or it will pull from
- // this class's classloader first
- final URLClassLoader classloader = new URLClassLoader(new URL[]{url}, null);
- final Class> clientClass = classloader.loadClass(initialClass);
- return loadFromClass(config, clientClass);
- }
-
- private static Applet loadFromClass(final RSConfig config, final Class> clientClass) throws IllegalAccessException, InstantiationException
- {
- final Applet rs = (Applet) clientClass.newInstance();
- rs.setStub(new RSAppletStub(config));
- return rs;
- }
}
diff --git a/runelite-client/src/main/java/net/runelite/client/rs/PrivateRSAppletStub.java b/runelite-client/src/main/java/net/runelite/client/rs/PrivateRSAppletStub.java
new file mode 100644
index 0000000000..9855226b2e
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/rs/PrivateRSAppletStub.java
@@ -0,0 +1,115 @@
+package net.runelite.client.rs;
+
+import java.applet.AppletContext;
+import java.applet.AppletStub;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+public class PrivateRSAppletStub implements AppletStub
+{
+
+ public static final Logger logger = Logger.getLogger(RSAppletStub.class.getSimpleName());
+
+ private static final HashMap params = new HashMap();
+ private static final HashMap cfg = new HashMap();
+ private static URL codebase;
+
+ public PrivateRSAppletStub()
+ {
+ try
+ {
+ parseParams(new FileInputStream(new File("./params.txt")));
+ String worldListKey = null;
+ for (Map.Entry paramEntry : params.entrySet())
+ {
+ String key = paramEntry.getKey();
+ String value = paramEntry.getValue();
+ if (value.contains("slr.ws"))
+ {
+ worldListKey = key;
+ break;
+ }
+ }
+ codebase = new URL("http://runeliteplus-ps.ddns.net"); //host
+ params.put(worldListKey, "http://" + codebase.getHost());
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private static void parseParams(InputStream stream) throws IOException
+ {
+ BufferedReader br = new BufferedReader(new InputStreamReader(stream));
+ String line;
+ while ((line = br.readLine()) != null)
+ {
+ int idx = line.indexOf('=');
+ if (idx != -1)
+ {
+ String key = line.substring(0, idx);
+ String val = line.substring(idx + 1);
+ if (key.equals("param"))
+ {
+ idx = val.indexOf('=');
+ key = val.substring(0, idx);
+ val = val.substring(idx + 1);
+ params.put(key, val);
+ }
+ else
+ {
+ cfg.put(key, val);
+ }
+ }
+ }
+ }
+
+ public static void log(String format, Object... params)
+ {
+ System.out.printf(format + "\n", params);
+ }
+
+ @Override
+ public boolean isActive()
+ {
+ return false;
+ }
+
+ @Override
+ public URL getDocumentBase()
+ {
+ return codebase;
+ }
+
+ @Override
+ public URL getCodeBase()
+ {
+ return codebase;
+ }
+
+ @Override
+ public String getParameter(String name)
+ {
+ return params.get(name);
+ }
+
+ @Override
+ public AppletContext getAppletContext()
+ {
+ return null;
+ }
+
+ @Override
+ public void appletResize(int width, int height)
+ {
+ }
+}
\ No newline at end of file
diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSBufferMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSBufferMixin.java
new file mode 100644
index 0000000000..8b6904f942
--- /dev/null
+++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSBufferMixin.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, Null (zeruth)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.runelite.mixins;
+
+import java.math.BigInteger;
+import net.runelite.api.mixins.Copy;
+import net.runelite.api.mixins.Inject;
+import net.runelite.api.mixins.Mixin;
+import net.runelite.api.mixins.Replace;
+import net.runelite.rs.api.RSBuffer;
+
+@Mixin(RSBuffer.class)
+public abstract class RSBufferMixin implements RSBuffer
+{
+ @Inject
+ private static BigInteger exponent = new BigInteger("10001", 16);
+
+ @Inject
+ private static BigInteger modulus = new BigInteger("83ff79a3e258b99ead1a70e1049883e78e513c4cdec538d8da9483879a9f81689c0c7d146d7b82b52d05cf26132b1cda5930eeef894e4ccf3d41eebc3aabe54598c4ca48eb5a31d736bfeea17875a35558b9e3fcd4aebe2a9cc970312a477771b36e173dc2ece6001ab895c553e2770de40073ea278026f36961c94428d8d7db", 16);
+
+ @Copy("encryptRsa")
+ public void rs$encryptRsa(BigInteger var1, BigInteger var2)
+ {
+ }
+
+ @Replace("encryptRsa")
+ public void rl$encryptRsa(BigInteger var1, BigInteger var2)
+ {
+ rs$encryptRsa(exponent, modulus);
+ }
+}
\ No newline at end of file
diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java
index 2f01378803..a75a1d2fd6 100644
--- a/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java
+++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSGameShellMixin.java
@@ -31,6 +31,7 @@ import net.runelite.api.mixins.FieldHook;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.MethodHook;
import net.runelite.api.mixins.Mixin;
+import net.runelite.api.mixins.Replace;
import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSGameShell;
@@ -97,4 +98,11 @@ public abstract class RSGameShellMixin implements RSGameShell
setResizeCanvasNextFrame(true);
}
}
+
+ @Replace("checkHost")
+ protected final boolean checkHost()
+ {
+ //Always allow host.
+ return true;
+ }
}