From 74f675acee6de7c50114369c8fb69a43a464bcba Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sat, 8 Aug 2009 06:57:55 +0000 Subject: [PATCH] dump recent scores to separate XML files for uploading to a web service instead of saving in stats.xml --- stepmania/src/Profile.cpp | 200 ++++++++++--------------------- stepmania/src/Profile.h | 25 ++-- stepmania/src/ProfileManager.cpp | 8 +- stepmania/src/StepMania.cpp | 30 +---- 4 files changed, 81 insertions(+), 182 deletions(-) diff --git a/stepmania/src/Profile.cpp b/stepmania/src/Profile.cpp index 48339ee7cb..b093d14b4a 100644 --- a/stepmania/src/Profile.cpp +++ b/stepmania/src/Profile.cpp @@ -37,6 +37,7 @@ const RString PUBLIC_KEY_FILE = "public.key"; const RString SCREENSHOTS_SUBDIR = "Screenshots/"; const RString EDIT_STEPS_SUBDIR = "Edits/"; const RString EDIT_COURSES_SUBDIR = "EditCourses/"; +const RString UPLOAD_SUBDIR = "Upload/"; ThemeMetric SHOW_COIN_DATA( "Profile", "ShowCoinData" ); static Preference g_bProfileDataCompress( "ProfileDataCompress", false ); @@ -177,16 +178,6 @@ void Profile::InitCalorieData() m_mapDayToCaloriesBurned.clear(); } -void Profile::InitRecentSongScores() -{ - m_vRecentStepsScores.clear(); -} - -void Profile::InitRecentCourseScores() -{ - m_vRecentCourseScores.clear(); -} - RString Profile::GetDisplayNameOrHighScoreName() const { if( !m_sDisplayName.empty() ) @@ -919,8 +910,6 @@ ProfileLoadResult Profile::LoadStatsXmlFromNode( const XNode *xml, bool bIgnoreE LOAD_NODE( CategoryScores ); LOAD_NODE( ScreenshotData ); LOAD_NODE( CalorieData ); - LOAD_NODE( RecentSongScores ); - LOAD_NODE( RecentCourseScores ); if( bIgnoreEditable ) { @@ -967,8 +956,6 @@ XNode *Profile::SaveStatsXmlCreateNode() const xml->AppendChild( SaveCategoryScoresCreateNode() ); xml->AppendChild( SaveScreenshotDataCreateNode() ); xml->AppendChild( SaveCalorieDataCreateNode() ); - xml->AppendChild( SaveRecentSongScoresCreateNode() ); - xml->AppendChild( SaveRecentCourseScoresCreateNode() ); if( SHOW_COIN_DATA.GetValue() && IsMachine() ) xml->AppendChild( SaveCoinDataCreateNode() ); @@ -1748,6 +1735,22 @@ float Profile::GetCaloriesBurnedForDay( DateTime day ) const return i->second.fCals; } +static void SaveRecentScore( XNode* xml ) +{ + RString sDate = DateTime::GetNowDate().GetString(); + sDate.Replace(":","-"); + + RString sFileNameNoExtension = Profile::MakeUniqueFileNameNoExtension(UPLOAD_SUBDIR, sDate ); + RString fn = UPLOAD_SUBDIR + sFileNameNoExtension + ".xml"; + + if( !XmlFileUtil::SaveToFile( xml, fn, STATS_XSL, false ) ) + return; + + RString sStatsXmlSigFile = fn+SIGNATURE_APPEND; + CryptManager::SignFileToFile(fn, sStatsXmlSigFile); +} + + XNode* Profile::HighScoreForASongAndSteps::CreateNode() const { XNode* pNode = new XNode( "HighScoreForASongAndSteps" ); @@ -1759,57 +1762,7 @@ XNode* Profile::HighScoreForASongAndSteps::CreateNode() const return pNode; } -void Profile::HighScoreForASongAndSteps::LoadFromNode( const XNode* pNode ) -{ - Unset(); - - ASSERT( pNode->GetName() == "HighScoreForASongAndSteps" ); - const XNode* p; - if( (p = pNode->GetChild("Song")) ) - songID.LoadFromNode( p ); - if( (p = pNode->GetChild("Steps")) ) - stepsID.LoadFromNode( p ); - if( (p = pNode->GetChild("HighScore")) ) - hs.LoadFromNode( p ); -} - -void Profile::LoadRecentSongScoresFromNode( const XNode* pRecentSongScores ) -{ - CHECKPOINT; - - ASSERT( pRecentSongScores->GetName() == "RecentSongScores" ); - FOREACH_CONST_Child( pRecentSongScores, p ) - { - if( p->GetName() == "HighScoreForASongAndSteps" ) - { - HighScoreForASongAndSteps h; - h.LoadFromNode( p ); - - m_vRecentStepsScores.push_back( h ); - } - else - { - WARN_AND_CONTINUE_M( p->GetName() ); - } - } -} - -XNode* Profile::SaveRecentSongScoresCreateNode() const -{ - CHECKPOINT; - - const Profile* pProfile = this; - ASSERT( pProfile ); - - XNode* pNode = new XNode( "RecentSongScores" ); - - FOREACHD_CONST( HighScoreForASongAndSteps, m_vRecentStepsScores, i ) - pNode->AppendChild( i->CreateNode() ); - - return pNode; -} - -void Profile::AddStepsRecentScore( const Song* pSong, const Steps* pSteps, HighScore hs ) +void Profile::SaveStepsRecentScore( const Song* pSong, const Steps* pSteps, HighScore hs ) { ASSERT( pSong ); ASSERT( pSteps ); @@ -1819,12 +1772,13 @@ void Profile::AddStepsRecentScore( const Song* pSong, const Steps* pSteps, HighS h.stepsID.FromSteps( pSteps ); ASSERT( h.stepsID.IsValid() ); h.hs = hs; - m_vRecentStepsScores.push_back( h ); - int iMaxRecentScoresToSave = IsMachine() ? PREFSMAN->m_iMaxRecentScoresForMachine : PREFSMAN->m_iMaxRecentScoresForPlayer; - int iNumToErase = m_vRecentStepsScores.size() - iMaxRecentScoresToSave; - if( iNumToErase > 0 ) - m_vRecentStepsScores.erase( m_vRecentStepsScores.begin(), m_vRecentStepsScores.begin() + iNumToErase ); + auto_ptr xml( new XNode("Stats") ); + xml->AppendChild( "MachineGuid", PROFILEMAN->GetMachineProfile()->m_sGuid ); + XNode *recent = xml->AppendChild( new XNode("RecentSongScores") ); + recent->AppendChild( h.CreateNode() ); + + SaveRecentScore( xml.get() ); } @@ -1839,76 +1793,19 @@ XNode* Profile::HighScoreForACourseAndTrail::CreateNode() const return pNode; } -void Profile::HighScoreForACourseAndTrail::LoadFromNode( const XNode* pNode ) -{ - Unset(); - - ASSERT( pNode->GetName() == "HighScoreForACourseAndTrail" ); - const XNode* p; - if( (p = pNode->GetChild("Course")) ) - courseID.LoadFromNode( p ); - if( (p = pNode->GetChild("Trail")) ) - trailID.LoadFromNode( p ); - if( (p = pNode->GetChild("HighScore")) ) - hs.LoadFromNode( p ); -} - -void Profile::LoadRecentCourseScoresFromNode( const XNode* pRecentCourseScores ) -{ - CHECKPOINT; - - ASSERT( pRecentCourseScores->GetName() == "RecentCourseScores" ); - FOREACH_CONST_Child( pRecentCourseScores, p ) - { - if( p->GetName() == "HighScoreForACourseAndTrail" ) - { - HighScoreForACourseAndTrail h; - h.LoadFromNode( p ); - - m_vRecentCourseScores.push_back( h ); - } - else - { - WARN_AND_CONTINUE_M( p->GetName() ); - } - } -} - -XNode* Profile::SaveRecentCourseScoresCreateNode() const -{ - CHECKPOINT; - - const Profile* pProfile = this; - ASSERT( pProfile ); - - XNode* pNode = new XNode( "RecentCourseScores" ); - - FOREACHD_CONST( HighScoreForACourseAndTrail, m_vRecentCourseScores, i ) - pNode->AppendChild( i->CreateNode() ); - - return pNode; -} - -void Profile::AddCourseRecentScore( const Course* pCourse, const Trail* pTrail, HighScore hs ) +void Profile::SaveCourseRecentScore( const Course* pCourse, const Trail* pTrail, HighScore hs ) { HighScoreForACourseAndTrail h; h.courseID.FromCourse( pCourse ); h.trailID.FromTrail( pTrail ); h.hs = hs; - m_vRecentCourseScores.push_back( h ); - - int iMaxRecentScoresToSave = IsMachine() ? PREFSMAN->m_iMaxRecentScoresForMachine : PREFSMAN->m_iMaxRecentScoresForPlayer; - int iNumToErase = m_vRecentCourseScores.size() - iMaxRecentScoresToSave; - if( iNumToErase > 0 ) - m_vRecentCourseScores.erase( m_vRecentCourseScores.begin(), m_vRecentCourseScores.begin() + iNumToErase ); -} + + auto_ptr xml( new XNode("Stats") ); + xml->AppendChild( "MachineGuid", PROFILEMAN->GetMachineProfile()->m_sGuid ); + XNode *recent = xml->AppendChild( new XNode("RecentCourseScores") ); + recent->AppendChild( h.CreateNode() ); -StepsType Profile::GetLastPlayedStepsType() const -{ - if( m_vRecentStepsScores.empty() ) - return StepsType_Invalid; - const HighScoreForASongAndSteps &h = m_vRecentStepsScores.back(); - return h.stepsID.GetStepsType(); + SaveRecentScore( xml.get() ); } const Profile::HighScoresForASong *Profile::GetHighScoresForASong( const SongID& songID ) const @@ -1998,6 +1895,39 @@ void Profile::MoveBackupToDir( RString sFromDir, RString sToDir ) FILEMAN->Move( sFromDir+DONT_SHARE_SIG, sToDir+DONT_SHARE_SIG ); } +RString Profile::MakeUniqueFileNameNoExtension( RString sDir, RString sFileNameBeginning ) +{ + // + // Find a file name for the screenshot + // + FILEMAN->FlushDirCache( sDir ); + + vector files; + GetDirListing( sDir + "sFileNameBeginning*", files, false, false ); + sort( files.begin(), files.end() ); + + int iIndex = 0; + + for( int i = files.size()-1; i >= 0; --i ) + { + static Regex re( "^" + sFileNameBeginning + "([0-9]{5})\\....$" ); + vector matches; + if( !re.Compare( files[i], matches ) ) + continue; + + ASSERT( matches.size() == 1 ); + iIndex = atoi( matches[0] )+1; + break; + } + + return MakeFileNameNoExtension( sFileNameBeginning, iIndex ); +} + +RString Profile::MakeFileNameNoExtension( RString sFileNameBeginning, int iIndex ) +{ + return sFileNameBeginning + ssprintf( "%05d", iIndex ); +} + // lua start #include "LuaBinding.h" @@ -2049,7 +1979,6 @@ public: static int GetTotalStepsWithTopGrade( T* p, lua_State *L ) { lua_pushnumber(L, p->GetTotalStepsWithTopGrade(Enum::Check(L, 1),Enum::Check(L, 2),Enum::Check(L, 3)) ); return 1; } static int GetTotalTrailsWithTopGrade( T* p, lua_State *L ) { lua_pushnumber(L, p->GetTotalTrailsWithTopGrade(Enum::Check(L, 1),Enum::Check(L, 2),Enum::Check(L, 3)) ); return 1; } static int GetNumTotalSongsPlayed( T* p, lua_State *L ) { lua_pushnumber(L, p->m_iNumTotalSongsPlayed ); return 1; } - static int GetLastPlayedStepsType( T* p, lua_State *L ) { lua_pushnumber(L, p->GetLastPlayedStepsType() ); return 1; } static int GetSongsAndCoursesPercentCompleteAllDifficulties( T* p, lua_State *L ) { lua_pushnumber(L, p->GetSongsAndCoursesPercentCompleteAllDifficulties(Enum::Check(L, 1)) ); return 1; } static int GetTotalCaloriesBurned( T* p, lua_State *L ) { lua_pushnumber(L, p->m_fTotalCaloriesBurned ); return 1; } static int GetDisplayTotalCaloriesBurned( T* p, lua_State *L ) { lua_pushstring(L, p->GetDisplayTotalCaloriesBurned() ); return 1; } @@ -2118,7 +2047,6 @@ public: ADD_METHOD( GetTotalStepsWithTopGrade ); ADD_METHOD( GetTotalTrailsWithTopGrade ); ADD_METHOD( GetNumTotalSongsPlayed ); - ADD_METHOD( GetLastPlayedStepsType ); ADD_METHOD( GetSongsAndCoursesPercentCompleteAllDifficulties ); ADD_METHOD( GetTotalCaloriesBurned ); ADD_METHOD( GetDisplayTotalCaloriesBurned ); diff --git a/stepmania/src/Profile.h b/stepmania/src/Profile.h index d72a370de2..1a92d4b90a 100644 --- a/stepmania/src/Profile.h +++ b/stepmania/src/Profile.h @@ -247,14 +247,10 @@ public: void Unset() { stepsID.Unset(); songID.Unset(); hs.Unset(); } XNode* CreateNode() const; - void LoadFromNode( const XNode* pNode ); }; - deque m_vRecentStepsScores; - void AddStepsRecentScore( const Song* pSong, const Steps* pSteps, HighScore hs ); - - - StepsType GetLastPlayedStepsType() const; + void SaveStepsRecentScore( const Song* pSong, const Steps* pSteps, HighScore hs ); + // // RecentCourseScores // @@ -268,10 +264,8 @@ public: void Unset() { courseID.Unset(); hs.Unset(); } XNode* CreateNode() const; - void LoadFromNode( const XNode* pNode ); }; - deque m_vRecentCourseScores; // add to back, erase from front - void AddCourseRecentScore( const Course* pCourse, const Trail* pTrail, HighScore hs ); + void SaveCourseRecentScore( const Course* pCourse, const Trail* pTrail, HighScore hs ); // // Init'ing @@ -285,8 +279,6 @@ public: InitCategoryScores(); InitScreenshotData(); InitCalorieData(); - InitRecentSongScores(); - InitRecentCourseScores(); } void InitEditableData(); void InitGeneralData(); @@ -295,8 +287,6 @@ public: void InitCategoryScores(); void InitScreenshotData(); void InitCalorieData(); - void InitRecentSongScores(); - void InitRecentCourseScores(); void ClearStats(); // @@ -313,9 +303,7 @@ public: void LoadCategoryScoresFromNode( const XNode* pNode ); void LoadScreenshotDataFromNode( const XNode* pNode ); void LoadCalorieDataFromNode( const XNode* pNode ); - void LoadRecentSongScoresFromNode( const XNode* pNode ); - void LoadRecentCourseScoresFromNode( const XNode* pNode ); - + void SaveEditableDataToDir( RString sDir ) const; bool SaveStatsXmlToDir( RString sDir, bool bSignData ) const; XNode* SaveStatsXmlCreateNode() const; @@ -325,8 +313,6 @@ public: XNode* SaveCategoryScoresCreateNode() const; XNode* SaveScreenshotDataCreateNode() const; XNode* SaveCalorieDataCreateNode() const; - XNode* SaveRecentSongScoresCreateNode() const; - XNode* SaveRecentCourseScoresCreateNode() const; XNode* SaveCoinDataCreateNode() const; @@ -334,6 +320,9 @@ public: void SaveMachinePublicKeyToDir( RString sDir ) const; static void MoveBackupToDir( RString sFromDir, RString sToDir ); + static RString MakeUniqueFileNameNoExtension( RString sDir, RString sFileNameBeginning ); + static RString MakeFileNameNoExtension( RString sFileNameBeginning, int iIndex ); + // Lua void PushSelf( lua_State *L ); diff --git a/stepmania/src/ProfileManager.cpp b/stepmania/src/ProfileManager.cpp index 1617e62c86..65b1d74536 100644 --- a/stepmania/src/ProfileManager.cpp +++ b/stepmania/src/ProfileManager.cpp @@ -672,8 +672,8 @@ void ProfileManager::AddStepsScore( const Song* pSong, const Steps* pSteps, Play // save recent score // if( IsPersistentProfile(pn) ) - GetProfile(pn)->AddStepsRecentScore( pSong, pSteps, hs ); - GetMachineProfile()->AddStepsRecentScore( pSong, pSteps, hs ); + GetProfile(pn)->SaveStepsRecentScore( pSong, pSteps, hs ); + GetMachineProfile()->SaveStepsRecentScore( pSong, pSteps, hs ); } void ProfileManager::IncrementStepsPlayCount( const Song* pSong, const Steps* pSteps, PlayerNumber pn ) @@ -722,8 +722,8 @@ void ProfileManager::AddCourseScore( const Course* pCourse, const Trail* pTrail, // save recent score // if( IsPersistentProfile(pn) ) - GetProfile(pn)->AddCourseRecentScore( pCourse, pTrail, hs ); - GetMachineProfile()->AddCourseRecentScore( pCourse, pTrail, hs ); + GetProfile(pn)->SaveCourseRecentScore( pCourse, pTrail, hs ); + GetMachineProfile()->SaveCourseRecentScore( pCourse, pTrail, hs ); } void ProfileManager::IncrementCoursePlayCount( const Course* pCourse, const Trail* pTrail, PlayerNumber pn ) diff --git a/stepmania/src/StepMania.cpp b/stepmania/src/StepMania.cpp index 112cf07215..00307f3ec9 100644 --- a/stepmania/src/StepMania.cpp +++ b/stepmania/src/StepMania.cpp @@ -70,6 +70,7 @@ #include "StatsManager.h" #include "GameLoop.h" #include "SpecialFiles.h" +#include "Profile.h" #if defined(XBOX) #include "Archutils/Xbox/VirtualMemory.h" @@ -1196,31 +1197,12 @@ RString StepMania::SaveScreenshot( RString sDir, bool bSaveCompressed, bool bMak * write the same screenshot number for different formats (screen00011.bmp, * screen00011.jpg), and we always increase from the end, so if screen00003.jpg * is deleted, we won't fill in the hole (which makes screenshots hard to find). */ + RString sFileNameNoExtension; if( iIndex == -1 ) - { - // - // Find a file name for the screenshot - // - FILEMAN->FlushDirCache( sDir ); + sFileNameNoExtension = Profile::MakeUniqueFileNameNoExtension( sDir, "screen" ); + else + sFileNameNoExtension = Profile::MakeFileNameNoExtension( "screen", iIndex ); - vector files; - GetDirListing( sDir + "screen*", files, false, false ); - sort( files.begin(), files.end() ); - - iIndex = 0; - - for( int i = files.size()-1; i >= 0; --i ) - { - static Regex re( "^screen([0-9]{5})\\....$" ); - vector matches; - if( !re.Compare( files[i], matches ) ) - continue; - - ASSERT( matches.size() == 1 ); - iIndex = atoi( matches[0] )+1; - break; - } - } // // Save the screenshot. If writing lossy to a memcard, use SAVE_LOSSY_LOW_QUAL, so we @@ -1234,7 +1216,7 @@ RString StepMania::SaveScreenshot( RString sDir, bool bSaveCompressed, bool bMak else fmt = RageDisplay::SAVE_LOSSLESS; - RString sFileName = ssprintf( "screen%05d.%s",iIndex,bSaveCompressed ? "jpg" : "bmp" ); + RString sFileName = sFileNameNoExtension + "." + (bSaveCompressed ? "jpg" : "bmp"); RString sPath = sDir+sFileName; bool bResult = DISPLAY->SaveScreenshot( sPath, fmt ); if( !bResult )