Merge remote-tracking branch 'upstream/master' into runelite
Also pulled out a couple of our merged apis into our own classes. Getting much easier to keep up to date with their data # Conflicts: # .github/FUNDING.yml # .github/workflows/CI.yml # cache-client/pom.xml # cache-updater/pom.xml # cache/pom.xml # cache/src/main/java/net/runelite/cache/fs/jagex/DiskStorage.java # ci/build.sh # http-api/pom.xml # http-service/pom.xml # http-service/src/main/java/net/runelite/http/service/chat/ChatController.java # http-service/src/main/java/net/runelite/http/service/config/ConfigController.java # http-service/src/main/java/net/runelite/http/service/config/ConfigService.java # http-service/src/main/java/net/runelite/http/service/ge/GrandExchangeController.java # http-service/src/main/java/net/runelite/http/service/ge/Trade.java # http-service/src/test/java/net/runelite/http/service/config/ConfigServiceTest.java # http-service/src/test/java/net/runelite/http/service/hiscore/HiscoreServiceTest.java # pom.xml # runelite-api/pom.xml # runelite-api/src/main/java/net/runelite/api/Client.java # runelite-api/src/main/java/net/runelite/api/ObjectID.java # runelite-api/src/main/java/net/runelite/api/ParamHolder.java # runelite-api/src/main/java/net/runelite/api/ParamID.java # runelite-api/src/main/java/net/runelite/api/Preferences.java # runelite-api/src/main/java/net/runelite/api/ScriptEvent.java # runelite-api/src/main/java/net/runelite/api/ScriptID.java # runelite-api/src/main/java/net/runelite/api/SettingID.java # runelite-api/src/main/java/net/runelite/api/StructComposition.java # runelite-api/src/main/java/net/runelite/api/StructID.java # runelite-api/src/main/java/net/runelite/api/Varbits.java # runelite-api/src/main/java/net/runelite/api/events/PlayerChanged.java # runelite-api/src/main/java/net/runelite/api/events/PostStructComposition.java # runelite-api/src/main/java/net/runelite/api/events/WidgetClosed.java # runelite-api/src/main/java/net/runelite/api/events/WidgetHiddenChanged.java # runelite-api/src/main/java/net/runelite/api/events/WidgetPositioned.java # runelite-api/src/main/java/net/runelite/api/events/WorldChanged.java # runelite-api/src/main/java/net/runelite/api/widgets/Widget.java # runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java # runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java # runelite-api/src/main/java/net/runelite/api/widgets/WidgetModalMode.java # runelite-api/src/test/java/net/runelite/api/plugins/combatlevel/CombatLevelOverlayTest.java # runelite-client/pom.xml # runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java # runelite-client/src/main/java/net/runelite/client/callback/Hooks.java # runelite-client/src/main/java/net/runelite/client/plugins/config/PluginToggleButton.java # runelite-client/src/main/java/net/runelite/client/plugins/customcursor/CustomCursor.java # runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java # runelite-client/src/main/java/net/runelite/client/plugins/mta/alchemy/AlchemyRoomTimer.java # runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixOverlay.java # runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixPlugin.java # runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java # runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableRow.java # runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java # runelite-client/src/main/resources/net/runelite/client/runelite.properties # runelite-client/src/main/scripts/OptionsPanelZoomUpdater.hash # runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java # runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java # runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java # runelite-client/src/test/java/net/runelite/client/plugins/chatnotifications/ChatNotificationsPluginTest.java # runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java # runelite-client/src/test/java/net/runelite/client/plugins/grandexchange/GrandExchangePluginTest.java # runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java # runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java # runelite-client/src/test/java/net/runelite/client/plugins/timers/TimersPluginTest.java # runelite-client/src/test/java/net/runelite/client/util/ColorUtilTest.java # runelite-script-assembler-plugin/pom.xml
This commit is contained in:
@@ -29,37 +29,15 @@ package com.openosrs.client.plugins.openosrs;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import com.openosrs.client.plugins.openosrs.externals.ExternalPluginManagerPanel;
|
||||
import com.openosrs.client.config.OpenOSRSConfig;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.ScriptID.BANK_PIN_OP;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.widgets.WidgetID;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_1;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_10;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_2;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_3;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_4;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_5;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_6;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_7;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_8;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_9;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_EXIT_BUTTON;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_FIRST_ENTERED;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_FORGOT_BUTTON;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_FOURTH_ENTERED;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_INSTRUCTION_TEXT;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_SECOND_ENTERED;
|
||||
import static net.runelite.api.widgets.WidgetInfo.BANK_PIN_THIRD_ENTERED;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.Keybind;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
@@ -78,8 +56,6 @@ import org.slf4j.LoggerFactory;
|
||||
@Slf4j
|
||||
public class OpenOSRSPlugin extends Plugin
|
||||
{
|
||||
private final openosrsKeyListener keyListener = new openosrsKeyListener();
|
||||
|
||||
@Inject
|
||||
private OpenOSRSConfig config;
|
||||
|
||||
@@ -107,9 +83,6 @@ public class OpenOSRSPlugin extends Plugin
|
||||
client.setOculusOrbNormalSpeed(detach ? 36 : 12);
|
||||
}
|
||||
};
|
||||
private int entered = -1;
|
||||
private int enterIdx;
|
||||
private boolean expectInput;
|
||||
private boolean detach;
|
||||
private Keybind keybind;
|
||||
|
||||
@@ -128,9 +101,6 @@ public class OpenOSRSPlugin extends Plugin
|
||||
.build();
|
||||
clientToolbar.addNavigation(navButton);
|
||||
|
||||
entered = -1;
|
||||
enterIdx = 0;
|
||||
expectInput = false;
|
||||
this.keybind = config.detachHotkey();
|
||||
keyManager.registerKeyListener(hotkeyListener);
|
||||
}
|
||||
@@ -139,12 +109,6 @@ public class OpenOSRSPlugin extends Plugin
|
||||
protected void shutDown()
|
||||
{
|
||||
clientToolbar.removeNavigation(navButton);
|
||||
|
||||
entered = 0;
|
||||
enterIdx = 0;
|
||||
expectInput = false;
|
||||
keyManager.unregisterKeyListener(keyListener);
|
||||
keyManager.unregisterKeyListener(hotkeyListener);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -157,14 +121,6 @@ public class OpenOSRSPlugin extends Plugin
|
||||
|
||||
this.keybind = config.detachHotkey();
|
||||
|
||||
if (!config.keyboardPin())
|
||||
{
|
||||
entered = 0;
|
||||
enterIdx = 0;
|
||||
expectInput = false;
|
||||
keyManager.unregisterKeyListener(keyListener);
|
||||
}
|
||||
|
||||
if (event.getKey().equals("shareLogs") && !config.shareLogs())
|
||||
{
|
||||
final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||
@@ -172,118 +128,4 @@ public class OpenOSRSPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
private void onScriptCallbackEvent(ScriptCallbackEvent e)
|
||||
{
|
||||
if (!config.keyboardPin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.getEventName().equals("bankpin"))
|
||||
{
|
||||
int[] intStack = client.getIntStack();
|
||||
int intStackSize = client.getIntStackSize();
|
||||
|
||||
// This'll be anywhere from -1 to 3
|
||||
// 0 = first number, 1 second, etc
|
||||
// Anything other than 0123 means the bankpin interface closes
|
||||
int enterIdx = intStack[intStackSize - 1];
|
||||
|
||||
if (enterIdx < 0 || enterIdx > 3)
|
||||
{
|
||||
keyManager.unregisterKeyListener(keyListener);
|
||||
this.enterIdx = 0;
|
||||
this.entered = 0;
|
||||
expectInput = false;
|
||||
return;
|
||||
}
|
||||
else if (enterIdx == 0)
|
||||
{
|
||||
keyManager.registerKeyListener(keyListener);
|
||||
}
|
||||
|
||||
this.enterIdx = enterIdx;
|
||||
expectInput = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleKey(char c)
|
||||
{
|
||||
if (client.getWidget(WidgetID.BANK_PIN_GROUP_ID, BANK_PIN_INSTRUCTION_TEXT.getChildId()) == null
|
||||
|| !client.getWidget(BANK_PIN_INSTRUCTION_TEXT).getText().equals("First click the FIRST digit.")
|
||||
&& !client.getWidget(BANK_PIN_INSTRUCTION_TEXT).getText().equals("Now click the SECOND digit.")
|
||||
&& !client.getWidget(BANK_PIN_INSTRUCTION_TEXT).getText().equals("Time for the THIRD digit.")
|
||||
&& !client.getWidget(BANK_PIN_INSTRUCTION_TEXT).getText().equals("Finally, the FOURTH digit."))
|
||||
|
||||
{
|
||||
entered = 0;
|
||||
enterIdx = 0;
|
||||
expectInput = false;
|
||||
keyManager.unregisterKeyListener(keyListener);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!expectInput)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int num = Character.getNumericValue(c);
|
||||
|
||||
// We gotta copy this cause enteridx changes while the script is executing
|
||||
int oldEnterIdx = enterIdx;
|
||||
|
||||
// Script 685 will call 653, which in turn will set expectInput to true
|
||||
expectInput = false;
|
||||
client.runScript(BANK_PIN_OP, num, enterIdx, entered, BANK_PIN_EXIT_BUTTON.getId(), BANK_PIN_FORGOT_BUTTON.getId(), BANK_PIN_1.getId(), BANK_PIN_2.getId(), BANK_PIN_3.getId(), BANK_PIN_4.getId(), BANK_PIN_5.getId(), BANK_PIN_6.getId(), BANK_PIN_7.getId(), BANK_PIN_8.getId(), BANK_PIN_9.getId(), BANK_PIN_10.getId(), BANK_PIN_FIRST_ENTERED.getId(), BANK_PIN_SECOND_ENTERED.getId(), BANK_PIN_THIRD_ENTERED.getId(), BANK_PIN_FOURTH_ENTERED.getId(), BANK_PIN_INSTRUCTION_TEXT.getId());
|
||||
|
||||
if (oldEnterIdx == 0)
|
||||
{
|
||||
entered = num * 1000;
|
||||
}
|
||||
else if (oldEnterIdx == 1)
|
||||
{
|
||||
entered += num * 100;
|
||||
}
|
||||
else if (oldEnterIdx == 2)
|
||||
{
|
||||
entered += num * 10;
|
||||
}
|
||||
}
|
||||
|
||||
private class openosrsKeyListener implements KeyListener
|
||||
{
|
||||
private int lastKeyCycle;
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent keyEvent)
|
||||
{
|
||||
if (!Character.isDigit(keyEvent.getKeyChar()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (client.getGameCycle() - lastKeyCycle <= 5)
|
||||
{
|
||||
keyEvent.consume();
|
||||
return;
|
||||
}
|
||||
|
||||
lastKeyCycle = client.getGameCycle();
|
||||
|
||||
clientThread.invoke(() -> handleKey(keyEvent.getKeyChar()));
|
||||
keyEvent.consume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent keyEvent)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent keyEvent)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import net.runelite.api.Constants;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.ui.ContainableFrame;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.util.OSType;
|
||||
|
||||
@ConfigGroup(RuneLiteConfig.GROUP_NAME)
|
||||
public interface RuneLiteConfig extends Config
|
||||
@@ -122,14 +123,14 @@ public interface RuneLiteConfig extends Config
|
||||
@ConfigItem(
|
||||
keyName = "uiEnableCustomChrome",
|
||||
name = "Enable custom window chrome",
|
||||
description = "Use Runelite's custom window title and borders.",
|
||||
description = "Use RuneLite's custom window title and borders.",
|
||||
warning = "Please restart your client after changing this setting",
|
||||
position = 15,
|
||||
section = windowSettings
|
||||
)
|
||||
default boolean enableCustomChrome()
|
||||
{
|
||||
return true;
|
||||
return OSType.getOSType() == OSType.Windows;
|
||||
}
|
||||
|
||||
@Range(
|
||||
@@ -150,7 +151,7 @@ public interface RuneLiteConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gameAlwaysOnTop",
|
||||
name = "Enable client always on top",
|
||||
name = "Always on top",
|
||||
description = "The game will always be on the top of the screen",
|
||||
position = 17,
|
||||
section = windowSettings
|
||||
@@ -162,8 +163,8 @@ public interface RuneLiteConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "warningOnExit",
|
||||
name = "Display warning on exit",
|
||||
description = "Toggles a warning popup when trying to exit the client",
|
||||
name = "Exit warning",
|
||||
description = "Shows a warning popup when trying to exit the client",
|
||||
position = 18,
|
||||
section = windowSettings
|
||||
)
|
||||
@@ -198,7 +199,7 @@ public interface RuneLiteConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationRequestFocus",
|
||||
name = "Request focus on notification",
|
||||
name = "Request focus",
|
||||
description = "Configures the window focus request type on notification",
|
||||
position = 21,
|
||||
section = notificationSettings
|
||||
@@ -222,8 +223,8 @@ public interface RuneLiteConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationGameMessage",
|
||||
name = "Enable game message notifications",
|
||||
description = "Puts a notification message in the chatbox",
|
||||
name = "Game message notifications",
|
||||
description = "Adds a notification message to the chatbox",
|
||||
position = 23,
|
||||
section = notificationSettings
|
||||
)
|
||||
@@ -234,7 +235,7 @@ public interface RuneLiteConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "flashNotification",
|
||||
name = "Flash notification",
|
||||
name = "Flash",
|
||||
description = "Flashes the game frame as a notification",
|
||||
position = 24,
|
||||
section = notificationSettings
|
||||
@@ -259,7 +260,7 @@ public interface RuneLiteConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "notificationFlashColor",
|
||||
name = "Notification Flash Color",
|
||||
name = "Notification Flash",
|
||||
description = "Sets the color of the notification flashes.",
|
||||
position = 26,
|
||||
section = notificationSettings
|
||||
@@ -295,7 +296,7 @@ public interface RuneLiteConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "interfaceFontType",
|
||||
name = "Interface Overlay Font",
|
||||
name = "Interface Font",
|
||||
description = "Configures what font type is used for in-game interface overlays such as panels, opponent info, clue scrolls etc.",
|
||||
position = 32,
|
||||
section = overlaySettings
|
||||
|
||||
@@ -689,6 +689,11 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse
|
||||
log.warn("Unable to get clipboard", ex);
|
||||
}
|
||||
return;
|
||||
case KeyEvent.VK_A:
|
||||
selectionStart = 0;
|
||||
selectionEnd = value.length();
|
||||
cursorAt(0, selectionEnd);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -753,11 +758,25 @@ public class ChatboxTextInput extends ChatboxInput implements KeyListener, Mouse
|
||||
return;
|
||||
case KeyEvent.VK_LEFT:
|
||||
ev.consume();
|
||||
newPos--;
|
||||
if (cursorStart != cursorEnd)
|
||||
{
|
||||
newPos = cursorStart;
|
||||
}
|
||||
else
|
||||
{
|
||||
newPos--;
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_RIGHT:
|
||||
ev.consume();
|
||||
newPos++;
|
||||
if (cursorStart != cursorEnd)
|
||||
{
|
||||
newPos = cursorEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
newPos++;
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_UP:
|
||||
ev.consume();
|
||||
|
||||
@@ -50,9 +50,9 @@ public class KaramjaDiaryRequirement extends GenericDiaryRequirement
|
||||
add("Claim a ticket from the Agility Arena in Brimhaven.",
|
||||
new SkillRequirement(Skill.AGILITY, 30));
|
||||
add("Discover hidden wall in the dungeon below the volcano.",
|
||||
new QuestRequirement(Quest.DRAGON_SLAYER, true));
|
||||
new QuestRequirement(Quest.DRAGON_SLAYER_I, true));
|
||||
add("Visit the Isle of Crandor via the dungeon below the volcano.",
|
||||
new QuestRequirement(Quest.DRAGON_SLAYER, true));
|
||||
new QuestRequirement(Quest.DRAGON_SLAYER_I, true));
|
||||
add("Use Vigroy and Hajedy's cart service.",
|
||||
new QuestRequirement(Quest.SHILO_VILLAGE));
|
||||
add("Earn 100% favour in the village of Tai Bwo Wannai.",
|
||||
|
||||
@@ -147,7 +147,7 @@ public interface AgilityConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "portalsHighlight",
|
||||
name = "Portals Highlight Color",
|
||||
name = "Portals Color",
|
||||
description = "Color of highlighted Prifddinas portals",
|
||||
position = 9
|
||||
)
|
||||
|
||||
@@ -81,7 +81,7 @@ public interface BoostsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "displayNextBuffChange",
|
||||
name = "Display next buff change",
|
||||
name = "Next buff change",
|
||||
description = "Configures whether or not to display when the next buffed stat change will be",
|
||||
position = 4
|
||||
)
|
||||
@@ -92,7 +92,7 @@ public interface BoostsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "displayNextDebuffChange",
|
||||
name = "Display next debuff change",
|
||||
name = "Next debuff change",
|
||||
description = "Configures whether or not to display when the next debuffed stat change will be",
|
||||
position = 5
|
||||
)
|
||||
@@ -103,7 +103,7 @@ public interface BoostsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "boostThreshold",
|
||||
name = "Boost amount threshold",
|
||||
name = "Boost threshold",
|
||||
description = "The threshold at which boosted levels will be displayed in a different color. A value of 0 will disable the feature.",
|
||||
position = 6
|
||||
)
|
||||
|
||||
@@ -51,7 +51,7 @@ public interface CannonConfig extends Config
|
||||
)
|
||||
@ConfigItem(
|
||||
keyName = "lowWarningThreshold",
|
||||
name = "Low Warning Threshold",
|
||||
name = "Low warning threshold",
|
||||
description = "Configures the number of cannonballs remaining before a notification is sent. <br>Regardless of this value, a notification will still be sent when your cannon is empty.",
|
||||
position = 2
|
||||
)
|
||||
@@ -62,7 +62,7 @@ public interface CannonConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showInfobox",
|
||||
name = "Show Cannonball infobox",
|
||||
name = "Show cannonball infobox",
|
||||
description = "Configures whether to show the cannonballs in an infobox",
|
||||
position = 3
|
||||
)
|
||||
@@ -85,7 +85,7 @@ public interface CannonConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "highlightDoubleHitColor",
|
||||
name = "Color of double hit spots",
|
||||
name = "Double hit spots",
|
||||
description = "Configures the highlight color of double hit spots",
|
||||
position = 5
|
||||
)
|
||||
|
||||
@@ -156,7 +156,7 @@ public interface ChatFilterConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "maxRepeatedPublicChats",
|
||||
name = "Max repeated public chats",
|
||||
name = "Repeat filter",
|
||||
description = "Block player chat message if repeated this many times. 0 is off",
|
||||
position = 11
|
||||
)
|
||||
|
||||
@@ -105,7 +105,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
|
||||
new CrypticClue("A crate found in the tower of a church is your next location.", CRATE_357, new WorldPoint(2612, 3304, 1), "Climb the ladder and search the crates on the first floor in the Church in Ardougne."),
|
||||
new CrypticClue("Covered in shadows, the centre of the circle is where you will find the answer.", new WorldPoint(3488, 3289, 0), "Dig in the centre of Mort'ton, where the roads intersect."),
|
||||
new CrypticClue("I lie lonely and forgotten in mid wilderness, where the dead rise from their beds. Feel free to quarrel and wind me up, and dig while you shoot their heads.", new WorldPoint(3174, 3663, 0), "Directly under the crossbow respawn in the Graveyard of Shadows in level 18 Wilderness."),
|
||||
new CrypticClue("In the city where merchants are said to have lived, talk to a man with a splendid cape, but a hat dropped by goblins.", "Head chef", new WorldPoint(3143, 3445, 0), "Talk to the Head chef in Cooks' Guild west of Varrock. You will need a chef hat or cooking cape to enter."),
|
||||
new CrypticClue("In the city where merchants are said to have lived, talk to a man with a splendid cape, but a hat dropped by goblins.", "Head chef", new WorldPoint(3143, 3445, 0), "Talk to the Head chef in Cooks' Guild west of Varrock. You will need a chef's hat, Varrock armour 3 or 4, or the Cooking cape to enter."),
|
||||
new CrypticClue("The mother of the reptilian sacrifice.", "Zul-Cheray", new WorldPoint(2204, 3050, 0), "Talk to Zul-Cheray in a house near the sacrificial boat at Zul-Andra."),
|
||||
new CrypticClue("I watch the sea. I watch you fish. I watch your tree.", "Ellena", new WorldPoint(2860, 3431, 0), "Speak to Ellena at Catherby fruit tree patch."),
|
||||
new CrypticClue("Dig between some ominous stones in Falador.", new WorldPoint(3040, 3399, 0), "Three standing stones inside a walled area. East of the northern Falador gate."),
|
||||
|
||||
@@ -50,7 +50,7 @@ import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
public class FaloTheBardClue extends ClueScroll implements TextClueScroll, NpcClueScroll
|
||||
{
|
||||
private static final List<FaloTheBardClue> CLUES = ImmutableList.of(
|
||||
new FaloTheBardClue("A blood red weapon, a strong curved sword, found on the island of primate lords.", item(DRAGON_SCIMITAR)),
|
||||
new FaloTheBardClue("A blood red weapon, a strong curved sword, found on the island of primate lords.", any("Dragon scimitar", item(DRAGON_SCIMITAR), item(DRAGON_SCIMITAR_OR))),
|
||||
new FaloTheBardClue("A book that preaches of some great figure, lending strength, might and vigour.", any("Any god book (must be complete)", item(HOLY_BOOK), item(BOOK_OF_BALANCE), item(UNHOLY_BOOK), item(BOOK_OF_LAW), item(BOOK_OF_WAR), item(BOOK_OF_DARKNESS))),
|
||||
new FaloTheBardClue("A bow of elven craft was made, it shimmers bright, but will soon fade.", any("Crystal Bow", item(CRYSTAL_BOW), item(CRYSTAL_BOW_24123))),
|
||||
new FaloTheBardClue("A fiery axe of great inferno, when you use it, you'll wonder where the logs go.", item(INFERNAL_AXE)),
|
||||
|
||||
@@ -91,7 +91,7 @@ public enum HotColdLocation
|
||||
FREMENNIK_PROVINCE_FREMMY_ISLES_MINE(new WorldPoint(2374, 3850, 0), FREMENNIK_PROVINCE, "Central Fremennik Isles mine.", ANCIENT_WIZARDS),
|
||||
FREMENNIK_PROVINCE_WEST_ISLES_MINE(new WorldPoint(2313, 3850, 0), FREMENNIK_PROVINCE, "West Fremennik Isles mine.", ANCIENT_WIZARDS),
|
||||
FREMENNIK_PROVINCE_WEST_JATIZSO_ENTRANCE(new WorldPoint(2393, 3812, 0), FREMENNIK_PROVINCE, "West of the Jatizso mine entrance.", BRASSICAN_MAGE),
|
||||
FREMENNIK_PROVINCE_PIRATES_COVE(new WorldPoint(2210, 3814, 0), FREMENNIK_PROVINCE, "Pirates' Cove", ANCIENT_WIZARDS),
|
||||
FREMENNIK_PROVINCE_PIRATES_COVE(new WorldPoint(2211, 3817, 0), FREMENNIK_PROVINCE, "Pirates' Cove", ANCIENT_WIZARDS),
|
||||
FREMENNIK_PROVINCE_ASTRAL_ALTER(new WorldPoint(2149, 3865, 0), FREMENNIK_PROVINCE, "Astral altar", ANCIENT_WIZARDS),
|
||||
FREMENNIK_PROVINCE_LUNAR_VILLAGE(new WorldPoint(2084, 3916, 0), FREMENNIK_PROVINCE, "Lunar Isle, inside the village.", ANCIENT_WIZARDS),
|
||||
FREMENNIK_PROVINCE_LUNAR_NORTH(new WorldPoint(2106, 3949, 0), FREMENNIK_PROVINCE, "Lunar Isle, north of the village.", ANCIENT_WIZARDS),
|
||||
|
||||
@@ -487,15 +487,19 @@ class ConfigPanel extends PluginPanel
|
||||
if (cid.getType().isEnum())
|
||||
{
|
||||
Class<? extends Enum> type = (Class<? extends Enum>) cid.getType();
|
||||
JComboBox box = new JComboBox(type.getEnumConstants());
|
||||
|
||||
JComboBox<Enum<?>> box = new JComboBox<Enum<?>>(type.getEnumConstants()); // NOPMD: UseDiamondOperator
|
||||
// set renderer prior to calling box.getPreferredSize(), since it will invoke the renderer
|
||||
// to build components for each combobox element in order to compute the display size of the
|
||||
// combobox
|
||||
box.setRenderer(new ComboBoxListRenderer<>());
|
||||
box.setPreferredSize(new Dimension(box.getPreferredSize().width, 25));
|
||||
box.setRenderer(new ComboBoxListRenderer());
|
||||
box.setForeground(Color.WHITE);
|
||||
box.setFocusable(false);
|
||||
box.setPrototypeDisplayValue("XXXXXXXX"); //sorry but this is the way to keep the size of the combobox in check.
|
||||
|
||||
try
|
||||
{
|
||||
Enum selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()));
|
||||
Enum<?> selectedItem = Enum.valueOf(type, configManager.getConfiguration(cd.getGroup().value(), cid.getItem().keyName()));
|
||||
box.setSelectedItem(selectedItem);
|
||||
box.setToolTipText(Text.titleCase(selectedItem));
|
||||
}
|
||||
@@ -508,7 +512,7 @@ class ConfigPanel extends PluginPanel
|
||||
if (e.getStateChange() == ItemEvent.SELECTED)
|
||||
{
|
||||
changeConfiguration(box, cd, cid);
|
||||
box.setToolTipText(Text.titleCase((Enum) box.getSelectedItem()));
|
||||
box.setToolTipText(Text.titleCase((Enum<?>) box.getSelectedItem()));
|
||||
}
|
||||
});
|
||||
item.add(box, BorderLayout.EAST);
|
||||
|
||||
@@ -56,4 +56,11 @@ public enum CustomCursor
|
||||
this.name = name;
|
||||
this.cursorImage = ImageUtil.loadImageResource(CustomCursorPlugin.class, icon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ public interface DriftNetConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tagAnnette",
|
||||
name = "Tag Annette when no nets in inventory",
|
||||
name = "Tag Annette",
|
||||
description = "Tag Annette when no nets in inventory",
|
||||
position = 6
|
||||
)
|
||||
|
||||
@@ -93,7 +93,7 @@ public interface FishingConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "minnowsOverlayColor",
|
||||
name = "Minnows Overlay Color",
|
||||
name = "Minnows Overlay",
|
||||
description = "Color of overlays for Minnows",
|
||||
position = 5
|
||||
)
|
||||
@@ -105,7 +105,7 @@ public interface FishingConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "aerialOverlayColor",
|
||||
name = "Aerial Overlay Color",
|
||||
name = "Aerial Overlay",
|
||||
description = "Color of overlays when 1-tick aerial fishing",
|
||||
position = 6
|
||||
)
|
||||
|
||||
@@ -156,7 +156,7 @@ public interface GroundItemsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notifyTier",
|
||||
name = "Notify >= Tier",
|
||||
name = "Notify tier",
|
||||
description = "Configures which price tiers will trigger a notification on drop",
|
||||
position = 8
|
||||
)
|
||||
@@ -211,7 +211,7 @@ public interface GroundItemsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hideUnderValue",
|
||||
name = "Hide < Value",
|
||||
name = "Hide under value",
|
||||
description = "Configures hidden ground items under both GE and HA value",
|
||||
position = 13
|
||||
)
|
||||
@@ -223,7 +223,7 @@ public interface GroundItemsConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "defaultColor",
|
||||
name = "Default items color",
|
||||
name = "Default items",
|
||||
description = "Configures the color for default, non-highlighted items",
|
||||
position = 14
|
||||
)
|
||||
@@ -235,7 +235,7 @@ public interface GroundItemsConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "highlightedColor",
|
||||
name = "Highlighted items color",
|
||||
name = "Highlighted items",
|
||||
description = "Configures the color for highlighted items",
|
||||
position = 15
|
||||
)
|
||||
@@ -247,7 +247,7 @@ public interface GroundItemsConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "hiddenColor",
|
||||
name = "Hidden items color",
|
||||
name = "Hidden items",
|
||||
description = "Configures the color for hidden items in right-click menu and when holding ALT",
|
||||
position = 16
|
||||
)
|
||||
@@ -259,7 +259,7 @@ public interface GroundItemsConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "lowValueColor",
|
||||
name = "Low value items color",
|
||||
name = "Low value items",
|
||||
description = "Configures the color for low value items",
|
||||
position = 17
|
||||
)
|
||||
@@ -282,7 +282,7 @@ public interface GroundItemsConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "mediumValueColor",
|
||||
name = "Medium value items color",
|
||||
name = "Medium value items",
|
||||
description = "Configures the color for medium value items",
|
||||
position = 19
|
||||
)
|
||||
@@ -305,7 +305,7 @@ public interface GroundItemsConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "highValueColor",
|
||||
name = "High value items color",
|
||||
name = "High value items",
|
||||
description = "Configures the color for high value items",
|
||||
position = 21
|
||||
)
|
||||
@@ -328,7 +328,7 @@ public interface GroundItemsConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "insaneValueColor",
|
||||
name = "Insane value items color",
|
||||
name = "Insane value items",
|
||||
description = "Configures the color for insane value items",
|
||||
position = 23
|
||||
)
|
||||
@@ -361,8 +361,8 @@ public interface GroundItemsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "doubleTapDelay",
|
||||
name = "Delay for double-tap ALT to hide",
|
||||
description = "Decrease this number if you accidentally hide ground items often. (0 = Disabled)",
|
||||
name = "Double-tap delay",
|
||||
description = "Delay for the double-tap ALT to hide ground items. 0 to disable.",
|
||||
position = 26
|
||||
)
|
||||
@Units(Units.MILLISECONDS)
|
||||
@@ -373,7 +373,7 @@ public interface GroundItemsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "collapseEntries",
|
||||
name = "Collapse ground item menu entries",
|
||||
name = "Collapse ground item menu",
|
||||
description = "Collapses ground item menu entries together and appends count",
|
||||
position = 27
|
||||
)
|
||||
|
||||
@@ -90,7 +90,7 @@ public interface IdleNotifierConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hitpoints",
|
||||
name = "Hitpoints Notification Threshold",
|
||||
name = "Hitpoints Threshold",
|
||||
description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.",
|
||||
position = 6
|
||||
)
|
||||
@@ -101,7 +101,7 @@ public interface IdleNotifierConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "prayer",
|
||||
name = "Prayer Notification Threshold",
|
||||
name = "Prayer Threshold",
|
||||
description = "The amount of prayer points to send a notification at. A value of 0 will disable notification.",
|
||||
position = 7
|
||||
)
|
||||
@@ -112,7 +112,7 @@ public interface IdleNotifierConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "oxygen",
|
||||
name = "Oxygen Notification Threshold",
|
||||
name = "Oxygen Threshold",
|
||||
position = 8,
|
||||
description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification."
|
||||
)
|
||||
@@ -124,9 +124,9 @@ public interface IdleNotifierConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "spec",
|
||||
name = "Special Attack Energy Notification Threshold",
|
||||
name = "Spec Threshold",
|
||||
position = 9,
|
||||
description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification."
|
||||
description = "The amount of special attack energy reached to send a notification at. A value of 0 will disable notification."
|
||||
)
|
||||
@Units(Units.PERCENT)
|
||||
default int getSpecEnergyThreshold()
|
||||
|
||||
@@ -55,7 +55,7 @@ public interface ImplingsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "showbaby",
|
||||
name = "Show Baby implings",
|
||||
name = "Baby implings",
|
||||
description = "Configures whether or not Baby impling tags are displayed",
|
||||
section = implingSection
|
||||
)
|
||||
@@ -80,7 +80,7 @@ public interface ImplingsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "showyoung",
|
||||
name = "Show Young implings",
|
||||
name = "Young implings",
|
||||
description = "Configures whether or not Young impling tags are displayed",
|
||||
section = implingSection
|
||||
)
|
||||
@@ -105,7 +105,7 @@ public interface ImplingsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "showgourmet",
|
||||
name = "Show Gourmet implings",
|
||||
name = "Gourmet implings",
|
||||
description = "Configures whether or not Gourmet impling tags are displayed",
|
||||
section = implingSection
|
||||
)
|
||||
@@ -130,7 +130,7 @@ public interface ImplingsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "showearth",
|
||||
name = "Show Earth implings",
|
||||
name = "Earth implings",
|
||||
description = "Configures whether or not Earth impling tags are displayed",
|
||||
section = implingSection
|
||||
)
|
||||
@@ -155,7 +155,7 @@ public interface ImplingsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
keyName = "showessence",
|
||||
name = "Show Essence implings",
|
||||
name = "Essence implings",
|
||||
description = "Configures whether or not Essence impling tags are displayed",
|
||||
section = implingSection
|
||||
)
|
||||
@@ -180,7 +180,7 @@ public interface ImplingsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 11,
|
||||
keyName = "showeclectic",
|
||||
name = "Show Eclectic implings",
|
||||
name = "Eclectic implings",
|
||||
description = "Configures whether or not Eclectic impling tags are displayed",
|
||||
section = implingSection
|
||||
)
|
||||
@@ -205,7 +205,7 @@ public interface ImplingsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "shownature",
|
||||
name = "Show Nature implings",
|
||||
name = "Nature implings",
|
||||
description = "Configures whether or not Nature impling tags are displayed",
|
||||
section = implingSection
|
||||
)
|
||||
@@ -230,7 +230,7 @@ public interface ImplingsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 15,
|
||||
keyName = "showmagpie",
|
||||
name = "Show Magpie implings",
|
||||
name = "Magpie implings",
|
||||
description = "Configures whether or not Magpie impling tags are displayed",
|
||||
section = implingSection
|
||||
)
|
||||
@@ -255,7 +255,7 @@ public interface ImplingsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 17,
|
||||
keyName = "showninja",
|
||||
name = "Show Ninja implings",
|
||||
name = "Ninja implings",
|
||||
description = "Configures whether or not Ninja impling tags are displayed",
|
||||
section = implingSection
|
||||
)
|
||||
@@ -280,7 +280,7 @@ public interface ImplingsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 19,
|
||||
keyName = "showCrystal",
|
||||
name = "Show Crystal implings",
|
||||
name = "Crystal implings",
|
||||
description = "Configures whether or not Crystal implings are displayed",
|
||||
section = implingSection
|
||||
)
|
||||
@@ -305,7 +305,7 @@ public interface ImplingsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 21,
|
||||
keyName = "showdragon",
|
||||
name = "Show Dragon implings",
|
||||
name = "Dragon implings",
|
||||
description = "Configures whether or not Dragon impling tags are displayed",
|
||||
section = implingSection
|
||||
)
|
||||
@@ -330,7 +330,7 @@ public interface ImplingsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 23,
|
||||
keyName = "showlucky",
|
||||
name = "Show Lucky implings",
|
||||
name = "Lucky implings",
|
||||
description = "Configures whether or not Lucky impling tags are displayed",
|
||||
section = implingSection
|
||||
)
|
||||
|
||||
@@ -51,7 +51,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "veryLowWarningColor",
|
||||
name = "Very Low Warning Color",
|
||||
name = "Very Low Warning",
|
||||
description = "The color of the overlay when charges are very low",
|
||||
position = 1
|
||||
)
|
||||
@@ -62,7 +62,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lowWarningColor",
|
||||
name = "Low Warning Color",
|
||||
name = "Low Warning",
|
||||
description = "The color of the overlay when charges are low",
|
||||
position = 2
|
||||
)
|
||||
@@ -95,7 +95,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showTeleportCharges",
|
||||
name = "Show Teleport Charges",
|
||||
name = "Teleport Charges",
|
||||
description = "Show teleport item charge counts",
|
||||
position = 5,
|
||||
section = chargesSection
|
||||
@@ -149,7 +149,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showImpCharges",
|
||||
name = "Show Imp-in-a-box charges",
|
||||
name = "Imp-in-a-box charges",
|
||||
description = "Show Imp-in-a-box item charges",
|
||||
position = 8,
|
||||
section = chargesSection
|
||||
@@ -161,7 +161,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showFungicideCharges",
|
||||
name = "Show Fungicide Charges",
|
||||
name = "Fungicide Charges",
|
||||
description = "Show Fungicide item charges",
|
||||
position = 9,
|
||||
section = chargesSection
|
||||
@@ -173,7 +173,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showWateringCanCharges",
|
||||
name = "Show Watering Can Charges",
|
||||
name = "Watering Can Charges",
|
||||
description = "Show Watering can item charges",
|
||||
position = 10,
|
||||
section = chargesSection
|
||||
@@ -185,7 +185,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showWaterskinCharges",
|
||||
name = "Show Waterskin Charges",
|
||||
name = "Waterskin Charges",
|
||||
description = "Show Waterskin dose counts",
|
||||
position = 11,
|
||||
section = chargesSection
|
||||
@@ -197,7 +197,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showBellowCharges",
|
||||
name = "Show Bellows Charges",
|
||||
name = "Bellows Charges",
|
||||
description = "Show Ogre bellows item charges",
|
||||
position = 12,
|
||||
section = chargesSection
|
||||
@@ -209,7 +209,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showBasketCharges",
|
||||
name = "Show Basket Charges",
|
||||
name = "Basket Charges",
|
||||
description = "Show Fruit basket item counts",
|
||||
position = 13,
|
||||
section = chargesSection
|
||||
@@ -221,7 +221,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showSackCharges",
|
||||
name = "Show Sack Charges",
|
||||
name = "Sack Charges",
|
||||
description = "Show Sack item counts",
|
||||
position = 14,
|
||||
section = chargesSection
|
||||
@@ -233,7 +233,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showAbyssalBraceletCharges",
|
||||
name = "Show Abyssal Bracelet Charges",
|
||||
name = "Abyssal Bracelet Charges",
|
||||
description = "Show Abyssal bracelet item charges",
|
||||
position = 15,
|
||||
section = chargesSection
|
||||
@@ -245,7 +245,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showAmuletOfChemistryCharges",
|
||||
name = "Show Amulet of Chemistry Charges",
|
||||
name = "Amulet of Chemistry Charges",
|
||||
description = "Show Amulet of chemistry item charges",
|
||||
position = 16,
|
||||
section = chargesSection
|
||||
@@ -275,7 +275,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showAmuletOfBountyCharges",
|
||||
name = "Show Amulet of Bounty Charges",
|
||||
name = "Amulet of Bounty Charges",
|
||||
description = "Show Amulet of bounty item charges",
|
||||
position = 17,
|
||||
section = chargesSection
|
||||
@@ -317,7 +317,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showBindingNecklaceCharges",
|
||||
name = "Show Binding Necklace Charges",
|
||||
name = "Binding Necklace Charges",
|
||||
description = "Show Binding necklace item charges",
|
||||
position = 19,
|
||||
section = chargesSection
|
||||
@@ -359,7 +359,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showExplorerRingCharges",
|
||||
name = "Show Explorer's Ring Alch Charges",
|
||||
name = "Explorer's Ring Alch Charges",
|
||||
description = "Show Explorer's ring alchemy charges",
|
||||
position = 21,
|
||||
section = chargesSection
|
||||
@@ -389,7 +389,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showRingOfForgingCount",
|
||||
name = "Show Ring of Forging Charges",
|
||||
name = "Ring of Forging Charges",
|
||||
description = "Show Ring of forging item charges",
|
||||
position = 22,
|
||||
section = chargesSection
|
||||
@@ -431,7 +431,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showInfoboxes",
|
||||
name = "Show Infoboxes",
|
||||
name = "Infoboxes",
|
||||
description = "Show an infobox with remaining charges for equipped items",
|
||||
position = 24
|
||||
)
|
||||
@@ -442,7 +442,7 @@ public interface ItemChargeConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showPotionDoseCount",
|
||||
name = "Show Potion Doses",
|
||||
name = "Potion Doses",
|
||||
description = "Show remaining potion doses",
|
||||
position = 25,
|
||||
section = chargesSection
|
||||
|
||||
@@ -131,7 +131,7 @@ public class ItemStatChanges
|
||||
add(boost(DEFENCE, perc(.15, 5)), SUPER_DEFENCE1, SUPER_DEFENCE2, SUPER_DEFENCE3, SUPER_DEFENCE4);
|
||||
add(boost(MAGIC, 3), MAGIC_ESSENCE1, MAGIC_ESSENCE2, MAGIC_ESSENCE3, MAGIC_ESSENCE4);
|
||||
add(combo(3, boost(ATTACK, perc(.15, 5)), boost(STRENGTH, perc(.15, 5)), boost(DEFENCE, perc(.15, 5))), SUPER_COMBAT_POTION1, SUPER_COMBAT_POTION2, SUPER_COMBAT_POTION3, SUPER_COMBAT_POTION4);
|
||||
add(combo(3, boost(ATTACK, perc(.20, 2)), boost(STRENGTH, perc(.12, 2)), heal(PRAYER, perc(.10, 0)), heal(DEFENCE, perc(.10, -2)), new BoostedStatBoost(HITPOINTS, false, perc(-.12, 0))), ZAMORAK_BREW1, ZAMORAK_BREW2, ZAMORAK_BREW3, ZAMORAK_BREW4);
|
||||
add(combo(3, boost(ATTACK, perc(.20, 2)), boost(STRENGTH, perc(.12, 2)), heal(PRAYER, perc(.10, 0)), new BoostedStatBoost(DEFENCE, false, perc(.10, -2)), new BoostedStatBoost(HITPOINTS, false, perc(-.12, 0))), ZAMORAK_BREW1, ZAMORAK_BREW2, ZAMORAK_BREW3, ZAMORAK_BREW4);
|
||||
add(new SaradominBrew(0.15, 0.2, 0.1, 2, 2), SARADOMIN_BREW1, SARADOMIN_BREW2, SARADOMIN_BREW3, SARADOMIN_BREW4);
|
||||
add(boost(RANGED, perc(.15, 5)), SUPER_RANGING_1, SUPER_RANGING_2, SUPER_RANGING_3, SUPER_RANGING_4);
|
||||
add(boost(MAGIC, perc(.15, 5)), SUPER_MAGIC_POTION_1, SUPER_MAGIC_POTION_2, SUPER_MAGIC_POTION_3, SUPER_MAGIC_POTION_4);
|
||||
@@ -214,6 +214,10 @@ public class ItemStatChanges
|
||||
add(heal(HITPOINTS, 20), PADDLEFISH);
|
||||
add(new GauntletPotion(), EGNIOL_POTION_1, EGNIOL_POTION_2, EGNIOL_POTION_3, EGNIOL_POTION_4);
|
||||
|
||||
// Soul Wars
|
||||
add(combo(2, heal(HITPOINTS, perc(.20, 2)), heal(RUN_ENERGY, 100)), BANDAGES_25202);
|
||||
add(combo(6, boost(ATTACK, perc(.15, 5)), boost(STRENGTH, perc(.15, 5)), boost(DEFENCE, perc(.15, 5)), boost(RANGED, perc(.15, 5)), boost(MAGIC, perc(.15, 5)), heal(PRAYER, perc(.25, 8))), POTION_OF_POWER1, POTION_OF_POWER2, POTION_OF_POWER3, POTION_OF_POWER4);
|
||||
|
||||
log.debug("{} items; {} behaviours loaded", effects.size(), new HashSet<>(effects.values()).size());
|
||||
}
|
||||
|
||||
|
||||
@@ -227,6 +227,10 @@ public class LootTrackerPlugin extends Plugin
|
||||
|
||||
private static final String CASKET_EVENT = "Casket";
|
||||
|
||||
// Soul Wars
|
||||
private static final String SPOILS_OF_WAR_EVENT = "Spoils of war";
|
||||
private static final Set<Integer> SOUL_WARS_REGIONS = ImmutableSet.of(8493, 8749, 9005);
|
||||
|
||||
private static final Set<Character> VOWELS = ImmutableSet.of('a', 'e', 'i', 'o', 'u');
|
||||
|
||||
@Inject
|
||||
@@ -487,8 +491,8 @@ public class LootTrackerPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onPlayerLootReceived(final PlayerLootReceived playerLootReceived)
|
||||
{
|
||||
// Ignore Last Man Standing player loots
|
||||
if (isPlayerWithinMapRegion(LAST_MAN_STANDING_REGIONS))
|
||||
// Ignore Last Man Standing and Soul Wars player loots
|
||||
if (isPlayerWithinMapRegion(LAST_MAN_STANDING_REGIONS) || isPlayerWithinMapRegion(SOUL_WARS_REGIONS))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -763,6 +767,7 @@ public class LootTrackerPlugin extends Plugin
|
||||
|| SEEDPACK_EVENT.equals(eventType)
|
||||
|| CASKET_EVENT.equals(eventType)
|
||||
|| BIRDNEST_EVENT.equals(eventType)
|
||||
|| SPOILS_OF_WAR_EVENT.equals(eventType)
|
||||
|| eventType.endsWith("Bird House")
|
||||
|| eventType.startsWith("H.A.M. chest")
|
||||
|| lootRecordType == LootRecordType.PICKPOCKET)
|
||||
@@ -808,6 +813,12 @@ public class LootTrackerPlugin extends Plugin
|
||||
setEvent(LootRecordType.EVENT, CASKET_EVENT);
|
||||
takeInventorySnapshot();
|
||||
}
|
||||
|
||||
if (event.getMenuOption().equals("Open") && event.getId() == ItemID.SPOILS_OF_WAR)
|
||||
{
|
||||
setEvent(LootRecordType.EVENT, SPOILS_OF_WAR_EVENT);
|
||||
takeInventorySnapshot();
|
||||
}
|
||||
}
|
||||
|
||||
@Schedule(
|
||||
|
||||
@@ -606,4 +606,15 @@ public interface MenuEntrySwapperConfig extends Config
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapRockCake",
|
||||
name = "Dwarven rock cake",
|
||||
description = "Swap Eat with Guzzle on the Dwarven rock cake",
|
||||
section = itemSection
|
||||
)
|
||||
default boolean swapRockCake()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,6 +355,8 @@ public class MenuEntrySwapperPlugin extends Plugin
|
||||
swapTeleport("camelot teleport", "seers'");
|
||||
swapTeleport("watchtower teleport", "yanille");
|
||||
swapTeleport("teleport to house", "outside");
|
||||
|
||||
swap("eat", "guzzle", config::swapRockCake);
|
||||
}
|
||||
|
||||
private void swap(String option, String swappedOption, Supplier<Boolean> enabled)
|
||||
|
||||
@@ -44,7 +44,7 @@ public interface OpponentInfoConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hitpointsDisplayStyle",
|
||||
name = "Hitpoints display style",
|
||||
name = "Display style",
|
||||
description = "Show opponent's hitpoints as a value (if known), percentage, or both",
|
||||
position = 1
|
||||
)
|
||||
|
||||
@@ -55,7 +55,7 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "ownNameColor",
|
||||
name = "Own player color",
|
||||
name = "Own player",
|
||||
description = "Color of your own player",
|
||||
section = highlightSection
|
||||
)
|
||||
@@ -79,7 +79,7 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "friendNameColor",
|
||||
name = "Friend color",
|
||||
name = "Friend",
|
||||
description = "Color of friend names",
|
||||
section = highlightSection
|
||||
)
|
||||
@@ -103,7 +103,7 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "clanMemberColor",
|
||||
name = "Friends chat member color",
|
||||
name = "Friends chat",
|
||||
description = "Color of friends chat members",
|
||||
section = highlightSection
|
||||
)
|
||||
@@ -127,7 +127,7 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "teamMemberColor",
|
||||
name = "Team member color",
|
||||
name = "Team member",
|
||||
description = "Color of team members",
|
||||
section = highlightSection
|
||||
)
|
||||
@@ -151,7 +151,7 @@ public interface PlayerIndicatorsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
keyName = "nonClanMemberColor",
|
||||
name = "Others color",
|
||||
name = "Others",
|
||||
description = "Color of other players names",
|
||||
section = highlightSection
|
||||
)
|
||||
|
||||
@@ -133,7 +133,7 @@ public interface PrayerConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 9,
|
||||
keyName = "replaceOrbText",
|
||||
name = "Replace orb text with prayer time left",
|
||||
name = "Show time left",
|
||||
description = "Show time remaining of current prayers in the prayer orb."
|
||||
)
|
||||
default boolean replaceOrbText()
|
||||
|
||||
@@ -69,7 +69,7 @@ public interface PyramidPlunderConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "highlightDoorsColor",
|
||||
name = "Highlight doors color",
|
||||
name = "Highlight doors",
|
||||
description = "Selects the color for highlighting tomb doors"
|
||||
)
|
||||
default Color highlightDoorsColor()
|
||||
@@ -92,7 +92,7 @@ public interface PyramidPlunderConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "highlightSpeartrapColor",
|
||||
name = "Highlight speartrap color",
|
||||
name = "Highlight speartrap",
|
||||
description = "Selects the color for highlighting speartraps"
|
||||
)
|
||||
default Color highlightSpeartrapsColor()
|
||||
@@ -115,7 +115,7 @@ public interface PyramidPlunderConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "highlightContainersColor",
|
||||
name = "Highlight containers color",
|
||||
name = "Highlight containers",
|
||||
description = "Selects the color for highlighting urns, chests and sarcophagus"
|
||||
)
|
||||
default Color highlightContainersColor()
|
||||
|
||||
@@ -47,7 +47,7 @@ public interface RaidsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "pointsMessage",
|
||||
name = "Display points in chatbox after raid",
|
||||
name = "Display points in chatbox",
|
||||
description = "Display a message with total points, individual points and percentage at the end of a raid"
|
||||
)
|
||||
default boolean pointsMessage()
|
||||
@@ -69,8 +69,8 @@ public interface RaidsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "scoutOverlayAtBank",
|
||||
name = "Show scout overlay outside lobby",
|
||||
description = "Keep the overlay active while at the raids area"
|
||||
name = "Show scout overlay outside",
|
||||
description = "Keep the overlay active outside of the raid starting room"
|
||||
)
|
||||
default boolean scoutOverlayAtBank()
|
||||
{
|
||||
@@ -168,8 +168,8 @@ public interface RaidsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 12,
|
||||
keyName = "layoutMessage",
|
||||
name = "Send raid layout message when entering raid",
|
||||
description = "Sends game message with raid layout on entering new raid"
|
||||
name = "Raid layout message",
|
||||
description = "Sends a game message with the raid layout on entering a raid"
|
||||
)
|
||||
default boolean layoutMessage()
|
||||
{
|
||||
@@ -179,7 +179,7 @@ public interface RaidsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 13,
|
||||
keyName = "screenshotHotkey",
|
||||
name = "Scouter screenshot hotkey",
|
||||
name = "Screenshot hotkey",
|
||||
description = "Hotkey used to screenshot the scouting overlay"
|
||||
)
|
||||
default Keybind screenshotHotkey()
|
||||
@@ -190,7 +190,7 @@ public interface RaidsConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 14,
|
||||
keyName = "uploadScreenshot",
|
||||
name = "Upload scouting screenshot",
|
||||
name = "Upload screenshot",
|
||||
description = "Uploads the scouting screenshot to Imgur or the clipboard"
|
||||
)
|
||||
default ImageUploadStyle uploadScreenshot()
|
||||
|
||||
@@ -52,7 +52,7 @@ public interface RegenMeterConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showWhenNoChange",
|
||||
name = "Show hitpoints regen at full hitpoints",
|
||||
name = "Show at full hitpoints",
|
||||
description = "Always show the hitpoints regen orb, even if there will be no stat change")
|
||||
default boolean showWhenNoChange()
|
||||
{
|
||||
@@ -61,7 +61,7 @@ public interface RegenMeterConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notifyBeforeHpRegenDuration",
|
||||
name = "Hitpoint Regen Notification",
|
||||
name = "Hitpoint Notification",
|
||||
description = "Notify approximately when your next hitpoint is about to regen. A value of 0 will disable notification."
|
||||
)
|
||||
@Units(Units.SECONDS)
|
||||
|
||||
@@ -64,7 +64,7 @@ public interface StatusBarsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "leftBarMode",
|
||||
name = "Left Status Bar",
|
||||
name = "Left Bar",
|
||||
description = "Configures the left status bar"
|
||||
)
|
||||
default BarMode leftBarMode()
|
||||
@@ -74,7 +74,7 @@ public interface StatusBarsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rightBarMode",
|
||||
name = "Right Status Bar",
|
||||
name = "Right Bar",
|
||||
description = "Configures the right status bar"
|
||||
)
|
||||
default BarMode rightBarMode()
|
||||
|
||||
@@ -36,8 +36,9 @@ public interface TileIndicatorsConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "highlightDestinationColor",
|
||||
name = "Color of current destination highlighting",
|
||||
description = "Configures the highlight color of current destination"
|
||||
name = "Destination tile",
|
||||
description = "Configures the highlight color of current destination",
|
||||
position = 1
|
||||
)
|
||||
default Color highlightDestinationColor()
|
||||
{
|
||||
@@ -47,7 +48,8 @@ public interface TileIndicatorsConfig extends Config
|
||||
@ConfigItem(
|
||||
keyName = "highlightDestinationTile",
|
||||
name = "Highlight destination tile",
|
||||
description = "Highlights tile player is walking to"
|
||||
description = "Highlights tile player is walking to",
|
||||
position = 2
|
||||
)
|
||||
default boolean highlightDestinationTile()
|
||||
{
|
||||
@@ -57,8 +59,9 @@ public interface TileIndicatorsConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "highlightHoveredColor",
|
||||
name = "Color of current hovered highlighting",
|
||||
description = "Configures the highlight color of hovered tile"
|
||||
name = "Hovered tile",
|
||||
description = "Configures the highlight color of hovered tile",
|
||||
position = 3
|
||||
)
|
||||
default Color highlightHoveredColor()
|
||||
{
|
||||
@@ -68,7 +71,8 @@ public interface TileIndicatorsConfig extends Config
|
||||
@ConfigItem(
|
||||
keyName = "highlightHoveredTile",
|
||||
name = "Highlight hovered tile",
|
||||
description = "Highlights tile player is hovering with mouse"
|
||||
description = "Highlights tile player is hovering with mouse",
|
||||
position = 4
|
||||
)
|
||||
default boolean highlightHoveredTile()
|
||||
{
|
||||
@@ -78,8 +82,9 @@ public interface TileIndicatorsConfig extends Config
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "highlightCurrentColor",
|
||||
name = "Color of current true tile highlighting",
|
||||
description = "Configures the highlight color of current true tile"
|
||||
name = "True tile",
|
||||
description = "Configures the highlight color of current true tile",
|
||||
position = 5
|
||||
)
|
||||
default Color highlightCurrentColor()
|
||||
{
|
||||
@@ -88,8 +93,9 @@ public interface TileIndicatorsConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightCurrentTile",
|
||||
name = "Highlight current true tile",
|
||||
description = "Highlights true tile player is on as seen by server"
|
||||
name = "Highlight true tile",
|
||||
description = "Highlights true tile player is on as seen by server",
|
||||
position = 6
|
||||
)
|
||||
default boolean highlightCurrentTile()
|
||||
{
|
||||
|
||||
@@ -110,7 +110,7 @@ public interface TimeTrackingConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "timerWarningThreshold",
|
||||
name = "Timer Warning Threshold",
|
||||
name = "Warning Threshold",
|
||||
description = "The time at which to change the timer color to the warning color",
|
||||
position = 6
|
||||
)
|
||||
|
||||
@@ -51,7 +51,7 @@ public interface WintertodtConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "damageNotificationColor",
|
||||
name = "Damage Notification Color",
|
||||
name = "Damage Notification",
|
||||
description = "Color of damage notification text in chat"
|
||||
)
|
||||
default Color damageNotificationColor()
|
||||
@@ -62,7 +62,7 @@ public interface WintertodtConfig extends Config
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "roundNotification",
|
||||
name = "Wintertodt round notification",
|
||||
name = "Round notification",
|
||||
description = "Notifies you before the round starts (in seconds)"
|
||||
)
|
||||
@Range(
|
||||
|
||||
@@ -71,7 +71,13 @@ enum MinigameLocation
|
||||
CATAPULT_ROOM("Catapult Room", new WorldPoint(2842, 3545, 0)),
|
||||
SHOT_PUT_ROOM("Shot Put Room", new WorldPoint(2863, 3550, 0)),
|
||||
HALLOWED_SEPULCHRE("Hallowed Sepulchre", new WorldPoint(3653, 3386, 1)),
|
||||
THE_GAUNTLET("The Gauntlet", new WorldPoint(3223, 12505, 1));
|
||||
THE_GAUNTLET("The Gauntlet", new WorldPoint(3223, 12505, 1)),
|
||||
MAHOGANY_HOMES_ARDOUGNE("Mahogany Homes", new WorldPoint(2634, 3295, 0)),
|
||||
MAHOGANY_HOMES_FALADOR("Mahogany Homes", new WorldPoint(2989, 3363, 0)),
|
||||
MAHOGANY_HOMES_HOSIDIUS("Mahogany Homes", new WorldPoint(1780, 3623, 0)),
|
||||
MAHOGANY_HOMES_VARROCK("Mahogany Homes", new WorldPoint(3240, 3471, 0)),
|
||||
SOUL_WARS("Soul Wars", new WorldPoint(2209, 2855, 0)),
|
||||
SOUL_WARS_EDGEVILLE_PORTAL("Soul Wars", new WorldPoint(3082, 3474, 0));
|
||||
|
||||
private final String tooltip;
|
||||
private final WorldPoint location;
|
||||
|
||||
@@ -38,7 +38,7 @@ enum QuestStartLocation
|
||||
THE_CORSAIR_CURSE(Quest.THE_CORSAIR_CURSE, new WorldPoint(3029, 3273, 0)),
|
||||
DEMON_SLAYER(Quest.DEMON_SLAYER, new WorldPoint(3204, 3424, 0)),
|
||||
DORICS_QUEST(Quest.DORICS_QUEST, new WorldPoint(2952, 3450, 0)),
|
||||
DRAGON_SLAYER(Quest.DRAGON_SLAYER, new WorldPoint(3190, 3362, 0)),
|
||||
DRAGON_SLAYER_I(Quest.DRAGON_SLAYER_I, new WorldPoint(3190, 3362, 0)),
|
||||
ERNEST_THE_CHICKEN(Quest.ERNEST_THE_CHICKEN, new WorldPoint(3109, 3330, 0)),
|
||||
GOBLIN_DIPLOMACY(Quest.GOBLIN_DIPLOMACY, new WorldPoint(2957, 3509, 0)),
|
||||
IMP_CATCHER(Quest.IMP_CATCHER, new WorldPoint(3108, 3160, 0)),
|
||||
@@ -136,7 +136,7 @@ enum QuestStartLocation
|
||||
A_PORCINE_OF_INTEREST(Quest.A_PORCINE_OF_INTEREST, new WorldPoint(3085, 3251, 0)),
|
||||
PRIEST_IN_PERIL(Quest.PRIEST_IN_PERIL, new WorldPoint(3219, 3473, 0)),
|
||||
THE_QUEEN_OF_THIEVES(Quest.THE_QUEEN_OF_THIEVES, new WorldPoint(1795, 3782, 0)),
|
||||
RAG_AND_BONE_MAN(new Quest[]{Quest.RAG_AND_BONE_MAN, Quest.RAG_AND_BONE_MAN_II}, new WorldPoint(3359, 3504, 0)),
|
||||
RAG_AND_BONE_MAN_I(new Quest[]{Quest.RAG_AND_BONE_MAN_I, Quest.RAG_AND_BONE_MAN_II}, new WorldPoint(3359, 3504, 0)),
|
||||
RECRUITMENT_DRIVE_BLACK_KNIGHTS_FORTRESS(new Quest[]{Quest.BLACK_KNIGHTS_FORTRESS, Quest.RECRUITMENT_DRIVE}, new WorldPoint(2959, 3336, 0)),
|
||||
ROVING_ELVES(Quest.ROVING_ELVES, new WorldPoint(2288, 3146, 0)),
|
||||
RUM_DEAL(Quest.RUM_DEAL, new WorldPoint(3679, 3535, 0)),
|
||||
|
||||
@@ -192,6 +192,7 @@ enum TransportationPointLocation
|
||||
MUSHTREE_TAR_SWAMP("Mushtree", new WorldPoint(3676, 3755, 0)),
|
||||
MUSHTREE_VERDANT_VALLEY("Mushtree", new WorldPoint(3757, 3756, 0)),
|
||||
MYTHS_GUILD_PORTAL("Portal to Guilds", new WorldPoint(2456, 2856, 0)),
|
||||
SOUL_WARS_PORTAL("Portal to Edgeville/Ferox Enclave", new WorldPoint(2204, 2858, 0)),
|
||||
TRAIN_KELDAGRIM("Railway Station", new WorldPoint(2941, 10179, 0)),
|
||||
WILDERNESS_LEVER_ARDOUGNE("Wilderness Lever to Deserted Keep", new WorldPoint(2559, 3309, 0), new WorldPoint(3154, 3924, 0)),
|
||||
WILDERNESS_LEVER_EDGEVILLE("Wilderness Lever to Deserted Keep", new WorldPoint(3088, 3474, 0), new WorldPoint(3154, 3924, 0)),
|
||||
|
||||
@@ -34,7 +34,7 @@ public interface WorldMapConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_FAIRY_RING_TOOLTIPS,
|
||||
name = "Show fairy ring codes in tooltip",
|
||||
name = "Fairy ring code tooltip",
|
||||
description = "Display the code for fairy rings in the icon tooltip",
|
||||
position = 1
|
||||
)
|
||||
@@ -45,7 +45,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_FAIRY_RING_ICON,
|
||||
name = "Show fairy ring travel icon",
|
||||
name = "Fairy ring travel icon",
|
||||
description = "Override the travel icon for fairy rings",
|
||||
position = 2
|
||||
)
|
||||
@@ -56,7 +56,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_AGILITY_SHORTCUT_TOOLTIPS,
|
||||
name = "Show agility level requirement",
|
||||
name = "Agility level requirement",
|
||||
description = "Display the required Agility level in the icon tooltip",
|
||||
position = 3
|
||||
)
|
||||
@@ -78,7 +78,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_AGILITY_COURSE_TOOLTIPS,
|
||||
name = "Show agility course in tooltip",
|
||||
name = "Agility course tooltip",
|
||||
description = "Displays the name of the agility course in the tooltip",
|
||||
position = 5
|
||||
)
|
||||
@@ -100,7 +100,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_NORMAL_TELEPORT_ICON,
|
||||
name = "Show Standard Spellbook destinations",
|
||||
name = "Standard Spellbook destinations",
|
||||
description = "Show icons at the destinations for teleports in the Standard Spellbook",
|
||||
position = 7
|
||||
)
|
||||
@@ -111,7 +111,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_MINIGAME_TOOLTIP,
|
||||
name = "Show minigame name in tooltip",
|
||||
name = "Minigame names",
|
||||
description = "Display the name of the minigame in the icon tooltip",
|
||||
position = 8
|
||||
)
|
||||
@@ -122,7 +122,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_ANCIENT_TELEPORT_ICON,
|
||||
name = "Show Ancient Magicks destinations",
|
||||
name = "Ancient Magicks destinations",
|
||||
description = "Show icons at the destinations for teleports in the Ancient Spellbook",
|
||||
position = 9
|
||||
)
|
||||
@@ -133,7 +133,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_LUNAR_TELEPORT_ICON,
|
||||
name = "Show Lunar Spellbook destinations",
|
||||
name = "Lunar Spellbook destinations",
|
||||
description = "Show icons at the destinations for teleports in the Lunar Spellbook",
|
||||
position = 10
|
||||
)
|
||||
@@ -144,7 +144,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_ARCEUUS_TELEPORT_ICON,
|
||||
name = "Show Arceuus Spellbook destinations",
|
||||
name = "Arceuus Spellbook destinations",
|
||||
description = "Show icons at the destinations for teleports in the Arceuus Spellbook",
|
||||
position = 11
|
||||
)
|
||||
@@ -155,7 +155,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_JEWELLERY_TELEPORT_ICON,
|
||||
name = "Show jewellery teleport locations",
|
||||
name = "Jewellery teleport destinations",
|
||||
description = "Show icons at the destinations for teleports from jewellery",
|
||||
position = 12
|
||||
)
|
||||
@@ -166,7 +166,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_SCROLL_TELEPORT_ICON,
|
||||
name = "Show teleport scroll locations",
|
||||
name = "Teleport scroll destinations",
|
||||
description = "Show icons at the destinations for teleports from scrolls",
|
||||
position = 13
|
||||
)
|
||||
@@ -177,7 +177,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_MISC_TELEPORT_ICON,
|
||||
name = "Show misc teleport locations",
|
||||
name = "Misc teleport destinations",
|
||||
description = "Show icons at the destinations for miscellaneous teleport items",
|
||||
position = 14
|
||||
)
|
||||
@@ -188,7 +188,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_QUEST_START_TOOLTIPS,
|
||||
name = "Show quest names and status",
|
||||
name = "Quest names and status",
|
||||
description = "Indicates the names of quests and shows completion status",
|
||||
position = 15
|
||||
)
|
||||
@@ -199,7 +199,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_FARMING_PATCH_TOOLTIPS,
|
||||
name = "Show farming patch type",
|
||||
name = "Farming patch type",
|
||||
description = "Display the type of farming patches in the icon tooltip",
|
||||
position = 16
|
||||
)
|
||||
@@ -210,7 +210,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_RARE_TREE_TOOLTIPS,
|
||||
name = "Show rare tree type",
|
||||
name = "Rare tree type",
|
||||
description = "Display the type of rare tree in the icon tooltip",
|
||||
position = 17
|
||||
)
|
||||
@@ -232,7 +232,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_TRANSPORTATION_TELEPORT_TOOLTIPS,
|
||||
name = "Show transportation tooltips",
|
||||
name = "Transportation tooltips",
|
||||
description = "Indicates types and destinations of Transportation",
|
||||
position = 19
|
||||
)
|
||||
@@ -243,7 +243,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_RUNECRAFTING_ALTAR_ICON,
|
||||
name = "Show runecrafting altar locations",
|
||||
name = "Runecrafting altar locations",
|
||||
description = "Show the icons of runecrafting altars",
|
||||
position = 20
|
||||
)
|
||||
@@ -254,7 +254,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_MINING_SITE_TOOLTIPS,
|
||||
name = "Show mining site tooltips",
|
||||
name = "Mining site tooltips",
|
||||
description = "Indicates the ore available at mining sites",
|
||||
position = 21
|
||||
)
|
||||
@@ -265,7 +265,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_DUNGEON_TOOLTIPS,
|
||||
name = "Show dungeon tooltips",
|
||||
name = "Dungeon tooltips",
|
||||
description = "Indicates the names of dungeons",
|
||||
position = 22
|
||||
)
|
||||
@@ -276,7 +276,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_HUNTER_AREA_TOOLTIPS,
|
||||
name = "Show hunter area tooltips",
|
||||
name = "Hunter area tooltips",
|
||||
description = "Indicates the creatures inside a hunting area",
|
||||
position = 23
|
||||
)
|
||||
@@ -287,7 +287,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_FISHING_SPOT_TOOLTIPS,
|
||||
name = "Show fishing spot tooltips",
|
||||
name = "Fishing spot tooltips",
|
||||
description = "Indicates the type of fish fishable at the fishing spot",
|
||||
position = 24
|
||||
)
|
||||
@@ -298,7 +298,7 @@ public interface WorldMapConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
keyName = WorldMapPlugin.CONFIG_KEY_KOUREND_TASK_TOOLTIPS,
|
||||
name = "Show Kourend task tooltips",
|
||||
name = "Kourend task tooltips",
|
||||
description = "Indicates the task or unlock for Kourend Favour locations",
|
||||
position = 25
|
||||
)
|
||||
|
||||
@@ -69,7 +69,7 @@ public class SplashScreen extends JFrame implements ActionListener
|
||||
|
||||
private SplashScreen() throws IOException
|
||||
{
|
||||
BufferedImage logo = ImageUtil.getResourceStreamFromClass(SplashScreen.class, "runelite_transparent.png");
|
||||
BufferedImage logo = ImageUtil.loadImageResource(SplashScreen.class, "runelite_transparent.png");
|
||||
|
||||
setTitle("RuneLite Launcher");
|
||||
|
||||
|
||||
@@ -39,11 +39,11 @@ import net.runelite.client.util.Text;
|
||||
* was very hard to see in the dark gray background, this makes the selected
|
||||
* item white and adds some padding to the elements for more readable list.
|
||||
*/
|
||||
public final class ComboBoxListRenderer extends JLabel implements ListCellRenderer
|
||||
public final class ComboBoxListRenderer<T> extends JLabel implements ListCellRenderer<T>
|
||||
{
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object o, int index, boolean isSelected, boolean cellHasFocus)
|
||||
public Component getListCellRendererComponent(JList<? extends T> list, T o, int index, boolean isSelected, boolean cellHasFocus)
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
5464D17DCD348F352EFFE6AA6AEEC5A5609ECBA30EAC2CB2B3D479D2C0DDDA9A
|
||||
@@ -0,0 +1,75 @@
|
||||
.id 3898
|
||||
.int_stack_count 6
|
||||
.string_stack_count 0
|
||||
.int_var_count 11
|
||||
.string_var_count 0
|
||||
get_varbit 4606
|
||||
iconst 0
|
||||
if_icmpne LABEL4
|
||||
jump LABEL5
|
||||
LABEL4:
|
||||
return
|
||||
LABEL5:
|
||||
iconst 512
|
||||
istore 6
|
||||
iconst 512
|
||||
istore 7
|
||||
iload 2
|
||||
iconst 16
|
||||
sub
|
||||
istore 8
|
||||
iconst 0
|
||||
iload 3
|
||||
invoke 1045
|
||||
istore 3
|
||||
iload 2
|
||||
iconst 16
|
||||
sub
|
||||
iload 3
|
||||
invoke 1046
|
||||
istore 3
|
||||
iconst 896
|
||||
sconst "innerZoomLimit"
|
||||
runelite_callback
|
||||
iconst 128
|
||||
sconst "outerZoomLimit"
|
||||
runelite_callback
|
||||
sub
|
||||
istore 9
|
||||
iconst 896
|
||||
sconst "innerZoomLimit"
|
||||
runelite_callback
|
||||
iconst 128
|
||||
sconst "outerZoomLimit"
|
||||
runelite_callback
|
||||
sub
|
||||
istore 10
|
||||
iload 3
|
||||
iload 9
|
||||
multiply
|
||||
iload 8
|
||||
div
|
||||
iconst 128
|
||||
sconst "outerZoomLimit"
|
||||
runelite_callback
|
||||
add
|
||||
istore 6
|
||||
iload 3
|
||||
iload 10
|
||||
multiply
|
||||
iload 8
|
||||
div
|
||||
iconst 128
|
||||
sconst "outerZoomLimit"
|
||||
runelite_callback
|
||||
add
|
||||
istore 7
|
||||
iload 0
|
||||
iload 1
|
||||
iload 7
|
||||
iload 6
|
||||
iload 2
|
||||
iload 4
|
||||
iload 5
|
||||
invoke 3899
|
||||
return
|
||||
@@ -0,0 +1 @@
|
||||
AA98471D04D9CB1172253D0B479EFD2D58394BDD2852F3AE8CD2B2D46FA826C3
|
||||
@@ -0,0 +1,96 @@
|
||||
.id 3899
|
||||
.int_stack_count 7
|
||||
.string_stack_count 0
|
||||
.int_var_count 11
|
||||
.string_var_count 0
|
||||
get_varbit 4606
|
||||
iconst 0
|
||||
if_icmpne LABEL4
|
||||
jump LABEL5
|
||||
LABEL4:
|
||||
return
|
||||
LABEL5:
|
||||
iconst 896
|
||||
sconst "innerZoomLimit"
|
||||
runelite_callback
|
||||
iload 2
|
||||
invoke 1046
|
||||
istore 2
|
||||
iconst 128
|
||||
sconst "outerZoomLimit"
|
||||
runelite_callback
|
||||
iload 2
|
||||
invoke 1045
|
||||
istore 2
|
||||
iconst 896
|
||||
sconst "innerZoomLimit"
|
||||
runelite_callback
|
||||
iload 3
|
||||
invoke 1046
|
||||
istore 3
|
||||
iconst 128
|
||||
sconst "outerZoomLimit"
|
||||
runelite_callback
|
||||
iload 3
|
||||
invoke 1045
|
||||
istore 3
|
||||
iload 2
|
||||
iload 3
|
||||
viewport_setfov
|
||||
iconst 0
|
||||
istore 7
|
||||
iconst 0
|
||||
istore 8
|
||||
viewport_geteffectivesize
|
||||
istore 8
|
||||
istore 7
|
||||
iload 8
|
||||
iconst 334
|
||||
sub
|
||||
istore 9
|
||||
iload 9
|
||||
iconst 0
|
||||
if_icmplt LABEL39
|
||||
jump LABEL42
|
||||
LABEL39:
|
||||
iconst 0
|
||||
istore 9
|
||||
jump LABEL48
|
||||
LABEL42:
|
||||
iload 9
|
||||
iconst 100
|
||||
if_icmpgt LABEL46
|
||||
jump LABEL48
|
||||
LABEL46:
|
||||
iconst 100
|
||||
istore 9
|
||||
LABEL48:
|
||||
iload 2
|
||||
iload 3
|
||||
iload 2
|
||||
sub
|
||||
iload 9
|
||||
multiply
|
||||
iconst 100
|
||||
div
|
||||
add
|
||||
istore 10
|
||||
iconst 25
|
||||
iconst 25
|
||||
iload 10
|
||||
multiply
|
||||
iconst 256
|
||||
div
|
||||
add
|
||||
cam_setfollowheight
|
||||
iload 2
|
||||
iload 3
|
||||
set_varc_int 74
|
||||
set_varc_int 73
|
||||
iload 0
|
||||
iload 1
|
||||
iload 4
|
||||
iload 5
|
||||
iload 6
|
||||
invoke 3900
|
||||
return
|
||||
@@ -0,0 +1 @@
|
||||
03D7F1AF9E8405CB4A74779254E8C65563123F865CC0181186238B038A740755
|
||||
@@ -0,0 +1,78 @@
|
||||
.id 3900
|
||||
.int_stack_count 5
|
||||
.string_stack_count 0
|
||||
.int_var_count 11
|
||||
.string_var_count 0
|
||||
iconst 896
|
||||
sconst "innerZoomLimit"
|
||||
runelite_callback
|
||||
iconst 128
|
||||
sconst "outerZoomLimit"
|
||||
runelite_callback
|
||||
sub
|
||||
istore 5
|
||||
iconst 896
|
||||
sconst "innerZoomLimit"
|
||||
runelite_callback
|
||||
iconst 128
|
||||
sconst "outerZoomLimit"
|
||||
runelite_callback
|
||||
sub
|
||||
istore 6
|
||||
iload 2
|
||||
iconst 16
|
||||
sub
|
||||
istore 7
|
||||
iconst 0
|
||||
istore 8
|
||||
iconst 0
|
||||
istore 9
|
||||
viewport_geteffectivesize
|
||||
istore 9
|
||||
istore 8
|
||||
iconst 0
|
||||
istore 10
|
||||
iload 8
|
||||
iconst 334
|
||||
if_icmpgt LABEL25
|
||||
jump LABEL34
|
||||
LABEL25:
|
||||
get_varc_int 74
|
||||
iconst 128
|
||||
sconst "outerZoomLimit"
|
||||
runelite_callback
|
||||
sub
|
||||
iload 7
|
||||
multiply
|
||||
iload 5
|
||||
div
|
||||
istore 10
|
||||
jump LABEL42
|
||||
LABEL34:
|
||||
get_varc_int 73
|
||||
iconst 128
|
||||
sconst "outerZoomLimit"
|
||||
runelite_callback
|
||||
sub
|
||||
iload 7
|
||||
multiply
|
||||
iload 6
|
||||
div
|
||||
istore 10
|
||||
LABEL42:
|
||||
iload 0
|
||||
iload 1
|
||||
cc_find
|
||||
iconst 1
|
||||
if_icmpeq LABEL48
|
||||
jump LABEL55
|
||||
LABEL48:
|
||||
iload 4
|
||||
iload 10
|
||||
add
|
||||
iload 3
|
||||
iconst 0
|
||||
iconst 0
|
||||
cc_setposition
|
||||
LABEL55:
|
||||
return
|
||||
@@ -0,0 +1 @@
|
||||
A1B6D1B291AA3594728DDEA47049E17119F5CCB6F8E757E1524FA89DE92F9A34
|
||||
@@ -0,0 +1,663 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.chatcommands;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import static net.runelite.api.ChatMessageType.FRIENDSCHATNOTIFICATION;
|
||||
import static net.runelite.api.ChatMessageType.GAMEMESSAGE;
|
||||
import static net.runelite.api.ChatMessageType.TRADE;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.MessageNode;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import static net.runelite.api.widgets.WidgetID.ADVENTURE_LOG_ID;
|
||||
import static net.runelite.api.widgets.WidgetID.GENERIC_SCROLL_GROUP_ID;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.chat.ChatCommandManager;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.config.ChatColorConfig;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.http.api.chat.ChatClient;
|
||||
import net.runelite.http.api.hiscore.HiscoreClient;
|
||||
import net.runelite.http.api.hiscore.HiscoreSkill;
|
||||
import net.runelite.http.api.hiscore.SingleHiscoreSkillResult;
|
||||
import net.runelite.http.api.hiscore.Skill;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyString;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ChatCommandsPluginTest
|
||||
{
|
||||
private static final String PLAYER_NAME = "Adam";
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ConfigManager configManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ScheduledExecutorService scheduledExecutorService;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ChatColorConfig chatColorConfig;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ChatCommandManager chatCommandManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
HiscoreClient hiscoreClient;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ChatMessageManager chatMessageManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ChatClient chatClient;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ChatCommandsConfig chatCommandsConfig;
|
||||
|
||||
@Inject
|
||||
ChatCommandsPlugin chatCommandsPlugin;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
|
||||
Player player = mock(Player.class);
|
||||
when(player.getName()).thenReturn(PLAYER_NAME);
|
||||
when(client.getLocalPlayer()).thenReturn(player);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartupShutdown()
|
||||
{
|
||||
chatCommandsPlugin.startUp();
|
||||
chatCommandsPlugin.shutDown();
|
||||
|
||||
ArgumentCaptor<String> registerCaptor = ArgumentCaptor.forClass(String.class);
|
||||
verify(chatCommandManager, atLeastOnce()).registerCommand(registerCaptor.capture(), any());
|
||||
verify(chatCommandManager, atLeastOnce()).registerCommandAsync(registerCaptor.capture(), any());
|
||||
verify(chatCommandManager, atLeastOnce()).registerCommandAsync(registerCaptor.capture(), any(), any());
|
||||
|
||||
ArgumentCaptor<String> unregisterCaptor = ArgumentCaptor.forClass(String.class);
|
||||
verify(chatCommandManager, atLeastOnce()).unregisterCommand(unregisterCaptor.capture());
|
||||
|
||||
assertEquals(Sets.newHashSet(registerCaptor.getAllValues()), Sets.newHashSet(unregisterCaptor.getAllValues()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorporealBeastKill()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your Corporeal Beast kill count is: <col=ff0000>4</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "corporeal beast", 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTheatreOfBlood()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Wave 'The Final Challenge' complete! Duration: <col=ff0000>5:04</col><br>Theatre of Blood wave completion time: <col=ff0000>37:04</col> (Personal best!)", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Theatre of Blood count is: <col=ff0000>73</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "theatre of blood", 73);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood", 37 * 60 + 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTheatreOfBloodNoPb()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Wave 'The Final Challenge' complete! Duration: <col=ff0000>5:04</col><br>Theatre of Blood wave completion time: <col=ff0000>38:17</col><br></col>Personal best: 37:04", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Theatre of Blood count is: <col=ff0000>73</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "theatre of blood", 73);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "theatre of blood", 37 * 60 + 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWintertodt()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your subdued Wintertodt count is: <col=ff0000>4</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "wintertodt", 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKreearra()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your Kree'arra kill count is: <col=ff0000>4</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "kree'arra", 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBarrows()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your Barrows chest count is: <col=ff0000>277</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "barrows chests", 277);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHerbiboar()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your herbiboar harvest count is: <col=ff0000>4091</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "herbiboar", 4091);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGauntlet()
|
||||
{
|
||||
ChatMessage gauntletMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Gauntlet completion count is: <col=ff0000>123</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(gauntletMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "gauntlet", 123);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorruptedGauntlet()
|
||||
{
|
||||
ChatMessage corruptedGauntletMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Corrupted Gauntlet completion count is: <col=ff0000>4729</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(corruptedGauntletMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "corrupted gauntlet", 4729);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersonalBest()
|
||||
{
|
||||
final String FIGHT_DURATION = "Fight duration: <col=ff0000>2:06</col>. Personal best: 1:19.";
|
||||
|
||||
// This sets lastBoss
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Kree'arra kill count is: <col=ff0000>4</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", FIGHT_DURATION, null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "kree'arra", 79);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersonalBestNoTrailingPeriod()
|
||||
{
|
||||
final String FIGHT_DURATION = "Fight duration: <col=ff0000>0:59</col>. Personal best: 0:55";
|
||||
|
||||
// This sets lastBoss
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Zulrah kill count is: <col=ff0000>4</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", FIGHT_DURATION, null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "zulrah", 55);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewPersonalBest()
|
||||
{
|
||||
final String NEW_PB = "Fight duration: <col=ff0000>3:01</col> (new personal best).";
|
||||
|
||||
// This sets lastBoss
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Kree'arra kill count is: <col=ff0000>4</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", NEW_PB, null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "kree'arra", 181);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuelArenaWin()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, TRADE, "", "You won! You have now won 27 duels.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "duel arena wins", 27);
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "duel arena win streak", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuelArenaWin2()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, TRADE, "", "You were defeated! You have won 22 duels.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "duel arena wins", 22);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuelArenaLose()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, TRADE, "", "You have now lost 999 duels.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "duel arena losses", 999);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAgilityLap()
|
||||
{
|
||||
final String NEW_PB = "Lap duration: <col=ff0000>1:01</col> (new personal best).";
|
||||
|
||||
// This sets lastBoss
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Prifddinas Agility Course lap count is: <col=ff0000>2</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", NEW_PB, null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "prifddinas agility course", 61);
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "prifddinas agility course", 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZukNewPb()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your TzKal-Zuk kill count is: <col=ff0000>2</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Duration: <col=ff0000>104:31</col> (new personal best)", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "tzkal-zuk", 104 * 60 + 31);
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "tzkal-zuk", 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZukKill()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your TzKal-Zuk kill count is: <col=ff0000>3</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Duration: <col=ff0000>172:18</col>. Personal best: 134:52", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "tzkal-zuk", 134 * 60 + 52);
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "tzkal-zuk", 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGgNewPb()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Fight duration: <col=ff0000>1:36</col> (new personal best)", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Grotesque Guardians kill count is: <col=ff0000>179</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "grotesque guardians", 96);
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "grotesque guardians", 179);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGgKill()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Fight duration: <col=ff0000>2:41</col>. Personal best: 2:14", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Grotesque Guardians kill count is: <col=ff0000>32</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "grotesque guardians", 2 * 60 + 14);
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "grotesque guardians", 32);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGuantletPersonalBest()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Challenge duration: <col=ff0000>10:24</col>. Personal best: 7:59.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Gauntlet completion count is: <col=ff0000>124</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "gauntlet", 124);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "gauntlet", 7 * 60 + 59);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGuantletNewPersonalBest()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Challenge duration: <col=ff0000>10:24</col> (new personal best).", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Gauntlet completion count is: <col=ff0000>124</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "gauntlet", 10 * 60 + 24);
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "gauntlet", 124);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCoXKill()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, FRIENDSCHATNOTIFICATION, "", "<col=ef20ff>Congratulations - your raid is complete!</col><br>Team size: <col=ff0000>24+ players</col> Duration:</col> <col=ff0000>37:04</col> (new personal best)</col>>", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Chambers of Xeric count is: <col=ff0000>51</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "chambers of xeric", 51);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "chambers of xeric", 37 * 60 + 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCoXKillNoPb()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, FRIENDSCHATNOTIFICATION, "", "<col=ef20ff>Congratulations - your raid is complete!</col><br>Team size: <col=ff0000>11-15 players</col> Duration:</col> <col=ff0000>23:25</col> Personal best: </col><col=ff0000>20:19</col>", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Chambers of Xeric count is: <col=ff0000>52</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "chambers of xeric", 52);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "chambers of xeric", 20 * 60 + 19);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdventureLogCountersPage()
|
||||
{
|
||||
Widget advLogWidget = mock(Widget.class);
|
||||
Widget advLogExploitsTextWidget = mock(Widget.class);
|
||||
when(advLogWidget.getChild(ChatCommandsPlugin.ADV_LOG_EXPLOITS_TEXT_INDEX)).thenReturn(advLogExploitsTextWidget);
|
||||
when(advLogExploitsTextWidget.getText()).thenReturn("The Exploits of " + PLAYER_NAME);
|
||||
when(client.getWidget(WidgetInfo.ADVENTURE_LOG)).thenReturn(advLogWidget);
|
||||
when(configManager.getRSProfileConfiguration(anyString(), anyString(), any(Class.class))).thenReturn(2224);
|
||||
|
||||
WidgetLoaded advLogEvent = new WidgetLoaded();
|
||||
advLogEvent.setGroupId(ADVENTURE_LOG_ID);
|
||||
chatCommandsPlugin.onWidgetLoaded(advLogEvent);
|
||||
chatCommandsPlugin.onGameTick(new GameTick());
|
||||
|
||||
String COUNTER_TEXT = "Duel Arena<br>Wins: <col=d0c0b0>4</col><br>Losses: <col=d0c0b0>2</col>" +
|
||||
"<br><br>Last Man Standing<br>Rank: <col=d0c0b0>0</col>" +
|
||||
"<br><br>Treasure Trails<br>Beginner: <col=d0c0b0>0</col><br>Easy: <col=d0c0b0>7</col>" +
|
||||
"<br>Medium: <col=d0c0b0>28</col><br>Hard: <col=d0c0b0>108</col><br>Elite: <col=d0c0b0>15</col>" +
|
||||
"<br>Master: <col=d0c0b0>27</col><br>Rank: <col=d0c0b0>Novice</col>" +
|
||||
"<br><br>Chompy Hunting<br>Kills: <col=d0c0b0>1,000</col><br>Rank: <col=d0c0b0>Ogre Expert</col>" +
|
||||
"<br><br>Order of the White Knights<br>Rank: <col=d0c0b0>Master</col><br>with a kill score of <col=d0c0b0>1,300</col>" +
|
||||
"<br><br>TzHaar Fight Cave<br>Fastest run: <col=d0c0b0>38:10</col>" +
|
||||
"<br><br>Inferno<br>Fastest run: <col=d0c0b0>-</col><br><br>Zulrah<br>" +
|
||||
"Fastest kill: <col=d0c0b0>5:48</col><br><br>Vorkath<br>Fastest kill: <col=d0c0b0>1:21</col>" +
|
||||
"<br><br>Galvek<br>Fastest kill: <col=d0c0b0>-</col><br><br>Grotesque Guardians<br>" +
|
||||
"Fastest kill: <col=d0c0b0>2:49</col><br><br>Alchemical Hydra<br>Fastest kill: <col=d0c0b0>-</col>" +
|
||||
"<br><br>Hespori<br>Fastest kill: <col=d0c0b0>0:57</col><br><br>Nightmare<br>" +
|
||||
"Fastest kill: <col=d0c0b0>3:30</col><br><br>The Gauntlet<br>Fastest run: <col=d0c0b0>-</col>" +
|
||||
"<br><br>The Corrupted Gauntlet<br>Fastest run: <col=d0c0b0>-</col><br><br>Fragment of Seren<br>Fastest kill: <col=d0c0b0>-</col>" +
|
||||
"<br><br>Chambers of Xeric<br>Fastest run - (Team size: 24+ players): <col=d0c0b0>24:17</col>" +
|
||||
"<br><br>Chambers of Xeric - Challenge mode<br>Fastest run - (Team size: Solo): <col=d0c0b0>22:15</col>" +
|
||||
"<br><br>Barbarian Assault<br>High-level gambles: <col=d0c0b0>0</col><br><br>Fremennik spirits rested: <col=d0c0b0>0</col>";
|
||||
|
||||
Widget countersPage = mock(Widget.class);
|
||||
when(countersPage.getText()).thenReturn(COUNTER_TEXT);
|
||||
when(client.getWidget(WidgetInfo.GENERIC_SCROLL_TEXT)).thenReturn(countersPage);
|
||||
|
||||
WidgetLoaded countersLogEvent = new WidgetLoaded();
|
||||
countersLogEvent.setGroupId(GENERIC_SCROLL_GROUP_ID);
|
||||
chatCommandsPlugin.onWidgetLoaded(countersLogEvent);
|
||||
chatCommandsPlugin.onGameTick(new GameTick());
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "tztok-jad", 38 * 60 + 10);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "zulrah", 5 * 60 + 48);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "vorkath", 1 * 60 + 21);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "grotesque guardians", 2 * 60 + 49);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "hespori", 57);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "nightmare", 3 * 60 + 30);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "chambers of xeric", 24 * 60 + 17);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "chambers of xeric challenge mode", 22 * 60 + 15);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdventurerLogCountersPage2()
|
||||
{
|
||||
Widget advLogWidget = mock(Widget.class);
|
||||
Widget advLogExploitsTextWidget = mock(Widget.class);
|
||||
when(advLogWidget.getChild(ChatCommandsPlugin.ADV_LOG_EXPLOITS_TEXT_INDEX)).thenReturn(advLogExploitsTextWidget);
|
||||
when(advLogExploitsTextWidget.getText()).thenReturn("The Exploits of " + PLAYER_NAME);
|
||||
when(client.getWidget(WidgetInfo.ADVENTURE_LOG)).thenReturn(advLogWidget);
|
||||
|
||||
WidgetLoaded advLogEvent = new WidgetLoaded();
|
||||
advLogEvent.setGroupId(ADVENTURE_LOG_ID);
|
||||
chatCommandsPlugin.onWidgetLoaded(advLogEvent);
|
||||
chatCommandsPlugin.onGameTick(new GameTick());
|
||||
|
||||
String COUNTER_TEXT = "Duel Arena<br>Wins: <col=d0c0b0>12</col><br>Losses: <col=d0c0b0>20</col>" +
|
||||
"<br><br>Last Man Standing<br>Rank: <col=d0c0b0>0</col>" +
|
||||
"<br><br>Treasure Trails<br>Beginner: <col=d0c0b0>1</col><br>Easy: <col=d0c0b0>4</col>" +
|
||||
"<br>Medium: <col=d0c0b0>35</col><br>Hard: <col=d0c0b0>66</col><br>Elite: <col=d0c0b0>2</col>" +
|
||||
"<br>Master: <col=d0c0b0>0</col><br>Rank: <col=d0c0b0>Novice</col>" +
|
||||
"<br><br>Chompy Hunting<br>Kills: <col=d0c0b0>300</col><br>Rank: <col=d0c0b0>Ogre Forester</col>" +
|
||||
"<br><br>Order of the White Knights<br>Rank: <col=d0c0b0>Unrated</col><br>with a kill score of <col=d0c0b0>99</col>" +
|
||||
"<br><br>TzHaar Fight Cave<br>Fastest run: <col=d0c0b0>65:12</col>" +
|
||||
"<br><br>Inferno<br>Fastest run: <col=d0c0b0>-</col><br><br>Zulrah<br>" +
|
||||
"Fastest kill: <col=d0c0b0>2:55</col><br><br>Vorkath<br>Fastest kill: <col=d0c0b0>1:37</col>" +
|
||||
"<br><br>Galvek<br>Fastest kill: <col=d0c0b0>-</col><br><br>Grotesque Guardians<br>" +
|
||||
"Fastest kill: <col=d0c0b0>-</col><br><br>Alchemical Hydra<br>Fastest kill: <col=d0c0b0>-</col>" +
|
||||
"<br><br>Hespori<br>Fastest kill: <col=d0c0b0>1:42</col><br><br>Nightmare<br>" +
|
||||
"Fastest kill: <col=d0c0b0>-</col><br><br>The Gauntlet<br>Fastest run: <col=d0c0b0>-</col>" +
|
||||
"<br><br>The Corrupted Gauntlet<br>Fastest run: <col=d0c0b0>-</col><br><br>Fragment of Seren<br>Fastest kill: <col=d0c0b0>-</col>" +
|
||||
"<br><br>Chambers of Xeric<br>Fastest run - (Team size: Solo): <col=d0c0b0>21:23</col><br>Fastest run - (Team size: 3 players): <col=d0c0b0>27:16</col>" +
|
||||
"<br><br>Chambers of Xeric - Challenge mode<br>Fastest run - (Team size: Solo): <col=d0c0b0>34:30</col><br>Fastest run - (Team size: 4 players): <col=d0c0b0>21:26</col>" +
|
||||
"<br><br>Barbarian Assault<br>High-level gambles: <col=d0c0b0>0</col><br><br>Fremennik spirits rested: <col=d0c0b0>0</col>";
|
||||
|
||||
Widget countersPage = mock(Widget.class);
|
||||
when(countersPage.getText()).thenReturn(COUNTER_TEXT);
|
||||
when(client.getWidget(WidgetInfo.GENERIC_SCROLL_TEXT)).thenReturn(countersPage);
|
||||
|
||||
WidgetLoaded countersLogEvent = new WidgetLoaded();
|
||||
countersLogEvent.setGroupId(GENERIC_SCROLL_GROUP_ID);
|
||||
chatCommandsPlugin.onWidgetLoaded(countersLogEvent);
|
||||
chatCommandsPlugin.onGameTick(new GameTick());
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "tztok-jad", 65 * 60 + 12);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "zulrah", 2 * 60 + 55);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "vorkath", 1 * 60 + 37);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "hespori", 1 * 60 + 42);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "chambers of xeric", 21 * 60 + 23);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "chambers of xeric challenge mode", 21 * 60 + 26);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotYourAdventureLogCountersPage()
|
||||
{
|
||||
Widget advLogWidget = mock(Widget.class);
|
||||
Widget advLogExploitsTextWidget = mock(Widget.class);
|
||||
when(advLogWidget.getChild(ChatCommandsPlugin.ADV_LOG_EXPLOITS_TEXT_INDEX)).thenReturn(advLogExploitsTextWidget);
|
||||
when(advLogExploitsTextWidget.getText()).thenReturn("The Exploits of " + "not the player");
|
||||
when(client.getWidget(WidgetInfo.ADVENTURE_LOG)).thenReturn(advLogWidget);
|
||||
|
||||
WidgetLoaded advLogEvent = new WidgetLoaded();
|
||||
advLogEvent.setGroupId(ADVENTURE_LOG_ID);
|
||||
chatCommandsPlugin.onWidgetLoaded(advLogEvent);
|
||||
chatCommandsPlugin.onGameTick(new GameTick());
|
||||
|
||||
WidgetLoaded countersLogEvent = new WidgetLoaded();
|
||||
countersLogEvent.setGroupId(GENERIC_SCROLL_GROUP_ID);
|
||||
chatCommandsPlugin.onWidgetLoaded(countersLogEvent);
|
||||
chatCommandsPlugin.onGameTick(new GameTick());
|
||||
|
||||
verifyNoMoreInteractions(configManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPlayerSkillLookup() throws IOException
|
||||
{
|
||||
when(chatCommandsConfig.lvl()).thenReturn(true);
|
||||
|
||||
SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult();
|
||||
skillResult.setPlayer(PLAYER_NAME);
|
||||
skillResult.setSkill(new Skill(10, 1000, -1));
|
||||
|
||||
when(hiscoreClient.lookup(PLAYER_NAME, HiscoreSkill.ZULRAH, null)).thenReturn(skillResult);
|
||||
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setName(PLAYER_NAME);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
chatCommandsPlugin.playerSkillLookup(chatMessage, "!lvl zulrah");
|
||||
|
||||
verify(messageNode).setRuneLiteFormatMessage("<colNORMAL>Level <colHIGHLIGHT>Zulrah: 1000<colNORMAL> Rank: <colHIGHLIGHT>10");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHsFloorNoPb()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Floor 1 time: <col=ff0000>1:19</col>. Personal best: 0:28", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre floor 1", 28);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHsFloorPb()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Floor 2 time: <col=ff0000>0:47</col> (new personal best)", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre floor 2", 47);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHsOverallPb_Pb()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Floor 5 time: <col=ff0000>4:46</col> (new personal best)<br>Overall time: <col=ff0000>9:53</col> (new personal best)<br>", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre floor 5", 4 * 60 + 46);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre", 9 * 60 + 53);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHsOverallPb_NoPb()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Floor 5 time: <col=ff0000>3:26</col> (new personal best)<br>Overall time: <col=ff0000>9:17</col>. Personal best: 9:15<br>", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre floor 5", 3 * 60 + 26);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre", 9 * 60 + 15);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHsOverallNoPb_NoPb()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Floor 5 time: <col=ff0000>3:56</col>. Personal best: 3:05<br>Overall time: <col=ff0000>9:14</col>. Personal best: 7:49<br>", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre floor 5", 3 * 60 + 5);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre", 7 * 60 + 49);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHsOverallNoPb_Pb()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Floor 5 time: <col=ff0000>3:10</col>. Personal best: 3:04<br>Overall time: <col=ff0000>7:47</col> (new personal best)<br>", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre floor 5", 3 * 60 + 4);
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "hallowed sepulchre", 7 * 60 + 47);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHsFloorKc()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "You have completed Floor 5 of the Hallowed Sepulchre! Total completions: <col=ff0000>81</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "hallowed sepulchre floor 5", 81);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHsGhcKc()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "You have opened the Grand Hallowed Coffin <col=ff0000>36</col> times!", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "hallowed sepulchre", 36);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJadNewPbWithLeagueTask()
|
||||
{
|
||||
ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your TzTok-Jad kill count is: <col=ff0000>2</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Congratulations, you've completed a master task: <col=7f3700>Complete the Fight Caves in 25:00</col>.", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Duration: <col=ff0000>21:58</col> (new personal best)", null, 0);
|
||||
chatCommandsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(configManager).setRSProfileConfiguration("personalbest", "tztok-jad", 21 * 60 + 58);
|
||||
verify(configManager).setRSProfileConfiguration("killcount", "tztok-jad", 2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2019, osrs-music-map <osrs-music-map@users.noreply.github.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.chatfilter;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.IterableHashTable;
|
||||
import net.runelite.api.MessageNode;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.client.game.FriendChatManager;
|
||||
import static net.runelite.client.plugins.chatfilter.ChatFilterPlugin.CENSOR_MESSAGE;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ChatFilterPluginTest
|
||||
{
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ChatFilterConfig chatFilterConfig;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private FriendChatManager friendChatManager;
|
||||
|
||||
@Mock
|
||||
private Player localPlayer;
|
||||
|
||||
@Inject
|
||||
private ChatFilterPlugin chatFilterPlugin;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_WORDS);
|
||||
when(chatFilterConfig.filteredWords()).thenReturn("");
|
||||
when(chatFilterConfig.filteredRegex()).thenReturn("");
|
||||
when(chatFilterConfig.filteredNames()).thenReturn("");
|
||||
when(client.getLocalPlayer()).thenReturn(localPlayer);
|
||||
}
|
||||
|
||||
private ScriptCallbackEvent createCallbackEvent(final String sender, final String chatMessage, final ChatMessageType messageType)
|
||||
{
|
||||
ScriptCallbackEvent event = new ScriptCallbackEvent();
|
||||
event.setScript(null);
|
||||
event.setEventName("chatFilterCheck");
|
||||
int[] simulatedIntStack =
|
||||
new int[]{1, messageType.getType(), 1}; // is msg allowed to show, ChatMessageType.PUBLICCHAT, message id
|
||||
String[] simulatedStringStack = new String[]{chatMessage};
|
||||
IterableHashTable<MessageNode> messageTable = mock(IterableHashTable.class);
|
||||
MessageNode mockedMsgNode = mockMessageNode(sender);
|
||||
when(client.getIntStack()).thenReturn(simulatedIntStack);
|
||||
when(client.getIntStackSize()).thenReturn(simulatedIntStack.length);
|
||||
when(client.getStringStack()).thenReturn(simulatedStringStack);
|
||||
when(client.getStringStackSize()).thenReturn(simulatedStringStack.length);
|
||||
when(client.getMessages()).thenReturn(messageTable);
|
||||
when(messageTable.get(1)).thenReturn(mockedMsgNode);
|
||||
return event;
|
||||
}
|
||||
|
||||
private MessageNode mockMessageNode(String sender)
|
||||
{
|
||||
MessageNode node = mock(MessageNode.class);
|
||||
when(node.getName()).thenReturn(sender);
|
||||
return node;
|
||||
}
|
||||
|
||||
private MessageNode mockMessageNode(int id)
|
||||
{
|
||||
MessageNode node = mock(MessageNode.class);
|
||||
when(node.getId()).thenReturn(id);
|
||||
return node;
|
||||
}
|
||||
|
||||
private MessageNode mockMessageNode(int id, String sender, String value)
|
||||
{
|
||||
MessageNode node = mock(MessageNode.class);
|
||||
when(node.getId()).thenReturn(id);
|
||||
when(node.getName()).thenReturn(sender);
|
||||
when(node.getValue()).thenReturn(value);
|
||||
return node;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCensorWords()
|
||||
{
|
||||
when(chatFilterConfig.filteredWords()).thenReturn("hat");
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
assertEquals("w***s up", chatFilterPlugin.censorMessage("Blue", "whats up"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCensorRegex()
|
||||
{
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
|
||||
when(chatFilterConfig.filteredRegex()).thenReturn("5[0-9]x2\n(");
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
assertNull(chatFilterPlugin.censorMessage("Blue", "55X2 Dicing | Trusted Ranks | Huge Pay Outs!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrokenRegex()
|
||||
{
|
||||
when(chatFilterConfig.filteredRegex()).thenReturn("Test\n)\n73");
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
assertEquals("** isn't funny", chatFilterPlugin.censorMessage("Blue", "73 isn't funny"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCaseSensitivity()
|
||||
{
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_MESSAGE);
|
||||
when(chatFilterConfig.filteredWords()).thenReturn("ReGeX!!!");
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
assertEquals(CENSOR_MESSAGE, chatFilterPlugin.censorMessage("Blue", "I love regex!!!!!!!!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonPrintableCharacters()
|
||||
{
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
|
||||
when(chatFilterConfig.filteredWords()).thenReturn("test");
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
assertNull(chatFilterPlugin.censorMessage("Blue", "te\u008Cst"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplayedMessage()
|
||||
{
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
|
||||
when(chatFilterConfig.filteredWords()).thenReturn("hello osrs");
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
assertNull(chatFilterPlugin.censorMessage("Blue", "hello\u00A0osrs"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageFromFriendIsFiltered()
|
||||
{
|
||||
when(friendChatManager.isMember("Iron Mammal")).thenReturn(false);
|
||||
when(chatFilterConfig.filterFriends()).thenReturn(true);
|
||||
assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("Iron Mammal"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageFromFriendIsNotFiltered()
|
||||
{
|
||||
when(client.isFriended("Iron Mammal", false)).thenReturn(true);
|
||||
when(chatFilterConfig.filterFriends()).thenReturn(false);
|
||||
assertFalse(chatFilterPlugin.shouldFilterPlayerMessage("Iron Mammal"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageFromFriendsChatIsFiltered()
|
||||
{
|
||||
when(client.isFriended("B0aty", false)).thenReturn(false);
|
||||
when(chatFilterConfig.filterFriendsChat()).thenReturn(true);
|
||||
assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("B0aty"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageFromFriendsChatIsNotFiltered()
|
||||
{
|
||||
when(friendChatManager.isMember("B0aty")).thenReturn(true);
|
||||
when(chatFilterConfig.filterFriendsChat()).thenReturn(false);
|
||||
assertFalse(chatFilterPlugin.shouldFilterPlayerMessage("B0aty"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageFromSelfIsNotFiltered()
|
||||
{
|
||||
when(localPlayer.getName()).thenReturn("Swampletics");
|
||||
assertFalse(chatFilterPlugin.shouldFilterPlayerMessage("Swampletics"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageFromNonFriendNonFCIsFiltered()
|
||||
{
|
||||
when(client.isFriended("Woox", false)).thenReturn(false);
|
||||
when(friendChatManager.isMember("Woox")).thenReturn(false);
|
||||
assertTrue(chatFilterPlugin.shouldFilterPlayerMessage("Woox"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldFilterByName()
|
||||
{
|
||||
when(chatFilterConfig.filteredNames()).thenReturn("Gamble [0-9]*");
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
assertTrue(chatFilterPlugin.shouldFilterByName("Gamble 1234"));
|
||||
assertFalse(chatFilterPlugin.shouldFilterByName("Adam"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCensorWordsByName()
|
||||
{
|
||||
when(chatFilterConfig.filteredNames()).thenReturn("Blue");
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
assertEquals("************", chatFilterPlugin.censorMessage("Blue", "Gamble today"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void textCensorMessageByName()
|
||||
{
|
||||
when(chatFilterConfig.filteredNames()).thenReturn("Blue");
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_MESSAGE);
|
||||
assertEquals(CENSOR_MESSAGE,
|
||||
chatFilterPlugin.censorMessage("Blue", "Meet swampletics, my morytania locked ultimate ironman"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveMessageByName()
|
||||
{
|
||||
when(chatFilterConfig.filteredNames()).thenReturn("Blue");
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
|
||||
assertNull(
|
||||
chatFilterPlugin.censorMessage("Blue", "What about now it's time to rock with the biggity buck bumble"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEventRemoveByName()
|
||||
{
|
||||
when(chatFilterConfig.filteredNames()).thenReturn("Gamble [0-9]*");
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
ScriptCallbackEvent event = createCallbackEvent("Gamble 1234", "filterme", ChatMessageType.PUBLICCHAT);
|
||||
chatFilterPlugin.onScriptCallbackEvent(event);
|
||||
assertEquals(0, client.getIntStack()[client.getIntStackSize() - 3]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEventRemoveByText()
|
||||
{
|
||||
when(chatFilterConfig.filteredWords()).thenReturn("filterme");
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
ScriptCallbackEvent event = createCallbackEvent("Adam", "please filterme plugin", ChatMessageType.PUBLICCHAT);
|
||||
chatFilterPlugin.onScriptCallbackEvent(event);
|
||||
assertEquals(0, client.getIntStack()[client.getIntStackSize() - 3]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEventCensorWordsByName()
|
||||
{
|
||||
when(chatFilterConfig.filteredNames()).thenReturn("Gamble [0-9]*");
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_WORDS);
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
ScriptCallbackEvent event = createCallbackEvent("Gamble 1234", "filterme", ChatMessageType.PUBLICCHAT);
|
||||
chatFilterPlugin.onScriptCallbackEvent(event);
|
||||
assertEquals("********", client.getStringStack()[client.getStringStackSize() - 1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEventCensorWordsByText()
|
||||
{
|
||||
when(chatFilterConfig.filteredWords()).thenReturn("filterme");
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_WORDS);
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
ScriptCallbackEvent event = createCallbackEvent("Adam", "please filterme plugin", ChatMessageType.PUBLICCHAT);
|
||||
chatFilterPlugin.onScriptCallbackEvent(event);
|
||||
assertEquals("please ******** plugin", client.getStringStack()[client.getStringStackSize() - 1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEventCensorMessageByName()
|
||||
{
|
||||
when(chatFilterConfig.filteredNames()).thenReturn("Gamble [0-9]*");
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_MESSAGE);
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
ScriptCallbackEvent event = createCallbackEvent("Gamble 1234", "filterme", ChatMessageType.PUBLICCHAT);
|
||||
chatFilterPlugin.onScriptCallbackEvent(event);
|
||||
assertEquals(CENSOR_MESSAGE, client.getStringStack()[client.getStringStackSize() - 1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEventCensorMessageByText()
|
||||
{
|
||||
when(chatFilterConfig.filteredWords()).thenReturn("filterme");
|
||||
when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.CENSOR_MESSAGE);
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
ScriptCallbackEvent event = createCallbackEvent("Adam", "please filterme plugin", ChatMessageType.PUBLICCHAT);
|
||||
chatFilterPlugin.onScriptCallbackEvent(event);
|
||||
assertEquals(CENSOR_MESSAGE, client.getStringStack()[client.getStringStackSize() - 1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateChatFiltered()
|
||||
{
|
||||
when(chatFilterConfig.collapseGameChat()).thenReturn(true);
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(0, null, "testMessage"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
|
||||
ScriptCallbackEvent event = createCallbackEvent(null, "testMessage", ChatMessageType.GAMEMESSAGE);
|
||||
chatFilterPlugin.onScriptCallbackEvent(event);
|
||||
|
||||
assertEquals(0, client.getIntStack()[client.getIntStackSize() - 3]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoDuplicate()
|
||||
{
|
||||
when(chatFilterConfig.collapseGameChat()).thenReturn(true);
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(1), ChatMessageType.GAMEMESSAGE, null, "testMessage", null, 0));
|
||||
ScriptCallbackEvent event = createCallbackEvent(null, "testMessage", ChatMessageType.GAMEMESSAGE);
|
||||
chatFilterPlugin.onScriptCallbackEvent(event);
|
||||
|
||||
assertEquals(1, client.getIntStack()[client.getIntStackSize() - 3]);
|
||||
assertEquals("testMessage", client.getStringStack()[client.getStringStackSize() - 1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateChatCount()
|
||||
{
|
||||
when(chatFilterConfig.collapseGameChat()).thenReturn(true);
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(4, null, "testMessage"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(3, null, "testMessage"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(2, null, "testMessage"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(1, null, "testMessage"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
|
||||
ScriptCallbackEvent event = createCallbackEvent(null, "testMessage", ChatMessageType.GAMEMESSAGE);
|
||||
chatFilterPlugin.onScriptCallbackEvent(event);
|
||||
|
||||
assertEquals(1, client.getIntStack()[client.getIntStackSize() - 3]);
|
||||
assertEquals("testMessage (4)", client.getStringStack()[client.getStringStackSize() - 1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publicChatFilteredOnDuplicate()
|
||||
{
|
||||
when(chatFilterConfig.collapsePlayerChat()).thenReturn(true);
|
||||
when(chatFilterConfig.maxRepeatedPublicChats()).thenReturn(2);
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(1, "testName", "testMessage"), ChatMessageType.PUBLICCHAT, null, null, null, 0));
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(1, "testName", "testMessage"), ChatMessageType.PUBLICCHAT, null, null, null, 0));
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(1, "testName", "testMessage"), ChatMessageType.PUBLICCHAT, null, null, null, 0));
|
||||
ScriptCallbackEvent event = createCallbackEvent("testName", "testMessage", ChatMessageType.PUBLICCHAT);
|
||||
chatFilterPlugin.onScriptCallbackEvent(event);
|
||||
|
||||
assertEquals(0, client.getIntStack()[client.getIntStackSize() - 3]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateChatFilterIgnoresFormatting()
|
||||
{
|
||||
when(chatFilterConfig.collapseGameChat()).thenReturn(true);
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(4, null, "<col=000000>testMessage</col>"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(3, null, "<col=000000>testMessage</col>"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(2, null, "<col=000000>testMessage</col>"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
|
||||
chatFilterPlugin.onChatMessage(new ChatMessage(mockMessageNode(1, null, "<col=000000>testMessage</col>"), ChatMessageType.GAMEMESSAGE, null, null, null, 0));
|
||||
ScriptCallbackEvent event = createCallbackEvent(null, "<col=000000>testMessage</col>", ChatMessageType.GAMEMESSAGE);
|
||||
chatFilterPlugin.onScriptCallbackEvent(event);
|
||||
|
||||
assertEquals(1, client.getIntStack()[client.getIntStackSize() - 3]);
|
||||
assertEquals("<col=000000>testMessage</col> (4)", client.getStringStack()[client.getStringStackSize() - 1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChatIcons()
|
||||
{
|
||||
when(chatFilterConfig.filteredWords()).thenReturn("test");
|
||||
// if this test is broken, this stubbing is required to trip the assert
|
||||
lenient().when(chatFilterConfig.filterType()).thenReturn(ChatFilterType.REMOVE_MESSAGE);
|
||||
when(friendChatManager.isMember("Lazark")).thenReturn(true);
|
||||
|
||||
chatFilterPlugin.updateFilteredPatterns();
|
||||
ScriptCallbackEvent event = createCallbackEvent("<img=22>Lazark", "test", ChatMessageType.PUBLICCHAT);
|
||||
chatFilterPlugin.onScriptCallbackEvent(event);
|
||||
assertEquals(1, client.getIntStack()[client.getIntStackSize() - 3]); // not filtered
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.chatnotifications;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.MessageNode;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.util.Text;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ChatNotificationsPluginTest
|
||||
{
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ChatNotificationsConfig config;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ChatMessageManager chatMessageManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Notifier notifier;
|
||||
|
||||
@Bind
|
||||
@Named("runelite.title")
|
||||
private String runeliteTitle = "RuneLite";
|
||||
|
||||
@Inject
|
||||
private ChatNotificationsPlugin chatNotificationsPlugin;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onChatMessage()
|
||||
{
|
||||
when(config.highlightWordsString()).thenReturn("Deathbeam, Deathbeam OSRS , test");
|
||||
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
when(messageNode.getValue()).thenReturn("Deathbeam, Deathbeam OSRS");
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
|
||||
chatNotificationsPlugin.startUp(); // load highlight config
|
||||
chatNotificationsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setValue("<colHIGHLIGHT>Deathbeam<colNORMAL>, <colHIGHLIGHT>Deathbeam<colNORMAL> OSRS");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLtGt()
|
||||
{
|
||||
when(config.highlightWordsString()).thenReturn("<test>");
|
||||
|
||||
String message = "test <lt>test<gt> test";
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
when(messageNode.getValue()).thenReturn(message);
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
|
||||
chatNotificationsPlugin.startUp(); // load highlight config
|
||||
chatNotificationsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setValue("test <colHIGHLIGHT><lt>test<gt><colNORMAL> test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchEntireMessage()
|
||||
{
|
||||
when(config.highlightWordsString()).thenReturn(".Your divine potion effect is about to expire.");
|
||||
|
||||
String message = ".Your divine potion effect is about to expire.";
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
when(messageNode.getValue()).thenReturn(message);
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
|
||||
chatNotificationsPlugin.startUp(); // load highlight config
|
||||
chatNotificationsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setValue("<colHIGHLIGHT>.Your divine potion effect is about to expire.<colNORMAL>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFullStop()
|
||||
{
|
||||
when(config.highlightWordsString()).thenReturn("test");
|
||||
|
||||
String message = "foo test. bar";
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
when(messageNode.getValue()).thenReturn(message);
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
|
||||
chatNotificationsPlugin.startUp(); // load highlight config
|
||||
chatNotificationsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setValue("foo <colHIGHLIGHT>test<colNORMAL>. bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testColor()
|
||||
{
|
||||
when(config.highlightWordsString()).thenReturn("you. It");
|
||||
|
||||
String message = "Your dodgy necklace protects you. <col=ff0000>It has 1 charge left.</col>";
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
when(messageNode.getValue()).thenReturn(message);
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
|
||||
chatNotificationsPlugin.startUp(); // load highlight config
|
||||
chatNotificationsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setValue("Your dodgy necklace protects <colHIGHLIGHT>you. It<col=ff0000> has 1 charge left.</col>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreceedingColor()
|
||||
{
|
||||
when(config.highlightWordsString()).thenReturn("you. It");
|
||||
|
||||
String message = "Your dodgy <col=00ff00>necklace protects you. It has 1 charge left.</col>";
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
when(messageNode.getValue()).thenReturn(message);
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
|
||||
chatNotificationsPlugin.startUp(); // load highlight config
|
||||
chatNotificationsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setValue("Your dodgy <col=00ff00>necklace protects <colHIGHLIGHT>you. It<col=00ff00> has 1 charge left.</col>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmoji()
|
||||
{
|
||||
when(config.highlightWordsString()).thenReturn("test");
|
||||
|
||||
String message = "emoji test <img=29>";
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
when(messageNode.getValue()).thenReturn(message);
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
|
||||
chatNotificationsPlugin.startUp(); // load highlight config
|
||||
chatNotificationsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setValue("emoji <colHIGHLIGHT>test<colNORMAL> <img=29>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonMatchedColors()
|
||||
{
|
||||
when(config.highlightWordsString()).thenReturn("test");
|
||||
|
||||
String message = "<col=ff0000>color</col> test <img=29>";
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
when(messageNode.getValue()).thenReturn(message);
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage();
|
||||
chatMessage.setType(ChatMessageType.PUBLICCHAT);
|
||||
chatMessage.setMessageNode(messageNode);
|
||||
|
||||
chatNotificationsPlugin.startUp(); // load highlight config
|
||||
chatNotificationsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setValue("<col=ff0000>color</col> <colHIGHLIGHT>test<colNORMAL> <img=29>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void highlightListTest()
|
||||
{
|
||||
when(config.highlightWordsString()).thenReturn("this,is, a , test, ");
|
||||
final List<String> higlights = Text.fromCSV(config.highlightWordsString());
|
||||
assertEquals(4, higlights.size());
|
||||
|
||||
final Iterator<String> iterator = higlights.iterator();
|
||||
assertEquals("this", iterator.next());
|
||||
assertEquals("is", iterator.next());
|
||||
assertEquals("a", iterator.next());
|
||||
assertEquals("test", iterator.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStripColor()
|
||||
{
|
||||
assertEquals("you. It", ChatNotificationsPlugin.stripColor("you. <col=ff0000>It"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHighlightOwnName()
|
||||
{
|
||||
Player player = mock(Player.class);
|
||||
when(player.getName()).thenReturn("Logic Knot");
|
||||
when(client.getLocalPlayer()).thenReturn(player);
|
||||
|
||||
when(config.highlightOwnName()).thenReturn(true);
|
||||
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
when(messageNode.getValue()).thenReturn("<col=005f00>Logic Knot received a drop: Adamant longsword</col>");
|
||||
ChatMessage chatMessage = new ChatMessage(messageNode, ChatMessageType.GAMEMESSAGE, "", "", "", 0);
|
||||
chatNotificationsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(messageNode).setValue("<col=005f00><colHIGHLIGHT><u>Logic Knot</u><colNORMAL> received a drop: Adamant longsword</col>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHighlightOwnNameNbsp()
|
||||
{
|
||||
Player player = mock(Player.class);
|
||||
when(player.getName()).thenReturn("Logic Knot");
|
||||
when(client.getLocalPlayer()).thenReturn(player);
|
||||
|
||||
when(config.highlightOwnName()).thenReturn(true);
|
||||
|
||||
MessageNode messageNode = mock(MessageNode.class);
|
||||
when(messageNode.getValue()).thenReturn("<col=005f00>Logic\u00a0Knot received a drop: Adamant longsword</col>");
|
||||
ChatMessage chatMessage = new ChatMessage(messageNode, ChatMessageType.GAMEMESSAGE, "", "", "", 0);
|
||||
chatNotificationsPlugin.onChatMessage(chatMessage);
|
||||
|
||||
// set value uses our player name, which has nbsp replaced
|
||||
verify(messageNode).setValue("<col=005f00><colHIGHLIGHT><u>Logic Knot</u><colNORMAL> received a drop: Adamant longsword</col>");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.discord;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.discord.DiscordPresence;
|
||||
import net.runelite.client.discord.DiscordService;
|
||||
import net.runelite.client.ws.PartyService;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DiscordStateTest
|
||||
{
|
||||
@Inject
|
||||
DiscordState discordState;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
DiscordConfig discordConfig;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
DiscordService discordService;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
PartyService partyService;
|
||||
|
||||
@Bind
|
||||
@Named("runelite.title")
|
||||
private String runeliteTitle = "RuneLite";
|
||||
|
||||
@Bind
|
||||
@Named("runelite.version")
|
||||
private String runeliteVersion = "version";
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
when(partyService.getLocalPartyId()).thenReturn(UUID.nameUUIDFromBytes("test".getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusReset()
|
||||
{
|
||||
when(discordConfig.actionTimeout()).thenReturn(-1);
|
||||
when(discordConfig.elapsedTimeType()).thenReturn(DiscordConfig.ElapsedTimeType.ACTIVITY);
|
||||
|
||||
discordState.triggerEvent(DiscordGameEventType.IN_MENU);
|
||||
verify(discordService).updatePresence(any(DiscordPresence.class));
|
||||
|
||||
discordState.checkForTimeout();
|
||||
ArgumentCaptor<DiscordPresence> captor = ArgumentCaptor.forClass(DiscordPresence.class);
|
||||
verify(discordService, times(2)).updatePresence(captor.capture());
|
||||
List<DiscordPresence> captured = captor.getAllValues();
|
||||
assertNull(captured.get(captured.size() - 1).getEndTimestamp());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusTimeout()
|
||||
{
|
||||
when(discordConfig.actionTimeout()).thenReturn(-1);
|
||||
when(discordConfig.elapsedTimeType()).thenReturn(DiscordConfig.ElapsedTimeType.ACTIVITY);
|
||||
|
||||
discordState.triggerEvent(DiscordGameEventType.TRAINING_AGILITY);
|
||||
verify(discordService).updatePresence(any(DiscordPresence.class));
|
||||
|
||||
discordState.checkForTimeout();
|
||||
verify(discordService, times(1)).clearPresence();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAreaChange()
|
||||
{
|
||||
when(discordConfig.elapsedTimeType()).thenReturn(DiscordConfig.ElapsedTimeType.TOTAL);
|
||||
|
||||
// Start with state of IN_GAME
|
||||
ArgumentCaptor<DiscordPresence> captor = ArgumentCaptor.forClass(DiscordPresence.class);
|
||||
discordState.triggerEvent(DiscordGameEventType.IN_GAME);
|
||||
verify(discordService, times(1)).updatePresence(captor.capture());
|
||||
assertEquals(DiscordGameEventType.IN_GAME.getState(), captor.getValue().getState());
|
||||
|
||||
// IN_GAME -> CITY
|
||||
discordState.triggerEvent(DiscordGameEventType.CITY_VARROCK);
|
||||
verify(discordService, times(2)).updatePresence(captor.capture());
|
||||
assertEquals(DiscordGameEventType.CITY_VARROCK.getState(), captor.getValue().getState());
|
||||
|
||||
// CITY -> IN_GAME
|
||||
discordState.triggerEvent(DiscordGameEventType.IN_GAME);
|
||||
verify(discordService, times(3)).updatePresence(captor.capture());
|
||||
assertEquals(DiscordGameEventType.IN_GAME.getState(), captor.getValue().getState());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Adam <Adam@sigterm.info>
|
||||
* 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.grandexchange;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.GrandExchangeOffer;
|
||||
import net.runelite.api.GrandExchangeOfferState;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.WorldType;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GrandExchangeOfferChanged;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.account.SessionManager;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.input.MouseManager;
|
||||
import static net.runelite.client.plugins.grandexchange.GrandExchangePlugin.findFuzzyIndices;
|
||||
import static net.runelite.http.api.RuneLiteAPI.GSON;
|
||||
import net.runelite.http.api.ge.GrandExchangeClient;
|
||||
import net.runelite.http.api.ge.GrandExchangeTrade;
|
||||
import net.runelite.http.api.osbuddy.OSBGrandExchangeClient;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class GrandExchangePluginTest
|
||||
{
|
||||
@Inject
|
||||
private GrandExchangePlugin grandExchangePlugin;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private GrandExchangeConfig grandExchangeConfig;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Notifier notifier;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private SessionManager sessionManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ConfigManager configManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private KeyManager keyManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private MouseManager mouseManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ScheduledExecutorService scheduledExecutorService;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private GrandExchangeClient grandExchangeClient;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private OSBGrandExchangeClient osbGrandExchangeClient;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private RuneLiteConfig runeLiteConfig;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
when(client.getWorldType()).thenReturn(EnumSet.noneOf(WorldType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindFuzzyIndices()
|
||||
{
|
||||
List<Integer> fuzzyIndices = findFuzzyIndices("Ancestral robe bottom", "obby");
|
||||
// r<u>ob</u>e <u>b</u>ottom
|
||||
assertEquals(Arrays.asList(11, 12, 15), fuzzyIndices);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubmitTrade()
|
||||
{
|
||||
// 1 @ 25
|
||||
SavedOffer savedOffer = new SavedOffer();
|
||||
savedOffer.setItemId(ItemID.ABYSSAL_WHIP);
|
||||
savedOffer.setQuantitySold(1);
|
||||
savedOffer.setTotalQuantity(10);
|
||||
savedOffer.setPrice(1000);
|
||||
savedOffer.setSpent(25);
|
||||
savedOffer.setState(GrandExchangeOfferState.BUYING);
|
||||
when(configManager.getRSProfileConfiguration("geoffer", "0")).thenReturn(GSON.toJson(savedOffer));
|
||||
|
||||
// buy 2 @ 10/ea
|
||||
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
|
||||
when(grandExchangeOffer.getQuantitySold()).thenReturn(1 + 2);
|
||||
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
|
||||
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
|
||||
when(grandExchangeOffer.getPrice()).thenReturn(1000);
|
||||
when(grandExchangeOffer.getSpent()).thenReturn(25 + 10 * 2);
|
||||
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.BUYING);
|
||||
grandExchangePlugin.submitTrade(0, grandExchangeOffer);
|
||||
|
||||
ArgumentCaptor<GrandExchangeTrade> captor = ArgumentCaptor.forClass(GrandExchangeTrade.class);
|
||||
verify(grandExchangeClient).submit(captor.capture());
|
||||
|
||||
GrandExchangeTrade trade = captor.getValue();
|
||||
assertTrue(trade.isBuy());
|
||||
assertEquals(ItemID.ABYSSAL_WHIP, trade.getItemId());
|
||||
assertEquals(2, trade.getDqty());
|
||||
assertEquals(10, trade.getTotal());
|
||||
assertEquals(45, trade.getSpent());
|
||||
assertEquals(20, trade.getDspent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateTrade()
|
||||
{
|
||||
SavedOffer savedOffer = new SavedOffer();
|
||||
savedOffer.setItemId(ItemID.ABYSSAL_WHIP);
|
||||
savedOffer.setQuantitySold(1);
|
||||
savedOffer.setTotalQuantity(10);
|
||||
savedOffer.setPrice(1000);
|
||||
savedOffer.setSpent(25);
|
||||
savedOffer.setState(GrandExchangeOfferState.BUYING);
|
||||
when(configManager.getRSProfileConfiguration("geoffer", "0")).thenReturn(GSON.toJson(savedOffer));
|
||||
|
||||
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
|
||||
when(grandExchangeOffer.getQuantitySold()).thenReturn(1);
|
||||
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
|
||||
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
|
||||
when(grandExchangeOffer.getPrice()).thenReturn(1000);
|
||||
lenient().when(grandExchangeOffer.getSpent()).thenReturn(25);
|
||||
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.BUYING);
|
||||
grandExchangePlugin.submitTrade(0, grandExchangeOffer);
|
||||
|
||||
verify(grandExchangeClient, never()).submit(any(GrandExchangeTrade.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelTrade()
|
||||
{
|
||||
SavedOffer savedOffer = new SavedOffer();
|
||||
savedOffer.setItemId(ItemID.ABYSSAL_WHIP);
|
||||
savedOffer.setQuantitySold(1);
|
||||
savedOffer.setTotalQuantity(10);
|
||||
savedOffer.setPrice(1000);
|
||||
savedOffer.setSpent(25);
|
||||
savedOffer.setState(GrandExchangeOfferState.BUYING);
|
||||
when(configManager.getRSProfileConfiguration("geoffer", "0")).thenReturn(GSON.toJson(savedOffer));
|
||||
|
||||
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
|
||||
when(grandExchangeOffer.getQuantitySold()).thenReturn(1);
|
||||
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
|
||||
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
|
||||
when(grandExchangeOffer.getPrice()).thenReturn(1000);
|
||||
when(grandExchangeOffer.getSpent()).thenReturn(25);
|
||||
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.CANCELLED_BUY);
|
||||
grandExchangePlugin.submitTrade(0, grandExchangeOffer);
|
||||
|
||||
ArgumentCaptor<GrandExchangeTrade> captor = ArgumentCaptor.forClass(GrandExchangeTrade.class);
|
||||
verify(grandExchangeClient).submit(captor.capture());
|
||||
|
||||
GrandExchangeTrade trade = captor.getValue();
|
||||
assertTrue(trade.isBuy());
|
||||
assertTrue(trade.isCancel());
|
||||
assertEquals(ItemID.ABYSSAL_WHIP, trade.getItemId());
|
||||
assertEquals(1, trade.getQty());
|
||||
assertEquals(10, trade.getTotal());
|
||||
assertEquals(25, trade.getSpent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHop()
|
||||
{
|
||||
when(client.getGameState()).thenReturn(GameState.HOPPING);
|
||||
|
||||
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
|
||||
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.EMPTY);
|
||||
|
||||
GrandExchangeOfferChanged grandExchangeOfferChanged = new GrandExchangeOfferChanged();
|
||||
grandExchangeOfferChanged.setOffer(grandExchangeOffer);
|
||||
|
||||
grandExchangePlugin.onGrandExchangeOfferChanged(grandExchangeOfferChanged);
|
||||
|
||||
verify(configManager, never()).unsetRSProfileConfiguration(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogin()
|
||||
{
|
||||
GrandExchangePanel panel = mock(GrandExchangePanel.class);
|
||||
when(panel.getOffersPanel()).thenReturn(mock(GrandExchangeOffersPanel.class));
|
||||
grandExchangePlugin.setPanel(panel);
|
||||
|
||||
when(itemManager.getItemComposition(anyInt())).thenReturn(mock(ItemComposition.class));
|
||||
|
||||
// provide config support so getOffer and setOffer work
|
||||
final Map<String, Object> config = new HashMap<>();
|
||||
doAnswer(a ->
|
||||
{
|
||||
Object[] arguments = a.getArguments();
|
||||
config.put((String) arguments[1], arguments[2]);
|
||||
return null;
|
||||
}).when(configManager).setRSProfileConfiguration(eq("geoffer"), anyString(), anyString());
|
||||
|
||||
when(configManager.getRSProfileConfiguration(eq("geoffer"), anyString())).thenAnswer(a ->
|
||||
{
|
||||
Object[] arguments = a.getArguments();
|
||||
return config.get((String) arguments[1]);
|
||||
});
|
||||
|
||||
// set loginBurstGeUpdates
|
||||
GameStateChanged gameStateChanged = new GameStateChanged();
|
||||
gameStateChanged.setGameState(GameState.LOGIN_SCREEN);
|
||||
|
||||
grandExchangePlugin.onGameStateChanged(gameStateChanged);
|
||||
|
||||
// 8x buy 10 whip @ 1k ea, bought 1 sofar.
|
||||
for (int i = 0; i < GrandExchangePlugin.GE_SLOTS; ++i)
|
||||
{
|
||||
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
|
||||
when(grandExchangeOffer.getQuantitySold()).thenReturn(1);
|
||||
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
|
||||
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
|
||||
when(grandExchangeOffer.getPrice()).thenReturn(1000);
|
||||
when(grandExchangeOffer.getSpent()).thenReturn(1000);
|
||||
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.SELLING);
|
||||
|
||||
GrandExchangeOfferChanged grandExchangeOfferChanged = new GrandExchangeOfferChanged();
|
||||
grandExchangeOfferChanged.setSlot(i);
|
||||
grandExchangeOfferChanged.setOffer(grandExchangeOffer);
|
||||
grandExchangePlugin.onGrandExchangeOfferChanged(grandExchangeOfferChanged);
|
||||
}
|
||||
|
||||
// Now send update for one of the slots
|
||||
GrandExchangeOffer grandExchangeOffer = mock(GrandExchangeOffer.class);
|
||||
when(grandExchangeOffer.getQuantitySold()).thenReturn(2);
|
||||
when(grandExchangeOffer.getItemId()).thenReturn(ItemID.ABYSSAL_WHIP);
|
||||
when(grandExchangeOffer.getTotalQuantity()).thenReturn(10);
|
||||
when(grandExchangeOffer.getPrice()).thenReturn(1000);
|
||||
when(grandExchangeOffer.getSpent()).thenReturn(2000);
|
||||
when(grandExchangeOffer.getState()).thenReturn(GrandExchangeOfferState.SELLING);
|
||||
|
||||
GrandExchangeOfferChanged grandExchangeOfferChanged = new GrandExchangeOfferChanged();
|
||||
grandExchangeOfferChanged.setSlot(2);
|
||||
grandExchangeOfferChanged.setOffer(grandExchangeOffer);
|
||||
grandExchangePlugin.onGrandExchangeOfferChanged(grandExchangeOfferChanged);
|
||||
|
||||
// verify trade update
|
||||
ArgumentCaptor<GrandExchangeTrade> captor = ArgumentCaptor.forClass(GrandExchangeTrade.class);
|
||||
verify(grandExchangeClient).submit(captor.capture());
|
||||
|
||||
GrandExchangeTrade trade = captor.getValue();
|
||||
assertFalse(trade.isBuy());
|
||||
assertEquals(ItemID.ABYSSAL_WHIP, trade.getItemId());
|
||||
assertEquals(2, trade.getQty());
|
||||
assertEquals(1, trade.getDqty());
|
||||
assertEquals(10, trade.getTotal());
|
||||
assertEquals(1000, trade.getDspent());
|
||||
assertEquals(2000, trade.getSpent());
|
||||
assertEquals(1000, trade.getOffer());
|
||||
assertEquals(2, trade.getSlot());
|
||||
assertTrue(trade.isLogin());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* 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.screenshot;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.function.Consumer;
|
||||
import javax.inject.Inject;
|
||||
import static net.runelite.api.ChatMessageType.GAMEMESSAGE;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.WidgetLoaded;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import static net.runelite.api.widgets.WidgetID.DIALOG_SPRITE_GROUP_ID;
|
||||
import static net.runelite.api.widgets.WidgetID.LEVEL_UP_GROUP_ID;
|
||||
import static net.runelite.api.widgets.WidgetInfo.DIALOG_SPRITE_TEXT;
|
||||
import static net.runelite.api.widgets.WidgetInfo.LEVEL_UP_LEVEL;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
import net.runelite.client.ui.DrawManager;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.ImageCapture;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ScreenshotPluginTest
|
||||
{
|
||||
private static final String CLUE_SCROLL = "<col=3300ff>You have completed 28 medium Treasure Trails</col>";
|
||||
private static final String BARROWS_CHEST = "Your Barrows chest count is <col=ff0000>310</col>";
|
||||
private static final String CHAMBERS_OF_XERIC_CHEST = "Your completed Chambers of Xeric count is: <col=ff0000>489</col>.";
|
||||
private static final String THEATRE_OF_BLOOD_CHEST = "Your completed Theatre of Blood count is: <col=ff0000>73</col>.";
|
||||
private static final String VALUABLE_DROP = "<col=ef1020>Valuable drop: 6 x Bronze arrow (42 coins)</col>";
|
||||
private static final String UNTRADEABLE_DROP = "<col=ef1020>Untradeable drop: Rusty sword";
|
||||
private static final String BA_HIGH_GAMBLE_REWARD = "Raw shark (x 300)!<br>High level gamble count: <col=7f0000>100</col>";
|
||||
private static final String HUNTER_LEVEL_2_TEXT = "<col=000080>Congratulations, you've just advanced a Hunter level.<col=000000><br><br>Your Hunter level is now 2.";
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ScreenshotPlugin screenshotPlugin;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ScreenshotConfig screenshotConfig;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
Notifier notifier;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ClientUI clientUi;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
DrawManager drawManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
RuneLiteConfig config;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
ScheduledExecutorService service;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ImageCapture imageCapture;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
when(screenshotConfig.screenshotLevels()).thenReturn(true);
|
||||
when(screenshotConfig.screenshotValuableDrop()).thenReturn(true);
|
||||
when(screenshotConfig.screenshotUntradeableDrop()).thenReturn(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClueScroll()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Seth", CLUE_SCROLL, null, 0);
|
||||
screenshotPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
assertEquals("medium", screenshotPlugin.getClueType());
|
||||
assertEquals(28, screenshotPlugin.getClueNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBarrowsChest()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Seth", BARROWS_CHEST, null, 0);
|
||||
screenshotPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
assertEquals(310, screenshotPlugin.getBarrowsNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChambersOfXericChest()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Seth", CHAMBERS_OF_XERIC_CHEST, null, 0);
|
||||
screenshotPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
assertEquals(489, screenshotPlugin.getChambersOfXericNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTheatreOfBloodChest()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "Magic fTail", THEATRE_OF_BLOOD_CHEST, null, 0);
|
||||
screenshotPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
assertEquals(73, screenshotPlugin.gettheatreOfBloodNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValuableDrop()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", VALUABLE_DROP, null, 0);
|
||||
screenshotPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(drawManager).requestNextFrameListener(any(Consumer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUntradeableDrop()
|
||||
{
|
||||
ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", UNTRADEABLE_DROP, null, 0);
|
||||
screenshotPlugin.onChatMessage(chatMessageEvent);
|
||||
|
||||
verify(drawManager).requestNextFrameListener(any(Consumer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHitpointsLevel99()
|
||||
{
|
||||
Widget levelChild = mock(Widget.class);
|
||||
when(client.getWidget(eq(LEVEL_UP_LEVEL))).thenReturn(levelChild);
|
||||
|
||||
when(levelChild.getText()).thenReturn("Your Hitpoints are now 99.");
|
||||
|
||||
assertEquals("Hitpoints(99)", screenshotPlugin.parseLevelUpWidget(LEVEL_UP_LEVEL));
|
||||
|
||||
WidgetLoaded event = new WidgetLoaded();
|
||||
event.setGroupId(LEVEL_UP_GROUP_ID);
|
||||
screenshotPlugin.onWidgetLoaded(event);
|
||||
|
||||
GameTick tick = new GameTick();
|
||||
screenshotPlugin.onGameTick(tick);
|
||||
|
||||
verify(drawManager).requestNextFrameListener(any(Consumer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFiremakingLevel9()
|
||||
{
|
||||
Widget levelChild = mock(Widget.class);
|
||||
when(client.getWidget(eq(LEVEL_UP_LEVEL))).thenReturn(levelChild);
|
||||
|
||||
when(levelChild.getText()).thenReturn("Your Firemaking level is now 9.");
|
||||
|
||||
assertEquals("Firemaking(9)", screenshotPlugin.parseLevelUpWidget(LEVEL_UP_LEVEL));
|
||||
|
||||
WidgetLoaded event = new WidgetLoaded();
|
||||
event.setGroupId(LEVEL_UP_GROUP_ID);
|
||||
screenshotPlugin.onWidgetLoaded(event);
|
||||
|
||||
GameTick tick = new GameTick();
|
||||
screenshotPlugin.onGameTick(tick);
|
||||
|
||||
verify(drawManager).requestNextFrameListener(any(Consumer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttackLevel70()
|
||||
{
|
||||
Widget levelChild = mock(Widget.class);
|
||||
when(client.getWidget(eq(LEVEL_UP_LEVEL))).thenReturn(levelChild);
|
||||
|
||||
when(levelChild.getText()).thenReturn("Your Attack level is now 70.");
|
||||
|
||||
assertEquals("Attack(70)", screenshotPlugin.parseLevelUpWidget(LEVEL_UP_LEVEL));
|
||||
|
||||
WidgetLoaded event = new WidgetLoaded();
|
||||
event.setGroupId(LEVEL_UP_GROUP_ID);
|
||||
screenshotPlugin.onWidgetLoaded(event);
|
||||
|
||||
GameTick tick = new GameTick();
|
||||
screenshotPlugin.onGameTick(tick);
|
||||
|
||||
verify(drawManager).requestNextFrameListener(any(Consumer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHunterLevel2()
|
||||
{
|
||||
Widget levelChild = mock(Widget.class);
|
||||
when(client.getWidget(eq(DIALOG_SPRITE_TEXT))).thenReturn(levelChild);
|
||||
|
||||
when(levelChild.getText()).thenReturn(HUNTER_LEVEL_2_TEXT);
|
||||
|
||||
assertEquals("Hunter(2)", screenshotPlugin.parseLevelUpWidget(DIALOG_SPRITE_TEXT));
|
||||
|
||||
WidgetLoaded event = new WidgetLoaded();
|
||||
event.setGroupId(DIALOG_SPRITE_GROUP_ID);
|
||||
screenshotPlugin.onWidgetLoaded(event);
|
||||
|
||||
GameTick tick = new GameTick();
|
||||
screenshotPlugin.onGameTick(tick);
|
||||
|
||||
verify(drawManager).requestNextFrameListener(any(Consumer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuestParsing()
|
||||
{
|
||||
assertEquals("Quest(The Corsair Curse)", ScreenshotPlugin.parseQuestCompletedWidget("You have completed The Corsair Curse!"));
|
||||
assertEquals("Quest(One Small Favour)", ScreenshotPlugin.parseQuestCompletedWidget("'One Small Favour' completed!"));
|
||||
assertEquals("Quest(Hazeel Cult partial completion)", ScreenshotPlugin.parseQuestCompletedWidget("You have... kind of... completed the Hazeel Cult Quest!"));
|
||||
assertEquals("Quest(Rag and Bone Man II)", ScreenshotPlugin.parseQuestCompletedWidget("You have completely completed Rag and Bone Man!"));
|
||||
assertEquals("Quest(Recipe for Disaster - Culinaromancer)", ScreenshotPlugin.parseQuestCompletedWidget("Congratulations! You have defeated the Culinaromancer!"));
|
||||
assertEquals("Quest(Recipe for Disaster - Another Cook's Quest)", ScreenshotPlugin.parseQuestCompletedWidget("You have completed Another Cook's Quest!"));
|
||||
assertEquals("Quest(Doric's Quest)", ScreenshotPlugin.parseQuestCompletedWidget("You have completed Doric's Quest!"));
|
||||
assertEquals("Quest(quest not found)", ScreenshotPlugin.parseQuestCompletedWidget("Sins of the Father forgiven!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBAHighGambleRewardParsing()
|
||||
{
|
||||
assertEquals("High Gamble(100)", ScreenshotPlugin.parseBAHighGambleWidget(BA_HIGH_GAMBLE_REWARD));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLevelUpScreenshotsDisabled()
|
||||
{
|
||||
// Level up dialogs use the same widget interface as BA high gamble results
|
||||
when(screenshotConfig.screenshotLevels()).thenReturn(false);
|
||||
when(screenshotConfig.screenshotHighGamble()).thenReturn(true);
|
||||
Widget dialogChild = mock(Widget.class);
|
||||
when(dialogChild.getText()).thenReturn(HUNTER_LEVEL_2_TEXT);
|
||||
when(client.getWidget(DIALOG_SPRITE_TEXT)).thenReturn(dialogChild);
|
||||
|
||||
WidgetLoaded event = new WidgetLoaded();
|
||||
event.setGroupId(DIALOG_SPRITE_GROUP_ID);
|
||||
screenshotPlugin.onWidgetLoaded(event);
|
||||
|
||||
screenshotPlugin.onGameTick(new GameTick());
|
||||
|
||||
verify(drawManager, times(0)).requestNextFrameListener(any(Consumer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBAHighGambleScreenshotsDisabled()
|
||||
{
|
||||
// BA high gamble results use the same widget interface as level up dialogs
|
||||
when(screenshotConfig.screenshotLevels()).thenReturn(true);
|
||||
when(screenshotConfig.screenshotHighGamble()).thenReturn(false);
|
||||
Widget dialogChild = mock(Widget.class);
|
||||
when(dialogChild.getText()).thenReturn(BA_HIGH_GAMBLE_REWARD);
|
||||
when(client.getWidget(DIALOG_SPRITE_TEXT)).thenReturn(dialogChild);
|
||||
|
||||
WidgetLoaded event = new WidgetLoaded();
|
||||
event.setGroupId(DIALOG_SPRITE_GROUP_ID);
|
||||
screenshotPlugin.onWidgetLoaded(event);
|
||||
|
||||
screenshotPlugin.onGameTick(new GameTick());
|
||||
|
||||
verify(drawManager, times(0)).requestNextFrameListener(any(Consumer.class));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Adam <Adam@sigterm.info>
|
||||
* 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.specialcounter;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.EquipmentInventorySlot;
|
||||
import net.runelite.api.Hitsplat;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.Item;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.ItemID;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.VarPlayer;
|
||||
import net.runelite.api.events.HitsplatApplied;
|
||||
import net.runelite.api.events.InteractingChanged;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.ws.PartyService;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SpecialCounterPluginTest
|
||||
{
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private PartyService partyService;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Notifier notifier;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private SpecialCounterConfig specialCounterConfig;
|
||||
|
||||
@Inject
|
||||
private SpecialCounterPlugin specialCounterPlugin;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
|
||||
// Set up spec weapon
|
||||
ItemContainer equipment = mock(ItemContainer.class);
|
||||
when(equipment.getItem(EquipmentInventorySlot.WEAPON.getSlotIdx())).thenReturn(new Item(ItemID.BANDOS_GODSWORD, 1));
|
||||
when(client.getItemContainer(InventoryID.EQUIPMENT)).thenReturn(equipment);
|
||||
|
||||
// Set up special attack energy
|
||||
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(100);
|
||||
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
|
||||
|
||||
}
|
||||
|
||||
private static HitsplatApplied hitsplat(Actor target, Hitsplat.HitsplatType type)
|
||||
{
|
||||
Hitsplat hitsplat = new Hitsplat(type, type == Hitsplat.HitsplatType.DAMAGE_ME ? 1 : 0, 42);
|
||||
HitsplatApplied hitsplatApplied = new HitsplatApplied();
|
||||
hitsplatApplied.setActor(target);
|
||||
hitsplatApplied.setHitsplat(hitsplat);
|
||||
return hitsplatApplied;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecDamage()
|
||||
{
|
||||
NPC target = mock(NPC.class);
|
||||
|
||||
Player player = mock(Player.class);
|
||||
when(client.getLocalPlayer()).thenReturn(player);
|
||||
|
||||
// spec npc
|
||||
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
|
||||
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
|
||||
lenient().when(player.getInteracting()).thenReturn(target);
|
||||
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, target));
|
||||
|
||||
// hit 1
|
||||
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
|
||||
|
||||
verify(infoBoxManager).addInfoBox(any(SpecialCounter.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecBlock()
|
||||
{
|
||||
NPC target = mock(NPC.class);
|
||||
|
||||
Player player = mock(Player.class);
|
||||
when(client.getLocalPlayer()).thenReturn(player);
|
||||
|
||||
// spec npc
|
||||
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
|
||||
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
|
||||
lenient().when(player.getInteracting()).thenReturn(target);
|
||||
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, target));
|
||||
|
||||
// block 0
|
||||
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.BLOCK_ME));
|
||||
|
||||
// hit 1
|
||||
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
|
||||
|
||||
verify(infoBoxManager, never()).addInfoBox(any(SpecialCounter.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnaggro()
|
||||
{
|
||||
NPC target = mock(NPC.class);
|
||||
|
||||
Player player = mock(Player.class);
|
||||
when(client.getLocalPlayer()).thenReturn(player);
|
||||
|
||||
// tick 1: attack npc
|
||||
when(player.getInteracting()).thenReturn(target);
|
||||
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, target));
|
||||
|
||||
// tick 2: spec fires and un-interact npc
|
||||
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
|
||||
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
|
||||
lenient().when(player.getInteracting()).thenReturn(null);
|
||||
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, null));
|
||||
|
||||
// tick 3: hit 1
|
||||
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
|
||||
|
||||
verify(infoBoxManager).addInfoBox(any(SpecialCounter.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameTick()
|
||||
{
|
||||
NPC targetA = mock(NPC.class);
|
||||
NPC targetB = mock(NPC.class);
|
||||
|
||||
Player player = mock(Player.class);
|
||||
when(client.getLocalPlayer()).thenReturn(player);
|
||||
|
||||
// tick 1: attack npc A
|
||||
when(player.getInteracting()).thenReturn(targetA);
|
||||
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, targetA));
|
||||
|
||||
// tick 2: spec npc B
|
||||
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
|
||||
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
|
||||
lenient().when(player.getInteracting()).thenReturn(targetB);
|
||||
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, targetB));
|
||||
|
||||
// tick 3: hitsplat A, hitsplat B
|
||||
specialCounterPlugin.onHitsplatApplied(hitsplat(targetA, Hitsplat.HitsplatType.DAMAGE_ME));
|
||||
verify(infoBoxManager, never()).addInfoBox(any(SpecialCounter.class));
|
||||
|
||||
specialCounterPlugin.onHitsplatApplied(hitsplat(targetB, Hitsplat.HitsplatType.DAMAGE_ME));
|
||||
verify(infoBoxManager).addInfoBox(any(SpecialCounter.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReset()
|
||||
{
|
||||
NPC targetA = mock(NPC.class);
|
||||
NPC targetB = mock(NPC.class);
|
||||
when(targetB.getId()).thenReturn(1); // a different npc type
|
||||
|
||||
Player player = mock(Player.class);
|
||||
when(client.getLocalPlayer()).thenReturn(player);
|
||||
|
||||
// spec npc
|
||||
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
|
||||
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
|
||||
lenient().when(player.getInteracting()).thenReturn(targetA);
|
||||
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, targetA));
|
||||
|
||||
// hit 1
|
||||
specialCounterPlugin.onHitsplatApplied(hitsplat(targetA, Hitsplat.HitsplatType.DAMAGE_ME));
|
||||
|
||||
verify(infoBoxManager).addInfoBox(any(SpecialCounter.class));
|
||||
|
||||
// attack npc 2
|
||||
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, targetB));
|
||||
|
||||
// hit 1
|
||||
specialCounterPlugin.onHitsplatApplied(hitsplat(targetB, Hitsplat.HitsplatType.DAMAGE_ME));
|
||||
|
||||
verify(infoBoxManager).removeInfoBox(any(SpecialCounter.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotification()
|
||||
{
|
||||
// Create an enemy
|
||||
NPC target = mock(NPC.class);
|
||||
|
||||
// Create player
|
||||
Player player = mock(Player.class);
|
||||
when(client.getLocalPlayer()).thenReturn(player);
|
||||
when(specialCounterConfig.bandosGodswordThreshold()).thenReturn(2);
|
||||
when(specialCounterConfig.thresholdNotification()).thenReturn(true);
|
||||
|
||||
// Attack enemy
|
||||
when(player.getInteracting()).thenReturn(target);
|
||||
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, target));
|
||||
|
||||
// First special attack
|
||||
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
|
||||
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
|
||||
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
|
||||
|
||||
// Second special attack
|
||||
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(0);
|
||||
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
|
||||
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
|
||||
|
||||
verify(notifier).notify("Bandos Godsword special attack threshold reached!");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotificationNotThreshold()
|
||||
{
|
||||
// Create an enemy
|
||||
NPC target = mock(NPC.class);
|
||||
|
||||
// Create player
|
||||
Player player = mock(Player.class);
|
||||
when(client.getLocalPlayer()).thenReturn(player);
|
||||
when(specialCounterConfig.bandosGodswordThreshold()).thenReturn(3);
|
||||
lenient().when(specialCounterConfig.thresholdNotification()).thenReturn(true);
|
||||
|
||||
// Attack enemy
|
||||
when(player.getInteracting()).thenReturn(target);
|
||||
specialCounterPlugin.onInteractingChanged(new InteractingChanged(player, target));
|
||||
|
||||
// First special attack
|
||||
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(50);
|
||||
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
|
||||
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
|
||||
|
||||
// Second special attack
|
||||
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(0);
|
||||
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
|
||||
specialCounterPlugin.onHitsplatApplied(hitsplat(target, Hitsplat.HitsplatType.DAMAGE_ME));
|
||||
|
||||
verify(notifier, never()).notify(any());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* 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.timers;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.InventoryID;
|
||||
import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.events.ChatMessage;
|
||||
import net.runelite.api.events.ItemContainerChanged;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.SpriteManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBox;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class TimersPluginTest
|
||||
{
|
||||
@Inject
|
||||
private TimersPlugin timersPlugin;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private TimersConfig timersConfig;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private SpriteManager spriteManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHalfTeleblock()
|
||||
{
|
||||
when(timersConfig.showTeleblock()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 2 minutes, 30 seconds.</col>", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
|
||||
assertEquals(Duration.ofSeconds(2 * 60 + 30), infoBox.getDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFullTeleblock()
|
||||
{
|
||||
when(timersConfig.showTeleblock()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 5 minutes.</col>", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
|
||||
assertEquals(Duration.ofMinutes(5), infoBox.getDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDmmHalfTb()
|
||||
{
|
||||
when(timersConfig.showTeleblock()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 1 minute, 15 seconds.</col>", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
|
||||
assertEquals(Duration.ofSeconds(60 + 15), infoBox.getDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDmmFullTb()
|
||||
{
|
||||
when(timersConfig.showTeleblock()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=4f006f>A Tele Block spell has been cast on you by Runelite. It will expire in 2 minutes, 30 seconds.</col>", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
|
||||
assertEquals(Duration.ofSeconds(60 * 2 + 30), infoBox.getDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDivineBastion()
|
||||
{
|
||||
when(timersConfig.showDivine()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "You drink some of your divine bastion potion.", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.DIVINE_BASTION, infoBox.getTimer());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDivineBattlemage()
|
||||
{
|
||||
when(timersConfig.showDivine()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "You drink some of your divine battlemage potion.", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.DIVINE_BATTLEMAGE, infoBox.getTimer());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransparentChatboxTb()
|
||||
{
|
||||
when(timersConfig.showTeleblock()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=c356ef>A Tele Block spell has been cast on you by Alexsuperfly. It will expire in 5 minutes.</col>", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
|
||||
assertEquals(Duration.ofMinutes(5), infoBox.getDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransparentChatboxTbRemoved()
|
||||
{
|
||||
when(timersConfig.showTeleblock()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=c356ef>Your Tele Block has been removed because you killed Alexsuperfly.</col>", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
verify(infoBoxManager, atLeastOnce()).removeIf(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMageArena2TbFull()
|
||||
{
|
||||
when(timersConfig.showTeleblock()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=c356ef>A Tele Block spell has been cast on you. It will expire in 2 minutes.</col>", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
|
||||
assertEquals(Duration.ofMinutes(2), infoBox.getDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMageArena2TbHalf()
|
||||
{
|
||||
when(timersConfig.showTeleblock()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=c356ef>A Tele Block spell has been cast on you. It will expire in 1 minute.</col>", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.TELEBLOCK, infoBox.getTimer());
|
||||
assertEquals(Duration.ofMinutes(1), infoBox.getDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStamina()
|
||||
{
|
||||
when(timersConfig.showStamina()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "You drink some of your stamina potion.", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.STAMINA, infoBox.getTimer());
|
||||
assertEquals(Duration.ofMinutes(2), infoBox.getDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSireStunTimer()
|
||||
{
|
||||
when(timersConfig.showAbyssalSireStun()).thenReturn(true);
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "The Sire has been disorientated temporarily.", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.ABYSSAL_SIRE_STUN, infoBox.getTimer());
|
||||
assertEquals(Duration.ofSeconds(30), infoBox.getDuration());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEndurance()
|
||||
{
|
||||
when(timersConfig.showStamina()).thenReturn(true);
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "Your Ring of endurance doubles the duration of your stamina potion's effect.", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "You drink some of your stamina potion.", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager).addInfoBox(captor.capture());
|
||||
TimerTimer infoBox = (TimerTimer) captor.getValue();
|
||||
assertEquals(GameTimer.STAMINA, infoBox.getTimer());
|
||||
assertEquals(Duration.ofMinutes(4), infoBox.getDuration());
|
||||
|
||||
// unwield ring
|
||||
timersPlugin.onItemContainerChanged(new ItemContainerChanged(InventoryID.EQUIPMENT.getId(), mock(ItemContainer.class)));
|
||||
// some time has elapsed in the test; this should be just under 2 mins
|
||||
int mins = (int) infoBox.getDuration().toMinutes();
|
||||
assertTrue(mins == 1 || mins == 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTzhaarTimer()
|
||||
{
|
||||
when(timersConfig.showTzhaarTimers()).thenReturn(true);
|
||||
when(client.getMapRegions()).thenReturn(new int[]{TimersPlugin.FIGHT_CAVES_REGION_ID});
|
||||
|
||||
class InstantRef
|
||||
{
|
||||
Instant i;
|
||||
}
|
||||
|
||||
InstantRef startTime = new InstantRef();
|
||||
when(timersConfig.tzhaarStartTime()).then(a -> startTime.i);
|
||||
doAnswer((Answer<Void>) invocationOnMock ->
|
||||
{
|
||||
Object argument = invocationOnMock.getArguments()[0];
|
||||
startTime.i = (Instant) argument;
|
||||
return null;
|
||||
}).when(timersConfig).tzhaarStartTime(nullable(Instant.class));
|
||||
|
||||
InstantRef lastTime = new InstantRef();
|
||||
when(timersConfig.tzhaarLastTime()).then(a -> lastTime.i);
|
||||
doAnswer((Answer<Void>) invocationOnMock ->
|
||||
{
|
||||
Object argument = invocationOnMock.getArguments()[0];
|
||||
lastTime.i = (Instant) argument;
|
||||
return null;
|
||||
}).when(timersConfig).tzhaarLastTime(nullable(Instant.class));
|
||||
|
||||
// test timer creation: verify the infobox was added and that it is an ElapsedTimer
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "<col=ef1020>Wave: 1</col>", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager, times(1)).addInfoBox(captor.capture());
|
||||
assertTrue(captor.getValue() instanceof ElapsedTimer);
|
||||
|
||||
// test timer pause: verify the added ElapsedTimer has a non-null lastTime
|
||||
chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "<col=ef1020>The Inferno has been paused. You may now log out.", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
verify(infoBoxManager, times(1)).removeInfoBox(captor.capture());
|
||||
verify(infoBoxManager, times(2)).addInfoBox(captor.capture());
|
||||
assertTrue(captor.getValue() instanceof ElapsedTimer);
|
||||
ElapsedTimer timer = (ElapsedTimer) captor.getValue();
|
||||
assertNotEquals(timer.getLastTime(), null);
|
||||
Instant oldTime = ((ElapsedTimer) captor.getValue()).getStartTime();
|
||||
|
||||
// test timer unpause: verify the last time is null after being unpaused
|
||||
chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "<col=ef1020>Wave: 2</col>", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
verify(infoBoxManager, times(2)).removeInfoBox(captor.capture());
|
||||
verify(infoBoxManager, times(3)).addInfoBox(captor.capture());
|
||||
assertTrue(captor.getValue() instanceof ElapsedTimer);
|
||||
timer = (ElapsedTimer) captor.getValue();
|
||||
assertNull(timer.getLastTime());
|
||||
|
||||
// test timer remove: verify the infobox was removed (and no more were added)
|
||||
chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "You have been defeated!", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
verify(infoBoxManager, times(3)).removeInfoBox(captor.capture());
|
||||
verify(infoBoxManager, times(3)).addInfoBox(captor.capture());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInfernoTimerStartOffset()
|
||||
{
|
||||
when(timersConfig.showTzhaarTimers()).thenReturn(true);
|
||||
when(client.getMapRegions()).thenReturn(new int[]{TimersPlugin.INFERNO_REGION_ID});
|
||||
|
||||
class InstantRef
|
||||
{
|
||||
Instant i;
|
||||
}
|
||||
|
||||
InstantRef startTime = new InstantRef();
|
||||
when(timersConfig.tzhaarStartTime()).then(a -> startTime.i);
|
||||
doAnswer((Answer<Void>) invocationOnMock ->
|
||||
{
|
||||
Object argument = invocationOnMock.getArguments()[0];
|
||||
startTime.i = (Instant) argument;
|
||||
return null;
|
||||
}).when(timersConfig).tzhaarStartTime(nullable(Instant.class));
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "<col=ef1020>Wave: 1</col>", "", 0);
|
||||
timersPlugin.onChatMessage(chatMessage);
|
||||
|
||||
ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
|
||||
verify(infoBoxManager, times(1)).addInfoBox(captor.capture());
|
||||
assertTrue(captor.getValue() instanceof ElapsedTimer);
|
||||
ElapsedTimer timer = (ElapsedTimer) captor.getValue();
|
||||
assertEquals("00:06", timer.getText());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@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.util;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.awt.Color;
|
||||
import java.util.Map;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ColorUtilTest
|
||||
{
|
||||
private static final Map<Color, String> COLOR_HEXSTRING_MAP = new ImmutableMap.Builder<Color, String>().
|
||||
put(Color.BLACK, "000000").
|
||||
put(new Color(0x1), "000001").
|
||||
put(new Color(0x100000), "100000").
|
||||
put(Color.RED, "ff0000").
|
||||
put(Color.GREEN, "00ff00").
|
||||
put(Color.BLUE, "0000ff").
|
||||
put(new Color(0xA1B2C3), "a1b2c3").
|
||||
put(Color.WHITE, "ffffff").build();
|
||||
|
||||
private static final Map<Color, String> COLOR_ALPHA_HEXSTRING_MAP = ImmutableMap.of(
|
||||
new Color(0x00000000, true), "00000000",
|
||||
new Color(0xA1B2C3D4, true), "a1b2c3d4"
|
||||
);
|
||||
|
||||
@Test
|
||||
public void colorTag()
|
||||
{
|
||||
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
|
||||
{
|
||||
assertEquals("<col=" + hex + ">", ColorUtil.colorTag(color));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prependColorTag()
|
||||
{
|
||||
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
|
||||
{
|
||||
assertEquals("<col=" + hex + ">test", ColorUtil.prependColorTag("test", color));
|
||||
assertEquals("<col=" + hex + ">", ColorUtil.prependColorTag("", color));
|
||||
});
|
||||
|
||||
assertEquals("<col=ff0000>94<col=ffffff>/99", ColorUtil.prependColorTag("94" + ColorUtil.prependColorTag("/99", Color.WHITE), Color.RED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrapWithColorTag()
|
||||
{
|
||||
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
|
||||
{
|
||||
assertEquals("<col=" + hex + ">test</col>", ColorUtil.wrapWithColorTag("test", color));
|
||||
assertEquals("<col=" + hex + "></col>", ColorUtil.wrapWithColorTag("", color));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toHexColor()
|
||||
{
|
||||
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
|
||||
{
|
||||
assertEquals("#" + hex, ColorUtil.toHexColor(color));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void colorWithAlpha()
|
||||
{
|
||||
int[] alpha = {73};
|
||||
|
||||
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
|
||||
{
|
||||
assertEquals(new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha[0]),
|
||||
ColorUtil.colorWithAlpha(color, alpha[0]));
|
||||
alpha[0] += 73;
|
||||
alpha[0] %= 255;
|
||||
});
|
||||
|
||||
COLOR_ALPHA_HEXSTRING_MAP.forEach((color, hex) ->
|
||||
{
|
||||
assertEquals(new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha[0]),
|
||||
ColorUtil.colorWithAlpha(color, alpha[0]));
|
||||
alpha[0] += 73;
|
||||
alpha[0] %= 255;
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void colorLerp()
|
||||
{
|
||||
assertEquals(Color.WHITE, ColorUtil.colorLerp(Color.WHITE, Color.WHITE, 0.9));
|
||||
assertEquals(new Color(128, 128, 128), ColorUtil.colorLerp(Color.BLACK, Color.WHITE, 0.5));
|
||||
assertEquals(Color.BLACK, ColorUtil.colorLerp(Color.BLACK, Color.CYAN, 0));
|
||||
assertEquals(Color.CYAN, ColorUtil.colorLerp(Color.BLACK, Color.CYAN, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void colorToHexCode()
|
||||
{
|
||||
COLOR_HEXSTRING_MAP.forEach((color, hex) ->
|
||||
{
|
||||
assertEquals(hex, ColorUtil.colorToHexCode(color));
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user