Merge pull request #522 from pklite/loot-tracker-update

Loot tracker update
This commit is contained in:
Tyler Bochard
2019-06-11 22:50:38 -04:00
committed by GitHub
8 changed files with 388 additions and 37 deletions

View File

@@ -26,8 +26,10 @@ package net.runelite.http.api.loottracker;
import java.time.Instant;
import java.util.Collection;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Data
@@ -36,7 +38,26 @@ import lombok.NoArgsConstructor;
public class LootRecord
{
private String eventId;
@Getter
private String username;
private LootRecordType type;
private Collection<GameItem> drops;
private Instant time;
/**
* constructor for lootRecords retrieved by http api (doesn't store/retrieve username)
* @param eventId - the eventID or the name/title of the LootRecord
* @param type - The LootRecordType
* @param gameItems - the list of items/quantities
* @param time - the Instant that the Loot Record was received
*/
public LootRecord(String eventId, LootRecordType type, List<GameItem> gameItems, Instant time)
{
// Insert blank username
this.username = "";
this.eventId = eventId;
this.type = type;
this.drops = gameItems;
this.time = time;
}
}

View File

@@ -29,5 +29,6 @@ public enum LootRecordType
NPC,
PLAYER,
EVENT,
DEATH,
UNKNOWN
}

View File

@@ -0,0 +1,56 @@
package net.runelite.client.plugins.loottracker;
import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;
import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.loottracker.LootRecordType;
/**
*
*/
@Slf4j
public enum LootRecordSortType implements Comparator<LootTrackerRecord>
{
TIMESTAMP
{
@Override
public int compare(LootTrackerRecord o1, LootTrackerRecord o2)
{
return Long.compare(o1.getTimestamp(), o2.getTimestamp());
}
},
TOTAL_VALUE
{
@Override
public int compare(LootTrackerRecord o1, LootTrackerRecord o2)
{
// We want deaths at the bottom of the list
if (o1.getSubTitle().equals(LootRecordType.DEATH.name()))
{
return Arrays.stream(o1.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getPrice() * lootTrackerItem.getQuantity())).sum();
}
if (o2.getSubTitle().equals(LootRecordType.DEATH.name()))
{
return Arrays.stream(o1.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getPrice() * lootTrackerItem.getQuantity())).sum();
}
int sum = Arrays.stream(o1.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getPrice() * lootTrackerItem.getQuantity())).sum();
log.info(String.valueOf(sum + Arrays.stream(o2.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getPrice() * lootTrackerItem.getQuantity())).sum()));
return sum + Arrays.stream(o2.getItems()).flatMapToInt(lootTrackerItem ->
IntStream.of((int) lootTrackerItem.getPrice() * lootTrackerItem.getQuantity())).sum();
}
},
ITEM_COUNT
{
@Override
public int compare(LootTrackerRecord o1, LootTrackerRecord o2)
{
return Integer.compare(o1.getItems().length, o2.getItems().length);
}
}
}

View File

