runeliteplus: refined private server support

This commit is contained in:
Zeruth
2019-07-20 19:12:35 -04:00
parent a56d92f476
commit 5625c3e743
13 changed files with 254 additions and 158 deletions

1
codebase Normal file
View File

@@ -0,0 +1 @@
http://oldschool17.runescape.com/

View File

@@ -1,24 +0,0 @@
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

View File

@@ -26,6 +26,7 @@ package net.runelite.api;
import java.awt.Canvas;
import java.awt.Dimension;
import java.math.BigInteger;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
@@ -1720,4 +1721,12 @@ public interface Client extends GameShell
* Remove player from friendlist
*/
void removeFriend(String name);
BigInteger getModulus();
void setModulus(BigInteger modulus);
String getCodebase();
void setCodebase(String codebase);
}

View File

@@ -181,7 +181,6 @@ 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")
@@ -252,13 +251,6 @@ public class RuneLite
}
}
final boolean privateServer = options.has("private-server");
if (privateServer)
{
ClientLoader.usePrivateServer = true;
}
PROFILES_DIR.mkdirs();
if (options.has("debug"))

View File

@@ -0,0 +1,34 @@
package net.runelite.client.plugins.privateserver;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup("privateserver")
public interface PrivateServerConfig extends Config
{
@ConfigItem(
keyName = "codebase",
name = "URL (codebase)",
description = "IP address or URL of RSPS you wish to connect to.",
position = 0
)
default String codebase()
{
return "http://oldschool17.runescape.com/";
}
@ConfigItem(
keyName = "modulus",
name = "Key (modulus)",
description = "RSA key used by the RSPS you wish to connect to.",
position = 1
)
default String modulus()
{
return "83ff79a3e258b99ead1a70e1049883e78e513c4cdec538d8da9483879a9f81689c0c7d146d7b82b52d05cf26132b1cda5930eeef894e4ccf3d41eebc3aabe54598c4ca48eb5a31d736bfeea17875a35558b9e3fcd4aebe2a9cc970312a477771b36e173dc2ece6001ab895c553e2770de40073ea278026f36961c94428d8d7db";
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2019, xperiaclash <https://github.com/xperiaclash>
* Copyright (c) 2019, ganom <https://github.com/Ganom>
* Copyright (c) 2019, gazivodag <https://github.com/gazivodag>
* 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.client.plugins.privateserver;
import com.google.inject.Provides;
import java.math.BigInteger;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.events.ConfigChanged;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
import net.runelite.client.util.StringFileUtils;
@PluginDescriptor(
name = "Private Server",
description = "Settings for connecting to non official servers",
tags = {"RSPS", "Server", "Private"},
type = PluginType.UTILITY,
enabledByDefault = false
)
@Singleton
@Slf4j
public class PrivateServerPlugin extends Plugin
{
@Inject
private Client client;
@Inject
private ClientThread clientThread;
@Inject
private PrivateServerConfig config;
@Inject
private ChatMessageManager chatMessageManager;
@Inject
private EventBus eventBus;
@Provides
PrivateServerConfig getConfig(ConfigManager configManager)
{
return configManager.getConfig(PrivateServerConfig.class);
}
@Override
protected void startUp() throws Exception
{
updateConfig();
addSubscriptions();
}
@Override
protected void shutDown() throws Exception
{
eventBus.unregister(this);
}
private void addSubscriptions()
{
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
}
private void onConfigChanged(ConfigChanged event)
{
if (event.getGroup().equals("privateserver") && event.getKey().equals("modulus"))
{
client.setModulus(new BigInteger(config.modulus(), 16));
}
if (event.getGroup().equals("privateserver") && event.getKey().equals("codebase"))
{
StringFileUtils.writeStringToFile("./codebase", config.codebase());
String message = "Client restart required after codebase change\n";
JOptionPane.showMessageDialog(new JFrame(), message, "Restart required",
JOptionPane.WARNING_MESSAGE);
}
}
private void updateConfig()
{
if (!config.modulus().equals(""))
client.setModulus(new BigInteger(config.modulus(), 16));
}
}

View File

@@ -140,11 +140,6 @@ public class ClientLoader
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;
}

View File

@@ -1,115 +0,0 @@
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)
{
}
}

View File

