From 94685b6ef4e4cf12ffe1e8cd1a68d17f2d806036 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 28 Apr 2021 10:28:07 -0400 Subject: [PATCH 01/18] widgets: fix modern resizable interface container component id This was referencing the classic layout's component id, which until today, happened to be the same between both interfaces --- .../src/main/java/net/runelite/api/widgets/WidgetID.java | 1 + .../src/main/java/net/runelite/api/widgets/WidgetInfo.java | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index bef1e15e09..815f74e78c 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -471,6 +471,7 @@ public class WidgetID static final int MUSIC_TAB = 40; static final int MUSIC_ICON = 49; static final int MAGIC_ICON = 66; + static final int INTERFACE_CONTAINER = 68; static final int INVENTORY_CONTAINER = 74; } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index 10ad860ebd..88e54965b9 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -263,6 +263,8 @@ public enum WidgetInfo RESIZABLE_VIEWPORT_OPTIONS_ICON(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.OPTIONS_ICON), RESIZABLE_VIEWPORT_EMOTES_ICON(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.EMOTES_ICON), RESIZABLE_VIEWPORT_MUSIC_ICON(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.MUSIC_ICON), + RESIZABLE_VIEWPORT_INTERFACE_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.INTERFACE_CONTAINER), + RESIZABLE_VIEWPORT_INVENTORY_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.INVENTORY_CONTAINER), RESIZABLE_VIEWPORT_BOTTOM_LINE(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.Viewport.RESIZABLE_VIEWPORT_BOTTOM_LINE), RESIZABLE_VIEWPORT_BOTTOM_LINE_LOGOUT_BUTTON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.LOGOUT_BUTTON_OVERLAY), @@ -281,9 +283,7 @@ public enum WidgetInfo RESIZABLE_VIEWPORT_BOTTOM_LINE_EMOTES_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.EMOTE_ICON), RESIZABLE_VIEWPORT_BOTTOM_LINE_MUSIC_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.MUSIC_ICON), RESIZABLE_VIEWPORT_BOTTOM_LINE_INVENTORY_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.INVENTORY_CONTAINER), - RESIZABLE_VIEWPORT_INTERFACE_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.INTERFACE_CONTAINER), - RESIZABLE_VIEWPORT_INVENTORY_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.INVENTORY_CONTAINER), - RESIZABLE_VIEWPORT_BOTTOM_LINE_INTERFACE_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewport.INTERFACE_CONTAINER), + RESIZABLE_VIEWPORT_BOTTOM_LINE_INTERFACE_CONTAINER(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.INTERFACE_CONTAINER), PRAYER_THICK_SKIN(WidgetID.PRAYER_GROUP_ID, WidgetID.Prayer.THICK_SKIN), PRAYER_BURST_OF_STRENGTH(WidgetID.PRAYER_GROUP_ID, WidgetID.Prayer.BURST_OF_STRENGTH), From aa443397694008f953e9e136b4581d93d4b7469f Mon Sep 17 00:00:00 2001 From: Hydrox6 Date: Mon, 26 Apr 2021 13:49:36 +0100 Subject: [PATCH 02/18] clues: highlight the last clue's STASH until items are deposited back --- .../plugins/cluescrolls/ClueScrollPlugin.java | 37 +++++++++++++-- .../cluescrolls/ClueScrollWorldOverlay.java | 7 +++ .../plugins/cluescrolls/clues/EmoteClue.java | 5 ++ .../cluescrolls/ClueScrollPluginTest.java | 47 +++++++++++++++++++ 4 files changed, 93 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java index 8fc616fcde..81aa28c38e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollPlugin.java @@ -217,6 +217,10 @@ public class ClueScrollPlugin extends Plugin private final TextComponent textComponent = new TextComponent(); + @Getter + private EmoteClue activeSTASHClue; + private EmoteClue clickedSTASHClue; + @Provides ClueScrollConfig getConfig(ConfigManager configManager) { @@ -264,9 +268,11 @@ public class ClueScrollPlugin extends Plugin return; } + String message = event.getMessage(); + if (clue instanceof HotColdClue) { - if (((HotColdClue) clue).update(event.getMessage(), this)) + if (((HotColdClue) clue).update(message, this)) { worldMapPointsSet = false; } @@ -274,7 +280,7 @@ public class ClueScrollPlugin extends Plugin if (clue instanceof SkillChallengeClue) { - String text = Text.removeTags(event.getMessage()); + String text = Text.removeTags(message); if (text.equals("Skill challenge completed.") || text.equals("You have completed your master level challenge!") || text.startsWith("You have completed Charlie's task,") || @@ -283,6 +289,19 @@ public class ClueScrollPlugin extends Plugin ((SkillChallengeClue) clue).setChallengeCompleted(true); } } + + if (message.endsWith(" the STASH unit.")) + { + if (clue instanceof EmoteClue && clickedSTASHClue != null && message.equals("You withdraw your items from the STASH unit.")) + { + activeSTASHClue = clickedSTASHClue; + } + else if (message.equals("You deposit your items into the STASH unit.")) + { + activeSTASHClue = null; + } + clickedSTASHClue = null; + } } @Subscribe @@ -300,7 +319,11 @@ public class ClueScrollPlugin extends Plugin @Subscribe public void onMenuOptionClicked(final MenuOptionClicked event) { - if (event.getMenuOption() != null && event.getMenuOption().equals("Read")) + if (event.getMenuOption() == null) + { + return; + } + if (event.getMenuOption().equals("Read")) { final ItemComposition itemComposition = itemManager.getItemComposition(event.getId()); @@ -310,6 +333,14 @@ public class ClueScrollPlugin extends Plugin updateClue(MapClue.forItemId(clueItemId)); } } + else if (event.getMenuOption().equals("Search") && clue instanceof EmoteClue) + { + EmoteClue emoteClue = (EmoteClue) clue; + if (emoteClue.getStashUnit() != null && emoteClue.getStashUnit().getObjectId() == event.getId()) + { + clickedSTASHClue = emoteClue; + } + } } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollWorldOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollWorldOverlay.java index d68f06a691..266163be8b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollWorldOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/ClueScrollWorldOverlay.java @@ -29,6 +29,7 @@ import java.awt.Dimension; import java.awt.Graphics2D; import javax.inject.Inject; import net.runelite.client.plugins.cluescrolls.clues.ClueScroll; +import net.runelite.client.plugins.cluescrolls.clues.EmoteClue; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; @@ -61,6 +62,12 @@ public class ClueScrollWorldOverlay extends Overlay clue.makeWorldOverlayHint(graphics, plugin); } + EmoteClue activeSTASHClue = plugin.getActiveSTASHClue(); + if (activeSTASHClue != null && activeSTASHClue != clue) + { + activeSTASHClue.makeSTASHOverlay(graphics, plugin); + } + return null; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java index 0eca2de62f..835a86718d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java @@ -311,6 +311,11 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu OverlayUtil.renderTileOverlay(plugin.getClient(), graphics, localPoint, plugin.getEmoteImage(), Color.ORANGE); } + makeSTASHOverlay(graphics, plugin); + } + + public void makeSTASHOverlay(Graphics2D graphics, ClueScrollPlugin plugin) + { if (stashUnit != null) { final WorldPoint[] worldPoints = stashUnit.getWorldPoints(); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/ClueScrollPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/ClueScrollPluginTest.java index 1c3cd1ecd4..59daa49af7 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/ClueScrollPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cluescrolls/ClueScrollPluginTest.java @@ -33,10 +33,12 @@ import com.google.inject.testing.fieldbinder.BoundFieldModule; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.NPC; +import net.runelite.api.NullObjectID; import net.runelite.api.Player; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameTick; +import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.game.ItemManager; @@ -45,6 +47,8 @@ import net.runelite.client.plugins.cluescrolls.clues.hotcold.HotColdLocation; import net.runelite.client.ui.overlay.OverlayManager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -168,4 +172,47 @@ public class ClueScrollPluginTest verify(client, times(++clueSetupHintArrowClears)).clearHintArrow(); verify(client, times(1)).setHintArrow(any(WorldPoint.class)); } + + @Test + public void testSTASHMarkerPersistence() + { + when(client.getCachedNPCs()).thenReturn(new NPC[] {}); + + // Set up emote clue + final Widget clueWidget = mock(Widget.class); + when(clueWidget.getText()).thenReturn("Spin in the Varrock Castle courtyard. Equip a black axe, a coif and a ruby ring."); + when(client.getWidget(WidgetInfo.CLUE_SCROLL_TEXT)).thenReturn(clueWidget); + plugin.onGameTick(new GameTick()); + + // Simulate clicking on the STASH + MenuOptionClicked menuOptionClicked = new MenuOptionClicked(); + menuOptionClicked.setMenuOption("Search"); + menuOptionClicked.setMenuTarget("STASH unit (easy)"); + menuOptionClicked.setId(NullObjectID.NULL_28983); + plugin.onMenuOptionClicked(menuOptionClicked); + + // Check that the STASH is stored after withdrawing + ChatMessage withdrawMessage = new ChatMessage(); + withdrawMessage.setType(ChatMessageType.GAMEMESSAGE); + withdrawMessage.setMessage("You withdraw your items from the STASH unit."); + plugin.onChatMessage(withdrawMessage); + assertNotNull(plugin.getActiveSTASHClue()); + + // Complete the step and get a new step, check that the clue is stored for rendering + when(clueWidget.getText()).thenReturn("Talk to the bartender of the Rusty Anchor in Port Sarim."); + plugin.onGameTick(new GameTick()); + assertNotNull(plugin.getActiveSTASHClue()); + + // Simulate depositing the emote items, make sure it's cleared the stored clue + ChatMessage depositMessage = new ChatMessage(); + depositMessage.setType(ChatMessageType.GAMEMESSAGE); + depositMessage.setMessage("You deposit your items into the STASH unit."); + plugin.onChatMessage(depositMessage); + assertNull(plugin.getActiveSTASHClue()); + + // Make sure that the STASH won't get re-marked if it's not part of the active clue. + plugin.onMenuOptionClicked(menuOptionClicked); + plugin.onChatMessage(withdrawMessage); + assertNull(plugin.getActiveSTASHClue()); + } } From 2e5d2a9b5fb4d4fdaa4813c6e0dd99edb29a968c Mon Sep 17 00:00:00 2001 From: Hydrox6 Date: Wed, 28 Apr 2021 20:30:10 +0100 Subject: [PATCH 03/18] chat commands: add support for tempoross pb messages --- .../chatcommands/ChatCommandsPlugin.java | 4 +- .../chatcommands/ChatCommandsPluginTest.java | 44 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index f37b892039..33f282d513 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -100,8 +100,8 @@ public class ChatCommandsPlugin extends Plugin private static final Pattern RAIDS_DURATION_PATTERN = Pattern.compile("Congratulations - your raid is complete!
Team size: " + COX_TEAM_SIZES + " Duration: [0-9:.]+ Personal best: (?[0-9:]+(?:\\.[0-9]+)?)"); private static final Pattern TOB_WAVE_PB_PATTERN = Pattern.compile("^.*Theatre of Blood wave completion time: (?[0-9:]+(?:\\.[0-9]+)?) \\(Personal best!\\)"); private static final Pattern TOB_WAVE_DURATION_PATTERN = Pattern.compile("^.*Theatre of Blood wave completion time: [0-9:.]+
Personal best: (?[0-9:]+(?:\\.[0-9]+)?)"); - private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("(?i)^(?:Fight |Lap |Challenge |Corrupted challenge )?duration: [0-9:.]+\\. Personal best: (?:)?(?[0-9:]+(?:\\.[0-9]+)?)"); - private static final Pattern NEW_PB_PATTERN = Pattern.compile("(?i)^(?:Fight |Lap |Challenge |Corrupted challenge )?duration: (?[0-9:]+(?:\\.[0-9]+)?) \\(new personal best\\)"); + private static final Pattern KILL_DURATION_PATTERN = Pattern.compile("(?i)^(?:(?:Fight |Lap |Challenge |Corrupted challenge )?duration:|Subdued in) [0-9:.]+\\. Personal best: (?:)?(?[0-9:]+(?:\\.[0-9]+)?)"); + private static final Pattern NEW_PB_PATTERN = Pattern.compile("(?i)^(?:(?:Fight |Lap |Challenge |Corrupted challenge )?duration:|Subdued in) (?[0-9:]+(?:\\.[0-9]+)?) \\(new personal best\\)"); private static final Pattern DUEL_ARENA_WINS_PATTERN = Pattern.compile("You (were defeated|won)! You have(?: now)? won (\\d+) duels?"); private static final Pattern DUEL_ARENA_LOSSES_PATTERN = Pattern.compile("You have(?: now)? lost (\\d+) duels?"); private static final Pattern ADVENTURE_LOG_TITLE_PATTERN = Pattern.compile("The Exploits of (.+)"); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java index 9967e9e661..775470f944 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java @@ -906,6 +906,50 @@ public class ChatCommandsPluginTest verify(configManager).setRSProfileConfiguration("personalbest", "TzHaar-Ket-Rak's First Challenge".toLowerCase(), 59.2); } + @Test + public void testTemporossNewPb() + { + ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Subdued in 6:35 (new personal best).", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Tempoross kill count is: 60.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + verify(configManager).setRSProfileConfiguration("killcount", "tempoross", 60); + verify(configManager).setRSProfileConfiguration("personalbest", "tempoross", 6 * 60 + 35.0); + + // Precise times + chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Subdued in 5:20.60 (new personal best).", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Tempoross kill count is: 60.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + verify(configManager).setRSProfileConfiguration("personalbest", "tempoross", 5 * 60 + 20.6); + } + + @Test + public void testTemporossNoPb() + { + ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Subdued in 7:40. Personal best: 5:38.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Tempoross kill count is: 55.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + verify(configManager).setRSProfileConfiguration("killcount", "tempoross", 55); + verify(configManager).setRSProfileConfiguration("personalbest", "tempoross", 5 * 60 + 38.0); + + // Precise times + chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Subdued in 6:19.80. Personal best: 5:42.60.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Tempoross kill count is: 55.", null, 0); + chatCommandsPlugin.onChatMessage(chatMessage); + + verify(configManager).setRSProfileConfiguration("personalbest", "tempoross", 5 * 60 + 42.6); + } + @Test public void testTimeStringToSeconds() { From 37895bd55494fdd86f1c68207ee52750743c1e52 Mon Sep 17 00:00:00 2001 From: molo-pl <62616086+molo-pl@users.noreply.github.com> Date: Sun, 2 May 2021 17:18:19 +0200 Subject: [PATCH 04/18] menu entry swapper: add Tempoross leave swap --- .../menuentryswapper/MenuEntrySwapperConfig.java | 11 +++++++++++ .../menuentryswapper/MenuEntrySwapperPlugin.java | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java index 30d54bfb65..cd9b9abc31 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperConfig.java @@ -661,4 +661,15 @@ public interface MenuEntrySwapperConfig extends Config { return false; } + + @ConfigItem( + keyName = "swapTemporossLeave", + name = "Tempoross Leave", + description = "Swap Talk-to with Leave after subduing Tempoross", + section = npcSection + ) + default boolean swapTemporossLeave() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java index 7f6148cf59..eaa1795f4f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/menuentryswapper/MenuEntrySwapperPlugin.java @@ -131,6 +131,13 @@ public class MenuEntrySwapperPlugin extends Plugin "brimstail" ); + private static final Set TEMPOROSS_NPCS = ImmutableSet.of( + "captain dudi", + "captain pudi", + "first mate deri", + "first mate peri" + ); + @Inject private Client client; @@ -222,6 +229,7 @@ public class MenuEntrySwapperPlugin extends Plugin swap("talk-to", ESSENCE_MINE_NPCS::contains, "teleport", config::swapEssenceMineTeleport); swap("talk-to", "collect", config::swapCollectMiscellania); swap("talk-to", "deposit-items", config::swapDepositItems); + swap("talk-to", TEMPOROSS_NPCS::contains, "leave", config::swapTemporossLeave); swap("leave tomb", "quick-leave", config::swapQuickLeave); swap("tomb door", "quick-leave", config::swapQuickLeave); From dd3fd8645c8aa68bb7f0335db804ca117368cbc0 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 2 May 2021 12:24:00 -0400 Subject: [PATCH 05/18] chat message manager: add default color for friendschatnotification chat type This allows the config value for friends chat notifications to just default to null, allowing plugins to detect whether or not we want to override the default color for friends chat notification messages. --- .../client/chat/ChatMessageManager.java | 2 + .../client/config/ChatColorConfig.java | 15 ++------ .../client/chat/ChatMessageManagerTest.java | 37 +++++++++++++++++++ 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java index bc3cfc96e7..3d14b7a5c4 100644 --- a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java +++ b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java @@ -231,6 +231,7 @@ public class ChatMessageManager case OBJECT_EXAMINE: case NPC_EXAMINE: case CONSOLE: + case FRIENDSCHATNOTIFICATION: return JagexColors.CHAT_GAME_EXAMINE_TEXT_OPAQUE_BACKGROUND; } } @@ -251,6 +252,7 @@ public class ChatMessageManager case OBJECT_EXAMINE: case NPC_EXAMINE: case CONSOLE: + case FRIENDSCHATNOTIFICATION: return JagexColors.CHAT_GAME_EXAMINE_TEXT_TRANSPARENT_BACKGROUND; } } diff --git a/runelite-client/src/main/java/net/runelite/client/config/ChatColorConfig.java b/runelite-client/src/main/java/net/runelite/client/config/ChatColorConfig.java index 30666249eb..d24d952435 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ChatColorConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ChatColorConfig.java @@ -25,7 +25,6 @@ package net.runelite.client.config; import java.awt.Color; -import net.runelite.client.ui.JagexColors; @ConfigGroup("textrecolor") public interface ChatColorConfig extends Config @@ -111,15 +110,12 @@ public interface ChatColorConfig extends Config @ConfigItem( position = 7, - keyName = "opaqueClanChatInfo", + keyName = "opaqueFriendsChatInfo", name = "Friends chat info", description = "Friends Chat Information (eg. when joining a channel)", section = opaqueSection ) - default Color opaqueFriendsChatInfo() - { - return JagexColors.CHAT_GAME_EXAMINE_TEXT_OPAQUE_BACKGROUND; - } + Color opaqueFriendsChatInfo(); @ConfigItem( position = 8, @@ -387,15 +383,12 @@ public interface ChatColorConfig extends Config @ConfigItem( position = 57, - keyName = "transparentClanChatInfo", + keyName = "transparentFriendsChatInfo", name = "Friends chat info (transparent)", description = "Friends chat information (eg. when joining a channel) (transparent)", section = transparentSection ) - default Color transparentFriendsChatInfo() - { - return JagexColors.CHAT_GAME_EXAMINE_TEXT_TRANSPARENT_BACKGROUND; - } + Color transparentFriendsChatInfo(); @ConfigItem( position = 58, diff --git a/runelite-client/src/test/java/net/runelite/client/chat/ChatMessageManagerTest.java b/runelite-client/src/test/java/net/runelite/client/chat/ChatMessageManagerTest.java index 6bdb200694..97b2caaef0 100644 --- a/runelite-client/src/test/java/net/runelite/client/chat/ChatMessageManagerTest.java +++ b/runelite-client/src/test/java/net/runelite/client/chat/ChatMessageManagerTest.java @@ -145,4 +145,41 @@ public class ChatMessageManagerTest verify(messageNode).setName("" + friendName + ""); } + + @Test + public void testDefaultFriendsChatInfoColors() + { + // no color is configured for opaqueFriendsChatInfo + when(chatColorConfig.opaqueFriendsChatInfoHighlight()).thenReturn(Color.RED); + + // rebuild color cache + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup("textrecolor"); + chatMessageManager.onConfigChanged(configChanged); + + String chatMessage = new ChatMessageBuilder() + .append(ChatColorType.NORMAL) + .append("Total points: ") + .append(ChatColorType.HIGHLIGHT) + .append("42") + .append(ChatColorType.NORMAL) + .append(", Personal points: ") + .append(ChatColorType.HIGHLIGHT) + .append("43") + .append(ChatColorType.NORMAL) + .append(" (") + .append(ChatColorType.HIGHLIGHT) + .append("44") + .append(ChatColorType.NORMAL) + .append("%)") + .build(); + + MessageNode messageNode = mock(MessageNode.class); + when(messageNode.getType()).thenReturn(ChatMessageType.FRIENDSCHATNOTIFICATION); + when(messageNode.getRuneLiteFormatMessage()).thenReturn(chatMessage); + + chatMessageManager.update(messageNode); + + verify(messageNode).setValue("Total points: 42, Personal points: 43 (44%)"); + } } \ No newline at end of file From c45d98edcbc6bf35bdcbe4aa95a9cc3e559016f9 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 2 May 2021 11:46:15 -0400 Subject: [PATCH 06/18] friends chat: use friendschatinfo color for join/part messages --- .../plugins/friendschat/FriendsChatPlugin.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/friendschat/FriendsChatPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/friendschat/FriendsChatPlugin.java index eda35b6578..a350f4521d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/friendschat/FriendsChatPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/friendschat/FriendsChatPlugin.java @@ -26,6 +26,7 @@ */ package net.runelite.client.plugins.friendschat; +import com.google.common.base.MoreObjects; import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.common.util.concurrent.Runnables; @@ -71,6 +72,7 @@ import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetType; import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatMessageBuilder; +import net.runelite.client.config.ChatColorConfig; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; @@ -119,6 +121,9 @@ public class FriendsChatPlugin extends Plugin @Inject private ChatboxPanelManager chatboxPanelManager; + @Inject + private ChatColorConfig chatColorConfig; + private List chats = new ArrayList<>(); private final List members = new ArrayList<>(); private MembersIndicator membersIndicator; @@ -388,14 +393,19 @@ public class FriendsChatPlugin extends Plugin { final String activityMessage = activityType == ActivityType.JOINED ? " has joined." : " has left."; final FriendsChatRank rank = member.getRank(); - Color textColor = CHAT_FC_TEXT_OPAQUE_BACKGROUND; - Color channelColor = CHAT_FC_NAME_OPAQUE_BACKGROUND; + final Color textColor, channelColor; int rankIcon = -1; + // Use configured friends chat info colors if set, otherwise default to the jagex text and fc name colors if (client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1) { - textColor = CHAT_FC_TEXT_TRANSPARENT_BACKGROUND; - channelColor = CHAT_FC_NAME_TRANSPARENT_BACKGROUND; + textColor = MoreObjects.firstNonNull(chatColorConfig.transparentFriendsChatInfo(), CHAT_FC_TEXT_TRANSPARENT_BACKGROUND); + channelColor = MoreObjects.firstNonNull(chatColorConfig.transparentFriendsChatChannelName(), CHAT_FC_NAME_TRANSPARENT_BACKGROUND); + } + else + { + textColor = MoreObjects.firstNonNull(chatColorConfig.opaqueFriendsChatInfo(), CHAT_FC_TEXT_OPAQUE_BACKGROUND); + channelColor = MoreObjects.firstNonNull(chatColorConfig.opaqueFriendsChatChannelName(), CHAT_FC_NAME_OPAQUE_BACKGROUND); } if (config.chatIcons() && rank != null && rank != FriendsChatRank.UNRANKED) From 5b12bcc907f9ce7c0ebf963fa8bc1d990152250f Mon Sep 17 00:00:00 2001 From: aHooder <831317+aHooder@users.noreply.github.com> Date: Fri, 30 Apr 2021 23:49:14 +0200 Subject: [PATCH 07/18] gpu: workaround for forced anti-aliasing Forced anti-aliasing by the GPU applies multisampling to the default framebuffer, and when blitting between two multisampled FBOs, the number of samples in both FBOs has to match. In order to make sure our anti-aliasing FBO has the same number of samples as the default FBO, we bind the default FBO and check whether its number of samples is non-zero. If it is, use this as the number of samples for our anti-aliasing FBO instead of getting it from the configured anti-aliasing mode. Co-authored-by: Adam --- .../java/net/runelite/client/plugins/gpu/GpuPlugin.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java index 8ba9db5a67..fd35d806b3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java @@ -1078,8 +1078,14 @@ public class GpuPlugin extends Plugin implements DrawCallbacks { shutdownAAFbo(); + // Bind default FBO to check whether anti-aliasing is forced + gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0); + final int forcedAASamples = glGetInteger(gl, gl.GL_SAMPLES); final int maxSamples = glGetInteger(gl, gl.GL_MAX_SAMPLES); - final int samples = Math.min(antiAliasingMode.getSamples(), maxSamples); + final int samples = forcedAASamples != 0 ? forcedAASamples : + Math.min(antiAliasingMode.getSamples(), maxSamples); + + log.debug("AA samples: {}, max samples: {}, forced samples: {}", samples, maxSamples, forcedAASamples); initAAFbo(stretchedCanvasWidth, stretchedCanvasHeight, samples); From 7f1baba7d8364d61cf7b713ab49586cbf5932729 Mon Sep 17 00:00:00 2001 From: Amit G <17098942+pristit@users.noreply.github.com> Date: Mon, 3 May 2021 07:44:23 +0300 Subject: [PATCH 08/18] SkillChallengeClue: Support inactive crystal tools (#13517) --- .../plugins/cluescrolls/clues/SkillChallengeClue.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java index 8fcb132123..570943cb57 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java @@ -87,7 +87,8 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam item(ItemID.INFERNAL_PICKAXE_UNCHARGED_25369), item(ItemID.GILDED_PICKAXE), item(ItemID._3RD_AGE_PICKAXE), - item(ItemID.CRYSTAL_PICKAXE) + item(ItemID.CRYSTAL_PICKAXE), + item(ItemID.CRYSTAL_PICKAXE_INACTIVE) ); private static final AnyRequirementCollection ANY_AXE = any("Any Axe", @@ -106,7 +107,8 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam item(ItemID.INFERNAL_AXE_UNCHARGED_25371), item(ItemID.GILDED_AXE), item(ItemID._3RD_AGE_AXE), - item(ItemID.CRYSTAL_AXE) + item(ItemID.CRYSTAL_AXE), + item(ItemID.CRYSTAL_AXE_INACTIVE) ); private static final AnyRequirementCollection ANY_HARPOON = any("Harpoon", @@ -118,7 +120,8 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam item(ItemID.INFERNAL_HARPOON_OR), item(ItemID.INFERNAL_HARPOON_UNCHARGED), item(ItemID.INFERNAL_HARPOON_UNCHARGED_25367), - item(ItemID.CRYSTAL_HARPOON) + item(ItemID.CRYSTAL_HARPOON), + item(ItemID.CRYSTAL_HARPOON_INACTIVE) ); private static final Set CLUES = ImmutableSet.of( From e6d45bd67a094779d0a0ca672260dab9213273fa Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Sun, 2 May 2021 22:58:27 -0700 Subject: [PATCH 09/18] HotColdLocation: Fix Seers' Village bank spot Ref: #9601 --- .../plugins/cluescrolls/clues/hotcold/HotColdLocation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java index 3baeee926c..ab01f4b3e3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java @@ -100,7 +100,7 @@ public enum HotColdLocation KANDARIN_SINCLAR_MANSION(new WorldPoint(2730, 3588, 0), KANDARIN, "North-west of the Sinclair Mansion, near the log balance shortcut.", BRASSICAN_MAGE), KANDARIN_CATHERBY(new WorldPoint(2774, 3436, 0), KANDARIN, "Catherby, between the bank and the beehives, near small rock formation.", BRASSICAN_MAGE), KANDARIN_GRAND_TREE(new WorldPoint(2448, 3503, 0), KANDARIN, "Grand Tree, just east of the terrorchick gnome enclosure.", BRASSICAN_MAGE), - KANDARIN_SEERS(new WorldPoint(2735, 3486, 0), KANDARIN, "Between the Seers' Village bank and Camelot.", BRASSICAN_MAGE), + KANDARIN_SEERS(new WorldPoint(2732, 3485, 0), KANDARIN, "Outside Seers' Village bank.", BRASSICAN_MAGE), KANDARIN_MCGRUBORS_WOOD(new WorldPoint(2653, 3485, 0), KANDARIN, "McGrubor's Wood", BRASSICAN_MAGE), KANDARIN_FISHING_BUILD(new WorldPoint(2590, 3369, 0), KANDARIN, "South of Fishing Guild", BRASSICAN_MAGE), KANDARIN_WITCHHAVEN(new WorldPoint(2707, 3306, 0), KANDARIN, "Outside Witchaven, west of Jeb, Holgart, and Caroline.", BRASSICAN_MAGE), From 491df445e92265c1e93f9788a97f33bcc1272bc8 Mon Sep 17 00:00:00 2001 From: Nicholas Anzalone <36175767+nganzalo@users.noreply.github.com> Date: Mon, 3 May 2021 02:53:23 -0400 Subject: [PATCH 10/18] skill calc: Add battlesaff to fletching calculator (#13525) --- .../client/plugins/skillcalculator/skill_fletching.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_fletching.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_fletching.json index 60214cc263..bb6e56fc59 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_fletching.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_fletching.json @@ -210,6 +210,12 @@ "name": "Willow Longbow", "xp": 41.5 }, + { + "level": 40, + "icon": 1391, + "name": "Battlestaff", + "xp": 80 + }, { "level": 41, "icon": 880, From 3ea7d90bde83a5903f6b78ae40f5eabf95d09b91 Mon Sep 17 00:00:00 2001 From: Matt Dennis Date: Mon, 3 May 2021 02:55:07 -0400 Subject: [PATCH 11/18] examine: Improve plugin description and tags (#13399) --- .../net/runelite/client/plugins/examine/ExaminePlugin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java index 72e7f4a085..5e1914b173 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/examine/ExaminePlugin.java @@ -68,8 +68,8 @@ import okhttp3.OkHttpClient; */ @PluginDescriptor( name = "Examine", - description = "Send examine information to the API", - tags = {"npcs", "items", "inventory", "objects"} + description = "Shows additional examine information (eg. GE Average, HA Value)", + tags = {"npcs", "items", "inventory", "objects", "prices", "high alchemy"} ) @Slf4j public class ExaminePlugin extends Plugin From b71759d598542ce345f854f45eae4bcff5c43395 Mon Sep 17 00:00:00 2001 From: Hydrox Date: Mon, 3 May 2021 08:28:07 +0100 Subject: [PATCH 12/18] Update discord invite links to start users in #welcome (#13549) --- .github/CONTRIBUTING.md | 4 ++-- README.md | 4 ++-- .../main/resources/net/runelite/client/runelite.properties | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 5d463d8bcf..8f0c7b7a03 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -14,7 +14,7 @@ Here are the guidelines we'd like you to follow: ## Got a Question or Problem? -If you have questions about how to contribute to runelite, please join our [Discord](https://discord.gg/mePCs8U) server. +If you have questions about how to contribute to runelite, please join our [Discord](https://discord.gg/ArdAhnN) server. ## Found an Issue? @@ -131,4 +131,4 @@ To ensure consistency throughout the source code, review our [code conventions]( [github]: https://github.com/runelite/runelite -[discord]: https://discord.gg/mePCs8U +[discord]: https://discord.gg/ArdAhnN diff --git a/README.md b/README.md index fa74cfbdce..04a036953b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ ![](https://runelite.net/img/logo.png) -# runelite [![CI](https://github.com/runelite/runelite/workflows/CI/badge.svg)](https://github.com/runelite/runelite/actions?query=workflow%3ACI+branch%3Amaster) [![Discord](https://img.shields.io/discord/301497432909414422.svg)](https://discord.gg/mePCs8U) +# runelite [![CI](https://github.com/runelite/runelite/workflows/CI/badge.svg)](https://github.com/runelite/runelite/actions?query=workflow%3ACI+branch%3Amaster) [![Discord](https://img.shields.io/discord/301497432909414422.svg)](https://discord.gg/ArdAhnN) RuneLite is a free, open source OldSchool RuneScape client. -If you have any questions, please join our IRC channel on [irc.rizon.net #runelite](http://qchat.rizon.net/?channels=runelite&uio=d4) or alternatively our [Discord](https://discord.gg/mePCs8U) server. +If you have any questions, please join our IRC channel on [irc.rizon.net #runelite](http://qchat.rizon.net/?channels=runelite&uio=d4) or alternatively our [Discord](https://discord.gg/ArdAhnN) server. ## Project Layout diff --git a/runelite-client/src/main/resources/net/runelite/client/runelite.properties b/runelite-client/src/main/resources/net/runelite/client/runelite.properties index e17aafef18..e5f37e2fe7 100644 --- a/runelite-client/src/main/resources/net/runelite/client/runelite.properties +++ b/runelite-client/src/main/resources/net/runelite/client/runelite.properties @@ -1,7 +1,7 @@ runelite.title=RuneLite runelite.version=${project.version} runelite.discord.appid=409416265891971072 -runelite.discord.invite=https://discord.gg/R4BQ8tU +runelite.discord.invite=https://discord.gg/ArdAhnN runelite.github.link=https://github.com/runelite runelite.wiki.link=https://github.com/runelite/runelite/wiki runelite.patreon.link=https://www.patreon.com/runelite From e41de4ca2a1538330164c7abf3b96c43a67389b8 Mon Sep 17 00:00:00 2001 From: Cyborger1 <45152844+Cyborger1@users.noreply.github.com> Date: Mon, 3 May 2021 03:31:22 -0400 Subject: [PATCH 13/18] SkillChallengeClue: Add Gold shade keys to Fiyr shade step (#13260) --- .../client/plugins/cluescrolls/clues/SkillChallengeClue.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java index 570943cb57..53dde73781 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java @@ -205,7 +205,10 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam new SkillChallengeClue("Chop a redwood log.", "chop a redwood log whilst sporting the finest lumberjack gear.", true, ANY_AXE, all("Lumberjack outfit", item(ItemID.LUMBERJACK_HAT), item(ItemID.LUMBERJACK_TOP), item(ItemID.LUMBERJACK_LEGS), item(ItemID.LUMBERJACK_BOOTS))), new SkillChallengeClue("Craft a light orb in the Dorgesh-Kaan bank.", item(ItemID.CAVE_GOBLIN_WIRE), item(ItemID.EMPTY_LIGHT_ORB)), new SkillChallengeClue("Kill a reanimated Abyssal Demon.", "kill a reanimated abyssal.", xOfItem(ItemID.SOUL_RUNE, 4), xOfItem(ItemID.BLOOD_RUNE, 2), any("Nature Rune x4", xOfItem(ItemID.NATURE_RUNE, 4), item(ItemID.BRYOPHYTAS_STAFF)), range("Ensouled abyssal head", ItemID.ENSOULED_ABYSSAL_HEAD, ItemID.ENSOULED_ABYSSAL_HEAD_13508)), - new SkillChallengeClue("Kill a Fiyr shade inside Mort'tons shade catacombs.", any("Any Silver Shade Key", item(ItemID.SILVER_KEY_RED), item(ItemID.SILVER_KEY_BROWN), item(ItemID.SILVER_KEY_CRIMSON), item(ItemID.SILVER_KEY_BLACK), item(ItemID.SILVER_KEY_PURPLE))) + new SkillChallengeClue("Kill a Fiyr shade inside Mort'tons shade catacombs.", + any("Any Gold or Silver Shade Key", + item(ItemID.GOLD_KEY_RED), item(ItemID.GOLD_KEY_BROWN), item(ItemID.GOLD_KEY_CRIMSON), item(ItemID.GOLD_KEY_BLACK), item(ItemID.GOLD_KEY_PURPLE), + item(ItemID.SILVER_KEY_RED), item(ItemID.SILVER_KEY_BROWN), item(ItemID.SILVER_KEY_CRIMSON), item(ItemID.SILVER_KEY_BLACK), item(ItemID.SILVER_KEY_PURPLE))) ); private final ChallengeType type; From 200d23b0c1b615a7a40e415888454990173095c8 Mon Sep 17 00:00:00 2001 From: LlemonDuck Date: Mon, 3 May 2021 03:33:44 -0400 Subject: [PATCH 14/18] clues: Fix location of Captain Bleemadge (#13531) --- .../runelite/client/plugins/cluescrolls/clues/CrypticClue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java index 4104c87d04..3cde11fec9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java @@ -79,7 +79,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("Stop crying! Talk to the head.", "Head mourner", new WorldPoint(2042, 4630, 0), "Talk to the Head mourner in the mourner headquarters in West Ardougne."), new CrypticClue("Search the crate near a cart in Port Khazard.", CRATE_366, new WorldPoint(2660, 3149, 0), "Search by the southern Khazard General Store in Port Khazard."), new CrypticClue("Speak to the bartender of the Blue Moon Inn in Varrock.", "Bartender", new WorldPoint(3226, 3399, 0), "Talk to the bartender in Blue Moon Inn in Varrock."), - new CrypticClue("This aviator is at the peak of his profession.", "Captain Bleemadge", new WorldPoint(2846, 1749, 0), "Captain Bleemadge, the gnome glider pilot, is found at the top of White Wolf Mountain."), + new CrypticClue("This aviator is at the peak of his profession.", "Captain Bleemadge", new WorldPoint(2847, 3499, 0), "Captain Bleemadge, the gnome glider pilot, is found at the top of White Wolf Mountain."), new CrypticClue("Search the crates in the shed just north of East Ardougne.", CRATE_355, new WorldPoint(2617, 3347, 0), "The crates in the shed north of the northern Ardougne bank."), new CrypticClue("I wouldn't wear this jean on my legs.", "Father Jean", new WorldPoint(1734, 3576, 0), "Talk to father Jean in the Hosidius church."), new CrypticClue("Search the crate in the Toad and Chicken pub.", CRATE_354, new WorldPoint(2913, 3536, 0), "The Toad and Chicken pub is located in Burthorpe."), From 91bac5821a1adb172157bd45e2f0d6eae7185b04 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 4 May 2021 10:29:51 -0400 Subject: [PATCH 15/18] agility plugin: add rellekka lighthouse obstacles --- .../net/runelite/client/plugins/agility/AgilityConfig.java | 2 +- .../runelite/client/plugins/agility/AgilityOverlay.java | 2 +- .../net/runelite/client/plugins/agility/AgilityPlugin.java | 2 +- .../net/runelite/client/plugins/agility/Obstacles.java | 7 +++++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityConfig.java index c68530ec95..0e2af795d1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityConfig.java @@ -45,7 +45,7 @@ public interface AgilityConfig extends Config @ConfigItem( keyName = "showClickboxes", name = "Show Clickboxes", - description = "Show agility course obstacle clickboxes", + description = "Show agility course and other obstacle clickboxes", position = 0 ) default boolean showClickboxes() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityOverlay.java index 6a45b399d4..7612c5b662 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityOverlay.java @@ -79,7 +79,7 @@ class AgilityOverlay extends Overlay { if (Obstacles.SHORTCUT_OBSTACLE_IDS.containsKey(object.getId()) && !config.highlightShortcuts() || Obstacles.TRAP_OBSTACLE_IDS.contains(object.getId()) && !config.showTrapOverlay() || - Obstacles.COURSE_OBSTACLE_IDS.contains(object.getId()) && !config.showClickboxes() || + Obstacles.OBSTACLE_IDS.contains(object.getId()) && !config.showClickboxes() || Obstacles.SEPULCHRE_OBSTACLE_IDS.contains(object.getId()) && !config.highlightSepulchreObstacles() || Obstacles.SEPULCHRE_SKILL_OBSTACLE_IDS.contains(object.getId()) && !config.highlightSepulchreSkilling()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java index b79de676b2..ae6494f867 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java @@ -434,7 +434,7 @@ public class AgilityPlugin extends Plugin return; } - if (Obstacles.COURSE_OBSTACLE_IDS.contains(newObject.getId()) || + if (Obstacles.OBSTACLE_IDS.contains(newObject.getId()) || Obstacles.PORTAL_OBSTACLE_IDS.contains(newObject.getId()) || (Obstacles.TRAP_OBSTACLE_IDS.contains(newObject.getId()) && Obstacles.TRAP_OBSTACLE_REGIONS.contains(newObject.getWorldLocation().getRegionID())) || diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacles.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacles.java index dd8809820b..98115f316f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacles.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/Obstacles.java @@ -36,7 +36,7 @@ import net.runelite.client.game.AgilityShortcut; class Obstacles { - static final Set COURSE_OBSTACLE_IDS = ImmutableSet.of( + static final Set OBSTACLE_IDS = ImmutableSet.of( // Gnome OBSTACLE_NET_23134, TREE_BRANCH_23559, TREE_BRANCH_23560, OBSTACLE_NET_23135, OBSTACLE_PIPE_23138, OBSTACLE_PIPE_23139, LOG_BALANCE_23145, BALANCING_ROPE_23557, @@ -95,7 +95,10 @@ class Obstacles ZIP_LINE_11645, ZIP_LINE_11646, // Prifddinas LADDER_36221, TIGHTROPE_36225, CHIMNEY_36227, ROOF_EDGE, DARK_HOLE_36229, LADDER_36231, LADDER_36232, - ROPE_BRIDGE_36233, TIGHTROPE_36234, ROPE_BRIDGE_36235, TIGHTROPE_36236, TIGHTROPE_36237, DARK_HOLE_36238 + ROPE_BRIDGE_36233, TIGHTROPE_36234, ROPE_BRIDGE_36235, TIGHTROPE_36236, TIGHTROPE_36237, DARK_HOLE_36238, + // Rellekka Lighthouse + BASALT_ROCK, BASALT_ROCK_4553, BASALT_ROCK_4554, BASALT_ROCK_4556, BASALT_ROCK_4558, ROCKY_SHORE, + BASALT_ROCK_4557, BASALT_ROCK_4555, BASALT_ROCK_4552, BEACH ); static final Set PORTAL_OBSTACLE_IDS = ImmutableSet.of( From 502895979d4b9e61fb0958b572c9ec86f05b1aff Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Mon, 15 Feb 2021 22:00:04 -0800 Subject: [PATCH 16/18] menu manager: add menu entries in insert order --- .../runelite/client/menus/MenuManager.java | 39 +++-- .../client/menus/MenuManagerTest.java | 135 ++++++++++++++++++ 2 files changed, 161 insertions(+), 13 deletions(-) create mode 100644 runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index f8e084f0d0..f5b76b335b 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -90,9 +90,9 @@ public class MenuManager managedMenuOptions.remove(customMenuOption.getWidgetId(), customMenuOption); } - private boolean menuContainsCustomMenu(WidgetMenuOption customMenuOption) + private static boolean menuContainsCustomMenu(MenuEntry[] menuEntries, WidgetMenuOption customMenuOption) { - for (MenuEntry menuEntry : client.getMenuEntries()) + for (MenuEntry menuEntry : menuEntries) { String option = menuEntry.getOption(); String target = menuEntry.getTarget(); @@ -115,23 +115,36 @@ public class MenuManager int widgetId = event.getActionParam1(); Collection options = managedMenuOptions.get(widgetId); + if (options.isEmpty()) + { + return; + } + MenuEntry[] menuEntries = client.getMenuEntries(); + + MenuEntry[] newMenuEntries = Arrays.copyOf(menuEntries, menuEntries.length + options.size()); + // Menu entries are sorted with higher-index entries appearing toward the top of the minimenu, so insert older + // managed menu entries at higher indices and work backward for newer entries so newly-added entries appear at + // the bottom + int insertIdx = newMenuEntries.length - 1; for (WidgetMenuOption currentMenu : options) { - if (!menuContainsCustomMenu(currentMenu))//Don't add if we have already added it to this widget + // Exit if we've inserted the managed menu entries already + if (menuContainsCustomMenu(menuEntries, currentMenu)) { - MenuEntry[] menuEntries = client.getMenuEntries(); - menuEntries = Arrays.copyOf(menuEntries, menuEntries.length + 1); - - MenuEntry menuEntry = menuEntries[menuEntries.length - 1] = new MenuEntry(); - menuEntry.setOption(currentMenu.getMenuOption()); - menuEntry.setParam1(widgetId); - menuEntry.setTarget(currentMenu.getMenuTarget()); - menuEntry.setType(MenuAction.RUNELITE.getId()); - - client.setMenuEntries(menuEntries); + return; } + + MenuEntry menuEntry = new MenuEntry(); + menuEntry.setOption(currentMenu.getMenuOption()); + menuEntry.setParam1(widgetId); + menuEntry.setTarget(currentMenu.getMenuTarget()); + menuEntry.setType(MenuAction.RUNELITE.getId()); + + newMenuEntries[insertIdx--] = menuEntry; } + + client.setMenuEntries(newMenuEntries); } public void addPlayerMenuItem(String menuText) diff --git a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java new file mode 100644 index 0000000000..891170ca48 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2021, Jordan Atwood + * 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.menus; + +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.Client; +import net.runelite.api.MenuAction; +import static net.runelite.api.MenuAction.CC_OP; +import static net.runelite.api.MenuAction.RUNELITE; +import net.runelite.api.MenuEntry; +import net.runelite.api.events.MenuEntryAdded; +import static net.runelite.api.widgets.WidgetInfo.WORLD_MAP_OPTION; +import net.runelite.client.util.Text; +import static org.junit.Assert.assertArrayEquals; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.doAnswer; +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 MenuManagerTest +{ + private static final MenuEntry CANCEL = new MenuEntry(); + + @Inject + private MenuManager menuManager; + + @Mock + @Bind + private Client client; + + private MenuEntry[] clientMenuEntries = {CANCEL}; + + @BeforeClass + public static void beforeClass() + { + CANCEL.setOption("Cancel"); + CANCEL.setType(MenuAction.CANCEL.getId()); + CANCEL.setParam1(WORLD_MAP_OPTION.getPackedId()); + } + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + doAnswer((Answer) invocationOnMock -> + { + clientMenuEntries = invocationOnMock.getArgument(0, MenuEntry[].class); + return null; + }).when(client).setMenuEntries(ArgumentMatchers.any(MenuEntry[].class)); + when(client.getMenuEntries()).thenAnswer((Answer) invocationMock -> clientMenuEntries); + } + + @Test + public void testManagedMenuOrder() + { + final MenuEntry first = new MenuEntry(); + final MenuEntry second = new MenuEntry(); + final MenuEntry third = new MenuEntry(); + first.setOption("Test"); + first.setTarget("First Entry"); + first.setParam1(WORLD_MAP_OPTION.getPackedId()); + first.setType(RUNELITE.getId()); + second.setOption("Test"); + second.setTarget("Second Entry"); + second.setParam1(WORLD_MAP_OPTION.getPackedId()); + second.setType(RUNELITE.getId()); + third.setOption("Test"); + third.setTarget("Third Entry"); + third.setParam1(WORLD_MAP_OPTION.getPackedId()); + third.setType(RUNELITE.getId()); + menuManager.addManagedCustomMenu(new WidgetMenuOption(first.getOption(), first.getTarget(), WORLD_MAP_OPTION)); + menuManager.addManagedCustomMenu(new WidgetMenuOption(second.getOption(), second.getTarget(), WORLD_MAP_OPTION)); + menuManager.addManagedCustomMenu(new WidgetMenuOption(third.getOption(), third.getTarget(), WORLD_MAP_OPTION)); + + menuManager.onMenuEntryAdded(new MenuEntryAdded( + CANCEL.getOption(), + CANCEL.getTarget(), + CC_OP.getId(), + CANCEL.getIdentifier(), + CANCEL.getParam0(), + CANCEL.getParam1())); + + ArgumentCaptor captor = ArgumentCaptor.forClass(MenuEntry[].class); + verify(client, atLeastOnce()).setMenuEntries(captor.capture()); + + final MenuEntry[] resultMenuEntries = captor.getValue(); + // Strip color tags from menu options before array comparison + for (MenuEntry resultEntry : resultMenuEntries) + { + final String resultTarget = resultEntry.getTarget(); + if (resultTarget != null) + { + resultEntry.setTarget(Text.removeTags(resultEntry.getTarget())); + } + } + + assertArrayEquals(new MenuEntry[]{CANCEL, third, second, first}, resultMenuEntries); + } +} From 217a5425d408dd22ab0ccf1f6e902886647cc342 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 6 May 2021 20:37:36 -0400 Subject: [PATCH 17/18] info: simplify language surrounding config import --- .../main/java/net/runelite/client/plugins/info/InfoPanel.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java index c59fa78798..5b4df7fe2e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java @@ -181,10 +181,10 @@ public class InfoPanel extends PluginPanel actionsContainer.setBorder(new EmptyBorder(10, 0, 0, 0)); actionsContainer.setLayout(new GridLayout(0, 1, 0, 10)); - syncPanel = buildLinkPanel(IMPORT_ICON, "Import local settings", "to remote RuneLite account", () -> + syncPanel = buildLinkPanel(IMPORT_ICON, "Import signed-out", "settings", () -> { final int result = JOptionPane.showOptionDialog(syncPanel, - "This will replace your current RuneLite account settings with settings from your local profile.", + "This will overwrite your settings with settings from your local profile, which
is the profile used when not logged into RuneLite with a RuneLite account.", "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, new String[]{"Yes", "No"}, "No"); From 7092c0a29ddbae48fccfe19d5406edd101a6ae35 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 4 Jun 2020 20:30:42 -0400 Subject: [PATCH 18/18] client: accept custom javconfig url --- .../src/main/java/net/runelite/client/RuneLite.java | 5 ++++- .../java/net/runelite/client/rs/ClientLoader.java | 12 ++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index aa6ef1e2e1..49ea8383a6 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -139,6 +139,9 @@ public class RuneLite parser.accepts("debug", "Show extra debugging output"); parser.accepts("safe-mode", "Disables external plugins and the GPU plugin"); parser.accepts("insecure-skip-tls-verification", "Disables TLS verification"); + parser.accepts("jav_config", "jav_config url") + .withRequiredArg() + .defaultsTo(RuneLiteProperties.getJavConfig()); final ArgumentAcceptingOptionSpec sessionfile = parser.accepts("sessionfile", "Use a specified session file") .withRequiredArg() @@ -204,7 +207,7 @@ public class RuneLite try { - final ClientLoader clientLoader = new ClientLoader(okHttpClient, options.valueOf(updateMode)); + final ClientLoader clientLoader = new ClientLoader(okHttpClient, options.valueOf(updateMode), (String) options.valueOf("jav_config")); new Thread(() -> { diff --git a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java index 6128c4474b..68b8d13c0f 100644 --- a/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/rs/ClientLoader.java @@ -87,15 +87,17 @@ public class ClientLoader implements Supplier private final ClientConfigLoader clientConfigLoader; private ClientUpdateCheckMode updateCheckMode; private final WorldSupplier worldSupplier; + private final String javConfigUrl; private Object client; - public ClientLoader(OkHttpClient okHttpClient, ClientUpdateCheckMode updateCheckMode) + public ClientLoader(OkHttpClient okHttpClient, ClientUpdateCheckMode updateCheckMode, String javConfigUrl) { this.okHttpClient = okHttpClient; this.clientConfigLoader = new ClientConfigLoader(okHttpClient); this.updateCheckMode = updateCheckMode; this.worldSupplier = new WorldSupplier(okHttpClient); + this.javConfigUrl = javConfigUrl; } @Override @@ -186,7 +188,7 @@ public class ClientLoader implements Supplier private RSConfig downloadConfig() throws IOException { - HttpUrl url = HttpUrl.parse(RuneLiteProperties.getJavConfig()); + HttpUrl url = HttpUrl.parse(javConfigUrl); IOException err = null; for (int attempt = 0; attempt < NUM_ATTEMPTS; attempt++) { @@ -204,6 +206,12 @@ public class ClientLoader implements Supplier catch (IOException e) { log.info("Failed to get jav_config from host \"{}\" ({})", url.host(), e.getMessage()); + + if (!javConfigUrl.equals(RuneLiteProperties.getJavConfig())) + { + throw e; + } + String host = worldSupplier.get().getAddress(); url = url.newBuilder().host(host).build(); err = e;