diff --git a/src/HighScore.cpp b/src/HighScore.cpp index fd76c12e98..f9557e9bc9 100644 --- a/src/HighScore.cpp +++ b/src/HighScore.cpp @@ -9,6 +9,10 @@ #include "Foreach.h" #include "RadarValues.h" #include +#include +#include +#include "CryptManager.h" +#include "ProfileManager.h" ThemeMetric EMPTY_NAME("HighScore","EmptyName"); @@ -16,6 +20,7 @@ struct HighScoreImpl { RString sName; // name that shows in the machine's ranking screen RString sHistoricChartKey; + RString ScoreKey; float SSRCalcVersion; Grade grade; unsigned int iScore; @@ -46,6 +51,8 @@ struct HighScoreImpl XNode *CreateNode() const; void LoadFromNode( const XNode *pNode ); + void WriteReplayFile(); + float RescoreToWifeTS(float ts); RString OffsetsToString(vector v) const; @@ -165,6 +172,7 @@ HighScoreImpl::HighScoreImpl() { sName = ""; sHistoricChartKey = ""; + ScoreKey = ""; SSRCalcVersion = 0.f; grade = Grade_NoData; iScore = 0; @@ -200,6 +208,7 @@ XNode *HighScoreImpl::CreateNode() const // TRICKY: Don't write "name to fill in" markers. pNode->AppendChild( "Name", IsRankingToFillIn(sName) ? RString("") : sName ); pNode->AppendChild( "HistoricChartKey", sHistoricChartKey); + pNode->AppendChild(" ScoreKey", ScoreKey); pNode->AppendChild( "SSRCalcVersion", SSRCalcVersion); pNode->AppendChild( "Grade", GradeToString(grade) ); pNode->AppendChild( "Score", iScore ); @@ -277,6 +286,8 @@ void HighScoreImpl::LoadFromNode(const XNode *pNode) } } pNode->GetChildValue( "DateTime", s ); dateTime.FromString( s ); + ScoreKey = "S" + BinaryToHex(CryptManager::GetSHA1ForString(dateTime.GetString())); + pNode->GetChildValue( "PlayerGuid", sPlayerGuid ); pNode->GetChildValue( "MachineGuid", sMachineGuid ); pNode->GetChildValue( "ProductID", iProductID ); @@ -305,11 +316,32 @@ void HighScoreImpl::LoadFromNode(const XNode *pNode) // special test case stuff - mina //if (vOffsetVector.size() > 1 && fWifeScore == 0.f) // fWifeScore = RescoreToWifeTS(fJudgeScale); - + if (vNoteRowVector.size() + vOffsetVector.size() > 2 && (vNoteRowVector.size() == vOffsetVector.size() )) + WriteReplayFile(); // Validate input. grade = clamp( grade, Grade_Tier01, Grade_Failed ); } +void HighScoreImpl::WriteReplayFile() { + RString append; + //open file + RString profiledir = PROFILEMAN->currentlyloadingprofile; + ofstream fileStream(profiledir + "ReplayData/" + ScoreKey, ios::binary); + //check file + if (!fileStream) + LOG->Warn("Failed to create replay file"); + + unsigned int idx = vNoteRowVector.size() - 1; + //loop for writing both vectors side by side + for (unsigned int i = 0; i < idx; i++) { + append = to_string(vNoteRowVector[i]) + " " + to_string(vOffsetVector[i]) + "\n"; + fileStream.write(append.c_str(), append.size()); + } + append = to_string(vNoteRowVector[idx]) + " " + to_string(vOffsetVector[idx]); + fileStream.write(append.c_str(), append.size()); + fileStream.close(); +} + REGISTER_CLASS_TRAITS( HighScoreImpl, new HighScoreImpl(*pCopy) ) HighScore::HighScore() diff --git a/src/Profile.cpp b/src/Profile.cpp index 94d184e361..e36f1817e5 100644 --- a/src/Profile.cpp +++ b/src/Profile.cpp @@ -43,6 +43,7 @@ const RString EDIT_STEPS_SUBDIR = "Edits/"; const RString EDIT_COURSES_SUBDIR = "EditCourses/"; //const RString UPLOAD_SUBDIR = "Upload/"; const RString RIVAL_SUBDIR = "Rivals/"; +const RString REPLAY_SUBDIR = "ReplayData/"; ThemeMetric SHOW_COIN_DATA( "Profile", "ShowCoinData" ); static Preference g_bProfileDataCompress( "ProfileDataCompress", false ); @@ -1134,9 +1135,10 @@ void Profile::HandleStatsPrefixChange(RString dir, bool require_signature) SaveAllToDir(dir, require_signature); } } - + ProfileLoadResult Profile::LoadAllFromDir( const RString &sDir, bool bRequireSignature ) { + FILEMAN->CreateDir(sDir + REPLAY_SUBDIR); LOG->Trace( "Profile::LoadAllFromDir( %s )", sDir.c_str() ); ASSERT( sDir.Right(1) == "/" ); @@ -1332,6 +1334,7 @@ bool Profile::SaveAllToDir( const RString &sDir, bool bSignData ) const FILEMAN->CreateDir( sDir + EDIT_COURSES_SUBDIR ); FILEMAN->CreateDir( sDir + SCREENSHOTS_SUBDIR ); FILEMAN->CreateDir( sDir + RIVAL_SUBDIR ); + FILEMAN->CreateDir( sDir + REPLAY_SUBDIR); /* Get the theme's custom save function: * [Profile] diff --git a/src/Profile.h b/src/Profile.h index ea4e10c5ee..e806081055 100644 --- a/src/Profile.h +++ b/src/Profile.h @@ -45,6 +45,7 @@ extern const RString DONT_SHARE_SIG; extern const RString PUBLIC_KEY_FILE; extern const RString SCREENSHOTS_SUBDIR; +extern const RString REPLAY_SUBDIR; extern const RString EDIT_STEPS_SUBDIR; extern const RString EDIT_COURSES_SUBDIR; extern const RString LASTGOOD_SUBDIR; diff --git a/src/ProfileManager.cpp b/src/ProfileManager.cpp index bb4491d3a0..c346c1c4f5 100644 --- a/src/ProfileManager.cpp +++ b/src/ProfileManager.cpp @@ -470,6 +470,7 @@ void ProfileManager::RefreshLocalProfilesFromDisk() add_category_to_global_list(categorized_profiles[ProfileType_Test]); FOREACH(DirAndProfile, g_vLocalProfile, curr) { + currentlyloadingprofile = curr->sDir.substr(1); curr->profile.LoadAllFromDir(curr->sDir, PREFSMAN->m_bSignProfileData); } } diff --git a/src/ProfileManager.h b/src/ProfileManager.h index 74398c4172..c46d5634a0 100644 --- a/src/ProfileManager.h +++ b/src/ProfileManager.h @@ -110,6 +110,7 @@ class ProfileManager static Preference m_bProfileStepEdits; static Preference m_bProfileCourseEdits; static Preference1D m_sDefaultLocalProfileID; + RString currentlyloadingprofile; private: ProfileLoadResult LoadProfile( PlayerNumber pn, const RString &sProfileDir, bool bIsMemCard );