Merge pull request #3668 from deathbeam/improve-client-creation

Improve client creation
This commit is contained in:
Adam
2018-07-21 20:25:35 -04:00
committed by GitHub
13 changed files with 489 additions and 514 deletions

View File

@@ -31,10 +31,10 @@ import com.google.common.eventbus.EventBus;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Provider;
import java.applet.Applet;
import java.io.File; import java.io.File;
import java.util.Locale; import java.util.Locale;
import javax.annotation.Nullable;
import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import joptsimple.ArgumentAcceptingOptionSpec; import joptsimple.ArgumentAcceptingOptionSpec;
import joptsimple.OptionParser; import joptsimple.OptionParser;
@@ -52,9 +52,9 @@ import net.runelite.client.game.ClanManager;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.MenuManager;
import net.runelite.client.plugins.PluginManager; import net.runelite.client.plugins.PluginManager;
import net.runelite.client.rs.ClientUpdateCheckMode;
import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.DrawManager; import net.runelite.client.ui.DrawManager;
import net.runelite.client.ui.TitleToolbar;
import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.ui.overlay.OverlayRenderer; import net.runelite.client.ui.overlay.OverlayRenderer;
import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
@@ -77,9 +77,6 @@ public class RuneLite
@Getter @Getter
private static Injector injector; private static Injector injector;
@Getter
private static OptionSet options;
@Inject @Inject
private PluginManager pluginManager; private PluginManager pluginManager;
@@ -116,9 +113,6 @@ public class RuneLite
@Inject @Inject
private ClientUI clientUI; private ClientUI clientUI;
@Inject
private TitleToolbar titleToolbar;
@Inject @Inject
private Provider<ItemManager> itemManager; private Provider<ItemManager> itemManager;
@@ -140,7 +134,9 @@ public class RuneLite
@Inject @Inject
private WorldMapOverlay worldMapOverlay; private WorldMapOverlay worldMapOverlay;
Client client; @Inject
@Nullable
private Client client;
public static void main(String[] args) throws Exception public static void main(String[] args) throws Exception
{ {
@@ -150,30 +146,32 @@ public class RuneLite
parser.accepts("developer-mode", "Enable developer tools"); parser.accepts("developer-mode", "Enable developer tools");
parser.accepts("debug", "Show extra debugging output"); parser.accepts("debug", "Show extra debugging output");
final ArgumentAcceptingOptionSpec<UpdateCheckMode> updateMode = parser final ArgumentAcceptingOptionSpec<ClientUpdateCheckMode> updateMode = parser
.accepts("rs", "Select client type") .accepts("rs", "Select client type")
.withRequiredArg() .withRequiredArg()
.ofType(UpdateCheckMode.class) .ofType(ClientUpdateCheckMode.class)
.defaultsTo(UpdateCheckMode.AUTO) .defaultsTo(ClientUpdateCheckMode.AUTO)
.withValuesConvertedBy(new EnumConverter<UpdateCheckMode>(UpdateCheckMode.class) .withValuesConvertedBy(new EnumConverter<ClientUpdateCheckMode>(ClientUpdateCheckMode.class)
{ {
@Override @Override
public UpdateCheckMode convert(String v) public ClientUpdateCheckMode convert(String v)
{ {
return super.convert(v.toUpperCase()); return super.convert(v.toUpperCase());
} }
}); });
parser.accepts("help", "Show this text").forHelp(); parser.accepts("help", "Show this text").forHelp();
options = parser.parse(args); OptionSet options = parser.parse(args);
if (getOptions().has("help")) if (options.has("help"))
{ {
parser.printHelpOn(System.out); parser.printHelpOn(System.out);
System.exit(0); System.exit(0);
} }
if (RuneLite.getOptions().has("developer-mode") && RuneLiteProperties.getLauncherVersion() == null) final boolean developerMode = options.has("developer-mode");
if (developerMode && RuneLiteProperties.getLauncherVersion() == null)
{ {
boolean assertions = false; boolean assertions = false;
assert assertions = true; assert assertions = true;
@@ -203,48 +201,24 @@ public class RuneLite
} }
}); });
injector = Guice.createInjector(new RuneLiteModule()); injector = Guice.createInjector(new RuneLiteModule(
injector.getInstance(RuneLite.class).start(getOptions().valueOf(updateMode)); options.valueOf(updateMode),
developerMode));
injector.getInstance(RuneLite.class).start();
} }
public void start(UpdateCheckMode updateMode) throws Exception public void start() throws Exception
{ {
// Load RuneLite or Vanilla client // Load RuneLite or Vanilla client
final Applet client = new ClientLoader().loadRs(updateMode); final boolean isOutdated = client == null;
final boolean isOutdated = !(client instanceof Client);
if (!isOutdated) if (!isOutdated)
{ {
this.client = (Client) client;
// Inject members into client // Inject members into client
injector.injectMembers(client); injector.injectMembers(client);
} }
// Initialize UI
clientUI.init(client);
// Initialize Discord service
discordService.init();
// Register event listeners
eventBus.register(clientUI);
eventBus.register(overlayRenderer);
eventBus.register(overlayManager);
eventBus.register(drawManager);
eventBus.register(menuManager);
eventBus.register(chatMessageManager);
eventBus.register(commandManager);
eventBus.register(pluginManager);
eventBus.register(clanManager);
eventBus.register(infoBoxManager);
if (this.client != null)
{
eventBus.register(itemManager.get());
}
// Load user configuration // Load user configuration
configManager.load(); configManager.load();
@@ -265,6 +239,29 @@ public class RuneLite
// Load the session, including saved configuration // Load the session, including saved configuration
sessionManager.loadSession(); sessionManager.loadSession();
// Initialize UI
clientUI.open(this);
// Initialize Discord service
discordService.init();
// Register event listeners
eventBus.register(clientUI);
eventBus.register(pluginManager);
eventBus.register(overlayRenderer);
eventBus.register(overlayManager);
eventBus.register(drawManager);
eventBus.register(menuManager);
eventBus.register(chatMessageManager);
eventBus.register(commandManager);
eventBus.register(clanManager);
eventBus.register(infoBoxManager);
if (!isOutdated)
{
eventBus.register(itemManager.get());
}
// Add core overlays after configuration has been loaded so their properties will be // Add core overlays after configuration has been loaded so their properties will be
// loaded properly // loaded properly
overlayManager.add(infoBoxOverlay); overlayManager.add(infoBoxOverlay);
@@ -273,12 +270,6 @@ public class RuneLite
// Start plugins // Start plugins
pluginManager.startCorePlugins(); pluginManager.startCorePlugins();
// Refresh title toolbar
titleToolbar.refresh();
// Show UI after all plugins are loaded
clientUI.show();
} }
public void shutdown() public void shutdown()
@@ -292,16 +283,4 @@ public class RuneLite
{ {
RuneLite.injector = injector; RuneLite.injector = injector;
} }
@VisibleForTesting
public static void setOptions(OptionSet options)
{
RuneLite.options = options;
}
@VisibleForTesting
public void setClient(Client client)
{
this.client = client;
}
} }

