diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index 26a612456a..0dd69bffd6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -102,6 +102,10 @@ public class ScreenshotPlugin extends Plugin private static final Pattern VALUABLE_DROP_PATTERN = Pattern.compile(".*Valuable drop: ([^<>]+)(?:)?"); private static final Pattern UNTRADEABLE_DROP_PATTERN = Pattern.compile(".*Untradeable drop: ([^<>]+)(?:)?"); private static final Pattern DUEL_END_PATTERN = Pattern.compile("You have now (won|lost) ([0-9]+) duels?\\."); + private static final Pattern QUEST_PATTERN_1 = Pattern.compile(".+?ve\\.*? (?been|rebuilt|.+?ed)? ?(?:the )?'?(?.+?)'?(?: [Qq]uest)?[!.]?$"); + private static final Pattern QUEST_PATTERN_2 = Pattern.compile("'?(?.+?)'?(?: [Qq]uest)? (?[a-z]\\w+?ed)?(?: f.*?)?[!.]?$"); + private static final ImmutableList RFD_TAGS = ImmutableList.of("Another Cook", "freed", "defeated", "saved"); + private static final ImmutableList WORD_QUEST_IN_NAME_TAGS = ImmutableList.of("Another Cook", "Doric", "Heroes", "Legends", "Observatory", "Olaf", "Waterfall"); private static final ImmutableList PET_MESSAGES = ImmutableList.of("You have a funny feeling like you're being followed", "You feel something weird sneaking into your backpack", "You have a funny feeling like you would have been followed"); @@ -238,9 +242,8 @@ public class ScreenshotPlugin extends Plugin } else if (client.getWidget(WidgetInfo.QUEST_COMPLETED_NAME_TEXT) != null) { - // "You have completed The Corsair Curse!" String text = client.getWidget(WidgetInfo.QUEST_COMPLETED_NAME_TEXT).getText(); - fileName = "Quest(" + text.substring(19, text.length() - 1) + ")"; + fileName = parseQuestCompletedWidget(text); screenshotSubDir = "Quests"; } @@ -574,6 +577,50 @@ public class ScreenshotPlugin extends Plugin return skillName + "(" + skillLevel + ")"; } + /** + * Parses the passed quest completion dialog text into a shortened string for filename usage. + * + * @param text The {@link Widget#getText() text} of the {@link WidgetInfo#QUEST_COMPLETED_NAME_TEXT} widget. + * @return Shortened string in the format "Quest(The Corsair Curse)" + */ + @VisibleForTesting + static String parseQuestCompletedWidget(final String text) + { + // "You have completed The Corsair Curse!" + final Matcher questMatch1 = QUEST_PATTERN_1.matcher(text); + // "'One Small Favour' completed!" + final Matcher questMatch2 = QUEST_PATTERN_2.matcher(text); + final Matcher questMatchFinal = questMatch1.matches() ? questMatch1 : questMatch2; + if (!questMatchFinal.matches()) + { + return "Quest(quest not found)"; + } + + String quest = questMatchFinal.group("quest"); + String verb = questMatchFinal.group("verb") != null ? questMatchFinal.group("verb") : ""; + + if (verb.contains("kind of")) + { + quest += " partial completion"; + } + else if (verb.contains("completely")) + { + quest += " II"; + } + + if (RFD_TAGS.stream().anyMatch((quest + verb)::contains)) + { + quest = "Recipe for Disaster - " + quest; + } + + if (WORD_QUEST_IN_NAME_TAGS.stream().anyMatch(quest::contains)) + { + quest += " Quest"; + } + + return "Quest(" + quest + ')'; + } + /** * Saves a screenshot of the client window to the screenshot folder as a PNG, * and optionally uploads it to an image-hosting service. diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java index b7058d4092..2616db357e 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/screenshot/ScreenshotPluginTest.java @@ -245,4 +245,17 @@ public class ScreenshotPluginTest 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!")); + } }