Skip to content

Commit

Permalink
add additional structure to etterna profile save/load
Browse files Browse the repository at this point in the history
  • Loading branch information
MinaciousGrace committed May 7, 2017
1 parent 99b3617 commit ac71458
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 17 deletions.
151 changes: 142 additions & 9 deletions src/Profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1012,11 +1012,32 @@ ProfileLoadResult Profile::LoadEttXmlFromNode(const XNode *xml) {
return ProfileLoadResult_FailedTampered;
}

const XNode* gen = xml->GetChild("GeneralData");
if(gen)
LoadEttGeneralDataFromNode(gen);

LOAD_NODE(GeneralData);
const XNode* favs = xml->GetChild("Favorites");
if(favs)
LoadFavoritesFromNode(favs);

LOG->Warn("wat");

const XNode* goals = xml->GetChild("ScoreGoals");
if(goals)
LoadScoreGoalsFromNode(goals);

LOG->Warn("wat");

const XNode* play = xml->GetChild("Playlists");
if (play)
LoadPlaylistsFromNode(play);

LOG->Warn("wat");

const XNode* scores = xml->GetChild("PlayerScores");
LoadEttScoresFromNode(scores);
if (scores)
LoadEttScoresFromNode(scores);

CalculateStatsFromScores();
return ProfileLoadResult_Success;
}
Expand Down Expand Up @@ -1079,9 +1100,16 @@ XNode *Profile::SaveEttXmlCreateNode() const
{
XNode *xml = new XNode("Stats");
xml->AppendChild(SaveEttGeneralDataCreateNode());
xml->AppendChild(SaveFavoritesCreateNode());
xml->AppendChild(SavePlaylistsCreateNode());
xml->AppendChild(SaveScoreGoalsCreateNode());

if(!FavoritedCharts.empty())
xml->AppendChild(SaveFavoritesCreateNode());

if (!SONGMAN->allplaylists.empty())
xml->AppendChild(SavePlaylistsCreateNode());

if(!goalmap.empty())
xml->AppendChild(SaveScoreGoalsCreateNode());

xml->AppendChild(SaveEttScoresCreateNode());
return xml;
}
Expand Down Expand Up @@ -1366,17 +1394,56 @@ XNode* Profile::SaveScoreGoalsCreateNode() const {
const GoalsForChart& cg = i->second;
goals->AppendChild(cg.CreateNode());
}

return goals;
}

XNode* Profile::SavePlaylistsCreateNode() const {
XNode* playlists = new XNode("PlayLists");
FOREACH_CONST(string, FavoritedCharts, it)
playlists->AppendChild(*it);
XNode* playlists = new XNode("Playlists");
auto& pls = SONGMAN->allplaylists;
FOREACH(Playlist, pls, pl)
playlists->AppendChild(pl->CreateNode());
return playlists;
}

void Profile::LoadFavoritesFromNode(const XNode *pNode) {
FOREACH_CONST_Child(pNode, ck) {
RString tmp = ck->GetName();
bool duplicated = false;
FOREACH(string, FavoritedCharts, chartkey)
if (*chartkey == tmp)
duplicated = true;
if (!duplicated)
FavoritedCharts.emplace_back(tmp);
}
SONGMAN->SetFavoritedStatus(FavoritedCharts);
}

void GoalsForChart::LoadFromNode(const XNode *pNode) {
FOREACH_CONST_Child(pNode, sg) {
ScoreGoal doot;
doot.LoadFromNode(sg);
Add(doot);
}
}

void Profile::LoadScoreGoalsFromNode(const XNode *pNode) {
RString ck;
FOREACH_CONST_Child(pNode, chgoals) {
chgoals->GetAttrValue("Key", ck);
goalmap[ck].LoadFromNode(chgoals);
}
}

void Profile::LoadPlaylistsFromNode(const XNode *pNode) {
auto& pls = SONGMAN->allplaylists;
FOREACH_CONST_Child(pNode, pl) {
Playlist tmp;
tmp.LoadFromNode(pl);
pls.emplace_back(tmp);
}
}


XNode* Profile::SaveEttGeneralDataCreateNode() const
{
XNode* pGeneralDataNode = new XNode("GeneralData");
Expand Down Expand Up @@ -1627,6 +1694,72 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode )

}


