diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index 48eb264d3d..b3b91165cc 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -4261,7 +4261,21 @@ MeterP2OnCommand=rotationz,-90 LevelP1OnCommand=addy,-140 LevelP2OnCommand=addy,-140 -[ProfileManager] -StatsTitle=StepMania Data -StatsFooter=generated by StepMania -StatsURL= +[ProfileHtml] +Title=StepMania Data +Footer=generated by StepMania +VerificationInstructions= + +[Grade] +01=AAAA +02=AAA +03=AA +04=A +05=B +06=C +07=D +Failed=E + + + + diff --git a/stepmania/src/CryptManager.cpp b/stepmania/src/CryptManager.cpp index fb04569042..9aaf2de837 100644 --- a/stepmania/src/CryptManager.cpp +++ b/stepmania/src/CryptManager.cpp @@ -17,8 +17,8 @@ using namespace CryptoPP; using namespace std; static const CString SIGNATURE_POSPEND = ".sig.rsa"; -static const CString PRIVATE_KEY_PATH = "private.rsa"; -static const CString PUBLIC_KEY_PATH = "public.rsa"; +static const CString PRIVATE_KEY_PATH = "private.key.rsa"; +static const CString PUBLIC_KEY_PATH = "public.key.rsa"; static const int KEY_LENGTH = 1024; CryptManager* CRYPTMAN = NULL; // global and accessable from anywhere in our program @@ -64,7 +64,8 @@ void CryptManager::SignFile( CString sPath ) CString sMessageFilename = sPath;; CString sSignatureFilename = sPath + SIGNATURE_POSPEND; - ASSERT( IsAFile(sPrivFilename) ); + if( !IsAFile(sPrivFilename) ) + return; if( !IsAFile(sMessageFilename) ) return; @@ -84,7 +85,8 @@ bool CryptManager::VerifyFile( CString sPath ) CString sMessageFilename = sPath;; CString sSignatureFilename = sPath + SIGNATURE_POSPEND; - ASSERT( IsAFile(sPubFilename) ); + if( !IsAFile(sPubFilename) ) + return false; if( !IsAFile(sSignatureFilename) ) return false; diff --git a/stepmania/src/Grade.cpp b/stepmania/src/Grade.cpp index 9919d08932..ae432391f7 100644 --- a/stepmania/src/Grade.cpp +++ b/stepmania/src/Grade.cpp @@ -12,6 +12,7 @@ #include "Grade.h" #include "RageUtil.h" +#include "ThemeManager.h" CString GradeToString( Grade g ) { @@ -25,6 +26,11 @@ CString GradeToString( Grade g ) } }; +CString GradeToThemedString( Grade g ) +{ + return THEME->GetMetric( "Grade",GradeToString(g) ); +} + CString GradeToOldString( Grade g ) { // string is meant to be human readable diff --git a/stepmania/src/Grade.h b/stepmania/src/Grade.h index df458a65f6..444954fea8 100644 --- a/stepmania/src/Grade.h +++ b/stepmania/src/Grade.h @@ -43,6 +43,7 @@ enum Grade CString GradeToString( Grade g ); CString GradeToOldString( Grade g ); // "AAA", "B", etc for backward compatibility +CString GradeToThemedString( Grade g ); Grade StringToGrade( const CString &s ); #endif diff --git a/stepmania/src/PrefsManager.cpp b/stepmania/src/PrefsManager.cpp index 95a69c0230..11923944bf 100644 --- a/stepmania/src/PrefsManager.cpp +++ b/stepmania/src/PrefsManager.cpp @@ -115,7 +115,7 @@ PrefsManager::PrefsManager() m_iGradeWeightHitMine = -8; m_iGradeWeightOK = 6; m_iGradeWeightNG = 0; - m_bGradeTier02IsAllPerfects = true; + m_iNumGradeTiersUsed = 7; for( int i=0; iGetMetric("ProfileManager","StatsTitle") -#define STATS_FOOTER THEME->GetMetric("ProfileManager","StatsFooter") +#define TITLE THEME->GetMetric("ProfileHtml","Title") +#define FOOTER THEME->GetMetric("ProfileHtml","Footer") +#define VERIFICATION_TEXT THEME->GetMetric("ProfileHtml","VerificationText") static int g_Level = 1; @@ -36,12 +38,6 @@ inline CString MakeUniqueId() { CString s="id"+ssprintf("%d%d%d",rand inline void PRINT_OPEN(RageFile &f,CString sName,bool bExpanded,CString sID){ g_Level++; ASSERT(g_Level>0 && g_Level<6); f.Write( ssprintf("
\n" "%s\n" "
\n", g_Level, g_Level, sID.c_str(), sName.c_str(), g_Level, sID.c_str(), bExpanded?"visibletext":"hiddentext") ); } inline void PRINT_OPEN(RageFile &f,CString sName,bool bExpanded=false) { PRINT_OPEN(f,sName,bExpanded,MakeUniqueId()); } inline void PRINT_CLOSE(RageFile &f) { f.Write( "
\n" "
\n" ); g_Level--; ASSERT(g_Level>=0); } -//inline void PRINT_LINK(RageFile &f,CString sName,CString sLink) { f.Write( ssprintf("

