Add local local loottracker data persistence

Signed-off-by: PKLite <stonewall@pklite.xyz>
This commit is contained in:
PKLite
2019-06-07 04:02:15 -04:00
parent 0d0bccada5
commit eee22165a9
2 changed files with 103 additions and 19 deletions

View File

@@ -80,4 +80,16 @@ public interface LootTrackerConfig extends Config
{ {
return true; 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;
}
} }

View File

@@ -30,9 +30,19 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multiset; import com.google.common.collect.Multiset;
import com.google.common.collect.Multisets; 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 com.google.inject.Provides;
import java.awt.image.BufferedImage; 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.io.IOException;
import java.nio.file.Files;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -68,6 +78,7 @@ import net.runelite.api.events.ItemContainerChanged;
import net.runelite.api.events.LocalPlayerDeath; import net.runelite.api.events.LocalPlayerDeath;
import net.runelite.api.events.WidgetLoaded; import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.WidgetID; import net.runelite.api.widgets.WidgetID;
import net.runelite.client.RuneLite;
import net.runelite.client.account.AccountSession; import net.runelite.client.account.AccountSession;
import net.runelite.client.account.SessionManager; import net.runelite.client.account.SessionManager;
import net.runelite.client.callback.ClientThread; import net.runelite.client.callback.ClientThread;
@@ -91,6 +102,7 @@ import net.runelite.client.ui.NavigationButton;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
import net.runelite.client.util.StackFormatter; import net.runelite.client.util.StackFormatter;
import net.runelite.client.util.Text; 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.GameItem;
import net.runelite.http.api.loottracker.LootRecord; import net.runelite.http.api.loottracker.LootRecord;
import net.runelite.http.api.loottracker.LootRecordType; import net.runelite.http.api.loottracker.LootRecordType;
@@ -120,8 +132,9 @@ public class LootTrackerPlugin extends Plugin
11573, "Crystal Chest" 11573, "Crystal Chest"
); );
// Player death handling // Player deaths
private static final String PLAYER_DEATH_MESSAGE = "Oh dear, you are dead!"; private static final String PLAYER_DEATH_MESSAGE = "Oh dear, you are dead!";
private static final File LOOT_RECORDS_FILE = new File(RuneLite.RUNELITE_DIR, "lootRecords.json");
private static final Set<Integer> RESPAWN_REGIONS = ImmutableSet.of( private static final Set<Integer> RESPAWN_REGIONS = ImmutableSet.of(
12850, // Lumbridge 12850, // Lumbridge
11828, // Falador 11828, // Falador
@@ -168,6 +181,9 @@ public class LootTrackerPlugin extends Plugin
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private LootTrackerClient lootTrackerClient; private LootTrackerClient lootTrackerClient;
private BufferedReader bufferedReader;
private JsonStreamParser jsonStreamParser;
private Collection<LootRecord> lootRecords = new ArrayList<>();
private static Collection<ItemStack> stack(Collection<ItemStack> items) private static Collection<ItemStack> stack(Collection<ItemStack> items)
{ {
@@ -263,9 +279,10 @@ public class LootTrackerPlugin extends Plugin
clientToolbar.addNavigation(navButton); clientToolbar.addNavigation(navButton);
AccountSession accountSession = sessionManager.getAccountSession(); 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(() -> clientThread.invokeLater(() ->
{ {
@@ -278,28 +295,41 @@ public class LootTrackerPlugin extends Plugin
executor.submit(() -> 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(); try
} {
catch (IOException e) lootRecords.addAll(RuneLiteAPI.GSON.fromJson(new FileReader(LOOT_RECORDS_FILE),
{ new TypeToken<ArrayList<LootRecord>>()
log.debug("Unable to look up loot", e); { }.getType()));
return; }
catch (IOException e)
{
e.printStackTrace();
}
} }
log.debug("Loaded {} data entries", lootRecords.size());
Collection<LootRecord> finalLootRecords = lootRecords;
clientThread.invokeLater(() -> clientThread.invokeLater(() ->
{ {
Collection<LootTrackerRecord> records = convertToLootTrackerRecord(lootRecords); Collection<LootTrackerRecord> records = convertToLootTrackerRecord(finalLootRecords);
SwingUtilities.invokeLater(() -> panel.addRecords(records)); SwingUtilities.invokeLater(() -> panel.addRecords(records));
}); });
}); });
@@ -324,12 +354,16 @@ public class LootTrackerPlugin extends Plugin
final int combat = npc.getCombatLevel(); final int combat = npc.getCombatLevel();
final LootTrackerItem[] entries = buildEntries(stack(items)); final LootTrackerItem[] entries = buildEntries(stack(items));
SwingUtilities.invokeLater(() -> panel.add(name, combat, entries)); SwingUtilities.invokeLater(() -> panel.add(name, combat, entries));
LootRecord lootRecord = new LootRecord(name, LootRecordType.NPC, toGameItems(items), Instant.now());
if (lootTrackerClient != null && config.saveLoot()) if (lootTrackerClient != null && config.saveLoot())
{ {
LootRecord lootRecord = new LootRecord(name, LootRecordType.NPC, toGameItems(items), Instant.now());
lootTrackerClient.submit(lootRecord); lootTrackerClient.submit(lootRecord);
} }
if (config.localPersistence())
{
saveLocalLootRecord(lootRecord);
}
} }
@Subscribe @Subscribe
@@ -341,12 +375,16 @@ public class LootTrackerPlugin extends Plugin
final int combat = player.getCombatLevel(); final int combat = player.getCombatLevel();
final LootTrackerItem[] entries = buildEntries(stack(items)); final LootTrackerItem[] entries = buildEntries(stack(items));
SwingUtilities.invokeLater(() -> panel.add(name, combat, entries)); SwingUtilities.invokeLater(() -> panel.add(name, combat, entries));
LootRecord lootRecord = new LootRecord(name, LootRecordType.PLAYER, toGameItems(items), Instant.now());
if (lootTrackerClient != null && config.saveLoot()) if (lootTrackerClient != null && config.saveLoot())
{ {
LootRecord lootRecord = new LootRecord(name, LootRecordType.PLAYER, toGameItems(items), Instant.now());
lootTrackerClient.submit(lootRecord); lootTrackerClient.submit(lootRecord);
} }
if (config.localPersistence() && lootTrackerClient == null)
{
saveLocalLootRecord(lootRecord);
}
} }
@Subscribe @Subscribe
@@ -553,13 +591,17 @@ public class LootTrackerPlugin extends Plugin
String name = "Death: " + client.getLocalPlayer().getName(); String name = "Death: " + client.getLocalPlayer().getName();
SwingUtilities.invokeLater(() -> panel.add(name, SwingUtilities.invokeLater(() -> panel.add(name,
client.getLocalPlayer().getCombatLevel(), entries)); client.getLocalPlayer().getCombatLevel(), entries));
LootRecord lootRecord = new LootRecord(name, LootRecordType.DEATH, toGameItems(itemsLost),
Instant.now());
if (lootTrackerClient != null && config.saveLoot()) if (lootTrackerClient != null && config.saveLoot())
{ {
LootRecord lootRecord = new LootRecord(name, LootRecordType.DEATH, toGameItems(itemsLost),
Instant.now());
lootTrackerClient.submit(lootRecord); lootTrackerClient.submit(lootRecord);
} }
if (config.localPersistence() && lootTrackerClient == null)
{
saveLocalLootRecord(lootRecord);
}
pvpDeath = false; pvpDeath = false;
inventorySnapshot = null; inventorySnapshot = null;
@@ -579,6 +621,36 @@ 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. * Takes a snapshot of the local player's inventory and equipment right before respawn.
*/ */