void Profile::LoadEttGeneralDataFromNode(const XNode* pNode)
{
ASSERT(pNode->GetName() == "GeneralData");

RString s;
const XNode* pTemp;

pNode->GetChildValue("DisplayName", m_sDisplayName);
pNode->GetChildValue("CharacterID", m_sCharacterID);
pNode->GetChildValue("LastUsedHighScoreName", m_sLastUsedHighScoreName);
pNode->GetChildValue("Guid", m_sGuid);
pNode->GetChildValue("SortOrder", s); m_SortOrder = StringToSortOrder(s);
pNode->GetChildValue("LastDifficulty", s); m_LastDifficulty = StringToDifficulty(s);
pNode->GetChildValue("LastStepsType", s); m_LastStepsType = GAMEMAN->StringToStepsType(s);
pTemp = pNode->GetChild("Song"); if (pTemp) m_lastSong.LoadFromNode(pTemp);
pNode->GetChildValue("CurrentCombo", m_iCurrentCombo);
pNode->GetChildValue("TotalSessions", m_iTotalSessions);
pNode->GetChildValue("TotalSessionSeconds", m_iTotalSessionSeconds);
pNode->GetChildValue("TotalGameplaySeconds", m_iTotalGameplaySeconds);
pNode->GetChildValue("LastPlayedDate", s); m_LastPlayedDate.FromString(s);
pNode->GetChildValue("TotalDancePoints", m_iTotalDancePoints);
pNode->GetChildValue("NumToasties", m_iNumToasties);
pNode->GetChildValue("TotalTapsAndHolds", m_iTotalTapsAndHolds);
pNode->GetChildValue("TotalJumps", m_iTotalJumps);
pNode->GetChildValue("TotalHolds", m_iTotalHolds);
pNode->GetChildValue("TotalRolls", m_iTotalRolls);
pNode->GetChildValue("TotalMines", m_iTotalMines);
pNode->GetChildValue("TotalHands", m_iTotalHands);
pNode->GetChildValue("TotalLifts", m_iTotalLifts);
pNode->GetChildValue("PlayerRating", m_fPlayerRating);

{
const XNode* pDefaultModifiers = pNode->GetChild("DefaultModifiers");
if (pDefaultModifiers)
{
FOREACH_CONST_Child(pDefaultModifiers, game_type)
{
game_type->GetTextValue(m_sDefaultModifiers[game_type->GetName()]);
}
}
}

{
const XNode* pPlayerSkillsets = pNode->GetChild("PlayerSkillsets");
if (pPlayerSkillsets) {
FOREACH_ENUM(Skillset, ss)
pPlayerSkillsets->GetChildValue(SkillsetToString(ss), m_fPlayerSkillsets[ss]);
}
}

const XNode *pUserTable = pNode->GetChild("UserTable");

Lua *L = LUA->Get();

// If we have custom data, load it. Otherwise, make a blank table.
if (pUserTable)
LuaHelpers::CreateTableFromXNode(L, pUserTable);
else
lua_newtable(L);

m_UserTable.SetFromStack(L);
LUA->Release(L);

}