%s

\n",sLink.c_str(),sName.c_str()) ); } -//inline void PRINT_LINE_S(RageFile &f,CString sName,CString sVal) { f.Write( ssprintf("

%s = %s

\n",sName.c_str(),sVal.c_str()) ); } -//inline void PRINT_LINE_B(RageFile &f,CString sName,bool bVal) { f.Write( ssprintf("

%s = %s

\n",sName.c_str(),(bVal)?"yes":"no") ); } -//inline void PRINT_LINE_I(RageFile &f,CString sName,int iVal) { f.Write( ssprintf("

%s = %d

\n",sName.c_str(),iVal) ); } -//inline void PRINT_LINE_RANK(RageFile &f,int iRank,CString sName,int iVal) { f.Write( ssprintf("

%d - %s (%d)

\n",iRank,sName.c_str(),iVal) ); } -//inline void PRINT_LINE_RANK_LINK(RageFile &f,int iRank,CString sName,CString sLink,int iVal) { f.Write( ssprintf("

%d - %s (%d)

\n",iRank,sLink.c_str(),sName.c_str(),iVal) ); } struct Table @@ -51,13 +47,18 @@ struct Table struct Line { Line() {} - Line(CString n,CString v) { sName = n; sValue = v; } - Line(CString n,bool v) { sName = n; sValue = ssprintf("%s",v?"yes":"no"); } - Line(CString n,int v) { sName = n; sValue = ssprintf("%d",v); } - Line(int r,CString n,int v) { sRank = ssprintf("%d",r); sName = n; sValue = ssprintf("%d",v); } + Line(CString n) { sName = n; } + Line(CString n,CString v) { sName = n; sValue = v; } + Line(CString n,bool v) { sName = n; sValue = ssprintf("%s",v?"yes":"no"); } + Line(CString n,int v) { sName = n; sValue = ssprintf("%d",v); } + Line(int r,CString n,int v) { sRank = ssprintf("%d",r); sName = n; sValue = ssprintf("%d",v); } + Line(int r,CString n,CString sn,int v) { sRank = ssprintf("%d",r); sName = n; sSubName = sn; sValue = ssprintf("%d",v); } + Line(int r,CString n,CString sn,CString ssn,int v) { sRank = ssprintf("%d",r); sName = n; sSubName = sn; sSubSubName = ssn; sValue = ssprintf("%d",v); } CString sRank; CString sName; + CString sSubName; + CString sSubSubName; CString sValue; }; @@ -65,15 +66,13 @@ struct Table vector vLines; }; -//inline CString MAKE_LINE_S(CString sName,CString sVal) { return ssprintf("

%s = %s

\n",sName.c_str(),sVal.c_str()); } -//inline CString MAKE_LINE_B(CString sName,bool bVal) { return ssprintf("

%s = %s

\n",sName.c_str(),(bVal)?"yes":"no"); } -//inline CString MAKE_LINE_I(CString sName,int iVal) { return ssprintf("

%s = %d

\n",sName.c_str(),iVal); } -//inline CString MAKE_LINE_RANK(int iRank,CString sName,int iVal) { return ssprintf("

%d - %s (%d)

\n",iRank,sName.c_str(),iVal); } - -#define BEGIN_TABLE(cols) { Table table; table.iNumCols=cols; -#define TABLE_LINE2(p1,p2) table.vLines.push_back( Table::Line(p1,p2) ); -#define TABLE_LINE3(p1,p2,p3) table.vLines.push_back( Table::Line(p1,p2,p3) ); -#define END_TABLE PrintTable( f, table ); } +#define BEGIN_TABLE(cols) { Table table; table.iNumCols=cols; +#define TABLE_LINE1(p1) table.vLines.push_back( Table::Line(p1) ); +#define TABLE_LINE2(p1,p2) table.vLines.push_back( Table::Line(p1,p2) ); +#define TABLE_LINE3(p1,p2,p3) table.vLines.push_back( Table::Line(p1,p2,p3) ); +#define TABLE_LINE4(p1,p2,p3,p4) table.vLines.push_back( Table::Line(p1,p2,p3,p4) ); +#define TABLE_LINE5(p1,p2,p3,p4,p5) table.vLines.push_back( Table::Line(p1,p2,p3,p4,p5) ); +#define END_TABLE PrintTable( f, table ); } inline void PrintTable(RageFile &f,Table &table) { @@ -109,13 +108,30 @@ inline void PrintTable(RageFile &f,Table &table) f.Write(""); f.Write(" "); } - f.Write(""); - f.Write( line.sName ); - f.Write(""); - f.Write(" "); - f.Write(""); - f.Write( line.sValue ); - f.Write(""); + if( bPrintRank ) + { + f.Write(""); + f.Write("