@@ -120,7 +120,8 @@ class LootTrackerBox extends JPanel
private long getTotalKills()
{
return hideIgnoredItems
? records.stream().filter(r -> !Arrays.stream(r.getItems()).allMatch(LootTrackerItem::isIgnored)).count()
? records.stream().filter(
r -> !Arrays.stream(r.getItems()).allMatch(LootTrackerItem::isIgnored)).count()
: records.size();
}
@@ -229,7 +230,7 @@ class LootTrackerBox extends JPanel
}
}
if (quantity > 0)
if (quantity != 0)
{
int newQuantity = entry.getQuantity() + quantity;
long pricePerItem = entry.getPrice() == 0 ? 0 : (entry.getPrice() / entry.getQuantity());
@@ -263,7 +264,7 @@ class LootTrackerBox extends JPanel
imageLabel.setVerticalAlignment(SwingConstants.CENTER);
imageLabel.setHorizontalAlignment(SwingConstants.CENTER);
AsyncBufferedImage itemImage = itemManager.getImage(item.getId(), item.getQuantity(), item.getQuantity() > 1);
AsyncBufferedImage itemImage = itemManager.getImage(item.getId(), Math.abs(item.getQuantity()), Math.abs(item.getQuantity()) > 1);
if (item.isIgnored())
{

View File

@@ -80,4 +80,25 @@ public interface LootTrackerConfig extends Config
{
return true;
}
@ConfigItem(
keyName = "localPersistence",
name = "Local Record Persistence",
description = "Stores/syncs loot records locally in the JSON format. Note: records will not be saved locally" +
" if they are successfully saved online. "
)
default boolean localPersistence()
{
return true;
}
@ConfigItem(
keyName = "sortType",
name = "Sorting",
description = "The method for sorting Loot Tracker entries"
)
default LootRecordSortType sortType()
{
return LootRecordSortType.TIMESTAMP;
}
}

View File

@@ -33,8 +33,11 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.IntStream;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
@@ -43,6 +46,10 @@ import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.border.EmptyBorder;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.GameState;
import net.runelite.client.game.ItemManager;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
@@ -53,6 +60,7 @@ import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.StackFormatter;
import net.runelite.http.api.loottracker.LootTrackerClient;
@Slf4j
class LootTrackerPanel extends PluginPanel
{
private static final int MAX_LOOT_BOXES = 500;
@@ -131,6 +139,11 @@ class LootTrackerPanel extends PluginPanel
INVISIBLE_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(invisibleImg, -220));
}
private final JPanel displaySelector;
@Getter @Setter
private LootRecordSortType lootRecordSortType = LootRecordSortType.TIMESTAMP;
LootTrackerPanel(final LootTrackerPlugin plugin, final ItemManager itemManager, final LootTrackerConfig config)
{
this.itemManager = itemManager;
@@ -289,6 +302,11 @@ class LootTrackerPanel extends PluginPanel
overallPanel.add(overallIcon, BorderLayout.WEST);
overallPanel.add(overallInfo, BorderLayout.CENTER);
displaySelector = new JPanel();
displaySelector.setLayout(new GridLayout(1, 1));
displaySelector.setBorder(new EmptyBorder(2, 10, 10, 10));
displaySelector.setBackground(ColorScheme.DARKER_GRAY_COLOR);
// Create reset all menu
final JMenuItem reset = new JMenuItem("Reset All");
reset.addActionListener(e ->
@@ -318,6 +336,7 @@ class LootTrackerPanel extends PluginPanel
logsContainer.setLayout(new BoxLayout(logsContainer, BoxLayout.Y_AXIS));
layoutPanel.add(actionsContainer);
layoutPanel.add(overallPanel);
layoutPanel.add(displaySelector);
layoutPanel.add(logsContainer);
// Add error pane
@@ -335,10 +354,10 @@ class LootTrackerPanel extends PluginPanel
* Creates a subtitle, adds a new entry and then passes off to the render methods, that will decide
* how to display this new data.
*/
void add(final String eventName, final int actorLevel, LootTrackerItem[] items)
void add(final String eventName, final String localUsername, final int actorLevel, LootTrackerItem[] items)
{
final String subTitle = actorLevel > -1 ? "(lvl-" + actorLevel + ")" : "";
final LootTrackerRecord record = new LootTrackerRecord(eventName, subTitle, items, System.currentTimeMillis());
final LootTrackerRecord record = new LootTrackerRecord( eventName, localUsername, subTitle, items, System.currentTimeMillis());
records.add(record);
LootTrackerBox box = buildBox(record);
if (box != null)
@@ -405,23 +424,37 @@ class LootTrackerPanel extends PluginPanel
/**
* Rebuilds all the boxes from scratch using existing listed records, depending on the grouping mode.
*/
private void rebuild()
public void rebuild()
{
logsContainer.removeAll();
boxes.clear();
int start = 0;
records.sort(lootRecordSortType);
if (!groupLoot && records.size() > MAX_LOOT_BOXES)
{
start = records.size() - MAX_LOOT_BOXES;
}
for (int i = start; i < records.size(); i++)
{
if (this.plugin.client.getGameState().equals(GameState.LOGGED_IN))
{
if (!(this.plugin.client.getLocalPlayer().getName().equals(records.get(i).getLocalUsername())))
{
continue;
}
}
buildBox(records.get(i));
log.info(String.valueOf(Arrays.stream(records.get(i).getItems()).flatMapToInt(a -> IntStream.of(a.getQuantity() * (int) a.getPrice())).sum()));
}
boxes.forEach(LootTrackerBox::rebuild);
updateOverall();
logsContainer.revalidate();
logsContainer.repaint();
}
/**
@@ -431,12 +464,21 @@ class LootTrackerPanel extends PluginPanel
*/
private LootTrackerBox buildBox(LootTrackerRecord record)
{
// If this record is not part of current view, return
if (!record.matches(currentView))
{
return null;
}
if (this.plugin.client.getGameState().equals(GameState.LOGGED_IN))
{
if (!(this.plugin.client.getLocalPlayer().getName().equals(record.getLocalUsername())))
{
return null;
}
}
// Group all similar loot together
if (groupLoot)
{
@@ -456,7 +498,8 @@ class LootTrackerPanel extends PluginPanel
overallPanel.setVisible(true);
// Create box
final LootTrackerBox box = new LootTrackerBox(itemManager, record.getTitle(), record.getSubTitle(), hideIgnoredItems, plugin::toggleItem);
final LootTrackerBox box = new LootTrackerBox(itemManager, record.getTitle(), record.getSubTitle(),
hideIgnoredItems, plugin::toggleItem);
box.combine(record);
// Create popup menu
@@ -519,6 +562,14 @@ class LootTrackerPanel extends PluginPanel
{
continue;
}
if (Objects.nonNull(record.getLocalUsername()) && Objects.nonNull(plugin.client.getLocalPlayer()))
{
if (!record.getLocalUsername().equals(plugin.client.getLocalPlayer().getName()))
{
continue;
}
}
int present = record.getItems().length;
@@ -542,7 +593,6 @@ class LootTrackerPanel extends PluginPanel
overallKillsLabel.setText(htmlLabel("Total count: ", overallKills));
overallGpLabel.setText(htmlLabel("Total value: ", overallGp));
}
private static String htmlLabel(String key, long value)
{
final String valueStr = StackFormatter.quantityToStackSize(value);

View File

@@ -25,13 +25,25 @@
*/
package net.runelite.client.plugins.loottracker;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multiset;
import com.google.common.collect.Multisets;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonStreamParser;
import com.google.gson.reflect.TypeToken;
import com.google.inject.Provides;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
@@ -53,17 +65,22 @@ import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemDefinition;
import net.runelite.api.ItemContainer;
import net.runelite.api.ItemDefinition;
import net.runelite.api.NPC;
import net.runelite.api.Player;
import net.runelite.api.SpriteID;
import net.runelite.api.Varbits;
import net.runelite.api.WorldType;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.ItemContainerChanged;
import net.runelite.api.events.LocalPlayerDeath;
import net.runelite.api.events.PlayerSpawned;
import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.WidgetID;
import net.runelite.client.RuneLite;
import net.runelite.client.account.AccountSession;
import net.runelite.client.account.SessionManager;
import net.runelite.client.callback.ClientThread;
@@ -87,6 +104,7 @@ import net.runelite.client.ui.NavigationButton;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.StackFormatter;
import net.runelite.client.util.Text;
import net.runelite.http.api.RuneLiteAPI;
import net.runelite.http.api.loottracker.GameItem;
import net.runelite.http.api.loottracker.LootRecord;
import net.runelite.http.api.loottracker.LootRecordType;
@@ -116,6 +134,18 @@ public class LootTrackerPlugin extends Plugin
11573, "Crystal Chest"
);
// Player deaths
public static HashSet<String> usernameSet = new HashSet<String>(Arrays.stream(new String[]{"All Records"}).collect(Collectors.toList()));
private static final File LOOT_RECORDS_FILE = new File(RuneLite.RUNELITE_DIR, "lootRecords.json");
private static final Set<Integer> RESPAWN_REGIONS = ImmutableSet.of(
12850, // Lumbridge
11828, // Falador
12342, // Edgeville
11062 // Camelot
);
private boolean pvpDeath = false;
@Inject
private ClientToolbar clientToolbar;
@@ -132,7 +162,7 @@ public class LootTrackerPlugin extends Plugin
private LootTrackerConfig config;
@Inject
private Client client;
public Client client;
@Inject
private ClientThread clientThread;
@@ -153,6 +183,10 @@ public class LootTrackerPlugin extends Plugin
@Getter(AccessLevel.PACKAGE)
private LootTrackerClient lootTrackerClient;
private BufferedReader bufferedReader;
private JsonStreamParser jsonStreamParser;
@VisibleForTesting
public Collection<LootRecord> lootRecords = new ArrayList<>();
private static Collection<ItemStack> stack(Collection<ItemStack> items)
{
@@ -209,14 +243,33 @@ public class LootTrackerPlugin extends Plugin
lootTrackerClient = null;
}
@Subscribe
public void onLocalPlayerDeath(LocalPlayerDeath event)
{
if (client.getVar(Varbits.IN_WILDERNESS) == 1 || WorldType.isPvpWorld(client.getWorldType()))
{
deathInventorySnapshot();
pvpDeath = true;
}
}
@Subscribe
public void onConfigChanged(ConfigChanged event)
{
if (event.getGroup().equals("loottracker"))
{
ignoredItems = Text.fromCSV(config.getIgnoredItems());
SwingUtilities.invokeLater(panel::updateIgnoredRecords);
if (event.getKey().equals("ignoredItems"))
{
ignoredItems = Text.fromCSV(config.getIgnoredItems());
SwingUtilities.invokeLater(panel::updateIgnoredRecords);
}
if (event.getKey().equals("sortType"))
{
panel.setLootRecordSortType(config.sortType());
SwingUtilities.invokeLater(panel::rebuild);
}
}
}
@Override
@@ -238,9 +291,10 @@ public class LootTrackerPlugin extends Plugin
clientToolbar.addNavigation(navButton);
AccountSession accountSession = sessionManager.getAccountSession();
if (accountSession != null)
LOOT_RECORDS_FILE.createNewFile();
bufferedReader = Files.newBufferedReader(LOOT_RECORDS_FILE.toPath());
if (accountSession != null || config.localPersistence())
{
lootTrackerClient = new LootTrackerClient(accountSession.getUuid());
clientThread.invokeLater(() ->
{
@@ -253,28 +307,42 @@ public class LootTrackerPlugin extends Plugin
executor.submit(() ->
{
Collection<LootRecord> lootRecords;
if (!config.syncPanel())
if (config.syncPanel() && lootTrackerClient != null)
{
return;
lootTrackerClient = new LootTrackerClient(accountSession.getUuid());
try
{
lootRecords = lootTrackerClient.get();
}
catch (IOException e)
{
log.debug("Unable to look up loot", e);
return;
}
log.debug("Loaded {} remote data entries", lootRecords.size());
}
try
if (config.localPersistence() )
{
lootRecords = lootTrackerClient.get();
}
catch (IOException e)
{
log.debug("Unable to look up loot", e);
return;
try
{
lootRecords.addAll(RuneLiteAPI.GSON.fromJson(new FileReader(LOOT_RECORDS_FILE),
new TypeToken<ArrayList<LootRecord>>()
{ }.getType()));
}
catch (IOException e)
{
e.printStackTrace();
}
}
log.debug("Loaded {} data entries", lootRecords.size());
Collection<LootRecord> finalLootRecords = lootRecords;
clientThread.invokeLater(() ->
{
Collection<LootTrackerRecord> records = convertToLootTrackerRecord(lootRecords);
Collection<LootTrackerRecord> records = convertToLootTrackerRecord(finalLootRecords);
SwingUtilities.invokeLater(() -> panel.addRecords(records));
});
});
@@ -288,6 +356,7 @@ public class LootTrackerPlugin extends Plugin
{
clientToolbar.removeNavigation(navButton);
lootTrackerClient = null;
lootRecords = new ArrayList<LootRecord>();
}
@Subscribe
@@ -298,13 +367,29 @@ public class LootTrackerPlugin extends Plugin
final String name = npc.getName();
final int combat = npc.getCombatLevel();
final LootTrackerItem[] entries = buildEntries(stack(items));
SwingUtilities.invokeLater(() -> panel.add(name, combat, entries));
String localUsername = client.getLocalPlayer().getName();
SwingUtilities.invokeLater(() -> panel.add(name, localUsername, combat, entries));
LootRecord lootRecord = new LootRecord( name, localUsername, LootRecordType.NPC,
toGameItems(items), Instant.now());
if (lootTrackerClient != null && config.saveLoot())
{
LootRecord lootRecord = new LootRecord(name, LootRecordType.NPC, toGameItems(items), Instant.now());
lootTrackerClient.submit(lootRecord);
}
if (config.localPersistence())
{
saveLocalLootRecord(lootRecord);
}
}
@Subscribe
public void onPlayerSpawned(PlayerSpawned event)
{
if (event.getPlayer().equals(client.getLocalPlayer()))
{
SwingUtilities.invokeLater(() -> panel.rebuild());
}
}
@Subscribe
@@ -315,13 +400,18 @@ public class LootTrackerPlugin extends Plugin
final String name = player.getName();
final int combat = player.getCombatLevel();
final LootTrackerItem[] entries = buildEntries(stack(items));
SwingUtilities.invokeLater(() -> panel.add(name, combat, entries));
String localUsername = client.getLocalPlayer().getName();
SwingUtilities.invokeLater(() -> panel.add(name, localUsername, combat, entries));
LootRecord lootRecord = new LootRecord( name, localUsername, LootRecordType.PLAYER,
toGameItems(items), Instant.now());
if (lootTrackerClient != null && config.saveLoot())
{
LootRecord lootRecord = new LootRecord(name, LootRecordType.PLAYER, toGameItems(items), Instant.now());
lootTrackerClient.submit(lootRecord);
}
if (config.localPersistence() && lootTrackerClient == null)
{
saveLocalLootRecord(lootRecord);
}
}
@Subscribe
@@ -384,6 +474,11 @@ public class LootTrackerPlugin extends Plugin
.build());
}
if (event.getGroupId() == WidgetID.CHATBOX_GROUP_ID)
{
panel.rebuild();
}
// Convert container items to array of ItemStack
final Collection<ItemStack> items = Arrays.stream(container.getItems())
.filter(item -> item.getId() > 0)
@@ -397,11 +492,12 @@ public class LootTrackerPlugin extends Plugin
}
final LootTrackerItem[] entries = buildEntries(stack(items));
SwingUtilities.invokeLater(() -> panel.add(eventType, -1, entries));
SwingUtilities.invokeLater(() -> panel.add(eventType, client.getLocalPlayer().getName(), -1, entries));
if (lootTrackerClient != null && config.saveLoot())
{
LootRecord lootRecord = new LootRecord(eventType, LootRecordType.EVENT, toGameItems(items), Instant.now());
LootRecord lootRecord = new LootRecord(eventType, client.getLocalPlayer().getName(), LootRecordType.EVENT,
toGameItems(items), Instant.now());
lootTrackerClient.submit(lootRecord);
}
}
@@ -470,6 +566,53 @@ public class LootTrackerPlugin extends Plugin
@Subscribe
public void onItemContainerChanged(ItemContainerChanged event)
{
final ItemContainer itemContainer = event.getItemContainer();
if (pvpDeath && RESPAWN_REGIONS.contains(client.getLocalPlayer().getWorldLocation().getRegionID()))
{
Multiset snapshot = HashMultiset.create();
snapshot = inventorySnapshot;
deathInventorySnapshot();
if (inventorySnapshot != snapshot)
{
inventorySnapshot = snapshot;
ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY);
if (inventorySnapshot != null)
{
Multiset<Integer> currentInventory = HashMultiset.create();
if (inventory != null)
{
Arrays.stream(client.getItemContainer(InventoryID.INVENTORY).getItems())
.forEach(item -> currentInventory.add(item.getId(), item.getQuantity()));
}
final Multiset<Integer> diff = Multisets.difference(inventorySnapshot, currentInventory);
List<ItemStack> itemsLost = diff.entrySet().stream()
.map(e -> new ItemStack(e.getElement(), (-1 * e.getCount()), client.getLocalPlayer().getLocalLocation()))
.collect(Collectors.toList());
final LootTrackerItem[] entries = buildEntries(stack(itemsLost));
String name = "Death: " + client.getLocalPlayer().getName();
SwingUtilities.invokeLater(() -> panel.add(name, client.getLocalPlayer().getName(),
client.getLocalPlayer().getCombatLevel(), entries));
LootRecord lootRecord = new LootRecord(name, client.getLocalPlayer().getName(), LootRecordType.DEATH,
toGameItems(itemsLost), Instant.now());
if (lootTrackerClient != null && config.saveLoot())
{
lootTrackerClient.submit(lootRecord);
}
if (config.localPersistence() && lootTrackerClient == null)
{
saveLocalLootRecord(lootRecord);
}
pvpDeath = false;
inventorySnapshot = null;
}
}
}
if (eventType != null && (CHEST_EVENT_TYPES.containsValue(eventType) || HERBIBOR_EVENT.equals(eventType)))
{
if (event.getItemContainer() != client.getItemContainer(InventoryID.INVENTORY))
@@ -482,6 +625,58 @@ public class LootTrackerPlugin extends Plugin
}
}
private void saveLocalLootRecord(LootRecord lootRecord)
{
lootRecords.add(lootRecord);
try
{
BufferedWriter bufferedWriter = Files.newBufferedWriter(LOOT_RECORDS_FILE.toPath());
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setPrettyPrinting();
Gson gson = gsonBuilder.create();
bufferedWriter.append(gson.toJson(lootRecords));
bufferedWriter.close();
}
catch (IOException e)
{
if (e instanceof FileNotFoundException)
{
try
{
LOOT_RECORDS_FILE.createNewFile();
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
e.printStackTrace();
}
}
/**
* Takes a snapshot of the local player's inventory and equipment right before respawn.
*/
private void deathInventorySnapshot()
{
final ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY);
final ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT);
inventorySnapshot = HashMultiset.create();
if (inventory != null)
{
Arrays.stream(inventory.getItems())
.forEach(item -> inventorySnapshot.add(item.getId(), item.getQuantity()));
}
if (equipment != null)
{
Arrays.stream(equipment.getItems())
.forEach(item -> inventorySnapshot.add(item.getId(), item.getQuantity()));
}
}
private void takeInventorySnapshot()
{
final ItemContainer itemContainer = client.getItemContainer(InventoryID.INVENTORY);
@@ -508,11 +703,12 @@ public class LootTrackerPlugin extends Plugin
.collect(Collectors.toList());
final LootTrackerItem[] entries = buildEntries(stack(items));
SwingUtilities.invokeLater(() -> panel.add(chestType, -1, entries));
SwingUtilities.invokeLater(() -> panel.add(chestType, client.getLocalPlayer().getName(), -1, entries));
if (lootTrackerClient != null && config.saveLoot())
{
LootRecord lootRecord = new LootRecord(chestType, LootRecordType.EVENT, toGameItems(items), Instant.now());
LootRecord lootRecord = new LootRecord(chestType, client.getLocalPlayer().getName(),
LootRecordType.EVENT, toGameItems(items), Instant.now());
lootTrackerClient.submit(lootRecord);
}
@@ -542,6 +738,7 @@ public class LootTrackerPlugin extends Plugin
return ignoredItems.contains(name);
}
@VisibleForTesting
private LootTrackerItem buildLootTrackerItem(int itemId, int quantity)
{
final ItemDefinition itemComposition = itemManager.getItemDefinition(itemId);
@@ -571,7 +768,7 @@ public class LootTrackerPlugin extends Plugin
.collect(Collectors.toList());
}
private Collection<LootTrackerRecord> convertToLootTrackerRecord(final Collection<LootRecord> records)
public Collection<LootTrackerRecord> convertToLootTrackerRecord(final Collection<LootRecord> records)
{
Collection<LootTrackerRecord> trackerRecords = new ArrayList<>();
for (LootRecord record : records)
@@ -580,7 +777,8 @@ public class LootTrackerPlugin extends Plugin
buildLootTrackerItem(itemStack.getId(), itemStack.getQty())
).toArray(LootTrackerItem[]::new);
trackerRecords.add(new LootTrackerRecord(record.getEventId(), "", drops, -1));
trackerRecords.add(new LootTrackerRecord(record.getEventId(), record.getUsername(),
"", drops, -1));
}
return trackerRecords;

View File

@@ -24,13 +24,16 @@
*/
package net.runelite.client.plugins.loottracker;
import com.google.gson.annotations.SerializedName;
import lombok.Value;
@Value
class LootTrackerRecord
{
private final String title;
private String localUsername;
private final String subTitle;
@SerializedName("item_records")
private final LootTrackerItem[] items;
private final long timestamp;