void Profile::AddStepTotals( int iTotalTapsAndHolds, int iTotalJumps, int iTotalHolds, int iTotalRolls, int iTotalMines, int iTotalHands, int iTotalLifts)
{
m_iTotalTapsAndHolds += iTotalTapsAndHolds;
Expand Down
11 changes: 8 additions & 3 deletions src/Profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,13 @@ class ScoreGoal

struct GoalsForChart {
public:
XNode* CreateNode() const;

void Add(ScoreGoal& sg) { goals.emplace_back(sg); }
vector<ScoreGoal>& Get() { return goals; }
vector<ScoreGoal> goals;

XNode* CreateNode() const;
void LoadFromNode(const XNode *pNode);
};

/**
Expand Down Expand Up @@ -259,8 +262,9 @@ class Profile
XNode* SaveFavoritesCreateNode() const;
XNode* SaveScoreGoalsCreateNode() const;
XNode* SavePlaylistsCreateNode() const;
void LoadFavoritesFromNode();

void LoadFavoritesFromNode(const XNode *pNode);
void LoadScoreGoalsFromNode(const XNode *pNode);
void LoadPlaylistsFromNode(const XNode *pNode);

// more future goalman stuff -mina
void CreateGoal(string& ck);
Expand Down Expand Up @@ -370,6 +374,7 @@ class Profile
// Etterna profile
ProfileLoadResult LoadEttFromDir(RString dir);
ProfileLoadResult LoadEttXmlFromNode(const XNode* pNode);
void LoadEttGeneralDataFromNode(const XNode* pNode);
void LoadEttScoresFromNode(const XNode* pNode);

bool SaveEttXmlToDir(RString sDir) const;
Expand Down
7 changes: 5 additions & 2 deletions src/ScoreManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,15 @@ vector<string> ScoresForChart::GetPlayedRateDisplayStrings() {
}

string ScoresForChart::RateKeyToDisplayString(float rate) {
rate = 0.9f;

string rs = ssprintf("%.2f", rate);
int j = 1;
if (rs.find_last_not_of('0') == rs.find('.'))
j = 2;
rs.erase(rs.find_last_not_of('0') + j, rs.npos);
rs.append("x");
LOG->Warn(rs.c_str());
return rs;
}

Expand Down Expand Up @@ -248,11 +251,11 @@ XNode * ScoresForChart::CreateNode(const string& ck) const {
XNode* o = new XNode("ChartScores");
Song* song = SONGMAN->GetSongByChartkey(ck);
if (song) {
o->AppendAttr("Song", song->GetDisplayMainTitle());
o->AppendAttr("Pack", song->m_sGroupName);
o->AppendAttr("Song", song->GetDisplayMainTitle());
} else {
o->AppendAttr("Song", LastSeenSong);
o->AppendAttr("Pack", LastSeenPack);
o->AppendAttr("Song", LastSeenSong);
}

FOREACHM_CONST(int, ScoresAtRate, ScoresByRate, i)
Expand Down
2 changes: 1 addition & 1 deletion src/ScoreManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class ScoreManager
HighScore * GetTopSSRHighScore(unsigned int rank, int ss);

bool KeyHasScores(const string& ck) { return pscores.count(ck) == 1; }

bool HasAnyScores() { return !AllScores.empty(); }



Expand Down
40 changes: 40 additions & 0 deletions src/SongManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,46 @@ void SongManager::InitSongsFromDisk( LoadingWindow *ld )
LOG->Trace( "Found %d songs in %f seconds.", (int)m_pSongs.size(), tm.GetDeltaTime() );
}



XNode* Playlist::CreateNode() const {
XNode* pl = new XNode("Playlist");
pl->AppendAttr("Name", name);

FOREACH_CONST(Chart, chartlist, ch) {
XNode* chart = new XNode(ch->key);
Song* song = SONGMAN->GetSongByChartkey(ch->key);
if (song) {
chart->AppendAttr("Pack", song->m_sGroupName);
chart->AppendAttr("Song", song->GetDisplayMainTitle());

}
else {
chart->AppendAttr("Pack", ch->lastpack);
chart->AppendAttr("Song", ch->lastsong);
}
pl->AppendChild(chart);
}

return pl;
}
void Playlist::LoadFromNode(const XNode* node) {
node->GetAttrValue("Name", name);
FOREACH_CONST_Child(node, chart) {
Chart ch;
ch.key = chart->GetName();
chart->GetAttrValue("Pack", ch.lastpack);
chart->GetAttrValue("Song", ch.lastsong);

Song* song = SONGMAN->GetSongByChartkey(ch.key);
if (song) {
ch.lastpack = song->m_sGroupName;
ch.lastsong = song->GetDisplayMainTitle();
}
chartlist.emplace_back(ch);
}
}

// Only store 1 steps/song pointer per key -Mina
void SongManager::AddKeyedPointers(Song* new_song) {
const vector<Steps*> steps = new_song->GetAllSteps();
Expand Down
34 changes: 32 additions & 2 deletions src/SongManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,39 @@ struct lua_State;
#include "RageUtil.h"
#include "Profile.h"

#include <unordered_map>
using std::string;

RString SONG_GROUP_COLOR_NAME( size_t i );
bool CompareNotesPointersForExtra(const Steps *n1, const Steps *n2);

/** @brief The max number of edit steps a profile can have. */
const int MAX_EDIT_STEPS_PER_PROFILE = 200;


struct Chart {
string key;
RString lastsong;
RString lastpack;
};

struct Playlist {
RString name;
vector<Chart> chartlist;
void Add(Chart ch) { chartlist.emplace_back(ch); }
void SwapPosition();


XNode* CreateNode() const;
void LoadFromNode(const XNode* node);

void PushSelf(lua_State *L);
};





/** @brief The holder for the Songs and its Steps. */
class SongManager
{
Expand Down Expand Up @@ -140,6 +167,9 @@ class SongManager
// Lua
void PushSelf( lua_State *L );


vector<Playlist> allplaylists;

protected:
void LoadStepManiaSongDir( RString sDir, LoadingWindow *ld );
void LoadDWISongDir( const RString &sDir );
Expand All @@ -154,8 +184,8 @@ class SongManager

// Indexed by chartkeys
void AddKeyedPointers(Song* new_song);
map<RString, Song*> SongsByKey;
map<RString, Steps*> StepsByKey;
unordered_map<string, Song*> SongsByKey;
unordered_map<string, Steps*> StepsByKey;

set<RString> m_GroupsToNeverCache;
/** @brief Hold pointers to all the songs that have been deleted from disk but must at least be kept temporarily alive for smooth audio transitions. */
Expand Down

0 comments on commit ac71458

Please sign in to comment.