From 1d53e4e64ca3d8d28a931c4863662c30e3d48692 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 28 Dec 2018 17:05:53 -0500 Subject: [PATCH] loot tracker plugin: support saving loot tracker data across restart Co-authored-by: TheStonedTurtle --- .../plugins/loottracker/LootTrackerBox.java | 2 + .../loottracker/LootTrackerConfig.java | 10 ++ .../plugins/loottracker/LootTrackerPanel.java | 33 ++++++ .../loottracker/LootTrackerPlugin.java | 105 +++++++++++++++--- 4 files changed, 133 insertions(+), 17 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerBox.java index 9ebc9f78b1..49faacbf2b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerBox.java @@ -42,6 +42,7 @@ import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.SwingConstants; import javax.swing.border.EmptyBorder; +import lombok.AccessLevel; import lombok.Getter; import net.runelite.client.game.AsyncBufferedImage; import net.runelite.client.game.ItemManager; @@ -58,6 +59,7 @@ class LootTrackerBox extends JPanel private final JLabel priceLabel = new JLabel(); private final JLabel subTitleLabel = new JLabel(); private final ItemManager itemManager; + @Getter(AccessLevel.PACKAGE) private final String id; @Getter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java index 5776543b81..98b7053117 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerConfig.java @@ -48,4 +48,14 @@ public interface LootTrackerConfig extends Config description = "" ) void setIgnoredItems(String key); + + @ConfigItem( + keyName = "saveLoot", + name = "Save loot", + description = "Save loot between client sessions (requires being logged in)" + ) + default boolean saveLoot() + { + return true; + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java index 001e747bb4..6db0459d7a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPanel.java @@ -33,6 +33,7 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import javax.swing.Box; import javax.swing.BoxLayout; @@ -50,6 +51,7 @@ import net.runelite.client.ui.components.PluginErrorPanel; import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.StackFormatter; +import net.runelite.http.api.loottracker.LootTrackerClient; class LootTrackerPanel extends PluginPanel { @@ -292,6 +294,13 @@ class LootTrackerPanel extends PluginPanel updateOverall(); logsContainer.removeAll(); logsContainer.repaint(); + + // Delete all loot, or loot matching the current view + LootTrackerClient client = plugin.getLootTrackerClient(); + if (client != null) + { + client.delete(currentView); + } }); // Create popup menu @@ -335,6 +344,23 @@ class LootTrackerPanel extends PluginPanel } } + /** + * Adds a Collection of records to the panel + */ + void addRecords(Collection recs) + { + for (LootTrackerRecord r : recs) + { + records.add(r); + LootTrackerBox box = buildBox(r); + if (box != null) + { + box.rebuild(); + } + } + updateOverall(); + } + /** * Changes grouping mode of panel * @@ -451,6 +477,13 @@ class LootTrackerPanel extends PluginPanel updateOverall(); logsContainer.remove(box); logsContainer.repaint(); + + LootTrackerClient client = plugin.getLootTrackerClient(); + // Without loot being grouped we have no way to identify single kills to be deleted + if (client != null && groupLoot) + { + client.delete(box.getId()); + } }); popupMenu.add(reset); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java index 90664a5622..d05be74f57 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java @@ -29,17 +29,21 @@ import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.inject.Provides; import java.awt.image.BufferedImage; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.ScheduledExecutorService; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.inject.Inject; import javax.swing.SwingUtilities; +import lombok.AccessLevel; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; @@ -58,6 +62,7 @@ import net.runelite.api.events.WidgetLoaded; import net.runelite.api.widgets.WidgetID; import net.runelite.client.account.AccountSession; import net.runelite.client.account.SessionManager; +import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.NpcLootReceived; @@ -111,15 +116,22 @@ public class LootTrackerPlugin extends Plugin @Inject private Client client; + @Inject + private ClientThread clientThread; + @Inject private SessionManager sessionManager; + @Inject + private ScheduledExecutorService executor; + private LootTrackerPanel panel; private NavigationButton navButton; private String eventType; private List ignoredItems = new ArrayList<>(); + @Getter(AccessLevel.PACKAGE) private LootTrackerClient lootTrackerClient; private static Collection stack(Collection items) @@ -209,6 +221,46 @@ public class LootTrackerPlugin extends Plugin if (accountSession != null) { lootTrackerClient = new LootTrackerClient(accountSession.getUuid()); + + clientThread.invokeLater(() -> + { + switch (client.getGameState()) + { + case STARTING: + case UNKNOWN: + return false; + } + + executor.submit(() -> + { + Collection lootRecords; + + if (!config.saveLoot()) + { + // don't load loot if we're not saving loot + return; + } + + try + { + lootRecords = lootTrackerClient.get(); + } + catch (IOException e) + { + log.debug("Unable to look up loot", e); + return; + } + + log.debug("Loaded {} data entries", lootRecords.size()); + + clientThread.invokeLater(() -> + { + Collection records = convertToLootTrackerRecord(lootRecords); + SwingUtilities.invokeLater(() -> panel.addRecords(records)); + }); + }); + return true; + }); } } @@ -229,7 +281,7 @@ public class LootTrackerPlugin extends Plugin final LootTrackerItem[] entries = buildEntries(stack(items)); SwingUtilities.invokeLater(() -> panel.add(name, combat, entries)); - if (lootTrackerClient != null) + if (lootTrackerClient != null && config.saveLoot()) { LootRecord lootRecord = new LootRecord(name, LootRecordType.NPC, toGameItems(items)); lootTrackerClient.submit(lootRecord); @@ -246,7 +298,7 @@ public class LootTrackerPlugin extends Plugin final LootTrackerItem[] entries = buildEntries(stack(items)); SwingUtilities.invokeLater(() -> panel.add(name, combat, entries)); - if (lootTrackerClient != null) + if (lootTrackerClient != null && config.saveLoot()) { LootRecord lootRecord = new LootRecord(name, LootRecordType.PLAYER, toGameItems(items)); lootTrackerClient.submit(lootRecord); @@ -305,7 +357,7 @@ public class LootTrackerPlugin extends Plugin final LootTrackerItem[] entries = buildEntries(stack(items)); SwingUtilities.invokeLater(() -> panel.add(eventType, -1, entries)); - if (lootTrackerClient != null) + if (lootTrackerClient != null && config.saveLoot()) { LootRecord lootRecord = new LootRecord(eventType, LootRecordType.EVENT, toGameItems(items)); lootTrackerClient.submit(lootRecord); @@ -368,22 +420,26 @@ public class LootTrackerPlugin extends Plugin return ignoredItems.contains(name); } + private LootTrackerItem buildLootTrackerItem(int itemId, int quantity) + { + final ItemComposition itemComposition = itemManager.getItemComposition(itemId); + final int realItemId = itemComposition.getNote() != -1 ? itemComposition.getLinkedNoteId() : itemId; + final long price = (long) itemManager.getItemPrice(realItemId) * (long) quantity; + final boolean ignored = ignoredItems.contains(itemComposition.getName()); + + return new LootTrackerItem( + itemId, + itemComposition.getName(), + quantity, + price, + ignored); + } + private LootTrackerItem[] buildEntries(final Collection itemStacks) { - return itemStacks.stream().map(itemStack -> - { - final ItemComposition itemComposition = itemManager.getItemComposition(itemStack.getId()); - final int realItemId = itemComposition.getNote() != -1 ? itemComposition.getLinkedNoteId() : itemStack.getId(); - final long price = (long) itemManager.getItemPrice(realItemId) * (long) itemStack.getQuantity(); - final boolean ignored = ignoredItems.contains(itemComposition.getName()); - - return new LootTrackerItem( - itemStack.getId(), - itemComposition.getName(), - itemStack.getQuantity(), - price, - ignored); - }).toArray(LootTrackerItem[]::new); + return itemStacks.stream() + .map(itemStack -> buildLootTrackerItem(itemStack.getId(), itemStack.getQuantity())) + .toArray(LootTrackerItem[]::new); } private static Collection toGameItems(Collection items) @@ -392,4 +448,19 @@ public class LootTrackerPlugin extends Plugin .map(item -> new GameItem(item.getId(), item.getQuantity())) .collect(Collectors.toList()); } + + private Collection convertToLootTrackerRecord(final Collection records) + { + Collection trackerRecords = new ArrayList<>(); + for (LootRecord record : records) + { + LootTrackerItem[] drops = record.getDrops().stream().map(itemStack -> + buildLootTrackerItem(itemStack.getId(), itemStack.getQty()) + ).toArray(LootTrackerItem[]::new); + + trackerRecords.add(new LootTrackerRecord(record.getEventId(), "", drops, -1)); + } + + return trackerRecords; + } }