View File

@@ -29,8 +29,10 @@ import com.google.common.eventbus.SubscriberExceptionContext;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.name.Names; import com.google.inject.name.Names;
import java.applet.Applet;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import javax.annotation.Nullable;
import javax.inject.Singleton; import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client; import net.runelite.api.Client;
@@ -44,19 +46,35 @@ import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.game.ItemManager; import net.runelite.client.game.ItemManager;
import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.MenuManager;
import net.runelite.client.plugins.PluginManager; import net.runelite.client.plugins.PluginManager;
import net.runelite.client.rs.ClientUpdateCheckMode;
import net.runelite.client.rs.ClientLoader;
import net.runelite.client.task.Scheduler; import net.runelite.client.task.Scheduler;
import net.runelite.client.util.DeferredEventBus; 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
{ {
private final ClientUpdateCheckMode updateCheckMode;
private final boolean developerMode;
public RuneLiteModule(final ClientUpdateCheckMode updateCheckMode, final boolean developerMode)
{
this.updateCheckMode = updateCheckMode;
this.developerMode = developerMode;
}
@Override @Override
protected void configure() protected void configure()
{ {
bindConstant().annotatedWith(Names.named("updateCheckMode")).to(updateCheckMode);
bindConstant().annotatedWith(Names.named("developerMode")).to(developerMode);
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);
@@ -78,9 +96,17 @@ public class RuneLiteModule extends AbstractModule
} }
@Provides @Provides
Client provideClient(RuneLite runeLite) @Singleton
Applet provideApplet(ClientLoader clientLoader)
{ {
return runeLite.client; return clientLoader.load();
}
@Provides
@Singleton
Client provideClient(@Nullable Applet applet)
{
return applet instanceof Client ? (Client) applet : null;
} }
@Provides @Provides

View File

@@ -24,6 +24,7 @@
*/ */
package net.runelite.client.plugins; package net.runelite.client.plugins;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus; import com.google.common.eventbus.EventBus;
@@ -36,7 +37,6 @@ import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo; import com.google.common.reflect.ClassPath.ClassInfo;
import com.google.inject.Binder; import com.google.inject.Binder;
import com.google.inject.CreationException; import com.google.inject.CreationException;
import com.google.inject.Inject;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Key; import com.google.inject.Key;
import com.google.inject.Module; import com.google.inject.Module;
@@ -52,6 +52,8 @@ import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import lombok.Setter; import lombok.Setter;
@@ -78,29 +80,38 @@ public class PluginManager
*/ */
private static final String PLUGIN_PACKAGE = "net.runelite.client.plugins"; private static final String PLUGIN_PACKAGE = "net.runelite.client.plugins";
@Inject private final boolean developerMode;
EventBus eventBus; private final EventBus eventBus;
private final Scheduler scheduler;
@Inject private final ConfigManager configManager;
Scheduler scheduler; private final ScheduledExecutorService executor;
private final SceneTileManager sceneTileManager;
@Inject
ConfigManager configManager;
@Inject
ScheduledExecutorService executor;
@Inject
SceneTileManager sceneTileManager;
@Setter
boolean isOutdated;
private final List<Plugin> plugins = new CopyOnWriteArrayList<>(); private final List<Plugin> plugins = new CopyOnWriteArrayList<>();
private final List<Plugin> activePlugins = new CopyOnWriteArrayList<>(); private final List<Plugin> activePlugins = new CopyOnWriteArrayList<>();
private final String runeliteGroupName = RuneLiteConfig.class private final String runeliteGroupName = RuneLiteConfig.class
.getAnnotation(ConfigGroup.class).value(); .getAnnotation(ConfigGroup.class).value();
@Setter
boolean isOutdated;
@Inject
@VisibleForTesting
PluginManager(
@Named("developerMode") final boolean developerMode,
final EventBus eventBus,
final Scheduler scheduler,
final ConfigManager configManager,
final ScheduledExecutorService executor,
final SceneTileManager sceneTileManager)
{
this.developerMode = developerMode;
this.eventBus = eventBus;
this.scheduler = scheduler;
this.configManager = configManager;
this.executor = executor;
this.sceneTileManager = sceneTileManager;
}
@Subscribe @Subscribe
public void onSessionOpen(SessionOpen event) public void onSessionOpen(SessionOpen event)
{ {
@@ -204,8 +215,6 @@ public class PluginManager
List<Plugin> scanAndInstantiate(ClassLoader classLoader, String packageName) throws IOException List<Plugin> scanAndInstantiate(ClassLoader classLoader, String packageName) throws IOException
{ {
boolean developerPlugins = RuneLite.getOptions().has("developer-mode");
MutableGraph<Class<? extends Plugin>> graph = GraphBuilder MutableGraph<Class<? extends Plugin>> graph = GraphBuilder
.directed() .directed()
.build(); .build();
@@ -242,7 +251,7 @@ public class PluginManager
continue; continue;
} }
if (pluginDescriptor.developerPlugin() && !developerPlugins) if (pluginDescriptor.developerPlugin() && !developerMode)
{ {
continue; continue;
} }

View File

@@ -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,37 +23,41 @@
* (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; 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 ConfigLoader @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 ConfigLoader
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;
} }
} }

