Allow RS loading classes to be used with Guice
- Provide OkHttpClient through Guice instead of using it from static variable - Chain the RS classes with Guice and inject ClientLoader to RuneLite class - Cleanup RS loading classes a bit Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
This commit is contained in:
@@ -130,6 +130,9 @@ public class RuneLite
|
|||||||
@Inject
|
@Inject
|
||||||
private InfoBoxManager infoBoxManager;
|
private InfoBoxManager infoBoxManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ClientLoader clientLoader;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private OverlayManager overlayManager;
|
private OverlayManager overlayManager;
|
||||||
|
|
||||||
@@ -212,7 +215,8 @@ public class RuneLite
|
|||||||
public void start(ClientUpdateCheckMode updateMode) throws Exception
|
public void start(ClientUpdateCheckMode updateMode) throws Exception
|
||||||
{
|
{
|
||||||
// Load RuneLite or Vanilla client
|
// Load RuneLite or Vanilla client
|
||||||
final Applet client = new ClientLoader().loadRs(updateMode);
|
clientLoader.setUpdateCheckMode(updateMode);
|
||||||
|
final Applet client = clientLoader.load();
|
||||||
|
|
||||||
final boolean isOutdated = !(client instanceof Client);
|
final boolean isOutdated = !(client instanceof Client);
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ import net.runelite.client.util.DeferredEventBus;
|
|||||||
import net.runelite.client.util.QueryRunner;
|
import net.runelite.client.util.QueryRunner;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import net.runelite.http.api.RuneLiteAPI;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class RuneLiteModule extends AbstractModule
|
public class RuneLiteModule extends AbstractModule
|
||||||
@@ -57,6 +59,7 @@ public class RuneLiteModule extends AbstractModule
|
|||||||
protected void configure()
|
protected void configure()
|
||||||
{
|
{
|
||||||
bind(ScheduledExecutorService.class).toInstance(Executors.newSingleThreadScheduledExecutor());
|
bind(ScheduledExecutorService.class).toInstance(Executors.newSingleThreadScheduledExecutor());
|
||||||
|
bind(OkHttpClient.class).toInstance(RuneLiteAPI.CLIENT);
|
||||||
bind(QueryRunner.class);
|
bind(QueryRunner.class);
|
||||||
bind(MenuManager.class);
|
bind(MenuManager.class);
|
||||||
bind(ChatMessageManager.class);
|
bind(ChatMessageManager.class);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -24,35 +25,39 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.rs;
|
package net.runelite.client.rs;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.HashMap;
|
import javax.inject.Inject;
|
||||||
import java.util.Map;
|
import javax.inject.Singleton;
|
||||||
import net.runelite.http.api.RuneLiteAPI;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.HttpUrl;
|
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
|
||||||
public class ClientConfigLoader
|
@Singleton
|
||||||
|
class ClientConfigLoader
|
||||||
{
|
{
|
||||||
private static final HttpUrl CONFIG_URL = HttpUrl.parse("http://oldschool.runescape.com/jav_config.ws"); // https redirects us to rs3
|
private static final String CONFIG_URL = "http://oldschool.runescape.com/jav_config.ws";
|
||||||
|
private final OkHttpClient httpClient;
|
||||||
|
|
||||||
public static final String CODEBASE = "codebase";
|
@Inject
|
||||||
public static final String INITIAL_JAR = "initial_jar";
|
@VisibleForTesting
|
||||||
public static final String INITIAL_CLASS = "initial_class";
|
ClientConfigLoader(final OkHttpClient httpClient)
|
||||||
|
|
||||||
private final Map<String, String> properties = new HashMap<>(),
|
|
||||||
appletProperties = new HashMap<>();
|
|
||||||
|
|
||||||
public void fetch() throws IOException
|
|
||||||
{
|
{
|
||||||
Request request = new Request.Builder()
|
this.httpClient = httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
RSConfig fetch() throws IOException
|
||||||
|
{
|
||||||
|
final Request request = new Request.Builder()
|
||||||
.url(CONFIG_URL)
|
.url(CONFIG_URL)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute();
|
final RSConfig config = new RSConfig();
|
||||||
BufferedReader in = new BufferedReader(new InputStreamReader(response.body().byteStream())))
|
|
||||||
|
try (final Response response = httpClient.newCall(request).execute(); final BufferedReader in = new BufferedReader(
|
||||||
|
new InputStreamReader(response.body().byteStream())))
|
||||||
{
|
{
|
||||||
String str;
|
String str;
|
||||||
|
|
||||||
@@ -67,43 +72,25 @@ public class ClientConfigLoader
|
|||||||
|
|
||||||
String s = str.substring(0, idx);
|
String s = str.substring(0, idx);
|
||||||
|
|
||||||
if (s.equals("param"))
|
switch (s)
|
||||||
{
|
{
|
||||||
str = str.substring(idx + 1);
|
case "param":
|
||||||
idx = str.indexOf('=');
|
str = str.substring(idx + 1);
|
||||||
s = str.substring(0, idx);
|
idx = str.indexOf('=');
|
||||||
|
s = str.substring(0, idx);
|
||||||
|
|
||||||
appletProperties.put(s, str.substring(idx + 1));
|
config.getAppletProperties().put(s, str.substring(idx + 1));
|
||||||
}
|
break;
|
||||||
else if (s.equals("msg"))
|
case "msg":
|
||||||
{
|
// ignore
|
||||||
// ignore
|
break;
|
||||||
}
|
default:
|
||||||
else
|
config.getClassLoaderProperties().put(s, str.substring(idx + 1));
|
||||||
{
|
break;
|
||||||
properties.put(s, str.substring(idx + 1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public String getProperty(String name)
|
return config;
|
||||||
{
|
|
||||||
return properties.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getProperties()
|
|
||||||
{
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAppletProperty(String name)
|
|
||||||
{
|
|
||||||
return appletProperties.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getAppletProperties()
|
|
||||||
{
|
|
||||||
return appletProperties;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -28,31 +29,70 @@ import java.applet.Applet;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.http.api.updatecheck.UpdateCheckClient;
|
import net.runelite.http.api.updatecheck.UpdateCheckClient;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ClientLoader
|
public class ClientLoader
|
||||||
{
|
{
|
||||||
public Applet loadRs(ClientUpdateCheckMode updateMode)
|
private final UpdateCheckClient updateCheckClient = new UpdateCheckClient();
|
||||||
{
|
private final ClientConfigLoader clientConfigLoader;
|
||||||
if (updateMode == ClientUpdateCheckMode.AUTO)
|
|
||||||
{
|
|
||||||
final UpdateCheckClient updateCheck = new UpdateCheckClient();
|
|
||||||
updateMode = updateCheck.isOutdated() ?
|
|
||||||
ClientUpdateCheckMode.VANILLA :
|
|
||||||
ClientUpdateCheckMode.RUNELITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private ClientUpdateCheckMode updateCheckMode = ClientUpdateCheckMode.AUTO;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ClientLoader(final ClientConfigLoader clientConfigLoader)
|
||||||
|
{
|
||||||
|
this.clientConfigLoader = clientConfigLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Applet loadRuneLite(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Applet load()
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
final RSConfig config = clientConfigLoader.fetch();
|
||||||
|
final ClientUpdateCheckMode updateMode = updateCheckMode == ClientUpdateCheckMode.AUTO
|
||||||
|
? updateCheckClient.isOutdated() ? ClientUpdateCheckMode.VANILLA : ClientUpdateCheckMode.RUNELITE
|
||||||
|
: updateCheckMode;
|
||||||
|
|
||||||
switch (updateMode)
|
switch (updateMode)
|
||||||
{
|
{
|
||||||
case RUNELITE:
|
case RUNELITE:
|
||||||
return loadRuneLite();
|
return loadRuneLite(config);
|
||||||
default:
|
default:
|
||||||
case VANILLA:
|
case VANILLA:
|
||||||
return loadVanilla();
|
return loadVanilla(config);
|
||||||
case NONE:
|
case NONE:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -71,48 +111,4 @@ public class ClientLoader
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Applet loadRuneLite() throws ClassNotFoundException, IOException, InstantiationException, IllegalAccessException
|
|
||||||
{
|
|
||||||
ClientConfigLoader config = new ClientConfigLoader();
|
|
||||||
|
|
||||||
config.fetch();
|
|
||||||
|
|
||||||
String initialClass = config.getProperty(ClientConfigLoader.INITIAL_CLASS).replace(".class", "");
|
|
||||||
|
|
||||||
// the injected client is a runtime scoped dependency
|
|
||||||
Class<?> clientClass = this.getClass().getClassLoader().loadClass(initialClass);
|
|
||||||
Applet rs = (Applet) clientClass.newInstance();
|
|
||||||
|
|
||||||
rs.setStub(new RSStub(config));
|
|
||||||
|
|
||||||
return rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Applet loadVanilla() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException
|
|
||||||
{
|
|
||||||
ClientConfigLoader config = new ClientConfigLoader();
|
|
||||||
|
|
||||||
config.fetch();
|
|
||||||
|
|
||||||
String codebase = config.getProperty(ClientConfigLoader.CODEBASE);
|
|
||||||
String initialJar = config.getProperty(ClientConfigLoader.INITIAL_JAR);
|
|
||||||
String initialClass = config.getProperty(ClientConfigLoader.INITIAL_CLASS).replace(".class", "");
|
|
||||||
|
|
||||||
URL url = new URL(codebase + initialJar);
|
|
||||||
|
|
||||||
// Must set parent classloader to null, or it will pull from
|
|
||||||
// this class's classloader first
|
|
||||||
URLClassLoader classloader = new URLClassLoader(new URL[]
|
|
||||||
{
|
|
||||||
url
|
|
||||||
}, null);
|
|
||||||
|
|
||||||
Class<?> clientClass = classloader.loadClass(initialClass);
|
|
||||||
Applet rs = (Applet) clientClass.newInstance();
|
|
||||||
|
|
||||||
rs.setStub(new RSStub(config));
|
|
||||||
|
|
||||||
return rs;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -22,22 +23,18 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.runelite.client.rs;
|
package net.runelite.client.rs;
|
||||||
|
|
||||||
import java.applet.AppletContext;
|
import java.applet.AppletContext;
|
||||||
import java.applet.AppletStub;
|
import java.applet.AppletStub;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
public class RSStub implements AppletStub
|
@RequiredArgsConstructor
|
||||||
|
class RSAppletStub implements AppletStub
|
||||||
{
|
{
|
||||||
private final ClientConfigLoader config;
|
private final RSConfig config;
|
||||||
|
|
||||||
public RSStub(ClientConfigLoader config)
|
|
||||||
{
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isActive()
|
public boolean isActive()
|
||||||
@@ -56,7 +53,7 @@ public class RSStub implements AppletStub
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return new URL(config.getProperty(ClientConfigLoader.CODEBASE));
|
return new URL(config.getCodeBase());
|
||||||
}
|
}
|
||||||
catch (MalformedURLException ex)
|
catch (MalformedURLException ex)
|
||||||
{
|
{
|
||||||
@@ -67,7 +64,7 @@ public class RSStub implements AppletStub
|
|||||||
@Override
|
@Override
|
||||||
public String getParameter(String name)
|
public String getParameter(String name)
|
||||||
{
|
{
|
||||||
return config.getAppletProperty(name);
|
return config.getAppletProperties().get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -79,7 +76,5 @@ public class RSStub implements AppletStub
|
|||||||
@Override
|
@Override
|
||||||
public void appletResize(int width, int height)
|
public void appletResize(int width, int height)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
|
* 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.rs;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
class RSConfig
|
||||||
|
{
|
||||||
|
private final Map<String, String> appletProperties = new HashMap<>();
|
||||||
|
private final Map<String, String> classLoaderProperties = new HashMap<>();
|
||||||
|
|
||||||
|
String getCodeBase()
|
||||||
|
{
|
||||||
|
return classLoaderProperties.get("codebase");
|
||||||
|
}
|
||||||
|
|
||||||
|
String getInitialJar()
|
||||||
|
{
|
||||||
|
return classLoaderProperties.get("initial_jar");
|
||||||
|
}
|
||||||
|
|
||||||
|
String getInitialClass()
|
||||||
|
{
|
||||||
|
return classLoaderProperties.get("initial_class").replace(".class", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
package net.runelite.client.rs;
|
package net.runelite.client.rs;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import net.runelite.client.rs.ClientConfigLoader;
|
import okhttp3.OkHttpClient;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,16 +38,20 @@ public class ClientConfigLoaderTest
|
|||||||
@Test
|
@Test
|
||||||
public void test() throws IOException
|
public void test() throws IOException
|
||||||
{
|
{
|
||||||
ClientConfigLoader loader = new ClientConfigLoader();
|
final ClientConfigLoader loader = new ClientConfigLoader(new OkHttpClient());
|
||||||
loader.fetch();
|
final RSConfig config = loader.fetch();
|
||||||
|
|
||||||
for (String key : loader.getProperties().keySet())
|
for (String key : config.getClassLoaderProperties().keySet())
|
||||||
System.out.println(key + ": " + loader.getProperty(key));
|
{
|
||||||
|
System.out.println(key + ": " + config.getClassLoaderProperties().get(key));
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println("Applet properties:");
|
System.out.println("Applet properties:");
|
||||||
|
|
||||||
for (String key : loader.getAppletProperties().keySet())
|
for (String key : config.getAppletProperties().keySet())
|
||||||
System.out.println(key + ": " + loader.getAppletProperty(key));
|
{
|
||||||
|
System.out.println(key + ": " + config.getAppletProperties().get(key));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user