diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/strongholdofsecurity/StrongholdAnswer.java b/runelite-client/src/main/java/net/runelite/client/plugins/strongholdofsecurity/StrongholdAnswer.java new file mode 100644 index 0000000000..3386588874 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/strongholdofsecurity/StrongholdAnswer.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2019, FlaxOnEm + * 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.strongholdofsecurity; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import net.runelite.api.widgets.Widget; +import java.util.HashMap; +import java.util.Map; + +@Getter +@RequiredArgsConstructor +enum StrongholdAnswer +{ + PAIR_0("To pass you must answer me this: Hey adventurer!
You've been randomly selected for a prize of 1 year of
free membership! I'm just going to need some of your
account details so I can put it on your account!", "No way! I'm reporting you to Jagex!"), + PAIR_1("To pass you must answer me this: Can I leave my
account logged in while I'm out of the room?", "No."), + PAIR_2("To pass you must answer me this: How do I remove a
hijacker from my account?", "Use the Account Recovery System."), + PAIR_3("To pass you must answer me this: What do you do if
someone asks you for your password or bank PIN to
make you a player moderator?", "Don't give them the information and send an 'Abuse report'."), + PAIR_4("To pass you must answer me this: You're watching a
stream by someone claiming to be Jagex offering double
xp. What do you do?", "Report the stream as a scam. Real Jagex streams have a 'verified' mark."), + PAIR_5("To pass you must answer me this: My friend asks me
for my password so that he can do a difficult quest for
me. Do I give it to them?", "Don't give them my password."), + PAIR_6("To pass you must answer me this: Who can I give my
password to?", "Nobody."), + PAIR_7("To pass you must answer me this: How do I set up
two-factor authentication for my Old School RuneScape
account?", "Through account settings on oldschool.runescape.com."), + PAIR_8("To pass you must answer me this: What is an example
of a good bank PIN?", "The birthday of a famous person or event."), + PAIR_9("To pass you must answer me this: What should you do
if your real-life friend asks for your password so he
can check your stats?", "Don't give out your password to anyone. Not even close friends."), + PAIR_A("To pass you must answer me this: A player tells you to
search for a video online, click the link in the description
and comment on the forum post to win a cash prize.
What do you do?", "Report the player for phishing."), + PAIR_B("To pass you must answer me this: You have been
offered an opportunity to check out a free giveaway or
double XP signup via email or in game chat. What
should I do?", "Report the incident and do not click any links."), + PAIR_C("To pass you must answer me this: How do I set a
bank PIN?", "Talk to any banker."), + PAIR_D("To pass you must answer me this: What do I do if a
moderator asks me for my account details?", "Politely tell them no and then use the 'Report Abuse' button."), + PAIR_E("To pass you must answer me this: You are part way
through the Stronghold of Security when you have to
answer another question. After you answer the question,
you should...", "Read the text and follow the advice given."), + PAIR_F("To pass you must answer me this: Will Jagex prevent
me from saying my PIN in game?", "No."), + PAIR_G("that sound?", "No way! You'll just take my gold for your own! Reported!"), + PAIR_H("To pass you must answer me this: What should I do if
I receive an email asking me to verify my identity or
Account details due to suspicious activity?", "Don't click any links, forward the email to reportphishing@jagex.com."), + PAIR_I("To pass you must answer me this: A website claims that
they can make me a player moderator. What should I
do?", "Inform Jagex by emailing reportphishing@jagex.com."), + PAIR_J("react?", "Don't share your information and report the player."), + PAIR_K("To pass you must answer me this: What do you do if
someone asks you for your password or bank PIN to
make you a member for free?", "Don't tell them anything and click the 'Report Abuse' button."), + PAIR_L("To pass you must answer me this: Is it OK to buy an
Old School RuneScape account?", "No, you should never buy an account."), + PAIR_M("To pass you must answer me this: You have been
offered an opportunity to check out a free giveaway or
double XP signup via social media or stream. What
should I do?", "Report the incident and do not click any links."), + PAIR_N("To pass you must answer me this: Where is it safe to
use my Old School RuneScape password?", "Only on the Old School RuneScape website."), + PAIR_O("To pass you must answer me this: What is the best
way to secure your account?", "Authenticator and two-step login on my registered email."), + PAIR_P("To pass you must answer me this: Who is it ok to
share my account with?", "Nobody."), + PAIR_Q("To pass you must answer me this: What should you do
if another player messages you recommending a website
to purchase items and/or gold?", "Do not visit the website and report the player who messaged you."), + PAIR_R("To pass you must answer me this: Whose responsibility
is it to keep your account secure?", "Me."), + PAIR_S("To pass you must answer me this: Is it safe to pay
someone to level your account?", "No, you should never allow anyone to level your account."), + PAIR_T("To pass you must answer me this: What do I do if my
account is compromised?", "Secure my device and reset my password."), + PAIR_U("respond?", "Decline the offer and report that player."), + PAIR_V("To pass you must answer me this: A player says that
Jagex prevents you from saying your password
backwards in game. What do you do?", "Don't type in my password backwards and report the player."), + PAIR_W("To pass you must answer me this: What do I do if I
think I have a keylogger or virus?", "Virus scan my device then change my password."), + PAIR_X("To pass you must answer me this: What is the best
security step you can take to keep your registered
email secure?", "Set up 2 step authentication with my email provider."); + + static final Map MATCHES = new HashMap<>(); + + static + { + for (StrongholdAnswer strongholdAnswer : StrongholdAnswer.values()) + { + MATCHES.put(strongholdAnswer.question, strongholdAnswer.answer); + } + } + + private final String question; + private final String answer; + + static Widget findCorrect(final String question, final Widget[] widgets) + { + final String s = MATCHES.get(question); + + for (Widget widget : widgets) + { + if (widget != null && widget.getText().equals(s)) + { + return widget; + } + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/strongholdofsecurity/StrongholdPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/strongholdofsecurity/StrongholdPlugin.java new file mode 100644 index 0000000000..a0c0c8b73f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/strongholdofsecurity/StrongholdPlugin.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2019, FlaxOnEm + * 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.strongholdofsecurity; + +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.events.ClientTick; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetID; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.PluginType; +import net.runelite.client.util.ColorUtil; +import javax.inject.Inject; +import java.awt.Color; + +@PluginDescriptor( + name = "Stronghold", + description = "Highlights the correct answer to Stronghold of Security questions", + tags = {"stronghold", "security", "overlay", "answer", "highlight"}, + type = PluginType.UTILITY +) +@Slf4j +public class StrongholdPlugin extends Plugin +{ + private static final Color ANSWER_COLOR = new Color(230, 0, 230); + + @Inject + private Client client; + + private boolean queueNPCDialogue; + private boolean queueNPCOption; + private String questionCache; + + @Subscribe + public void onWidgetLoaded(WidgetLoaded widgetLoaded) + { + switch (widgetLoaded.getGroupId()) + { + case WidgetID.DIALOG_NPC_GROUP_ID: + queueNPCDialogue = true; + break; + case WidgetID.DIALOG_OPTION_GROUP_ID: + queueNPCOption = true; + break; + } + } + + @Subscribe + public void onClientTick(ClientTick t) + { + if (queueNPCDialogue) + { + queueNPCDialogue = false; + onNPCDialogue(); + } + if (queueNPCOption) + { + queueNPCOption = false; + onNPCOption(); + } + } + + private void onNPCDialogue() + { + final Widget debugWidget = client.getWidget(WidgetInfo.DIALOG_NPC_TEXT); + final String npcText = debugWidget.getText(); + if (StrongholdAnswer.MATCHES.containsKey(npcText)) + { + questionCache = npcText; + } + } + + private void onNPCOption() + { + if (questionCache == null) + { + return; + } + + final Widget optionsWidget = client.getWidget(WidgetInfo.DIALOG_OPTION); + if (optionsWidget == null) + { + return; + } + + final Widget[] widgets = optionsWidget.getParent().getChildren(); + + final Widget answerWidget = StrongholdAnswer.findCorrect(questionCache, widgets); + questionCache = null; + if (answerWidget == null) + { + return; + } + + final String answerText = answerWidget.getText(); + answerWidget.setText(ColorUtil.wrapWithColorTag(answerText, ANSWER_COLOR)); + } +}