diff --git a/runelite-client/src/main/java/net/runelite/client/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/ClientLoader.java index 98564796cc..82b4614332 100644 --- a/runelite-client/src/main/java/net/runelite/client/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/ClientLoader.java @@ -28,10 +28,44 @@ import java.applet.Applet; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; +import java.util.Optional; +import lombok.extern.slf4j.Slf4j; +import net.runelite.http.api.updatecheck.UpdateCheckClient; +@Slf4j public class ClientLoader { - public Applet loadRunelite() throws ClassNotFoundException, IOException, InstantiationException, IllegalAccessException + public Optional loadRs() + { + final UpdateCheckClient updateCheck = new UpdateCheckClient(); + boolean isOutdated = updateCheck.isOutdated(); + + try + { + if (isOutdated) + { + log.info("Runelite is outdated - fetching vanilla client"); + return Optional.of(loadVanilla()); + } + + log.debug("Runelite is up to date"); + return Optional.of(loadRunelite()); + } + catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e) + { + if (e instanceof ClassNotFoundException) + { + log.error("Unable to load client - class not found. This means you" + + " are not running RuneLite with Maven as the injected client" + + " is not in your classpath."); + } + + log.error("Error loading RS!", e); + return Optional.empty(); + } + } + + private Applet loadRunelite() throws ClassNotFoundException, IOException, InstantiationException, IllegalAccessException { ConfigLoader config = new ConfigLoader(); @@ -48,7 +82,7 @@ public class ClientLoader return rs; } - public Applet loadVanilla() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException + private Applet loadVanilla() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { ConfigLoader config = new ConfigLoader(); diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 8febe52782..e76e44564d 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -29,6 +29,7 @@ import com.google.common.eventbus.EventBus; import com.google.inject.Guice; import com.google.inject.Inject; import com.google.inject.Injector; +import java.applet.Applet; import java.awt.AWTException; import java.awt.Frame; import java.awt.Image; @@ -39,6 +40,7 @@ import java.awt.event.MouseEvent; import java.io.File; import java.io.IOException; import java.net.URL; +import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import javax.imageio.ImageIO; import javax.inject.Singleton; @@ -52,7 +54,6 @@ import joptsimple.OptionParser; import joptsimple.OptionSet; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import net.runelite.api.Query; import net.runelite.client.account.SessionManager; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; @@ -78,7 +79,6 @@ public class RuneLite private static RuneLite runelite; private static TrayIcon trayIcon; - private Client client; private ClientUI gui; @Inject @@ -108,6 +108,7 @@ public class RuneLite @Inject private SessionManager sessionManager; + Client client; Notifier notifier; static @@ -149,6 +150,26 @@ public class RuneLite public void start() throws Exception { + // Load Runelite or Vanilla client + final boolean hasRs = !getOptions().has("no-rs"); + final Optional optionalClient = hasRs + ? new ClientLoader().loadRs() + : Optional.empty(); + + if (!optionalClient.isPresent() && hasRs) + { + System.exit(-1); + return; + } + + final Applet client = optionalClient.orElseGet(null); + final boolean isOutdated = client == null || !(client instanceof Client); + + if (!isOutdated) + { + this.client = (Client) client; + } + SwingUtilities.invokeAndWait(() -> { JFrame.setDefaultLookAndFeelDecorated(true); @@ -163,7 +184,7 @@ public class RuneLite log.warn("unable to set look and feel", ex); } - gui = new ClientUI(this); + gui = new ClientUI(client); setTitle(null); setupTrayIcon(); @@ -178,6 +199,9 @@ public class RuneLite // Setup the notifier notifier = new Notifier(properties.getTitle(), trayIcon); + // Tell the plugin manager if client is outdated or not + pluginManager.setOutdated(isOutdated); + // Load the plugins, but does not start them yet. // This will initialize configuration pluginManager.loadCorePlugins(); @@ -242,16 +266,6 @@ public class RuneLite }); } - public Client getClient() - { - return client; - } - - public void setClient(Client client) - { - this.client = client; - } - public ClientUI getGui() { return gui; diff --git a/runelite-client/src/main/java/net/runelite/client/RuneliteModule.java b/runelite-client/src/main/java/net/runelite/client/RuneliteModule.java index 405c07d172..bfd32d2c8e 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneliteModule.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneliteModule.java @@ -64,9 +64,9 @@ public class RuneliteModule extends AbstractModule } @Provides - Client provideClient(RuneLite runelite) + Client provideClient(RuneLite runeLite) { - return runelite.getClient(); + return runeLite.client; } @Provides diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/PluginDescriptor.java b/runelite-client/src/main/java/net/runelite/client/plugins/PluginDescriptor.java index 22f8e51fe9..19599c815c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/PluginDescriptor.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/PluginDescriptor.java @@ -38,4 +38,6 @@ public @interface PluginDescriptor String name(); boolean developerPlugin() default false; + + boolean loadWhenOutdated() default false; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java index 23ccea728e..a4b0a0194d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/PluginManager.java @@ -42,6 +42,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import javax.inject.Singleton; import javax.swing.SwingUtilities; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import net.runelite.client.RuneLite; import net.runelite.client.events.PluginChanged; @@ -67,6 +68,9 @@ public class PluginManager @Inject PluginWatcher pluginWatcher; + @Setter + boolean isOutdated; + private final List plugins = new CopyOnWriteArrayList<>(); public void loadCorePlugins() throws IOException @@ -127,6 +131,11 @@ public class PluginManager continue; } + if (!pluginDescriptor.loadWhenOutdated() && isOutdated) + { + continue; + } + if (pluginDescriptor.developerPlugin() && !developerPlugins) { continue; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java index 9b459fd6a5..38e949d6e8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java @@ -36,7 +36,8 @@ import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.NavigationButton; @PluginDescriptor( - name = "Hiscore plugin" + name = "Hiscore plugin", + loadWhenOutdated = true ) public class HiscorePlugin extends Plugin { diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientPanel.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientPanel.java index 0a07814130..92336b67ba 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientPanel.java @@ -25,89 +25,46 @@ package net.runelite.client.ui; import java.applet.Applet; +import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; -import java.awt.BorderLayout; -import java.io.IOException; +import javax.annotation.Nullable; import javax.swing.JPanel; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import net.runelite.client.ClientLoader; -import net.runelite.http.api.updatecheck.UpdateCheckClient; @Slf4j final class ClientPanel extends JPanel { public static final int PANEL_WIDTH = 765, PANEL_HEIGHT = 503; - private final ClientUI ui; - private Applet rs; - - public ClientPanel(ClientUI ui) + public ClientPanel(@Nullable Applet client) { - this.ui = ui; setSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); setMinimumSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT)); setLayout(new BorderLayout()); setBackground(Color.black); - } - public void loadRs() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException - { - ClientLoader loader = new ClientLoader(); - - UpdateCheckClient updateCheck = new UpdateCheckClient(); - boolean isOutdated = updateCheck.isOutdated(); - if (isOutdated) - { - log.info("Runelite is outdated - fetching vanilla client"); - rs = loader.loadVanilla(); - } - else - { - log.debug("Runelite is up to date"); - - try - { - rs = loader.loadRunelite(); - } - catch (ClassNotFoundException ex) - { - log.error("Unable to load client - class not found. This means you" - + " are not running RuneLite with Maven as the injected client" - + " is not in your classpath."); - throw new ClassNotFoundException("Unable to load injected client", ex); - } - } - - rs.setLayout(null); - rs.setSize(PANEL_WIDTH, PANEL_HEIGHT); - - rs.init(); - rs.start(); - - add(rs, BorderLayout.CENTER); - - if (isOutdated) + if (client == null) { return; } - if (!(rs instanceof Client)) - { - log.error("Injected client does not implement Client!"); - return; - } + client.setLayout(null); + client.setSize(PANEL_WIDTH, PANEL_HEIGHT); - Client client = (Client) rs; + client.init(); + client.start(); - ui.getRunelite().setClient(client); + add(client, BorderLayout.CENTER); // This causes the whole game frame to be redrawn each frame instead // of only the viewport, so we can hook to MainBufferProvider#draw // and draw anywhere without it leaving artifacts - client.setGameDrawingMode(2); + if (client instanceof Client) + { + ((Client)client).setGameDrawingMode(2); + } } - -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 2a7a278b93..ef26e13b0a 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -24,11 +24,11 @@ */ package net.runelite.client.ui; +import java.applet.Applet; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.io.IOException; import java.util.Enumeration; import javax.swing.JFrame; import javax.swing.JOptionPane; @@ -51,16 +51,16 @@ public class ClientUI extends JFrame private static final int SCROLLBAR_WIDTH = 17; private static final int EXPANDED_WIDTH = CLIENT_WIDTH + PluginPanel.PANEL_WIDTH + SCROLLBAR_WIDTH; - private final RuneLite runelite; + private final Applet client; private JPanel container; private JPanel navContainer; private ClientPanel panel; private PluginToolbar pluginToolbar; private PluginPanel pluginPanel; - public ClientUI(RuneLite runelite) + public ClientUI(Applet client) { - this.runelite = runelite; + this.client = client; setUIFont(new FontUIResource(FontManager.getRunescapeFont())); init(); pack(); @@ -107,19 +107,7 @@ public class ClientUI extends JFrame container = new JPanel(); container.setLayout(new BorderLayout(0, 0)); - panel = new ClientPanel(this); - if (!RuneLite.getOptions().has("no-rs")) - { - try - { - panel.loadRs(); - } - catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException ex) - { - log.error("Error loading RS!", ex); - System.exit(-1); - } - } + panel = new ClientPanel(client); container.add(panel, BorderLayout.CENTER); navContainer = new JPanel(); @@ -183,11 +171,10 @@ public class ClientUI extends JFrame private void checkExit() { - Client client = runelite.getClient(); int result = JOptionPane.OK_OPTION; // only ask if not logged out - if (client != null && client.getGameState() != GameState.LOGIN_SCREEN) + if (client != null && client instanceof Client && ((Client)client).getGameState() != GameState.LOGIN_SCREEN) { result = JOptionPane.showConfirmDialog(this, "Are you sure you want to exit?", "Exit", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); } @@ -207,9 +194,4 @@ public class ClientUI extends JFrame { return pluginPanel; } - - RuneLite getRunelite() - { - return runelite; - } }