View File

@@ -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,37 +23,79 @@
* (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; package net.runelite.client.rs;
import java.applet.Applet; 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 javax.inject.Named;
import javax.inject.Singleton;
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
@Singleton
public class ClientLoader public class ClientLoader
{ {
public Applet loadRs(UpdateCheckMode updateMode) private final UpdateCheckClient updateCheckClient = new UpdateCheckClient();
{ private final ClientConfigLoader clientConfigLoader;
if (updateMode == UpdateCheckMode.AUTO) private final ClientUpdateCheckMode updateCheckMode;
{
final UpdateCheckClient updateCheck = new UpdateCheckClient();
updateMode = updateCheck.isOutdated() ?
UpdateCheckMode.VANILLA :
UpdateCheckMode.RUNELITE;
}
@Inject
private ClientLoader(
@Named("updateCheckMode") final ClientUpdateCheckMode updateCheckMode,
final ClientConfigLoader clientConfigLoader)
{
this.updateCheckMode = updateCheckMode;
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 +114,4 @@ public class ClientLoader
return null; return null;
} }
} }
private Applet loadRuneLite() throws ClassNotFoundException, IOException, InstantiationException, IllegalAccessException
{
ConfigLoader config = new ConfigLoader();
config.fetch();
String initialClass = config.getProperty(ConfigLoader.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
{
ConfigLoader config = new ConfigLoader();
config.fetch();
String codebase = config.getProperty(ConfigLoader.CODEBASE);
String initialJar = config.getProperty(ConfigLoader.INITIAL_JAR);
String initialClass = config.getProperty(ConfigLoader.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;
}
} }

View File

@@ -22,9 +22,9 @@
* (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; package net.runelite.client.rs;
public enum UpdateCheckMode public enum ClientUpdateCheckMode
{ {
AUTO, AUTO,
NONE, NONE,

View File

@@ -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;
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 ConfigLoader config; private final RSConfig config;
public RSStub(ConfigLoader 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(ConfigLoader.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)
{ {
} }
}
}

View File

@@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018, 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,11 +23,30 @@
* (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.events; package net.runelite.client.rs;
import lombok.Data; import java.util.HashMap;
import java.util.Map;
import lombok.Getter;
@Data @Getter
public class ClientUILoaded 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", "");
}
} }

View File

@@ -24,7 +24,6 @@
*/ */
package net.runelite.client.ui; package net.runelite.client.ui;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import java.applet.Applet; import java.applet.Applet;
import java.awt.Canvas; import java.awt.Canvas;
@@ -67,7 +66,6 @@ import net.runelite.client.config.ConfigManager;
import net.runelite.client.config.ExpandResizeType; import net.runelite.client.config.ExpandResizeType;
import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.config.WarningOnExit; import net.runelite.client.config.WarningOnExit;
import net.runelite.client.events.ClientUILoaded;
import net.runelite.client.events.PluginToolbarButtonAdded; import net.runelite.client.events.PluginToolbarButtonAdded;
import net.runelite.client.events.PluginToolbarButtonRemoved; import net.runelite.client.events.PluginToolbarButtonRemoved;
import net.runelite.client.events.TitleToolbarButtonAdded; import net.runelite.client.events.TitleToolbarButtonAdded;
@@ -125,13 +123,12 @@ public class ClientUI
@Getter @Getter
private TrayIcon trayIcon; private TrayIcon trayIcon;
private final RuneLite runelite;
private final RuneLiteProperties properties; private final RuneLiteProperties properties;
private final RuneLiteConfig config; private final RuneLiteConfig config;
private final EventBus eventBus;
private final KeyManager keyManager; private final KeyManager keyManager;
private final Applet client;
private final ConfigManager configManager;
private final CardLayout cardLayout = new CardLayout(); private final CardLayout cardLayout = new CardLayout();
private Applet client;
private ContainableFrame frame; private ContainableFrame frame;
private JPanel navContainer; private JPanel navContainer;
private PluginPanel pluginPanel; private PluginPanel pluginPanel;
@@ -143,91 +140,34 @@ public class ClientUI
private JPanel container; private JPanel container;
private NavigationButton sidebarNavigationButton; private NavigationButton sidebarNavigationButton;
private JButton sidebarNavigationJButton; private JButton sidebarNavigationJButton;
private Dimension lastClientSize;
@Inject
private ConfigManager configManager;
@Inject @Inject
private ClientUI( private ClientUI(
RuneLite runelite,
RuneLiteProperties properties, RuneLiteProperties properties,
RuneLiteConfig config, RuneLiteConfig config,
EventBus eventBus, KeyManager keyManager,
KeyManager keyManager) @Nullable Applet client,
ConfigManager configManager)
{ {
this.runelite = runelite;
this.properties = properties; this.properties = properties;
this.config = config; this.config = config;
this.eventBus = eventBus;
this.keyManager = keyManager; this.keyManager = keyManager;
this.client = client;
this.configManager = configManager;
} }
@Subscribe @Subscribe
public void onConfigChanged(ConfigChanged event) public void onConfigChanged(ConfigChanged event)
{ {
if (!event.getGroup().equals("runelite")) if (!event.getGroup().equals("runelite") ||
event.getKey().equals(CONFIG_CLIENT_MAXIMIZED) ||
event.getKey().equals(CONFIG_CLIENT_BOUNDS))
{ {
return; return;
} }
SwingUtilities.invokeLater(() -> SwingUtilities.invokeLater(this::updateFrameConfig);
{
if (event.getKey().equals("gameAlwaysOnTop"))
{
if (frame.isAlwaysOnTopSupported())
{
frame.setAlwaysOnTop(config.gameAlwaysOnTop());
}
}
if (event.getKey().equals("lockWindowSize"))
{
frame.setResizable(!config.lockWindowSize());
}
if (event.getKey().equals("automaticResizeType"))
{
frame.setExpandResizeType(config.automaticResizeType());
}
if (event.getKey().equals("containInScreen") ||
event.getKey().equals("uiEnableCustomChrome"))
{
frame.setContainedInScreen(config.containInScreen() && config.enableCustomChrome());
}
if (event.getKey().equals("rememberScreenBounds") && event.getNewValue().equals("false"))
{
configManager.unsetConfiguration(CONFIG_GROUP, CONFIG_CLIENT_MAXIMIZED);
configManager.unsetConfiguration(CONFIG_GROUP, CONFIG_CLIENT_BOUNDS);
}
if (!event.getKey().equals("gameSize"))
{
return;
}
if (client == null)
{
return;
}
// The upper bounds are defined by the applet's max size
// The lower bounds are defined by the client's fixed size
int width = Math.max(Math.min(config.gameSize().width, 7680), Constants.GAME_FIXED_WIDTH);
int height = Math.max(Math.min(config.gameSize().height, 2160), Constants.GAME_FIXED_HEIGHT);
final Dimension size = new Dimension(width, height);
client.setSize(size);
client.setPreferredSize(size);
client.getParent().setPreferredSize(size);
client.getParent().setSize(size);
if (frame.isVisible())
{
frame.pack();
}
});
} }
@Subscribe @Subscribe
@@ -337,13 +277,11 @@ public class ClientUI
/** /**
* Initialize UI. * Initialize UI.
* *
* @param client the client * @param runelite runelite instance that will be shut down on exit
* @throws Exception exception that can occur during creation of the UI * @throws Exception exception that can occur during creation of the UI
*/ */
public void init(@Nullable final Applet client) throws Exception public void open(final RuneLite runelite) throws Exception
{ {
this.client = client;
SwingUtilities.invokeAndWait(() -> SwingUtilities.invokeAndWait(() ->
{ {
// Set some sensible swing defaults // Set some sensible swing defaults
@@ -373,9 +311,7 @@ public class ClientUI
saveClientBoundsConfig(); saveClientBoundsConfig();
runelite.shutdown(); runelite.shutdown();
}, },
() -> client != null this::showWarningOnExit
&& client instanceof Client
&& showWarningOnExit()
); );
container = new JPanel(); container = new JPanel();
@@ -400,35 +336,12 @@ public class ClientUI
final UiKeyListener uiKeyListener = new UiKeyListener(this); final UiKeyListener uiKeyListener = new UiKeyListener(this);
frame.addKeyListener(uiKeyListener); frame.addKeyListener(uiKeyListener);
keyManager.registerKeyListener(uiKeyListener); keyManager.registerKeyListener(uiKeyListener);
});
}
private boolean showWarningOnExit() // Update config
{ updateFrameConfig();
if (config.warningOnExit() == WarningOnExit.ALWAYS)
{
return true;
}
if (config.warningOnExit() == WarningOnExit.LOGGED_IN) // Decorate window with custom chrome and titlebar if needed
{ final boolean withTitleBar = config.enableCustomChrome();
return ((Client) client).getGameState() != GameState.LOGIN_SCREEN;
}
return false;
}
/**
* Show client UI after everything else is done.
*
* @throws Exception exception that can occur during modification of the UI
*/
public void show() throws Exception
{
final boolean withTitleBar = config.enableCustomChrome();
SwingUtilities.invokeAndWait(() ->
{
frame.setUndecorated(withTitleBar); frame.setUndecorated(withTitleBar);
if (withTitleBar) if (withTitleBar)
@@ -547,22 +460,35 @@ public class ClientUI
titleToolbar.addComponent(sidebarNavigationButton, sidebarNavigationJButton); titleToolbar.addComponent(sidebarNavigationButton, sidebarNavigationJButton);
toggleSidebar(); toggleSidebar();
log.info("Showing frame {}", frame);
}); });
eventBus.post(new ClientUILoaded()); // Show out of date dialog if needed
final boolean isOutdated = !(client instanceof Client); final boolean isOutdated = !(client instanceof Client);
if (isOutdated) if (isOutdated)
{ {
SwingUtilities.invokeLater(() -> SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(frame,
{ "RuneLite has not yet been updated to work with the latest\n"
JOptionPane.showMessageDialog(frame, "RuneLite has not yet been updated to work with the latest\n" + "game update, it will work with reduced functionality until then.",
+ "game update, it will work with reduced functionality until then.", "RuneLite is outdated", INFORMATION_MESSAGE));
"RuneLite is outdated", INFORMATION_MESSAGE);
});
} }
} }
private boolean showWarningOnExit()
{
if (config.warningOnExit() == WarningOnExit.ALWAYS)
{
return true;
}
if (config.warningOnExit() == WarningOnExit.LOGGED_IN && client instanceof Client)
{
return ((Client) client).getGameState() != GameState.LOGIN_SCREEN;
}
return false;
}
/** /**
* Paint this component to target graphics * Paint this component to target graphics
* *
@@ -766,6 +692,54 @@ public class ClientUI
} }
} }
private void updateFrameConfig()
{
if (frame == null)
{
return;
}
if (frame.isAlwaysOnTopSupported())
{
frame.setAlwaysOnTop(config.gameAlwaysOnTop());
}
frame.setResizable(!config.lockWindowSize());
frame.setExpandResizeType(config.automaticResizeType());
frame.setContainedInScreen(config.containInScreen() && config.enableCustomChrome());
if (!config.rememberScreenBounds())
{
configManager.unsetConfiguration(CONFIG_GROUP, CONFIG_CLIENT_MAXIMIZED);
configManager.unsetConfiguration(CONFIG_GROUP, CONFIG_CLIENT_BOUNDS);
}
if (client == null)
{
return;
}
// The upper bounds are defined by the applet's max size
// The lower bounds are defined by the client's fixed size
int width = Math.max(Math.min(config.gameSize().width, 7680), Constants.GAME_FIXED_WIDTH);
int height = Math.max(Math.min(config.gameSize().height, 2160), Constants.GAME_FIXED_HEIGHT);
final Dimension size = new Dimension(width, height);
if (!size.equals(lastClientSize))
{
lastClientSize = size;
client.setSize(size);
client.setPreferredSize(size);
client.getParent().setPreferredSize(size);
client.getParent().setSize(size);
if (frame.isVisible())
{
frame.pack();
}
}
}
private void saveClientBoundsConfig() private void saveClientBoundsConfig()
{ {
if ((frame.getExtendedState() & JFrame.MAXIMIZED_BOTH) != 0) if ((frame.getExtendedState() & JFrame.MAXIMIZED_BOTH) != 0)

View File

@@ -27,7 +27,6 @@ package net.runelite.client.ui;
import com.google.common.eventbus.EventBus; import com.google.common.eventbus.EventBus;
import java.util.Comparator; import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet; import java.util.TreeSet;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@@ -82,21 +81,4 @@ public class TitleToolbar
eventBus.post(new TitleToolbarButtonRemoved(button, index)); eventBus.post(new TitleToolbarButtonRemoved(button, index));
} }
} }
/**
* Refresh all buttons
*/
public void refresh()
{
final Iterator<NavigationButton> iterator = buttons.iterator();
int index = 0;
while (iterator.hasNext())
{
final NavigationButton button = iterator.next();
eventBus.post(new TitleToolbarButtonRemoved(button, index));
eventBus.post(new TitleToolbarButtonAdded(button, index));
index++;
}
}
} }

