Skip to content

Commit

Permalink
xp tracker: save and restore state
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam- committed Feb 2, 2025
1 parent 7429c9c commit 1eb5a22
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -957,10 +957,11 @@ public <T> void setRSProfileConfiguration(String groupName, String key, T value)
}

rsProfileKey = prof.getKey();
String previousProfile = this.rsProfileKey;
this.rsProfileKey = rsProfileKey;

log.debug("RS profile changed to {}", rsProfileKey);
eventBus.post(new RuneScapeProfileChanged());
eventBus.post(new RuneScapeProfileChanged(previousProfile, rsProfileKey));
}
setConfiguration(groupName, rsProfileKey, key, value);
}
Expand Down Expand Up @@ -1564,10 +1565,11 @@ private void updateRSProfile()
{
return;
}
String previousProfile = rsProfileKey;
rsProfileKey = key;

log.debug("RS profile changed to {}", key);
eventBus.post(new RuneScapeProfileChanged());
eventBus.post(new RuneScapeProfileChanged(previousProfile, key));
}

@Subscribe
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,20 @@
*/
package net.runelite.client.events;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import lombok.Value;

/**
* Posted when the user switches to a different RuneScape save profile
* This might be because they logged into a different account, or hopped
* to/from a Beta/Tournament/DMM/Leagues world
*/
@Value
public class RuneScapeProfileChanged
{
@Nullable
String previousProfile;
@Nonnull
String newProfile;
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,21 +191,14 @@ void resetAllInfoBoxes()

void resetSkill(Skill skill)
{
XpInfoBox xpInfoBox = infoBoxes.get(skill);
if (xpInfoBox != null)
{
xpInfoBox.reset();
}
final XpInfoBox xpInfoBox = infoBoxes.get(skill);
xpInfoBox.reset();
}

void updateSkillExperience(boolean updated, boolean paused, Skill skill, XpSnapshotSingle xpSnapshotSingle)
{
final XpInfoBox xpInfoBox = infoBoxes.get(skill);

if (xpInfoBox != null)
{
xpInfoBox.update(updated, paused, xpSnapshotSingle);
}
xpInfoBox.update(updated, paused, xpSnapshotSingle);
}

void updateTotal(XpSnapshotSingle xpSnapshotTotal)
Expand All @@ -230,5 +223,4 @@ private void rebuildAsync(XpSnapshotSingle xpSnapshotTotal)
overallExpGained.setText(XpInfoBox.htmlLabel("Gained: ", xpSnapshotTotal.getXpGainedInSession()));
overallExpHour.setText(XpInfoBox.htmlLabel("Per hour: ", xpSnapshotTotal.getXpPerHour()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2025, Adam <Adam@sigterm.info>
* 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.xptracker;

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import com.google.inject.Inject;
import java.util.HashMap;
import java.util.Map;
import net.runelite.api.Skill;
import net.runelite.client.config.ConfigSerializer;
import net.runelite.client.config.Serializer;

@ConfigSerializer(XpSaveSerializer.class)
class XpSave
{
Map<Skill, XpSaveSingle> skills = new HashMap<>();
XpSaveSingle overall;
}

class XpSaveSingle
{
@SerializedName("s")
long startXp;
@SerializedName("br")
int xpGainedBeforeReset;
@SerializedName("ar")
int xpGainedSinceReset;
@SerializedName("t")
long time; // ms
}

class XpSaveSerializer implements Serializer<XpSave>
{
private final Gson gson;

@Inject
private XpSaveSerializer(Gson gson)
{
this.gson = gson;
}

@Override
public String serialize(XpSave value)
{
return gson.toJson(value);
}

@Override
public XpSave deserialize(String s)
{
return gson.fromJson(s, XpSave.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@

/**
* Internal state for the XpTrackerPlugin
* <p>
* Note: This class's operations are not currently synchronized.
* It is intended to be called by the XpTrackerPlugin on the client thread.
*/
class XpState
{
Expand Down Expand Up @@ -213,4 +210,39 @@ XpSnapshotSingle getTotalSnapshot()
{
return overall.snapshot();
}

XpSave save()
{
if (overall.getStartXp() == -1)
{
return null;
}

XpSave save = new XpSave();
for (Map.Entry<Skill, XpStateSingle> entry : xpSkills.entrySet())
{
XpStateSingle state = entry.getValue();
if (state.getTotalXpGained() > 0)
{
save.skills.put(entry.getKey(), state.save());
}
}
save.overall = overall.save();
return save;
}

void restore(XpSave save)
{
reset();

for (Map.Entry<Skill, XpSaveSingle> entry : save.skills.entrySet())
{
Skill skill = entry.getKey();
XpSaveSingle s = entry.getValue();
XpStateSingle state = new XpStateSingle(s.startXp);
state.restore(s);
xpSkills.put(skill, state);
}
overall.restore(save.overall);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ class XpStateSingle

private int xpGainedBeforeReset = 0;

// how long the skill has been trained for in ms
@Setter
private long skillTime = 0;
// the last time the skill xp changed in ms
@Getter
private long lastChangeMillis;

Expand All @@ -68,12 +70,6 @@ long getCurrentXp()
return startXp + getTotalXpGained();
}

void setXpGainedSinceReset(int xpGainedSinceReset)
{
this.xpGainedSinceReset = xpGainedSinceReset;
lastChangeMillis = System.currentTimeMillis();
}

int getTotalXpGained()
{
return xpGainedBeforeReset + xpGainedSinceReset;
Expand Down Expand Up @@ -213,7 +209,8 @@ void resetPerHour()

//reset xp per hour
xpGainedBeforeReset += xpGainedSinceReset;
setXpGainedSinceReset(0);
xpGainedSinceReset = 0;
lastChangeMillis = System.currentTimeMillis();
setSkillTime(0);
}

Expand Down Expand Up @@ -251,7 +248,8 @@ boolean update(long currentXp)
actionsSinceReset++;

// Calculate experience gained
setXpGainedSinceReset((int) (currentXp - (startXp + xpGainedBeforeReset)));
xpGainedSinceReset = (int) (currentXp - (startXp + xpGainedBeforeReset));
lastChangeMillis = System.currentTimeMillis();

return true;
}
Expand Down Expand Up @@ -309,4 +307,22 @@ XpSnapshotSingle snapshot()
.endGoalXp(endLevelExp)
.build();
}

XpSaveSingle save()
{
XpSaveSingle save = new XpSaveSingle();
save.startXp = startXp;
save.xpGainedBeforeReset = xpGainedBeforeReset;
save.xpGainedSinceReset = xpGainedSinceReset;
save.time = skillTime;
return save;
}

void restore(XpSaveSingle save)
{
startXp = save.startXp;
xpGainedBeforeReset = save.xpGainedBeforeReset;
xpGainedSinceReset = save.xpGainedSinceReset;
skillTime = save.time;
}
}
Loading

0 comments on commit 1eb5a22

Please sign in to comment.