diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java b/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java
index 557bc675b1..f01c70a946 100644
--- a/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java
+++ b/runelite-client/src/main/java/net/runelite/client/RuneLiteProperties.java
@@ -38,6 +38,7 @@ public class RuneLiteProperties
{
private static final String RUNELITE_TITLE = "runelite.title";
private static final String RUNELITE_VERSION = "runelite.version";
+ private static final String RUNESCAPE_VERSION = "runescape.version";
private final Properties properties = new Properties();
@@ -64,4 +65,9 @@ public class RuneLiteProperties
{
return properties.getProperty(RUNELITE_VERSION);
}
+
+ public String getRunescapeVersion()
+ {
+ return properties.getProperty(RUNESCAPE_VERSION);
+ }
}
diff --git a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java
index 87527a8f43..ee74cc1fae 100644
--- a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java
+++ b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java
@@ -25,12 +25,17 @@
package net.runelite.client.account;
import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
import com.google.gson.Gson;
+import java.awt.Desktop;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.time.Instant;
import java.util.concurrent.ScheduledExecutorService;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -41,6 +46,8 @@ import net.runelite.client.config.ConfigManager;
import net.runelite.api.events.SessionClose;
import net.runelite.api.events.SessionOpen;
import net.runelite.http.api.account.AccountClient;
+import net.runelite.http.api.account.OAuthResponse;
+import net.runelite.http.api.ws.messages.LoginResponse;
@Singleton
@Slf4j
@@ -52,8 +59,7 @@ public class SessionManager
@Getter
private AccountSession accountSession;
- @Inject
- private EventBus eventBus;
+ private final EventBus eventBus;
@Inject
private ConfigManager configManager;
@@ -61,6 +67,15 @@ public class SessionManager
@Inject
private ScheduledExecutorService executor;
+ private final AccountClient loginClient = new AccountClient();
+
+ @Inject
+ public SessionManager(EventBus eventBus)
+ {
+ this.eventBus = eventBus;
+ eventBus.register(this);
+ }
+
public void loadSession()
{
if (!SESSION_FILE.exists())
@@ -165,6 +180,16 @@ public class SessionManager
log.debug("Logging out of account {}", accountSession.getUsername());
+ AccountClient client = new AccountClient(accountSession.getUuid());
+ try
+ {
+ client.logout();
+ }
+ catch (IOException ex)
+ {
+ log.warn("Unable to logout of session", ex);
+ }
+
accountSession = null; // No more account
// Restore config
@@ -172,4 +197,68 @@ public class SessionManager
eventBus.post(new SessionClose());
}
+
+ public void login()
+ {
+ OAuthResponse login;
+
+ try
+ {
+ login = loginClient.login();
+ }
+ catch (IOException ex)
+ {
+ log.warn("Unable to get oauth url", ex);
+ return;
+ }
+
+ // Create new session
+ openSession(new AccountSession(login.getUid(), Instant.now()));
+
+ if (!Desktop.isDesktopSupported())
+ {
+ log.info("Desktop is not supported. Visit {}", login.getOauthUrl());
+ return;
+ }
+
+ Desktop desktop = Desktop.getDesktop();
+ if (!desktop.isSupported(Desktop.Action.BROWSE))
+ {
+ log.info("Desktop browser is not supported. Visit {}", login.getOauthUrl());
+ return;
+ }
+
+ try
+ {
+ desktop.browse(new URI(login.getOauthUrl()));
+
+ log.debug("Opened browser to {}", login.getOauthUrl());
+ }
+ catch (IOException | URISyntaxException ex)
+ {
+ log.warn("Unable to open login page", ex);
+ }
+ }
+
+ @Subscribe
+ public void onLogin(LoginResponse loginResponse)
+ {
+ log.debug("Now logged in as {}", loginResponse.getUsername());
+
+ AccountSession session = getAccountSession();
+ session.setUsername(loginResponse.getUsername());
+
+ // Open session, again, now that we have a username
+ // This triggers onSessionOpen
+ openSession(session);
+
+ // Save session to disk
+ saveSession();
+ }
+
+ public void logout()
+ {
+ closeSession();
+ deleteSession();
+ }
}
\ No newline at end of file
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java
index 23890a8cea..b912aef0b9 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/account/AccountPlugin.java
@@ -25,16 +25,12 @@
package net.runelite.client.plugins.account;
import com.google.common.eventbus.Subscribe;
-import java.awt.Desktop;
import java.awt.event.ActionEvent;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.time.Instant;
import java.util.concurrent.ScheduledExecutorService;
import javax.imageio.ImageIO;
import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
+import net.runelite.api.events.SessionClose;
import net.runelite.client.account.AccountSession;
import net.runelite.client.account.SessionManager;
import net.runelite.api.events.SessionOpen;
@@ -44,9 +40,6 @@ import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.NavigationButton;
import net.runelite.client.ui.PluginToolbar;
import net.runelite.client.util.RunnableExceptionLogger;
-import net.runelite.http.api.account.AccountClient;
-import net.runelite.http.api.account.OAuthResponse;
-import net.runelite.http.api.ws.messages.LoginResponse;
@PluginDescriptor(
name = "Account plugin",
@@ -67,8 +60,6 @@ public class AccountPlugin extends Plugin
private NavigationButton loginButton;
private NavigationButton logoutButton;
- private final AccountClient loginClient = new AccountClient();
-
@Override
protected void startUp() throws Exception
{
@@ -88,91 +79,22 @@ public class AccountPlugin extends Plugin
private void loginClick(ActionEvent ae)
{
- executor.execute(RunnableExceptionLogger.wrap(this::openLoginPage));
+ executor.execute(RunnableExceptionLogger.wrap(sessionManager::login));
}
private void logoutClick(ActionEvent ae)
{
- // Destroy session
- AccountSession session = sessionManager.getAccountSession();
- if (session != null)
- {
- AccountClient client = new AccountClient(session.getUuid());
- try
- {
- client.logout();
- }
- catch (IOException ex)
- {
- log.warn("Unable to logout of session", ex);
- }
- }
-
- sessionManager.closeSession(); // remove session from client
- sessionManager.deleteSession(); // delete saved session file
+ sessionManager.logout();
+ }
+ @Subscribe
+ public void onSessionClose(SessionClose e)
+ {
// Replace logout nav button with login
PluginToolbar navigationPanel = ui.getPluginToolbar();
navigationPanel.removeNavigation(logoutButton);
navigationPanel.addNavigation(loginButton);
- }
-
- private void openLoginPage()
- {
- OAuthResponse login;
-
- try
- {
- login = loginClient.login();
- }
- catch (IOException ex)
- {
- log.warn("Unable to get oauth url", ex);
- return;
- }
-
- // Create new session
- sessionManager.openSession(new AccountSession(login.getUid(), Instant.now()));
-
- if (!Desktop.isDesktopSupported())
- {
- log.info("Desktop is not supported. Visit {}", login.getOauthUrl());
- return;
- }
-
- Desktop desktop = Desktop.getDesktop();
- if (!desktop.isSupported(Desktop.Action.BROWSE))
- {
- log.info("Desktop browser is not supported. Visit {}", login.getOauthUrl());
- return;
- }
-
- try
- {
- desktop.browse(new URI(login.getOauthUrl()));
-
- log.debug("Opened browser to {}", login.getOauthUrl());
- }
- catch (IOException | URISyntaxException ex)
- {
- log.warn("Unable to open login page", ex);
- }
- }
-
- @Subscribe
- public void onLogin(LoginResponse loginResponse)
- {
- log.debug("Now logged in as {}", loginResponse.getUsername());
-
- AccountSession session = sessionManager.getAccountSession();
- session.setUsername(loginResponse.getUsername());
-
- // Open session, again, now that we have a username
- // This triggers onSessionOpen
- sessionManager.openSession(session);
-
- // Save session to disk
- sessionManager.saveSession();
+ navigationPanel.repaint();
}
@Subscribe
@@ -187,15 +109,11 @@ public class AccountPlugin extends Plugin
log.debug("Session opened as {}", session.getUsername());
- replaceLoginWithLogout();
- }
-
- private void replaceLoginWithLogout()
- {
// Replace login nav button with logout
PluginToolbar navigationPanel = ui.getPluginToolbar();
navigationPanel.removeNavigation(loginButton);
navigationPanel.addNavigation(logoutButton);
+ navigationPanel.repaint();
}
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java
new file mode 100644
index 0000000000..e58c12c5f6
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2018 Abex
+ * 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.info;
+
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+import java.awt.Font;
+import com.google.inject.Inject;
+import java.util.concurrent.ScheduledExecutorService;
+import javax.annotation.Nullable;
+import javax.swing.GroupLayout;
+import javax.swing.JLabel;
+import javax.swing.LayoutStyle;
+import javax.swing.event.HyperlinkEvent;
+import lombok.extern.slf4j.Slf4j;
+import net.runelite.api.Client;
+import net.runelite.api.events.SessionClose;
+import net.runelite.api.events.SessionOpen;
+import net.runelite.client.RuneLiteProperties;
+import net.runelite.client.account.SessionManager;
+import net.runelite.client.ui.FontManager;
+import net.runelite.client.ui.PluginPanel;
+import net.runelite.client.util.RunnableExceptionLogger;
+
+@Slf4j
+public class InfoPanel extends PluginPanel
+{
+ private final static String RUNELITE_LOGIN = "https://runelite_login/";
+
+ @Inject
+ @Nullable
+ private Client client;
+
+ @Inject
+ private RuneLiteProperties runeLiteProperties;
+
+ @Inject
+ private EventBus eventBus;
+
+ @Inject
+ private SessionManager sessionManager;
+
+ @Inject
+ private ScheduledExecutorService executor;
+
+ private final GroupLayout layout = new GroupLayout(this);
+
+ private final JLabel usernameHeader = new JLabel();
+ private final JRichTextPane username = new JRichTextPane();
+
+ void init()
+ {
+ setLayout(layout);
+
+ final Font smallFont = FontManager.getRunescapeSmallFont();
+
+ final JLabel runeliteVersionHeader = new JLabel("RuneLite version");
+ runeliteVersionHeader.setFont(smallFont);
+ final JLabel runeliteVersion = new JLabel(runeLiteProperties.getVersion());
+
+ final JLabel runescapeVersionHeader = new JLabel("OldSchool Engine");
+ runescapeVersionHeader.setFont(smallFont);
+
+ String engineVer = "Unknown";
+ if (client != null)
+ {
+ engineVer = String.format("Rev %s", runeLiteProperties.getRunescapeVersion());
+ }
+ final JLabel runescapeVersion = new JLabel(engineVer);
+
+ usernameHeader.setFont(smallFont);
+ username.enableAutoLinkHandler(false);
+ username.addHyperlinkListener(e ->
+ {
+ if (HyperlinkEvent.EventType.ACTIVATED.equals(e.getEventType()) && e.getURL() != null)
+ {
+ if (e.getURL().toString().equals(RUNELITE_LOGIN))
+ {
+ executor.execute(RunnableExceptionLogger.wrap(sessionManager::login));
+ }
+ }
+ });
+ setNotLoggedIn();
+
+ final JRichTextPane issueLink = new JRichTextPane("text/html",
+ "RuneLite is open source!
"
+ + "Found an issue? Want a feature?
"
+ + ""
+ + "Open an issue on GitHub!"
+ + ""
+ );
+
+ layout.setVerticalGroup(layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup()
+ .addComponent(runeliteVersionHeader)
+ .addComponent(runescapeVersionHeader)
+ ).addGroup(layout.createParallelGroup()
+ .addComponent(runeliteVersion)
+ .addComponent(runescapeVersion)
+ ).addGap(6)
+ .addComponent(usernameHeader)
+ .addGroup(layout.createParallelGroup()
+ .addComponent(username)
+ )
+ .addGap(12)
+ .addComponent(issueLink)
+ );
+
+ layout.setHorizontalGroup(layout.createParallelGroup()
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(runeliteVersionHeader)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
+ .addComponent(runescapeVersionHeader)
+ ).addGroup(layout.createSequentialGroup()
+ .addComponent(runeliteVersion)
+ .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
+ .addComponent(runescapeVersion)
+ )
+ .addComponent(usernameHeader)
+ .addComponent(username)
+ .addComponent(issueLink)
+ );
+
+ eventBus.register(this);
+ }
+
+ private void setNotLoggedIn()
+ {
+ username.setContentType("text/html");
+ username.setText("Login to sync settings to the cloud.");
+ usernameHeader.setText("Not logged in");
+ }
+
+ @Subscribe
+ private void onSessionOpen(SessionOpen sessionOpen)
+ {
+ String name = sessionManager.getAccountSession().getUsername();
+ if (name != null)
+ {
+ username.setContentType("text/plain");
+ username.setText(name);
+ usernameHeader.setText("Logged in as");
+ }
+ }
+
+ @Subscribe
+ private void onSessionClose(SessionClose e)
+ {
+ setNotLoggedIn();
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPlugin.java
new file mode 100644
index 0000000000..8a1a1163b4
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPlugin.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018 Abex
+ * 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.info;
+
+import com.google.inject.Binder;
+import javax.imageio.ImageIO;
+import javax.inject.Inject;
+import net.runelite.client.plugins.Plugin;
+import net.runelite.client.plugins.PluginDescriptor;
+import net.runelite.client.ui.ClientUI;
+import net.runelite.client.ui.NavigationButton;
+
+@PluginDescriptor(
+ name = "Info panel plugin",
+ loadWhenOutdated = true
+)
+public class InfoPlugin extends Plugin
+{
+ @Inject
+ private ClientUI ui;
+
+ @Override
+ public void configure(Binder binder)
+ {
+ binder.bind(InfoPanel.class);
+ }
+
+ @Override
+ protected void startUp() throws Exception
+ {
+ final InfoPanel panel = injector.getInstance(InfoPanel.class);
+ panel.init();
+
+ final NavigationButton navButton = new NavigationButton(
+ "Info",
+ ImageIO.read(getClass().getResourceAsStream("info_icon.png")),
+ () -> panel
+ );
+
+ ui.getPluginToolbar().addNavigation(navButton);
+ }
+}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/info/JRichTextPane.java b/runelite-client/src/main/java/net/runelite/client/plugins/info/JRichTextPane.java
new file mode 100644
index 0000000000..21b8f46cd5
--- /dev/null
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/info/JRichTextPane.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2018 Abex
+ * 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.info;
+
+import java.awt.Desktop;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import javax.swing.BorderFactory;
+import javax.swing.JEditorPane;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+import javax.swing.text.html.HTMLEditorKit;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class JRichTextPane extends JEditorPane
+{
+ private HyperlinkListener linkHandler;
+
+ public JRichTextPane()
+ {
+ super();
+ setHighlighter(null);
+ setEditable(false);
+ setOpaque(false);
+ enableAutoLinkHandler(true);
+ setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
+ HTMLEditorKit ek = (HTMLEditorKit) getEditorKitForContentType("text/html");
+ ek.getStyleSheet().addRule("a {color: #DDDDDD }");
+ }
+
+ public JRichTextPane(String type, String text)
+ {
+ this();
+ setContentType(type);
+ setText(text);
+ }
+
+ public void enableAutoLinkHandler(boolean enable)
+ {
+ if (enable != (linkHandler != null))
+ {
+ if (enable)
+ {
+ linkHandler = e ->
+ {
+ log.info(e.toString());
+ if (HyperlinkEvent.EventType.ACTIVATED.equals(e.getEventType()) && e.getURL() != null)
+ {
+ if (Desktop.isDesktopSupported())
+ {
+ try
+ {
+ Desktop.getDesktop().browse(e.getURL().toURI());
+ }
+ catch (URISyntaxException | IOException ex)
+ {
+ log.info("Error opening link", ex);
+ }
+ }
+ }
+ };
+ addHyperlinkListener(linkHandler);
+ }
+ else
+ {
+ removeHyperlinkListener(linkHandler);
+ linkHandler = null;
+ }
+ }
+ }
+
+ public boolean getAutoLinkHandlerEnabled()
+ {
+ return linkHandler != null;
+ }
+}
diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/info/info_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/info/info_icon.png
new file mode 100644
index 0000000000..565f2a48b2
Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/info/info_icon.png differ
diff --git a/runelite-client/src/main/resources/net/runelite/client/runelite.properties b/runelite-client/src/main/resources/net/runelite/client/runelite.properties
index b8516ea64c..684a13c581 100644
--- a/runelite-client/src/main/resources/net/runelite/client/runelite.properties
+++ b/runelite-client/src/main/resources/net/runelite/client/runelite.properties
@@ -1,3 +1,3 @@
runelite.title=RuneLite
runelite.version=${project.version}
-
+runescape.version=${rs.version}