Update Presence
Adds RuneLitePlusPlugin -adds option for RL+ presence (disabled by default) -Redirects a lot of older RL links to our updated ones. Prepare for next development iteration 0.1.2
This commit is contained in:
@@ -81,7 +81,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class RuneLite
|
public class RuneLite
|
||||||
{
|
{
|
||||||
public static final String RUNELIT_VERSION = "0.1.1";
|
public static final String RUNELIT_VERSION = "0.1.2";
|
||||||
public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".runelite");
|
public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".runelite");
|
||||||
public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles");
|
public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles");
|
||||||
public static final File PLUGIN_DIR = new File(RUNELITE_DIR, "plugins");
|
public static final File PLUGIN_DIR = new File(RUNELITE_DIR, "plugins");
|
||||||
@@ -108,7 +108,7 @@ public class RuneLite
|
|||||||
private SessionManager sessionManager;
|
private SessionManager sessionManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DiscordService discordService;
|
public DiscordService discordService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ClientSessionManager clientSessionManager;
|
private ClientSessionManager clientSessionManager;
|
||||||
@@ -309,9 +309,6 @@ public class RuneLite
|
|||||||
// Close the splash screen
|
// Close the splash screen
|
||||||
splashScreen.close();
|
splashScreen.close();
|
||||||
|
|
||||||
// Initialize Discord service
|
|
||||||
discordService.init();
|
|
||||||
|
|
||||||
// Register event listeners
|
// Register event listeners
|
||||||
eventBus.register(clientUI);
|
eventBus.register(clientUI);
|
||||||
eventBus.register(pluginManager);
|
eventBus.register(pluginManager);
|
||||||
|
|||||||
@@ -31,11 +31,13 @@ import javax.annotation.Nullable;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.client.plugins.runeliteplus.RuneLitePlusPlugin;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class RuneLiteProperties
|
public class RuneLiteProperties
|
||||||
{
|
{
|
||||||
|
public static String discordAppID = "409416265891971072";
|
||||||
private static final String RUNELITE_TITLE = "runelite.title";
|
private static final String RUNELITE_TITLE = "runelite.title";
|
||||||
private static final String RUNELITE_VERSION = "runelite.version";
|
private static final String RUNELITE_VERSION = "runelite.version";
|
||||||
private static final String RUNESCAPE_VERSION = "runescape.version";
|
private static final String RUNESCAPE_VERSION = "runescape.version";
|
||||||
@@ -78,7 +80,11 @@ public class RuneLiteProperties
|
|||||||
|
|
||||||
public String getDiscordAppId()
|
public String getDiscordAppId()
|
||||||
{
|
{
|
||||||
return properties.getProperty(DISCORD_APP_ID);
|
if (RuneLitePlusPlugin.customPresenceEnabled) {
|
||||||
|
return properties.getProperty(RuneLitePlusPlugin.rlPlusDiscordApp);
|
||||||
|
} else {
|
||||||
|
return properties.getProperty(DISCORD_APP_ID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDiscordInvite()
|
public String getDiscordInvite()
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ import net.runelite.discord.DiscordUser;
|
|||||||
public class DiscordService implements AutoCloseable
|
public class DiscordService implements AutoCloseable
|
||||||
{
|
{
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final RuneLiteProperties runeLiteProperties;
|
public final RuneLiteProperties runeLiteProperties;
|
||||||
private final ScheduledExecutorService executorService;
|
private final ScheduledExecutorService executorService;
|
||||||
private final DiscordRPC discordRPC;
|
private final DiscordRPC discordRPC;
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ public class DiscordService implements AutoCloseable
|
|||||||
discordEventHandlers.joinGame = this::joinGame;
|
discordEventHandlers.joinGame = this::joinGame;
|
||||||
discordEventHandlers.spectateGame = this::spectateGame;
|
discordEventHandlers.spectateGame = this::spectateGame;
|
||||||
discordEventHandlers.joinRequest = this::joinRequest;
|
discordEventHandlers.joinRequest = this::joinRequest;
|
||||||
discordRPC.Discord_Initialize(runeLiteProperties.getDiscordAppId(), discordEventHandlers, true, null);
|
discordRPC.Discord_Initialize(runeLiteProperties.discordAppID, discordEventHandlers, true, null);
|
||||||
executorService.scheduleAtFixedRate(discordRPC::Discord_RunCallbacks, 0, 2, TimeUnit.SECONDS);
|
executorService.scheduleAtFixedRate(discordRPC::Discord_RunCallbacks, 0, 2, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -412,6 +412,7 @@ public class ConfigPanel extends PluginPanel
|
|||||||
topPanelBackButton.setToolTipText("Back");
|
topPanelBackButton.setToolTipText("Back");
|
||||||
topPanel.add(topPanelBackButton, BorderLayout.WEST);
|
topPanel.add(topPanelBackButton, BorderLayout.WEST);
|
||||||
|
|
||||||
|
if (!listItem.getName().equals("RuneLitePlus"))
|
||||||
topPanel.add(listItem.createToggleButton(), BorderLayout.EAST);
|
topPanel.add(listItem.createToggleButton(), BorderLayout.EAST);
|
||||||
|
|
||||||
String name = listItem.getName();
|
String name = listItem.getName();
|
||||||
|
|||||||
@@ -178,30 +178,32 @@ public class PluginListItem extends JPanel
|
|||||||
configPanel.openConfigList();
|
configPanel.openConfigList();
|
||||||
});
|
});
|
||||||
|
|
||||||
final JPanel buttonPanel = new JPanel();
|
|
||||||
buttonPanel.setLayout(new GridLayout(1, 2));
|
|
||||||
add(buttonPanel, BorderLayout.LINE_END);
|
|
||||||
|
|
||||||
configButton.setPreferredSize(new Dimension(25, 0));
|
final JPanel buttonPanel = new JPanel();
|
||||||
configButton.setVisible(false);
|
buttonPanel.setLayout(new GridLayout(1, 2));
|
||||||
buttonPanel.add(configButton);
|
add(buttonPanel, BorderLayout.LINE_END);
|
||||||
|
|
||||||
// add a listener to configButton only if there are config items to show
|
configButton.setPreferredSize(new Dimension(25, 0));
|
||||||
if (config != null && !configDescriptor.getItems().stream().allMatch(item -> item.getItem().hidden()))
|
configButton.setVisible(false);
|
||||||
{
|
buttonPanel.add(configButton);
|
||||||
configButton.addActionListener(e ->
|
|
||||||
|
// add a listener to configButton only if there are config items to show
|
||||||
|
if (config != null && !configDescriptor.getItems().stream().allMatch(item -> item.getItem().hidden()))
|
||||||
{
|
{
|
||||||
configButton.setIcon(CONFIG_ICON);
|
configButton.addActionListener(e ->
|
||||||
configPanel.openGroupConfigPanel(PluginListItem.this, config, configDescriptor);
|
{
|
||||||
});
|
configButton.setIcon(CONFIG_ICON);
|
||||||
|
configPanel.openGroupConfigPanel(PluginListItem.this, config, configDescriptor);
|
||||||
|
});
|
||||||
|
|
||||||
configButton.setVisible(true);
|
configButton.setVisible(true);
|
||||||
configButton.setToolTipText("Edit plugin configuration");
|
configButton.setToolTipText("Edit plugin configuration");
|
||||||
|
}
|
||||||
|
if (!name.equals("RuneLitePlus")) {
|
||||||
|
toggleButton.setPreferredSize(new Dimension(25, 0));
|
||||||
|
attachToggleButtonListener(toggleButton);
|
||||||
|
buttonPanel.add(toggleButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleButton.setPreferredSize(new Dimension(25, 0));
|
|
||||||
attachToggleButtonListener(toggleButton);
|
|
||||||
buttonPanel.add(toggleButton);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attachToggleButtonListener(IconButton button)
|
private void attachToggleButtonListener(IconButton button)
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ import okhttp3.Response;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class DiscordPlugin extends Plugin
|
public class DiscordPlugin extends Plugin
|
||||||
{
|
{
|
||||||
|
public static boolean discordEnabled = false;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Client client;
|
private Client client;
|
||||||
|
|
||||||
@@ -138,6 +140,7 @@ public class DiscordPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
wsClient.registerMessage(DiscordUserInfo.class);
|
wsClient.registerMessage(DiscordUserInfo.class);
|
||||||
|
discordEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -147,6 +150,7 @@ public class DiscordPlugin extends Plugin
|
|||||||
discordState.reset();
|
discordState.reset();
|
||||||
partyService.changeParty(null);
|
partyService.changeParty(null);
|
||||||
wsClient.unregisterMessage(DiscordUserInfo.class);
|
wsClient.unregisterMessage(DiscordUserInfo.class);
|
||||||
|
discordEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019, Zeruth <TheRealNull@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.plugins.runeliteplus;
|
||||||
|
|
||||||
|
import net.runelite.client.config.Config;
|
||||||
|
import net.runelite.client.config.ConfigGroup;
|
||||||
|
import net.runelite.client.config.ConfigItem;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
@ConfigGroup("runeliteplus")
|
||||||
|
public interface RuneLitePlusConfig extends Config
|
||||||
|
{
|
||||||
|
@ConfigItem(
|
||||||
|
position = 0,
|
||||||
|
keyName = "customPresence",
|
||||||
|
name = "RL+ Presence",
|
||||||
|
description = "Represent RL+ with a custom icon and discord presence."
|
||||||
|
)
|
||||||
|
default boolean customPresence() { return false; }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019, Zeruth <TheRealNull@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.plugins.runeliteplus;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.events.ConfigChanged;
|
||||||
|
import net.runelite.client.RuneLite;
|
||||||
|
import net.runelite.client.RuneLiteProperties;
|
||||||
|
import net.runelite.client.config.ConfigManager;
|
||||||
|
import net.runelite.client.discord.DiscordPresence;
|
||||||
|
import net.runelite.client.discord.DiscordService;
|
||||||
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
|
import net.runelite.client.plugins.PluginType;
|
||||||
|
import net.runelite.client.plugins.discord.DiscordPlugin;
|
||||||
|
import net.runelite.client.ui.ClientUI;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@PluginDescriptor(
|
||||||
|
|
||||||
|
loadWhenOutdated = true, // prevent users from disabling
|
||||||
|
hidden = true, // prevent users from disabling
|
||||||
|
name = "RuneLitePlus",
|
||||||
|
description = "Configures various aspects of RuneLitePlus",
|
||||||
|
type = PluginType.EXTERNAL
|
||||||
|
)
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class RuneLitePlusPlugin extends Plugin
|
||||||
|
{
|
||||||
|
public static boolean customPresenceEnabled = false;
|
||||||
|
public static String rlPlusDiscordApp = "560644885250572289";
|
||||||
|
public static String rlDiscordApp = "409416265891971072";
|
||||||
|
@Inject
|
||||||
|
public RuneLitePlusConfig config;
|
||||||
|
@Inject
|
||||||
|
private OverlayManager overlayManager;
|
||||||
|
@Inject
|
||||||
|
private ConfigManager configManager;
|
||||||
|
@Inject
|
||||||
|
public DiscordService discordService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
RuneLitePlusConfig getConfig(ConfigManager configManager)
|
||||||
|
{
|
||||||
|
return configManager.getConfig(RuneLitePlusConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startUp() throws Exception
|
||||||
|
{
|
||||||
|
if (getConfig(configManager).customPresence()) {
|
||||||
|
ClientUI.currentPresenceName = ("RuneLitePlus");
|
||||||
|
ClientUI.frame.setTitle(ClientUI.currentPresenceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.customPresence()) {
|
||||||
|
RuneLiteProperties.discordAppID = rlPlusDiscordApp;
|
||||||
|
discordService.close();
|
||||||
|
discordService.init();
|
||||||
|
} else {
|
||||||
|
RuneLiteProperties.discordAppID = rlDiscordApp;
|
||||||
|
discordService.close();
|
||||||
|
discordService.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
protected void onConfigChanged(ConfigChanged event) {
|
||||||
|
if (event.getKey().equals("customPresence")) {
|
||||||
|
if (config.customPresence()) {
|
||||||
|
ClientUI.currentPresenceName = ("RuneLitePlus");
|
||||||
|
ClientUI.frame.setTitle(ClientUI.currentPresenceName);
|
||||||
|
} else {
|
||||||
|
ClientUI.currentPresenceName = ("RuneLite");
|
||||||
|
ClientUI.frame.setTitle(ClientUI.currentPresenceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.customPresence()) {
|
||||||
|
RuneLiteProperties.discordAppID = rlPlusDiscordApp;
|
||||||
|
discordService.close();
|
||||||
|
discordService.init();
|
||||||
|
} else {
|
||||||
|
RuneLiteProperties.discordAppID = rlDiscordApp;
|
||||||
|
discordService.close();
|
||||||
|
discordService.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void shutDown() throws Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -106,6 +106,7 @@ public class ClientUI
|
|||||||
private static final int CLIENT_WELL_HIDDEN_MARGIN = 160;
|
private static final int CLIENT_WELL_HIDDEN_MARGIN = 160;
|
||||||
private static final int CLIENT_WELL_HIDDEN_MARGIN_TOP = 10;
|
private static final int CLIENT_WELL_HIDDEN_MARGIN_TOP = 10;
|
||||||
public static boolean allowInput = false;
|
public static boolean allowInput = false;
|
||||||
|
public static String currentPresenceName = "RuneLite";
|
||||||
public static final BufferedImage ICON = ImageUtil.getResourceStreamFromClass(ClientUI.class, "/runelite.png");
|
public static final BufferedImage ICON = ImageUtil.getResourceStreamFromClass(ClientUI.class, "/runelite.png");
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@@ -286,7 +287,7 @@ public class ClientUI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.setTitle(properties.getTitle() + " - " + name);
|
frame.setTitle(currentPresenceName + " - " + name);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -309,7 +310,7 @@ public class ClientUI
|
|||||||
// Try to enable fullscreen on OSX
|
// Try to enable fullscreen on OSX
|
||||||
OSXUtil.tryEnableFullscreen(frame);
|
OSXUtil.tryEnableFullscreen(frame);
|
||||||
|
|
||||||
frame.setTitle(properties.getTitle());
|
frame.setTitle(ClientUI.currentPresenceName);
|
||||||
frame.setIconImage(ICON);
|
frame.setIconImage(ICON);
|
||||||
frame.getLayeredPane().setCursor(Cursor.getDefaultCursor()); // Prevent substance from using a resize cursor for pointing
|
frame.getLayeredPane().setCursor(Cursor.getDefaultCursor()); // Prevent substance from using a resize cursor for pointing
|
||||||
frame.setLocationRelativeTo(frame.getOwner());
|
frame.setLocationRelativeTo(frame.getOwner());
|
||||||
@@ -832,12 +833,12 @@ public class ClientUI
|
|||||||
|
|
||||||
if (player != null && player.getName() != null)
|
if (player != null && player.getName() != null)
|
||||||
{
|
{
|
||||||
frame.setTitle(properties.getTitle() + " - " + player.getName());
|
frame.setTitle(currentPresenceName + " - " + player.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
frame.setTitle(properties.getTitle());
|
frame.setTitle(currentPresenceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame.isAlwaysOnTopSupported())
|
if (frame.isAlwaysOnTopSupported())
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ runelite.title=RuneLite
|
|||||||
runelite.version=${project.version}
|
runelite.version=${project.version}
|
||||||
runescape.version=${rs.version}
|
runescape.version=${rs.version}
|
||||||
runelite.discord.appid=409416265891971072
|
runelite.discord.appid=409416265891971072
|
||||||
runelite.discord.invite=https://discord.gg/R4BQ8tU
|
runelite.discord.invite=https://discord.gg/HN5gf3m
|
||||||
runelite.github.link=https://github.com/runelite
|
runelite.github.link=https://github.com/runelite-extended/runelite
|
||||||
runelite.wiki.link=https://github.com/runelite/runelite/wiki
|
runelite.wiki.link=https://github.com/runelite-extended/runelite/wiki
|
||||||
runelite.patreon.link=https://www.patreon.com/runelite
|
runelite.patreon.link=https://www.patreon.com/RuneLitePlus
|
||||||
Reference in New Issue
Block a user