@@ -30,6 +30,7 @@ import java.applet.AppletStub;
import java.net.MalformedURLException;
import java.net.URL;
import lombok.RequiredArgsConstructor;
import net.runelite.client.util.StringFileUtils;
@RequiredArgsConstructor
class RSAppletStub implements AppletStub
@@ -53,7 +54,7 @@ class RSAppletStub implements AppletStub
{
try
{
return new URL(config.getCodeBase());
return new URL(StringFileUtils.readStringFromFile("./codebase"));
}
catch (MalformedURLException ex)
{

View File

@@ -28,9 +28,12 @@ import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.annotation.Nullable;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.client.util.StringFileUtils;
final class ClientPanel extends JPanel
{
@@ -50,7 +53,19 @@ final class ClientPanel extends JPanel
client.setLayout(null);
client.setSize(Constants.GAME_FIXED_SIZE);
client.init();
try
{
client.init();
}
catch (Exception e)
{
String message = "Detected a bad codebase. Resetting...\n"
+ "Please restart client.\n";
JOptionPane.showMessageDialog(new JFrame(), message, "Bad Codebase",
JOptionPane.ERROR_MESSAGE);
StringFileUtils.writeStringToFile("./codebase", "http://oldschool17.runescape.com/");
System.exit(0);
}
client.start();
add(client, BorderLayout.CENTER);

View File

@@ -0,0 +1,53 @@
package net.runelite.client.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
public class StringFileUtils
{
//Read file content into string with - Files.readAllBytes(Path path)
public static String readStringFromFile(String filePath)
{
String content = "";
try
{
content = new String(Files.readAllBytes(Paths.get(filePath)));
}
catch (IOException e)
{
e.printStackTrace();
}
return content;
}
public static void writeStringToFile(String file, String string)
{
File f = new File(file);
if (!f.exists())
{
try
{
f.createNewFile();
}
catch (IOException e)
{
e.printStackTrace();
}
}
try (PrintWriter out = new PrintWriter(file))
{
out.println(string);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
}

View File

@@ -29,16 +29,18 @@ 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.api.mixins.Shadow;
import net.runelite.rs.api.RSBuffer;
import net.runelite.rs.api.RSClient;
@Mixin(RSBuffer.class)
public abstract class RSBufferMixin implements RSBuffer
{
@Inject
private static BigInteger exponent = new BigInteger("10001", 16);
@Shadow("client")
private static RSClient client;
@Inject
private static BigInteger modulus = new BigInteger("83ff79a3e258b99ead1a70e1049883e78e513c4cdec538d8da9483879a9f81689c0c7d146d7b82b52d05cf26132b1cda5930eeef894e4ccf3d41eebc3aabe54598c4ca48eb5a31d736bfeea17875a35558b9e3fcd4aebe2a9cc970312a477771b36e173dc2ece6001ab895c553e2770de40073ea278026f36961c94428d8d7db", 16);
private static BigInteger exponent = new BigInteger("10001", 16);
@Copy("encryptRsa")
public void rs$encryptRsa(BigInteger var1, BigInteger var2)
@@ -48,6 +50,6 @@ public abstract class RSBufferMixin implements RSBuffer
@Replace("encryptRsa")
public void rl$encryptRsa(BigInteger var1, BigInteger var2)
{
rs$encryptRsa(exponent, modulus);
rs$encryptRsa(exponent, client.getModulus());
}
}

View File

@@ -24,6 +24,7 @@
*/
package net.runelite.mixins;
import java.math.BigInteger;
import java.util.HashSet;
import java.util.Set;
import net.runelite.api.ChatMessageType;
@@ -1686,4 +1687,22 @@ public abstract class RSClientMixin implements RSClient
RSFriendSystem friendSystem = getFriendManager();
friendSystem.removeFriend(friend);
}
@Inject
BigInteger modulus = new BigInteger("83ff79a3e258b99ead1a70e1049883e78e513c4cdec538d8da9483879a9f81689c0c7d146d7b82b52d05cf26132b1cda5930eeef894e4ccf3d41eebc3aabe54598c4ca48eb5a31d736bfeea17875a35558b9e3fcd4aebe2a9cc970312a477771b36e173dc2ece6001ab895c553e2770de40073ea278026f36961c94428d8d7db", 16);
@Inject
@Override
public BigInteger getModulus()
{
return modulus;
}
@Inject
@Override
public void setModulus(BigInteger modulus)
{
this.modulus = modulus;
}
}