From 343f83bc81866ca1b5cb63da7cf87e7ac570713d Mon Sep 17 00:00:00 2001 From: Kyle <48519776+xKylee@users.noreply.github.com> Date: Sat, 27 Feb 2021 00:39:38 +0000 Subject: [PATCH 1/2] add: hotkeypressed + thieving plugin --- .../client/plugins/thieving/Chest.java | 75 +++++++ .../client/plugins/thieving/ChestOverlay.java | 125 +++++++++++ .../client/plugins/thieving/ChestRespawn.java | 54 +++++ .../plugins/thieving/ThievingConfig.java | 107 +++++++++ .../plugins/thieving/ThievingOverlay.java | 138 ++++++++++++ .../plugins/thieving/ThievingPlugin.java | 208 ++++++++++++++++++ .../plugins/thieving/ThievingSession.java | 61 +++++ .../runelite/client/util/HotkeyListener.java | 4 + 8 files changed, 772 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/Chest.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestRespawn.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingSession.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/Chest.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/Chest.java new file mode 100644 index 0000000000..ec2b374990 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/Chest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019, whs + * 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.thieving; + +import com.google.common.collect.ImmutableMap; +import java.time.Duration; +import java.util.Map; +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.ObjectID; + +enum Chest +{ + TEN_COIN(Duration.ofMillis(6000), ObjectID.CHEST_11735), + FIFTY_COIN(Duration.ofMillis(46000), ObjectID.CHEST_11737), + NATURE_RUNE(Duration.ofMillis(10000), ObjectID.CHEST_11736), + STEEL_ARROWTIPS(Duration.ofMillis(77000), ObjectID.CHEST_11742), + AVERAGE_CHEST(Duration.ofMillis(90000), ObjectID.CHEST_22697), + BLOOD_RUNE(Duration.ofMillis(120000), ObjectID.CHEST_11738), + ARDOUGNE_CASTLE(Duration.ofMillis(400000), ObjectID.CHEST_11739), // FIXME: Please time + RICH_CHEST(Duration.ofMillis(300000), ObjectID.CHEST_22681), // FIXME: Please time + ROGUE_CASTLE(Duration.ofMillis(10000), ObjectID.CHEST_26757); // FIXME: Please time + + private static final Map CHESTS; + + static + { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (Chest chest : values()) + { + for (int id : chest.ids) + { + builder.put(id, chest); + } + } + CHESTS = builder.build(); + } + + @Getter(AccessLevel.PACKAGE) + private final Duration respawnTime; + private final int[] ids; + + Chest(Duration respawnTime, int... ids) + { + this.respawnTime = respawnTime; + this.ids = ids; + } + + static Chest of(int id) + { + return CHESTS.get(id); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestOverlay.java new file mode 100644 index 0000000000..20d084df2b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestOverlay.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2019, whs + * 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.thieving; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Iterator; +import java.util.List; +import javax.inject.Inject; +import javax.inject.Singleton; +import lombok.AccessLevel; +import lombok.Setter; +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ProgressPieComponent; + +@Singleton +class ChestOverlay extends Overlay +{ + private final Client client; + private final List respawns; + + @Setter(AccessLevel.PACKAGE) + private Color pieFillColor; + @Setter(AccessLevel.PACKAGE) + private Color pieBorderColor; + @Setter(AccessLevel.PACKAGE) + private boolean respawnPieInverted; + @Setter(AccessLevel.PACKAGE) + private int respawnPieDiameter; + + @Inject + private ChestOverlay(final Client client, final ThievingPlugin plugin) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + this.respawns = plugin.getRespawns(); + this.client = client; + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (respawns.isEmpty()) + { + return null; + } + + Instant now = Instant.now(); + for (Iterator it = respawns.iterator(); it.hasNext(); ) + { + ChestRespawn chestRespawn = it.next(); + + float percent = 1.0f - (now.until(chestRespawn.getEndTime(), ChronoUnit.MILLIS) / (float) chestRespawn.getRespawnTime()); + if (percent > 1.0f) + { + it.remove(); + continue; + } + + if (chestRespawn.getWorld() != client.getWorld()) + { + continue; + } + + WorldPoint worldPoint = chestRespawn.getWorldPoint(); + LocalPoint loc = LocalPoint.fromWorld(client, worldPoint); + if (loc == null) + { + continue; + } + + Point point = Perspective.localToCanvas(client, loc, client.getPlane(), 0); + if (point == null) + { + continue; + } + + if (respawnPieInverted) + { + percent = 1.0f - percent; + } + + ProgressPieComponent ppc = new ProgressPieComponent(); + ppc.setDiameter(respawnPieDiameter); + ppc.setBorderColor(pieBorderColor); + ppc.setFill(pieFillColor); + ppc.setPosition(point); + ppc.setProgress(percent); + ppc.render(graphics); + } + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestRespawn.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestRespawn.java new file mode 100644 index 0000000000..f8231dd5c0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestRespawn.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019, whs + * 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.thieving; + +import java.time.Instant; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import net.runelite.api.coords.WorldPoint; + +@RequiredArgsConstructor +@Getter(AccessLevel.PACKAGE) +class ChestRespawn +{ + private final Chest chest; + private final WorldPoint worldPoint; + private final Instant endTime; + private final int world; + + private long respawnTime = -1; + + long getRespawnTime() + { + if (respawnTime != -1) + { + return respawnTime; + } + + respawnTime = chest.getRespawnTime().toMillis(); + return respawnTime; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingConfig.java new file mode 100644 index 0000000000..5ca9685773 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingConfig.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2018, Joris K + * Copyright (c) 2018, Lasse + * Copyright (c) 2019, ermalsh + * 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.thieving; + +import java.awt.Color; +import net.runelite.client.config.Alpha; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.ConfigSection; +import net.runelite.client.config.Range; +import net.runelite.client.config.Units; + +@ConfigGroup("thieving") +public interface ThievingConfig extends Config +{ + @ConfigSection( + keyName = "sessionTitle", + name = "Session", + description = "", + position = 1 + ) + String sessionTitle = "Session"; + + @ConfigItem( + position = 2, + keyName = "statTimeout", + name = "Reset stats", + description = "Change the time until the thieving session is reset and the overlay is hidden", + section = sessionTitle + ) + @Units(Units.MINUTES) + default int statTimeout() + { + return 5; + } + + @ConfigSection( + name = "Chest", + description = "", + position = 2, + keyName = "chestTitle" + ) + String chestTitle = "Chest"; + + @Alpha + @ConfigItem( + keyName = "respawnColor", + name = "Respawn timer color", + description = "Configures the color of the respawn timer", + section = chestTitle + ) + default Color respawnColor() + { + return Color.YELLOW; + } + + @ConfigItem( + keyName = "respawnPieInverted", + name = "Invert respawn timer", + description = "Configures whether the respawn timer goes from empty to full or the other way around", + section = chestTitle + ) + default boolean respawnPieInverted() + { + return false; + } + + @Range( + min = 1, + max = 50 + ) + @ConfigItem( + keyName = "respawnPieDiameter", + name = "Respawn pie diameter", + description = "Configures how big the respawn timer pie is", + section = chestTitle + ) + default int respawnPieDiameter() + { + return 30; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingOverlay.java new file mode 100644 index 0000000000..61589dabf9 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingOverlay.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2018, Joris K + * Copyright (c) 2018, Lasse + * Copyright (c) 2019, ermalsh + * 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.thieving; + +import com.openosrs.client.ui.overlay.components.table.TableAlignment; +import com.openosrs.client.ui.overlay.components.table.TableComponent; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.text.DecimalFormat; +import javax.inject.Inject; +import javax.inject.Singleton; +import net.runelite.api.Client; +import net.runelite.api.Skill; +import net.runelite.client.plugins.xptracker.XpTrackerService; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; + +@Singleton +public class ThievingOverlay extends Overlay +{ + private static final DecimalFormat FORMAT = new DecimalFormat("#.#"); + + private final Client client; + private final ThievingPlugin plugin; + private final XpTrackerService xpTrackerService; + private final PanelComponent panelComponent = new PanelComponent(); + public static final int PICKPOCKET_FAIL = 424; + public static final int THIEVING_STALL = 832; + public static final int PICKPOCKET_SUCCESS = 881; + + @Inject + private ThievingOverlay(final Client client, final ThievingPlugin plugin, final XpTrackerService xpTrackerService) + { + setPosition(OverlayPosition.TOP_LEFT); + this.client = client; + this.plugin = plugin; + this.xpTrackerService = xpTrackerService; + } + + @Override + public Dimension render(Graphics2D graphics) + { + ThievingSession session = plugin.getSession(); + if (session == null) + { + return null; + } + + panelComponent.setPreferredSize(new Dimension(145, 0)); + panelComponent.getChildren().clear(); + + if (isThieving()) + { + panelComponent.getChildren().add(TitleComponent.builder() + .text("Thieving") + .color(Color.GREEN) + .build()); + } + else if (isStunned()) + { + panelComponent.getChildren().add(TitleComponent.builder() + .text("Stunned") + .color(Color.ORANGE) + .build()); + } + else + { + panelComponent.getChildren().add(TitleComponent.builder() + .text("NOT thieving") + .color(Color.RED) + .build()); + } + + TableComponent tableComponent = new TableComponent(); + tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT); + + tableComponent.addRow("Succeeded:", session.getSuccessful() + (session.getSuccessful() >= 1 ? " (" + xpTrackerService.getActionsHr(Skill.THIEVING) + "/hr)" : "")); + tableComponent.addRow("Failed:", session.getFailed() + (session.getFailed() >= 1 ? " (" + FORMAT.format(session.getSuccessRate()) + "%)" : "")); + + panelComponent.getChildren().add(tableComponent); + + return panelComponent.render(graphics); + } + + private boolean isThieving() + { + if (client.getLocalPlayer() == null) + { + return false; + } + + switch (client.getLocalPlayer().getAnimation()) + { + case THIEVING_STALL: + case PICKPOCKET_SUCCESS: + return true; + default: + return false; + } + } + + private boolean isStunned() + { + if (client.getLocalPlayer() == null) + { + return false; + } + + return client.getLocalPlayer().getAnimation() == PICKPOCKET_FAIL; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingPlugin.java new file mode 100644 index 0000000000..ec93373fae --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingPlugin.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2018, Joris K + * Copyright (c) 2018, Lasse + * Copyright (c) 2019, ermalsh + * 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.thieving; + +import com.google.inject.Provides; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.GameObject; +import net.runelite.api.GameState; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameObjectDespawned; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.events.ConfigChanged; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDependency; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.xptracker.XpTrackerPlugin; +import net.runelite.client.ui.overlay.OverlayManager; +import org.pf4j.Extension; + +@Extension +@PluginDescriptor( + name = "Thieving", + enabledByDefault = false, + description = "Show thieving overlay", + tags = {"overlay", "skilling", "thieving", "pickpocketing"} +) +@PluginDependency(XpTrackerPlugin.class) +public class ThievingPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private ThievingConfig config; + + @Inject + private ThievingOverlay overlay; + + @Inject + private ChestOverlay chestOverlay; + + @Inject + private OverlayManager overlayManager; + + @Getter(AccessLevel.PACKAGE) + private ThievingSession session; + + @Getter(AccessLevel.PACKAGE) + private final List respawns = new ArrayList<>(); + + private boolean recentlyLoggedIn = false; + + @Provides + ThievingConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(ThievingConfig.class); + } + + @Override + protected void startUp() + { + chestOverlay.setPieFillColor(config.respawnColor()); + chestOverlay.setPieBorderColor(config.respawnColor().darker()); + chestOverlay.setRespawnPieInverted(config.respawnPieInverted()); + chestOverlay.setRespawnPieDiameter(config.respawnPieDiameter()); + + session = null; + overlayManager.add(overlay); + overlayManager.add(chestOverlay); + } + + @Override + protected void shutDown() + { + overlayManager.remove(overlay); + overlayManager.remove(chestOverlay); + session = null; + } + + @Subscribe + private void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == GameState.LOGGED_IN) + { + recentlyLoggedIn = true; + } + } + + @Subscribe + private void onGameTick(GameTick gameTick) + { + recentlyLoggedIn = false; + + if (session == null || config.statTimeout() == 0) + { + return; + } + + Duration statTimeout = Duration.ofMinutes(config.statTimeout()); + Duration sinceCut = Duration.between(session.getLastThievingAction(), Instant.now()); + + if (sinceCut.compareTo(statTimeout) >= 0) + { + session = null; + } + } + + @Subscribe + private void onChatMessage(ChatMessage event) + { + if (event.getType() != ChatMessageType.SPAM) + { + return; + } + + final String message = event.getMessage(); + + if (message.startsWith("You pickpocket") || message.startsWith("You pick-pocket") || message.startsWith("You steal") + || message.startsWith("You successfully pick-pocket") || message.startsWith("You successfully pick") || message.startsWith("You successfully steal") + || message.startsWith("You pick the knight") || message.startsWith("You pick the Elf") || message.startsWith("You pick the vyre")) + { + if (session == null) + { + session = new ThievingSession(); + } + + session.updateLastThievingAction(); + session.hasSucceeded(); + } + else if (message.startsWith("You fail to pick") || message.startsWith("You fail to steal")) + { + if (session == null) + { + session = new ThievingSession(); + } + + session.updateLastThievingAction(); + session.hasFailed(); + } + } + + @Subscribe + private void onGameObjectDespawned(GameObjectDespawned event) + { + if (client.getGameState() != GameState.LOGGED_IN || recentlyLoggedIn) + { + return; + } + + final GameObject object = event.getGameObject(); + + Chest chest = Chest.of(object.getId()); + if (chest != null) + { + ChestRespawn chestRespawn = new ChestRespawn(chest, object.getWorldLocation(), Instant.now().plus(chest.getRespawnTime()), client.getWorld()); + respawns.add(chestRespawn); + } + } + + @Subscribe + private void onConfigChanged(ConfigChanged event) + { + if (!"thieving".equals(event.getGroup())) + { + return; + } + + chestOverlay.setPieFillColor(config.respawnColor()); + chestOverlay.setPieBorderColor(config.respawnColor().darker()); + chestOverlay.setRespawnPieInverted(config.respawnPieInverted()); + chestOverlay.setRespawnPieDiameter(config.respawnPieDiameter()); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingSession.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingSession.java new file mode 100644 index 0000000000..56abcafd7f --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingSession.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018, Joris K + * Copyright (c) 2018, Lasse + * Copyright (c) 2019, ermalsh + * 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.thieving; + +import java.time.Instant; +import lombok.AccessLevel; +import lombok.Getter; + +class ThievingSession +{ + @Getter(AccessLevel.PACKAGE) + private Instant lastThievingAction; + @Getter(AccessLevel.PACKAGE) + private int successful; + @Getter(AccessLevel.PACKAGE) + private int failed; + + void updateLastThievingAction() + { + this.lastThievingAction = Instant.now(); + } + + void hasSucceeded() + { + this.successful++; + } + + void hasFailed() + { + this.failed++; + } + + double getSuccessRate() + { + return ((double) getFailed() / (getSuccessful() + getFailed())) * 100; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/util/HotkeyListener.java b/runelite-client/src/main/java/net/runelite/client/util/HotkeyListener.java index 2099564846..6f5555bfe7 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/HotkeyListener.java +++ b/runelite-client/src/main/java/net/runelite/client/util/HotkeyListener.java @@ -91,4 +91,8 @@ public abstract class HotkeyListener implements KeyListener public void hotkeyPressed() { } + + protected void hotkeyReleased() + { + } } From 202a71f24936c7244e65435e5df8e6f199971fa6 Mon Sep 17 00:00:00 2001 From: Kyle <48519776+xKylee@users.noreply.github.com> Date: Sat, 27 Feb 2021 00:42:43 +0000 Subject: [PATCH 2/2] ReMoVe ThIeViNg --- .../client/plugins/thieving/Chest.java | 75 ------- .../client/plugins/thieving/ChestOverlay.java | 125 ----------- .../client/plugins/thieving/ChestRespawn.java | 54 ----- .../plugins/thieving/ThievingConfig.java | 107 --------- .../plugins/thieving/ThievingOverlay.java | 138 ------------ .../plugins/thieving/ThievingPlugin.java | 208 ------------------ .../plugins/thieving/ThievingSession.java | 61 ----- 7 files changed, 768 deletions(-) delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/Chest.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestRespawn.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingConfig.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingOverlay.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingPlugin.java delete mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingSession.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/Chest.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/Chest.java deleted file mode 100644 index ec2b374990..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/Chest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2019, whs - * 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.thieving; - -import com.google.common.collect.ImmutableMap; -import java.time.Duration; -import java.util.Map; -import lombok.AccessLevel; -import lombok.Getter; -import net.runelite.api.ObjectID; - -enum Chest -{ - TEN_COIN(Duration.ofMillis(6000), ObjectID.CHEST_11735), - FIFTY_COIN(Duration.ofMillis(46000), ObjectID.CHEST_11737), - NATURE_RUNE(Duration.ofMillis(10000), ObjectID.CHEST_11736), - STEEL_ARROWTIPS(Duration.ofMillis(77000), ObjectID.CHEST_11742), - AVERAGE_CHEST(Duration.ofMillis(90000), ObjectID.CHEST_22697), - BLOOD_RUNE(Duration.ofMillis(120000), ObjectID.CHEST_11738), - ARDOUGNE_CASTLE(Duration.ofMillis(400000), ObjectID.CHEST_11739), // FIXME: Please time - RICH_CHEST(Duration.ofMillis(300000), ObjectID.CHEST_22681), // FIXME: Please time - ROGUE_CASTLE(Duration.ofMillis(10000), ObjectID.CHEST_26757); // FIXME: Please time - - private static final Map CHESTS; - - static - { - ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); - for (Chest chest : values()) - { - for (int id : chest.ids) - { - builder.put(id, chest); - } - } - CHESTS = builder.build(); - } - - @Getter(AccessLevel.PACKAGE) - private final Duration respawnTime; - private final int[] ids; - - Chest(Duration respawnTime, int... ids) - { - this.respawnTime = respawnTime; - this.ids = ids; - } - - static Chest of(int id) - { - return CHESTS.get(id); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestOverlay.java deleted file mode 100644 index 20d084df2b..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestOverlay.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2019, whs - * 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.thieving; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.Iterator; -import java.util.List; -import javax.inject.Inject; -import javax.inject.Singleton; -import lombok.AccessLevel; -import lombok.Setter; -import net.runelite.api.Client; -import net.runelite.api.Perspective; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.components.ProgressPieComponent; - -@Singleton -class ChestOverlay extends Overlay -{ - private final Client client; - private final List respawns; - - @Setter(AccessLevel.PACKAGE) - private Color pieFillColor; - @Setter(AccessLevel.PACKAGE) - private Color pieBorderColor; - @Setter(AccessLevel.PACKAGE) - private boolean respawnPieInverted; - @Setter(AccessLevel.PACKAGE) - private int respawnPieDiameter; - - @Inject - private ChestOverlay(final Client client, final ThievingPlugin plugin) - { - setPosition(OverlayPosition.DYNAMIC); - setLayer(OverlayLayer.ABOVE_SCENE); - this.respawns = plugin.getRespawns(); - this.client = client; - } - - @Override - public Dimension render(Graphics2D graphics) - { - if (respawns.isEmpty()) - { - return null; - } - - Instant now = Instant.now(); - for (Iterator it = respawns.iterator(); it.hasNext(); ) - { - ChestRespawn chestRespawn = it.next(); - - float percent = 1.0f - (now.until(chestRespawn.getEndTime(), ChronoUnit.MILLIS) / (float) chestRespawn.getRespawnTime()); - if (percent > 1.0f) - { - it.remove(); - continue; - } - - if (chestRespawn.getWorld() != client.getWorld()) - { - continue; - } - - WorldPoint worldPoint = chestRespawn.getWorldPoint(); - LocalPoint loc = LocalPoint.fromWorld(client, worldPoint); - if (loc == null) - { - continue; - } - - Point point = Perspective.localToCanvas(client, loc, client.getPlane(), 0); - if (point == null) - { - continue; - } - - if (respawnPieInverted) - { - percent = 1.0f - percent; - } - - ProgressPieComponent ppc = new ProgressPieComponent(); - ppc.setDiameter(respawnPieDiameter); - ppc.setBorderColor(pieBorderColor); - ppc.setFill(pieFillColor); - ppc.setPosition(point); - ppc.setProgress(percent); - ppc.render(graphics); - } - return null; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestRespawn.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestRespawn.java deleted file mode 100644 index f8231dd5c0..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ChestRespawn.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2019, whs - * 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.thieving; - -import java.time.Instant; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import net.runelite.api.coords.WorldPoint; - -@RequiredArgsConstructor -@Getter(AccessLevel.PACKAGE) -class ChestRespawn -{ - private final Chest chest; - private final WorldPoint worldPoint; - private final Instant endTime; - private final int world; - - private long respawnTime = -1; - - long getRespawnTime() - { - if (respawnTime != -1) - { - return respawnTime; - } - - respawnTime = chest.getRespawnTime().toMillis(); - return respawnTime; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingConfig.java deleted file mode 100644 index 5ca9685773..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingConfig.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2018, Joris K - * Copyright (c) 2018, Lasse - * Copyright (c) 2019, ermalsh - * 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.thieving; - -import java.awt.Color; -import net.runelite.client.config.Alpha; -import net.runelite.client.config.Config; -import net.runelite.client.config.ConfigGroup; -import net.runelite.client.config.ConfigItem; -import net.runelite.client.config.ConfigSection; -import net.runelite.client.config.Range; -import net.runelite.client.config.Units; - -@ConfigGroup("thieving") -public interface ThievingConfig extends Config -{ - @ConfigSection( - keyName = "sessionTitle", - name = "Session", - description = "", - position = 1 - ) - String sessionTitle = "Session"; - - @ConfigItem( - position = 2, - keyName = "statTimeout", - name = "Reset stats", - description = "Change the time until the thieving session is reset and the overlay is hidden", - section = sessionTitle - ) - @Units(Units.MINUTES) - default int statTimeout() - { - return 5; - } - - @ConfigSection( - name = "Chest", - description = "", - position = 2, - keyName = "chestTitle" - ) - String chestTitle = "Chest"; - - @Alpha - @ConfigItem( - keyName = "respawnColor", - name = "Respawn timer color", - description = "Configures the color of the respawn timer", - section = chestTitle - ) - default Color respawnColor() - { - return Color.YELLOW; - } - - @ConfigItem( - keyName = "respawnPieInverted", - name = "Invert respawn timer", - description = "Configures whether the respawn timer goes from empty to full or the other way around", - section = chestTitle - ) - default boolean respawnPieInverted() - { - return false; - } - - @Range( - min = 1, - max = 50 - ) - @ConfigItem( - keyName = "respawnPieDiameter", - name = "Respawn pie diameter", - description = "Configures how big the respawn timer pie is", - section = chestTitle - ) - default int respawnPieDiameter() - { - return 30; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingOverlay.java deleted file mode 100644 index 61589dabf9..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingOverlay.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2018, Joris K - * Copyright (c) 2018, Lasse - * Copyright (c) 2019, ermalsh - * 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.thieving; - -import com.openosrs.client.ui.overlay.components.table.TableAlignment; -import com.openosrs.client.ui.overlay.components.table.TableComponent; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.text.DecimalFormat; -import javax.inject.Inject; -import javax.inject.Singleton; -import net.runelite.api.Client; -import net.runelite.api.Skill; -import net.runelite.client.plugins.xptracker.XpTrackerService; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.components.PanelComponent; -import net.runelite.client.ui.overlay.components.TitleComponent; - -@Singleton -public class ThievingOverlay extends Overlay -{ - private static final DecimalFormat FORMAT = new DecimalFormat("#.#"); - - private final Client client; - private final ThievingPlugin plugin; - private final XpTrackerService xpTrackerService; - private final PanelComponent panelComponent = new PanelComponent(); - public static final int PICKPOCKET_FAIL = 424; - public static final int THIEVING_STALL = 832; - public static final int PICKPOCKET_SUCCESS = 881; - - @Inject - private ThievingOverlay(final Client client, final ThievingPlugin plugin, final XpTrackerService xpTrackerService) - { - setPosition(OverlayPosition.TOP_LEFT); - this.client = client; - this.plugin = plugin; - this.xpTrackerService = xpTrackerService; - } - - @Override - public Dimension render(Graphics2D graphics) - { - ThievingSession session = plugin.getSession(); - if (session == null) - { - return null; - } - - panelComponent.setPreferredSize(new Dimension(145, 0)); - panelComponent.getChildren().clear(); - - if (isThieving()) - { - panelComponent.getChildren().add(TitleComponent.builder() - .text("Thieving") - .color(Color.GREEN) - .build()); - } - else if (isStunned()) - { - panelComponent.getChildren().add(TitleComponent.builder() - .text("Stunned") - .color(Color.ORANGE) - .build()); - } - else - { - panelComponent.getChildren().add(TitleComponent.builder() - .text("NOT thieving") - .color(Color.RED) - .build()); - } - - TableComponent tableComponent = new TableComponent(); - tableComponent.setColumnAlignments(TableAlignment.LEFT, TableAlignment.RIGHT); - - tableComponent.addRow("Succeeded:", session.getSuccessful() + (session.getSuccessful() >= 1 ? " (" + xpTrackerService.getActionsHr(Skill.THIEVING) + "/hr)" : "")); - tableComponent.addRow("Failed:", session.getFailed() + (session.getFailed() >= 1 ? " (" + FORMAT.format(session.getSuccessRate()) + "%)" : "")); - - panelComponent.getChildren().add(tableComponent); - - return panelComponent.render(graphics); - } - - private boolean isThieving() - { - if (client.getLocalPlayer() == null) - { - return false; - } - - switch (client.getLocalPlayer().getAnimation()) - { - case THIEVING_STALL: - case PICKPOCKET_SUCCESS: - return true; - default: - return false; - } - } - - private boolean isStunned() - { - if (client.getLocalPlayer() == null) - { - return false; - } - - return client.getLocalPlayer().getAnimation() == PICKPOCKET_FAIL; - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingPlugin.java deleted file mode 100644 index ec93373fae..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingPlugin.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2018, Joris K - * Copyright (c) 2018, Lasse - * Copyright (c) 2019, ermalsh - * 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.thieving; - -import com.google.inject.Provides; -import java.time.Duration; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import javax.inject.Inject; -import lombok.AccessLevel; -import lombok.Getter; -import net.runelite.api.ChatMessageType; -import net.runelite.api.Client; -import net.runelite.api.GameObject; -import net.runelite.api.GameState; -import net.runelite.api.events.ChatMessage; -import net.runelite.api.events.GameObjectDespawned; -import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; -import net.runelite.client.config.ConfigManager; -import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.events.ConfigChanged; -import net.runelite.client.plugins.Plugin; -import net.runelite.client.plugins.PluginDependency; -import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.plugins.xptracker.XpTrackerPlugin; -import net.runelite.client.ui.overlay.OverlayManager; -import org.pf4j.Extension; - -@Extension -@PluginDescriptor( - name = "Thieving", - enabledByDefault = false, - description = "Show thieving overlay", - tags = {"overlay", "skilling", "thieving", "pickpocketing"} -) -@PluginDependency(XpTrackerPlugin.class) -public class ThievingPlugin extends Plugin -{ - @Inject - private Client client; - - @Inject - private ThievingConfig config; - - @Inject - private ThievingOverlay overlay; - - @Inject - private ChestOverlay chestOverlay; - - @Inject - private OverlayManager overlayManager; - - @Getter(AccessLevel.PACKAGE) - private ThievingSession session; - - @Getter(AccessLevel.PACKAGE) - private final List respawns = new ArrayList<>(); - - private boolean recentlyLoggedIn = false; - - @Provides - ThievingConfig getConfig(ConfigManager configManager) - { - return configManager.getConfig(ThievingConfig.class); - } - - @Override - protected void startUp() - { - chestOverlay.setPieFillColor(config.respawnColor()); - chestOverlay.setPieBorderColor(config.respawnColor().darker()); - chestOverlay.setRespawnPieInverted(config.respawnPieInverted()); - chestOverlay.setRespawnPieDiameter(config.respawnPieDiameter()); - - session = null; - overlayManager.add(overlay); - overlayManager.add(chestOverlay); - } - - @Override - protected void shutDown() - { - overlayManager.remove(overlay); - overlayManager.remove(chestOverlay); - session = null; - } - - @Subscribe - private void onGameStateChanged(GameStateChanged event) - { - if (event.getGameState() == GameState.LOGGED_IN) - { - recentlyLoggedIn = true; - } - } - - @Subscribe - private void onGameTick(GameTick gameTick) - { - recentlyLoggedIn = false; - - if (session == null || config.statTimeout() == 0) - { - return; - } - - Duration statTimeout = Duration.ofMinutes(config.statTimeout()); - Duration sinceCut = Duration.between(session.getLastThievingAction(), Instant.now()); - - if (sinceCut.compareTo(statTimeout) >= 0) - { - session = null; - } - } - - @Subscribe - private void onChatMessage(ChatMessage event) - { - if (event.getType() != ChatMessageType.SPAM) - { - return; - } - - final String message = event.getMessage(); - - if (message.startsWith("You pickpocket") || message.startsWith("You pick-pocket") || message.startsWith("You steal") - || message.startsWith("You successfully pick-pocket") || message.startsWith("You successfully pick") || message.startsWith("You successfully steal") - || message.startsWith("You pick the knight") || message.startsWith("You pick the Elf") || message.startsWith("You pick the vyre")) - { - if (session == null) - { - session = new ThievingSession(); - } - - session.updateLastThievingAction(); - session.hasSucceeded(); - } - else if (message.startsWith("You fail to pick") || message.startsWith("You fail to steal")) - { - if (session == null) - { - session = new ThievingSession(); - } - - session.updateLastThievingAction(); - session.hasFailed(); - } - } - - @Subscribe - private void onGameObjectDespawned(GameObjectDespawned event) - { - if (client.getGameState() != GameState.LOGGED_IN || recentlyLoggedIn) - { - return; - } - - final GameObject object = event.getGameObject(); - - Chest chest = Chest.of(object.getId()); - if (chest != null) - { - ChestRespawn chestRespawn = new ChestRespawn(chest, object.getWorldLocation(), Instant.now().plus(chest.getRespawnTime()), client.getWorld()); - respawns.add(chestRespawn); - } - } - - @Subscribe - private void onConfigChanged(ConfigChanged event) - { - if (!"thieving".equals(event.getGroup())) - { - return; - } - - chestOverlay.setPieFillColor(config.respawnColor()); - chestOverlay.setPieBorderColor(config.respawnColor().darker()); - chestOverlay.setRespawnPieInverted(config.respawnPieInverted()); - chestOverlay.setRespawnPieDiameter(config.respawnPieDiameter()); - } -} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingSession.java b/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingSession.java deleted file mode 100644 index 56abcafd7f..0000000000 --- a/runelite-client/src/main/java/net/runelite/client/plugins/thieving/ThievingSession.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2018, Joris K - * Copyright (c) 2018, Lasse - * Copyright (c) 2019, ermalsh - * 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.thieving; - -import java.time.Instant; -import lombok.AccessLevel; -import lombok.Getter; - -class ThievingSession -{ - @Getter(AccessLevel.PACKAGE) - private Instant lastThievingAction; - @Getter(AccessLevel.PACKAGE) - private int successful; - @Getter(AccessLevel.PACKAGE) - private int failed; - - void updateLastThievingAction() - { - this.lastThievingAction = Instant.now(); - } - - void hasSucceeded() - { - this.successful++; - } - - void hasFailed() - { - this.failed++; - } - - double getSuccessRate() - { - return ((double) getFailed() / (getSuccessful() + getFailed())) * 100; - } -}