View File

@@ -25,6 +25,7 @@
package net.runelite.client; package net.runelite.client;
import com.google.inject.Guice; import com.google.inject.Guice;
import net.runelite.client.rs.ClientUpdateCheckMode;
import org.junit.Test; import org.junit.Test;
public class RuneLiteModuleTest public class RuneLiteModuleTest
@@ -32,8 +33,6 @@ public class RuneLiteModuleTest
@Test @Test
public void testConfigure() public void testConfigure()
{ {
Guice.createInjector(new RuneLiteModule()); Guice.createInjector(new RuneLiteModule(ClientUpdateCheckMode.AUTO, true));
} }
} }

View File

@@ -1,153 +1,153 @@
/* /*
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info> * Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
* 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
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (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.plugins; package net.runelite.client.plugins;
import com.google.common.reflect.ClassPath; import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo; import com.google.common.reflect.ClassPath.ClassInfo;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Module; import com.google.inject.Module;
import com.google.inject.grapher.graphviz.GraphvizGrapher; import com.google.inject.grapher.graphviz.GraphvizGrapher;
import com.google.inject.grapher.graphviz.GraphvizModule; import com.google.inject.grapher.graphviz.GraphvizModule;
import com.google.inject.testing.fieldbinder.BoundFieldModule; import com.google.inject.testing.fieldbinder.Bind;
import java.io.File; import com.google.inject.testing.fieldbinder.BoundFieldModule;
import java.io.IOException; import com.google.inject.util.Modules;
import java.io.PrintWriter; import java.applet.Applet;
import java.util.ArrayList; import java.io.File;
import java.util.Collection; import java.io.IOException;
import java.util.HashSet; import java.io.PrintWriter;
import java.util.List; import java.util.ArrayList;
import java.util.Objects; import java.util.Collection;
import java.util.Set; import java.util.HashSet;
import joptsimple.OptionSet; import java.util.List;
import net.runelite.api.Client; import java.util.Objects;
import net.runelite.client.RuneLite; import java.util.Set;
import net.runelite.client.RuneLiteModule; import net.runelite.api.Client;
import static org.junit.Assert.assertEquals; import net.runelite.client.RuneLite;
import org.junit.Before; import net.runelite.client.RuneLiteModule;
import org.junit.Rule; import net.runelite.client.rs.ClientUpdateCheckMode;
import org.junit.Test; import static org.junit.Assert.assertEquals;
import org.junit.rules.TemporaryFolder; import org.junit.Before;
import org.junit.runner.RunWith; import org.junit.Rule;
import org.mockito.Mock; import org.junit.Test;
import static org.mockito.Mockito.mock; import org.junit.rules.TemporaryFolder;
import org.mockito.runners.MockitoJUnitRunner; import org.junit.runner.RunWith;
import org.mockito.Mock;
@RunWith(MockitoJUnitRunner.class) import org.mockito.runners.MockitoJUnitRunner;
public class PluginManagerTest
{ @RunWith(MockitoJUnitRunner.class)
private static final String PLUGIN_PACKAGE = "net.runelite.client.plugins"; public class PluginManagerTest
{
@Rule private static final String PLUGIN_PACKAGE = "net.runelite.client.plugins";
public TemporaryFolder folder = new TemporaryFolder();
@Rule
private RuneLite runelite; public TemporaryFolder folder = new TemporaryFolder();
private Set<Class> pluginClasses;
@Mock
@Mock @Bind
Client client; public Applet applet;
@Before @Mock
public void before() throws IOException @Bind
{ public Client client;
RuneLite.setOptions(mock(OptionSet.class));
private Set<Class> pluginClasses;
Injector injector = Guice.createInjector(new RuneLiteModule(),
BoundFieldModule.of(this)); @Before
RuneLite.setInjector(injector); public void before() throws IOException
{
runelite = injector.getInstance(RuneLite.class); Injector injector = Guice.createInjector(Modules
.override(new RuneLiteModule(ClientUpdateCheckMode.AUTO, true))
// Find plugins we expect to have .with(BoundFieldModule.of(this)));
pluginClasses = new HashSet<>();
Set<ClassInfo> classes = ClassPath.from(getClass().getClassLoader()).getTopLevelClassesRecursive(PLUGIN_PACKAGE); RuneLite.setInjector(injector);
for (ClassInfo classInfo : classes)
{ // Find plugins we expect to have
Class<?> clazz = classInfo.load(); pluginClasses = new HashSet<>();
PluginDescriptor pluginDescriptor = clazz.getAnnotation(PluginDescriptor.class); Set<ClassInfo> classes = ClassPath.from(getClass().getClassLoader()).getTopLevelClassesRecursive(PLUGIN_PACKAGE);
if (pluginDescriptor != null) for (ClassInfo classInfo : classes)
{ {
pluginClasses.add(clazz); Class<?> clazz = classInfo.load();
} PluginDescriptor pluginDescriptor = clazz.getAnnotation(PluginDescriptor.class);
} if (pluginDescriptor != null)
{
} pluginClasses.add(clazz);
}
@Test }
public void testLoadPlugins() throws Exception
{ }
PluginManager pluginManager = new PluginManager();
pluginManager.setOutdated(true); @Test
pluginManager.loadCorePlugins(); public void testLoadPlugins() throws Exception
Collection<Plugin> plugins = pluginManager.getPlugins(); {
long expected = pluginClasses.stream() PluginManager pluginManager = new PluginManager(false, null, null, null, null, null);
.map(cl -> (PluginDescriptor) cl.getAnnotation(PluginDescriptor.class)) pluginManager.setOutdated(true);
.filter(Objects::nonNull) pluginManager.loadCorePlugins();
.filter(pd -> pd.loadWhenOutdated()) Collection<Plugin> plugins = pluginManager.getPlugins();
.count(); long expected = pluginClasses.stream()
assertEquals(expected, plugins.size()); .map(cl -> (PluginDescriptor) cl.getAnnotation(PluginDescriptor.class))
.filter(Objects::nonNull)
runelite.setClient(client); .filter(PluginDescriptor::loadWhenOutdated)
.count();
pluginManager = new PluginManager(); assertEquals(expected, plugins.size());
pluginManager.loadCorePlugins();
plugins = pluginManager.getPlugins(); pluginManager = new PluginManager(false, null, null, null, null, null);
pluginManager.loadCorePlugins();
expected = pluginClasses.stream() plugins = pluginManager.getPlugins();
.map(cl -> (PluginDescriptor) cl.getAnnotation(PluginDescriptor.class))
.filter(Objects::nonNull) expected = pluginClasses.stream()
.filter(pd -> !pd.developerPlugin()) .map(cl -> (PluginDescriptor) cl.getAnnotation(PluginDescriptor.class))
.count(); .filter(Objects::nonNull)
assertEquals(expected, plugins.size()); .filter(pd -> !pd.developerPlugin())
} .count();
assertEquals(expected, plugins.size());
@Test }
public void dumpGraph() throws Exception
{ @Test
List<Module> modules = new ArrayList<>(); public void dumpGraph() throws Exception
modules.add(new GraphvizModule()); {
modules.add(new RuneLiteModule()); List<Module> modules = new ArrayList<>();
modules.add(new GraphvizModule());
runelite.setClient(client); modules.add(new RuneLiteModule(ClientUpdateCheckMode.AUTO, true));
PluginManager pluginManager = new PluginManager(); PluginManager pluginManager = new PluginManager(true, null, null, null, null, null);
pluginManager.loadCorePlugins(); pluginManager.loadCorePlugins();
for (Plugin p : pluginManager.getPlugins()) for (Plugin p : pluginManager.getPlugins())
{ {
modules.add(p); modules.add(p);
} }
File file = folder.newFile(); File file = folder.newFile();
try (PrintWriter out = new PrintWriter(file, "UTF-8")) try (PrintWriter out = new PrintWriter(file, "UTF-8"))
{ {
Injector injector = Guice.createInjector(modules); Injector injector = Guice.createInjector(modules);
GraphvizGrapher grapher = injector.getInstance(GraphvizGrapher.class); GraphvizGrapher grapher = injector.getInstance(GraphvizGrapher.class);
grapher.setOut(out); grapher.setOut(out);
grapher.setRankdir("TB"); grapher.setRankdir("TB");
grapher.graph(injector); grapher.graph(injector);
} }
} }
} }

View File

@@ -23,30 +23,35 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client; package net.runelite.client.rs;
import java.io.IOException; import java.io.IOException;
import okhttp3.OkHttpClient;
import org.junit.Test; import org.junit.Test;
/** /**
* *
* @author Adam * @author Adam
*/ */
public class ConfigLoaderTest public class ClientConfigLoaderTest
{ {
@Test @Test
public void test() throws IOException public void test() throws IOException
{ {
ConfigLoader loader = new ConfigLoader(); 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));
}
} }
} }