runeliteplus: adds full support for private servers into main project, also fixes -local-injected
This commit is contained in:
24
params.txt
Normal file
24
params.txt
Normal file
@@ -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
|
||||
@@ -199,12 +199,6 @@
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>injected-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>http-api</artifactId>
|
||||
|
||||
@@ -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<String> 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"))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String, String> params = new HashMap<String, String>();
|
||||
private static final HashMap<String, String> cfg = new HashMap<String, String>();
|
||||
private static URL codebase;
|
||||
|
||||
public PrivateRSAppletStub()
|
||||
{
|
||||
try
|
||||
{
|
||||
parseParams(new FileInputStream(new File("./params.txt")));
|
||||
String worldListKey = null;
|
||||
for (Map.Entry<String, String> 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user