diff --git a/src/HighScore.cpp b/src/HighScore.cpp index 6d06b1514c..18654ce0f1 100644 --- a/src/HighScore.cpp +++ b/src/HighScore.cpp @@ -73,6 +73,8 @@ struct HighScoreImpl RString NoteRowsToString(vector v) const; vector NoteRowsToVector(RString s); + bool is39import = false; + bool operator==( const HighScoreImpl& other ) const; bool operator!=( const HighScoreImpl& other ) const { return !(*this == other); } }; @@ -468,6 +470,52 @@ void HighScoreImpl::LoadFromNode(const XNode *pNode) UnloadReplayData(); } // Validate input. + + // 3.9 conversion stuff (wtf is this code??) -mina + if (pTapNoteScores) + FOREACH_ENUM(TapNoteScore, tns) { + pTapNoteScores->GetChildValue(TapNoteScoreToString(tns), iTapNoteScores[tns]); + if (tns == TNS_W1 && iTapNoteScores[tns] == 0) { + int old = iTapNoteScores[tns]; + pTapNoteScores->GetChildValue("Marvelous", iTapNoteScores[tns]); + + // only mark as import if loading the other tag changes the values + if(old != iTapNoteScores[tns]) + is39import = true; + } + else if (tns == TNS_W2 && iTapNoteScores[tns] == 0) + pTapNoteScores->GetChildValue("Perfect", iTapNoteScores[tns]); + else if (tns == TNS_W3 && iTapNoteScores[tns] == 0) + pTapNoteScores->GetChildValue("Great", iTapNoteScores[tns]); + else if (tns == TNS_W4 && iTapNoteScores[tns] == 0) + pTapNoteScores->GetChildValue("Good", iTapNoteScores[tns]); + else if (tns == TNS_W5 && iTapNoteScores[tns] == 0) + pTapNoteScores->GetChildValue("Boo", iTapNoteScores[tns]); + } + + if (pHoldNoteScores) + FOREACH_ENUM(HoldNoteScore, hns) { + pHoldNoteScores->GetChildValue(HoldNoteScoreToString(hns), iHoldNoteScores[hns]); + if (hns == HNS_Held && iHoldNoteScores[hns] == 0) + pHoldNoteScores->GetChildValue("OK", iHoldNoteScores[hns]); + else if (hns == HNS_LetGo && iHoldNoteScores[hns] == 0) + pHoldNoteScores->GetChildValue("NG", iHoldNoteScores[hns]); + } + + int basecmod = 0; + + // 3.9 doesnt save rates lol.... + if (is39import && basecmod > 0) { + string cmod = sModifiers.substr(0, sModifiers.find_first_of(",")); + if (cmod.substr(0, 1) == "C") { + int playedcmod = StringToInt(cmod.substr(1, cmod.size())); + float estrate = static_cast(basecmod) / static_cast(playedcmod); + int herp = lround(estrate * 10); + estrate = herp / 10.f; + fMusicRate = estrate; + } + } + grade = clamp( grade, Grade_Tier01, Grade_Failed ); } @@ -593,6 +641,8 @@ bool HighScore::IsEmpty() const return true; } +bool HighScore::Is39import() const { return m_Impl->is39import; } + string HighScore::GetName() const { return m_Impl->sName; } string HighScore::GetChartKey() const { return m_Impl->ChartKey; } int HighScore::GetSSRCalcVersion() const { return m_Impl->SSRCalcVersion; } diff --git a/src/HighScore.h b/src/HighScore.h index 2dbd1a597e..17ec92809c 100644 --- a/src/HighScore.h +++ b/src/HighScore.h @@ -133,6 +133,8 @@ struct HighScore void UnloadReplayData(); void ResetSkillsets(); + bool Is39import() const; + string GetDisplayName() const; // Mina stuff - Mina diff --git a/src/Profile.cpp b/src/Profile.cpp index 5e18b69c91..e6ed308813 100644 --- a/src/Profile.cpp +++ b/src/Profile.cpp @@ -1931,6 +1931,8 @@ void Profile::ImportScoresToEtterna() { int notloaded = 0; LOG->Trace("Beginning import of stats.xml scores"); + const vector& songs = SONGMAN->GetAllSongs(); + string ck; FOREACHM(SongID, HighScoresForASong, m_SongHighScores, i) { SongID id = i->first; @@ -1978,7 +1980,7 @@ void Profile::ImportScoresToEtterna() { for (size_t i = 0; i < hsv.size(); ++i) { HighScore hs = hsv[i]; // ignore historic key and just load from here since the hashing function was changed anyway - hs.SetChartKey(ck); + hs.SetChartKey(ck); SCOREMAN->AddScore(hs); ++loaded; } @@ -1986,14 +1988,39 @@ void Profile::ImportScoresToEtterna() { } // if we still haven't correlated a score to a key, match by song title and number of notes - // score import is meant to be a qol and pre-existing scores need not undergo strict filtering - // edit: this is mostly broken since the idea is to catch renamed packs, if the pack was renamed - // the id won't be valid. Need to strip group names from all loaded songdirs and match the latter - // half and then load any matched songs and attempt matches -mina - if (id.IsValid()) { - vector& hsv = j->second.hsl.vHighScores; + // score import is meant to be a qol and pre-existing scores need not undergo strict filtering -mina + if (!id.IsValid()) { + string unloaded = id.ToString(); + unloaded = unloaded.substr(0, unloaded.size() - 1); + int jjq = unloaded.find_last_of("/"); + unloaded = unloaded.substr(jjq + 1, unloaded.size() - jjq); + + LOG->Trace("Unloaded to be matched %s", id.ToString()); + + for (size_t i = 0; i < songs.size(); ++i) { + SongID matchid; + matchid.FromSong(songs[i]); + + string matchstring = matchid.ToString(); + matchstring = matchstring.substr(0, matchstring.size() - 1); + jjq = matchstring.find_last_of("/"); + matchstring = matchstring.substr(jjq + 1, matchstring.size() - jjq); + + if (unloaded == matchstring) { + LOG->Trace("Match at %s", matchid.ToString()); + id = matchid; + break; + } + } + Song* song = id.ToSong(); - const vector& songs = SONGMAN->GetAllSongs(); + + if (!song) { + LOG->Trace("no match found"); + continue; + } + + vector& hsv = j->second.hsl.vHighScores; string title = song->GetDisplayMainTitle(); for (size_t i = 0; i < hsv.size(); ++i) { @@ -2004,12 +2031,7 @@ void Profile::ImportScoresToEtterna() { bool matched = false; for (size_t j = 0; j < demsteps.size(); ++j) { Steps* steps = demsteps[j]; - if (!steps) { - LOG->Warn("What????"); - continue; - } - - int notes = steps->GetRadarValues()[RadarCategory_Notes]; + int notes = steps->GetRadarValues()[RadarCategory_TapsAndHolds]; int snotes = 0; snotes += tmp.GetTapNoteScore(TNS_Miss); @@ -2020,13 +2042,24 @@ void Profile::ImportScoresToEtterna() { snotes += tmp.GetTapNoteScore(TNS_W5); if (notes == snotes) { - LOG->Warn("Matched based on note count"); - ck = steps->GetChartKey(); + LOG->Trace("Matched based on taps count"); + matched = true; + break; + } + + notes = steps->GetRadarValues()[RadarCategory_Notes]; + + if (notes == snotes) { + LOG->Trace("Matched based on notes count"); matched = true; - SCOREMAN->AddScore(tmp); - loaded++; break; } + + if (matched) { + ck = steps->GetChartKey(); + loaded++; + SCOREMAN->AddScore(tmp); + } } } }