"); + f.Write( line.sName ); + f.Write("

"); + f.Write("

"); + f.Write( line.sSubName ); + f.Write("

"); + f.Write(""); + } + else + { + f.Write(""); + f.Write( line.sName ); + f.Write(""); + } + if( !line.sValue.empty() ) + { + f.Write(" "); + f.Write(""); + f.Write( line.sValue ); + f.Write(""); + } f.Write( "\n" ); f.Write(""); @@ -129,9 +145,9 @@ inline void PrintTable(RageFile &f,Table &table) void PrintStatistics( RageFile &f, const Profile *pProfile, CString sTitle, vector &vpSongs, vector &vpAllSteps, vector &vStepsTypesToShow, map mapStepsToSong, vector vpCourses ) { - PRINT_OPEN(f,sTitle); + PRINT_OPEN(f,sTitle,true); { - PRINT_OPEN(f,"This Profile",true); + PRINT_OPEN(f,"General Info",true); { BEGIN_TABLE(2); TABLE_LINE2( "Name", pProfile->m_sName ); @@ -149,7 +165,7 @@ void PrintStatistics( RageFile &f, const Profile *pProfile, CString sTitle, vect PRINT_CLOSE(f); - PRINT_OPEN(f,"Num Songs Played by PlayMode",true); + PRINT_OPEN(f,"Num Songs Played by PlayMode"); { BEGIN_TABLE(4); FOREACH_PlayMode( pm ) @@ -159,7 +175,7 @@ void PrintStatistics( RageFile &f, const Profile *pProfile, CString sTitle, vect PRINT_CLOSE(f); - PRINT_OPEN(f,"Num Songs Played by Style",true); + PRINT_OPEN(f,"Num Songs Played by Style"); { BEGIN_TABLE(4); for( int i=0; iGetStepsHighScoreList(pSteps); + if( hsl.vHighScores.empty() ) + continue; // no data, skip this one + Grade g = hsl.GetTopScore().grade; + ASSERT( g != GRADE_NO_DATA ); + ASSERT( g < NUM_GRADES ); + ASSERT( g >= 0 ); + iGradeCount[g] ++; + } + + BEGIN_TABLE(6); + for( int g=0; gm_iNumGradeTiersUsed; g++ ) + TABLE_LINE2( GradeToThemedString((Grade)g), iGradeCount[g] ); + TABLE_LINE2( GradeToThemedString(GRADE_FAILED), iGradeCount[GRADE_FAILED] ); + END_TABLE; + } + PRINT_CLOSE(f); } PRINT_CLOSE(f); } @@ -224,7 +266,7 @@ void PrintPopularity( RageFile &f, const Profile *pProfile, CString sTitle, vect int iNumTimesPlayed = pProfile->GetSongNumTimesPlayed(pSong); if( iNumTimesPlayed == 0 || iNumTimesPlayed < iPopularNumPlaysThreshold ) // not popular break; // done searching - TABLE_LINE3(i+1, pSong->GetFullDisplayTitle(), iNumTimesPlayed ); + TABLE_LINE4(i+1, pSong->GetDisplayMainTitle(), pSong->GetDisplaySubTitle(), iNumTimesPlayed ); } END_TABLE; } @@ -242,7 +284,7 @@ void PrintPopularity( RageFile &f, const Profile *pProfile, CString sTitle, vect int iNumTimesPlayed = pProfile->GetSongNumTimesPlayed(pSong); if( iNumTimesPlayed >= iPopularNumPlaysThreshold ) // not unpopular break; // done searching - TABLE_LINE3(i+1, pSong->GetFullDisplayTitle(), iNumTimesPlayed ); + TABLE_LINE4(i+1, pSong->GetDisplayMainTitle(), pSong->GetDisplaySubTitle(), iNumTimesPlayed ); } END_TABLE; } @@ -263,12 +305,10 @@ void PrintPopularity( RageFile &f, const Profile *pProfile, CString sTitle, vect continue; // skip Song* pSong = mapStepsToSong[pSteps]; CString s; - s += pSong->GetFullDisplayTitle(); - s += " - "; s += GAMEMAN->NotesTypeToString(pSteps->m_StepsType); s += " "; s += DifficultyToString(pSteps->GetDifficulty()); - TABLE_LINE3(i+1, s, pProfile->GetStepsNumTimesPlayed(pSteps) ); + TABLE_LINE5(i+1, pSong->GetDisplayMainTitle(), pSong->GetDisplaySubTitle(), s, pProfile->GetStepsNumTimesPlayed(pSteps) ); } END_TABLE; } @@ -612,6 +652,27 @@ void PrintBookkeeping( RageFile &f, const Profile *pProfile, CString sTitle, vec PRINT_CLOSE(f); } +void PrintScreenshots( RageFile &f, const Profile *pProfile, CString sTitle, CString sProfileDir ) +{ + PRINT_OPEN(f, sTitle ); + { + CStringArray asFiles; + GetDirListing( sProfileDir+"Screenshots/*.jpg", asFiles ); + + BEGIN_TABLE(2); + for( int i=0; i", sFile.c_str(), sFile.c_str() ); + + TABLE_LINE1( sImgTag ); + } + END_TABLE; + } + PRINT_CLOSE(f); +} + enum SaveType { SAVE_TYPE_PLAYER, SAVE_TYPE_MACHINE }; void SaveStatsWebPageToDir( CString sDir, SaveType saveType, const Profile *pProfile, const Profile *pProfileMachine ) @@ -719,7 +780,7 @@ function expandIt(whichEl)\n\ \n\ \n\ ", -STATS_TITLE.c_str(), STYLE_CSS ) ); +TITLE.c_str(), STYLE_CSS ) ); } CString sType; @@ -738,7 +799,7 @@ STATS_TITLE.c_str(), STYLE_CSS ) ); f.Write( ssprintf( "

%s

%s %s
%s
\n", - STATS_TITLE.c_str(), sType.c_str(), sName.c_str(), sTime.c_str() ) ); + TITLE.c_str(), sType.c_str(), sName.c_str(), sTime.c_str() ) ); CString sPlayerName = pProfile->GetDisplayName(); CString sMachineName = pProfileMachine->GetDisplayName(); @@ -749,6 +810,7 @@ STATS_TITLE.c_str(), STYLE_CSS ) ); PrintStatistics( f, pProfile, sPlayerName+"'s Statistics", vpSongs, vpAllSteps, vStepsTypesToShow, mapStepsToSong, vpCourses ); PrintPopularity( f, pProfile, sPlayerName+"'s Popularity", vpSongs, vpAllSteps, vStepsTypesToShow, mapStepsToSong, vpCourses ); PrintHighScores( f, pProfile, sPlayerName+"'s High Scores", vpSongs, vpAllSteps, vStepsTypesToShow, mapStepsToSong, vpCourses ); + PrintScreenshots( f, pProfile, sPlayerName+"'s Screenshots", sDir ); PrintPopularity( f, pProfileMachine, sMachineName+"'s Popularity", vpSongs, vpAllSteps, vStepsTypesToShow, mapStepsToSong, vpCourses ); PrintHighScores( f, pProfileMachine, sMachineName+"'s High Scores", vpSongs, vpAllSteps, vStepsTypesToShow, mapStepsToSong, vpCourses ); break; @@ -764,7 +826,7 @@ STATS_TITLE.c_str(), STYLE_CSS ) ); ASSERT(0); } - f.PutLine( ssprintf("\n", STATS_FOOTER.c_str()) ); + f.PutLine( ssprintf("\n", FOOTER.c_str()) ); f.PutLine( "" ); f.PutLine( "" ); diff --git a/stepmania/src/StepMania.cpp b/stepmania/src/StepMania.cpp index 9cb47065bd..231dbe3074 100644 --- a/stepmania/src/StepMania.cpp +++ b/stepmania/src/StepMania.cpp @@ -1127,18 +1127,23 @@ bool SaveScreenshot( CString sDir, bool bSaveCompressed, bool bMakeSignature ) // CString sScreenshotPath = ssprintf( sDir+"screen%04d.%s",fileno,bSaveCompressed ? "jpg" : "bmp" ); bool bResult = DISPLAY->SaveScreenshot( sScreenshotPath, bSaveCompressed ? RageDisplay::jpg : RageDisplay::bmp ); - if( bResult ) - SOUND->PlayOnce( THEME->GetPathToS("Common screenshot") ); - else + if( !bResult ) { SOUND->PlayOnce( THEME->GetPathToS("Common invalid") ); return false; } + SOUND->PlayOnce( THEME->GetPathToS("Common screenshot") ); + + // We wrote a new file, and SignFile won't pick it up unless we invalidate + // the Dir cache. There's got to be a better way of doing this than + // thowing out all the cache. -Chris + FlushDirCache(); + if( bMakeSignature ) CryptManager::SignFile( sScreenshotPath ); - return bResult; + return false; } /* Returns true if the key has been handled and should be discarded, false if