From 00c1b447f658c2c18600dfd17769f1c30f28491e Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 18 Jun 2018 19:21:13 -0400 Subject: [PATCH] item charges plugin: add dodgy necklace --- .../plugins/itemcharges/ItemChargeConfig.java | 50 +++++++++- .../itemcharges/ItemChargeOverlay.java | 58 +++++++---- .../plugins/itemcharges/ItemChargePlugin.java | 50 +++++++++- .../itemcharges/ItemChargePluginTest.java | 95 +++++++++++++++++++ 4 files changed, 227 insertions(+), 26 deletions(-) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/itemcharges/ItemChargePluginTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java index 8d33d384b8..e02ac1d3ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeConfig.java @@ -91,11 +91,51 @@ public interface ItemChargeConfig extends Config return true; } + @ConfigItem( + keyName = "showDodgyCount", + name = "Dodgy Necklace Count", + description = "Configures if Dodgy Necklace charge count is shown", + position = 6 + ) + default boolean showDodgyCount() + { + return true; + } + + @ConfigItem( + keyName = "dodgyNotification", + name = "Dodgy Necklace Notification", + description = "Configures if the dodgy necklace breaking notification is shown", + position = 7 + ) + default boolean dodgyNotification() + { + return true; + } + + @ConfigItem( + keyName = "dodgyNecklace", + name = "", + description = "", + hidden = true + ) + default int dodgyNecklace() + { + return -1; + } + + @ConfigItem( + keyName = "dodgyNecklace", + name = "", + description = "" + ) + void dodgyNecklace(int dodgyNecklace); + @ConfigItem( keyName = "showImpCharges", name = "Show Imp-in-a-box charges", description = "Configures if imp-in-a-box item charges is shown", - position = 6 + position = 8 ) default boolean showImpCharges() { @@ -106,7 +146,7 @@ public interface ItemChargeConfig extends Config keyName = "showFungicideCharges", name = "Show Fungicide Charges", description = "Configures if fungicide item charges is shown", - position = 7 + position = 9 ) default boolean showFungicideCharges() { @@ -117,7 +157,7 @@ public interface ItemChargeConfig extends Config keyName = "showWateringCanCharges", name = "Show Watering Can Charges", description = "Configures if watering can item charge is shown", - position = 8 + position = 10 ) default boolean showWateringCanCharges() { @@ -128,7 +168,7 @@ public interface ItemChargeConfig extends Config keyName = "showWaterskinCharges", name = "Show Waterskin Charges", description = "Configures if waterskin item charge is shown", - position = 9 + position = 11 ) default boolean showWaterskinCharges() { @@ -139,7 +179,7 @@ public interface ItemChargeConfig extends Config keyName = "recoilNotification", name = "Ring of Recoil Notification", description = "Configures if the ring of recoil breaking notification is shown", - position = 10 + position = 12 ) default boolean recoilNotification() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java index f1f3568c16..96be2ee08e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargeOverlay.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import javax.inject.Inject; +import net.runelite.api.ItemID; import net.runelite.api.Query; import net.runelite.api.queries.EquipmentItemQuery; import net.runelite.api.queries.InventoryWidgetItemQuery; @@ -53,22 +54,23 @@ import net.runelite.client.util.QueryRunner; class ItemChargeOverlay extends Overlay { private final QueryRunner queryRunner; + private final ItemChargePlugin itemChargePlugin; private final ItemChargeConfig config; @Inject - ItemChargeOverlay(QueryRunner queryRunner, ItemChargeConfig config) + ItemChargeOverlay(QueryRunner queryRunner, ItemChargePlugin itemChargePlugin, ItemChargeConfig config) { setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ABOVE_WIDGETS); this.queryRunner = queryRunner; + this.itemChargePlugin = itemChargePlugin; this.config = config; } @Override public Dimension render(Graphics2D graphics) { - if (!config.showTeleportCharges() && !config.showFungicideCharges() && !config.showImpCharges() - && !config.showWateringCanCharges() && !config.showWaterskinCharges()) + if (!displayOverlay()) { return null; } @@ -77,27 +79,41 @@ class ItemChargeOverlay extends Overlay for (WidgetItem item : getChargeWidgetItems()) { - ItemWithCharge chargeItem = ItemWithCharge.findItem(item.getId()); - if (chargeItem == null) + int charges; + if (item.getId() == ItemID.DODGY_NECKLACE) { - continue; + if (!config.showDodgyCount()) + { + continue; + } + + charges = itemChargePlugin.getDodgyCharges(); + } + else + { + ItemWithCharge chargeItem = ItemWithCharge.findItem(item.getId()); + if (chargeItem == null) + { + continue; + } + + ItemChargeType type = chargeItem.getType(); + if ((type == TELEPORT && !config.showTeleportCharges()) + || (type == FUNGICIDE_SPRAY && !config.showFungicideCharges()) + || (type == IMPBOX && !config.showImpCharges()) + || (type == WATERCAN && !config.showWateringCanCharges()) + || (type == WATERSKIN && !config.showWaterskinCharges())) + { + continue; + } + + charges = chargeItem.getCharges(); } - ItemChargeType type = chargeItem.getType(); - if ((type == TELEPORT && !config.showTeleportCharges()) - || (type == FUNGICIDE_SPRAY && !config.showFungicideCharges()) - || (type == IMPBOX && !config.showImpCharges()) - || (type == WATERCAN && !config.showWateringCanCharges()) - || (type == WATERSKIN && !config.showWaterskinCharges())) - { - continue; - } - - int charges = chargeItem.getCharges(); final Rectangle bounds = item.getCanvasBounds(); final TextComponent textComponent = new TextComponent(); textComponent.setPosition(new Point(bounds.x, bounds.y + 16)); - textComponent.setText(String.valueOf(charges)); + textComponent.setText(charges < 0 ? "?" : String.valueOf(charges)); textComponent.setColor(getColor(charges)); textComponent.render(graphics); } @@ -136,4 +152,10 @@ class ItemChargeOverlay extends Overlay } return color; } + + private boolean displayOverlay() + { + return config.showTeleportCharges() || config.showDodgyCount() || config.showFungicideCharges() + || config.showImpCharges() || config.showWateringCanCharges() || config.showWaterskinCharges(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java index 03a255bb82..166e418ff9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemChargePlugin.java @@ -26,7 +26,11 @@ package net.runelite.client.plugins.itemcharges; import com.google.common.eventbus.Subscribe; import com.google.inject.Provides; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; import net.runelite.api.ChatMessageType; import net.runelite.api.events.ChatMessage; import net.runelite.client.Notifier; @@ -40,6 +44,15 @@ import net.runelite.client.ui.overlay.OverlayManager; ) public class ItemChargePlugin extends Plugin { + private static final Pattern DODGY_CHECK_PATTERN = Pattern.compile( + "Your dodgy necklace has (\\d+) charges? left\\."); + private static final Pattern DODGY_PROTECT_PATTERN = Pattern.compile( + "Your dodgy necklace protects you\\..*It has (\\d+) charges? left\\."); + private static final Pattern DODGY_BREAK_PATTERN = Pattern.compile( + "Your dodgy necklace protects you\\..*It then crumbles to dust\\."); + + private static final int MAX_DODGY_CHARGES = 10; + @Inject private OverlayManager overlayManager; @@ -52,6 +65,9 @@ public class ItemChargePlugin extends Plugin @Inject private ItemChargeConfig config; + @Getter(AccessLevel.PACKAGE) + private int dodgyCharges; + @Provides ItemChargeConfig getConfig(ConfigManager configManager) { @@ -59,9 +75,10 @@ public class ItemChargePlugin extends Plugin } @Override - protected void startUp() throws Exception + protected void startUp() { overlayManager.add(overlay); + dodgyCharges = config.dodgyNecklace(); } @Override @@ -73,12 +90,39 @@ public class ItemChargePlugin extends Plugin @Subscribe public void onChatMessage(ChatMessage event) { - if (event.getType() == ChatMessageType.SERVER) + String message = event.getMessage(); + Matcher dodgyCheckMatcher = DODGY_CHECK_PATTERN.matcher(message); + Matcher dodgyProtectMatcher = DODGY_PROTECT_PATTERN.matcher(message); + Matcher dodgyBreakMatcher = DODGY_BREAK_PATTERN.matcher(message); + if (event.getType() == ChatMessageType.SERVER || event.getType() == ChatMessageType.FILTERED) { - if (config.recoilNotification() && event.getMessage().contains("Your Ring of Recoil has shattered.")) + if (config.recoilNotification() && message.contains("Your Ring of Recoil has shattered.")) { notifier.notify("Your Ring of Recoil has shattered"); } + else if (dodgyBreakMatcher.find()) + { + if (config.dodgyNotification()) + { + notifier.notify("Your dodgy necklace has crumbled to dust."); + } + + setDodgyCharges(MAX_DODGY_CHARGES); + } + else if (dodgyCheckMatcher.find()) + { + setDodgyCharges(Integer.parseInt(dodgyCheckMatcher.group(1))); + } + else if (dodgyProtectMatcher.find()) + { + setDodgyCharges(Integer.parseInt(dodgyProtectMatcher.group(1))); + } } } + + private void setDodgyCharges(int dodgyCharges) + { + this.dodgyCharges = dodgyCharges; + config.dodgyNecklace(dodgyCharges); + } } \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/itemcharges/ItemChargePluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/itemcharges/ItemChargePluginTest.java new file mode 100644 index 0000000000..36ffcf643e --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/itemcharges/ItemChargePluginTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2018, Adam + * 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.itemcharges; + +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.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.events.ChatMessage; +import net.runelite.client.Notifier; +import net.runelite.client.ui.overlay.OverlayManager; +import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class ItemChargePluginTest +{ + private static final String CHECK = "Your dodgy necklace has 10 charges left."; + private static final String PROTECT = "Your dodgy necklace protects you. It has 9 charges left."; + private static final String PROTECT_1 = "Your dodgy necklace protects you. It has 1 charge left."; + private static final String BREAK = "Your dodgy necklace protects you. It then crumbles to dust."; + + @Mock + @Bind + private Client client; + + @Mock + @Bind + private OverlayManager overlayManager; + + @Mock + @Bind + private Notifier notifier; + + @Mock + @Bind + private ItemChargeConfig config; + + @Inject + private ItemChargePlugin itemChargePlugin; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void testOnChatMessage() + { + ChatMessage chatMessage = new ChatMessage(ChatMessageType.SERVER, "", CHECK, ""); + itemChargePlugin.onChatMessage(chatMessage); + assertEquals(10, itemChargePlugin.getDodgyCharges()); + + chatMessage = new ChatMessage(ChatMessageType.SERVER, "", PROTECT, ""); + itemChargePlugin.onChatMessage(chatMessage); + assertEquals(9, itemChargePlugin.getDodgyCharges()); + + chatMessage = new ChatMessage(ChatMessageType.SERVER, "", PROTECT_1, ""); + itemChargePlugin.onChatMessage(chatMessage); + assertEquals(1, itemChargePlugin.getDodgyCharges()); + + chatMessage = new ChatMessage(ChatMessageType.SERVER, "", BREAK, ""); + itemChargePlugin.onChatMessage(chatMessage); + assertEquals(10, itemChargePlugin.getDodgyCharges()); + } +} \ No newline at end of file