add grade count and screenshots sections to stats.html

This commit is contained in:
Chris Danford
2004-02-16 09:23:34 +00:00
parent 4156126765
commit be49e33c53
8 changed files with 149 additions and 55 deletions
+18 -4
View File
@@ -4261,7 +4261,21 @@ MeterP2OnCommand=rotationz,-90
LevelP1OnCommand=addy,-140
LevelP2OnCommand=addy,-140
[ProfileManager]
StatsTitle=StepMania Data
StatsFooter=generated by <a href='http://www.stepmania.com'>StepMania</a>
StatsURL=
[ProfileHtml]
Title=StepMania Data
Footer=generated by <a href='http://www.stepmania.com'>StepMania</a>
VerificationInstructions=
[Grade]
01=AAAA
02=AAA
03=AA
04=A
05=B
06=C
07=D
Failed=E
+6 -4
View File
@@ -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;
+6
View File
@@ -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
+1
View File
@@ -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
+4 -1
View File
@@ -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; i<NUM_GRADE_TIERS; i++ )
m_fGradePercentTier[i] = 0;
m_fGradePercentTier[GRADE_TIER_1] = 1.0f;
@@ -124,6 +124,7 @@ PrefsManager::PrefsManager()
m_fGradePercentTier[GRADE_TIER_4] = 0.80f; // A
m_fGradePercentTier[GRADE_TIER_5] = 0.65f; // B
m_fGradePercentTier[GRADE_TIER_6] = 0.45f; // C
m_bGradeTier02IsAllPerfects = true;
m_fSuperMeterPercentChangeMarvelous = +0.05f;
m_fSuperMeterPercentChangePerfect = +0.04f;
@@ -375,6 +376,7 @@ void PrefsManager::ReadGlobalPrefsFromDisk()
ini.GetValue( "Options", "GradeWeightOK", m_iGradeWeightOK );
ini.GetValue( "Options", "GradeWeightNG", m_iGradeWeightNG );
ini.GetValue( "Options", "NumGradeTiersUsed", m_iNumGradeTiersUsed );
for( int g=0; g<NUM_GRADE_TIERS; g++ )
{
Grade grade = (Grade)g;
@@ -589,6 +591,7 @@ void PrefsManager::SaveGlobalPrefsToDisk() const
ini.SetValue( "Options", "GradeWeightOK", m_iGradeWeightOK );
ini.SetValue( "Options", "GradeWeightNG", m_iGradeWeightNG );
ini.SetValue( "Options", "NumGradeTiersUsed", m_iNumGradeTiersUsed );
for( int g=0; g<NUM_GRADE_TIERS; g++ )
{
Grade grade = (Grade)g;
+1
View File
@@ -119,6 +119,7 @@ public:
int m_iGradeWeightOK;
int m_iGradeWeightNG;
int m_iNumGradeTiersUsed;
float m_fGradePercentTier[NUM_GRADE_TIERS]; // the minimum percent necessary achieve a grade
bool m_bGradeTier02IsAllPerfects; // DDR special case. If true, m_fGradePercentTier[GRADE_TIER_2] is ignored
+104 -42
View File
@@ -21,13 +21,15 @@
#include "GameManager.h"
#include "Course.h"
#include "Bookkeeper.h"
#include "PrefsManager.h"
#define STATS_HTML "stats.html"
#define STYLE_CSS "style.css"
#define STATS_TITLE THEME->GetMetric("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("<div class='section%d'>\n" "<h%d onClick='expandIt(%s); return false' CLASS='outline'>%s</h%d>\n" "<DIV ID='%s' CLASS='%s'>\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( "</div>\n" "</div>\n" ); g_Level--; ASSERT(g_Level>=0); }
//inline void PRINT_LINK(RageFile &f,CString sName,CString sLink) { f.Write( ssprintf("<p><a href='%s'>%s</a></p>\n",sLink.c_str(),sName.c_str()) ); }
//inline void PRINT_LINE_S(RageFile &f,CString sName,CString sVal) { f.Write( ssprintf("<p>%s = <b>%s</b></p>\n",sName.c_str(),sVal.c_str()) ); }
//inline void PRINT_LINE_B(RageFile &f,CString sName,bool bVal) { f.Write( ssprintf("<p>%s = <b>%s</b></p>\n",sName.c_str(),(bVal)?"yes":"no") ); }
//inline void PRINT_LINE_I(RageFile &f,CString sName,int iVal) { f.Write( ssprintf("<p>%s = <b>%d</b></p>\n",sName.c_str(),iVal) ); }
//inline void PRINT_LINE_RANK(RageFile &f,int iRank,CString sName,int iVal) { f.Write( ssprintf("<p><b>%d</b> - %s (%d)</p>\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("<p><b>%d</b> - <a href='%s'>%s</a> (%d)</p>\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<Line> vLines;
};
//inline CString MAKE_LINE_S(CString sName,CString sVal) { return ssprintf("<p>%s = <b>%s</b></p>\n",sName.c_str(),sVal.c_str()); }
//inline CString MAKE_LINE_B(CString sName,bool bVal) { return ssprintf("<p>%s = <b>%s</b></p>\n",sName.c_str(),(bVal)?"yes":"no"); }
//inline CString MAKE_LINE_I(CString sName,int iVal) { return ssprintf("<p>%s = <b>%d</b></p>\n",sName.c_str(),iVal); }
//inline CString MAKE_LINE_RANK(int iRank,CString sName,int iVal) { return ssprintf("<p><b>%d</b> - %s (%d)</p>\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("</td>");
f.Write("<td>&nbsp;</td>");
}
f.Write("<td class='name'>");
f.Write( line.sName );
f.Write("</td>");
f.Write("<td>&nbsp;</td>");
f.Write("<td class='value'>");
f.Write( line.sValue );
f.Write("</td>");
if( bPrintRank )
{
f.Write("<td>");
f.Write("<p class='songtitle'>");
f.Write( line.sName );
f.Write("</p>");
f.Write("<p class='songsubtitle'>");
f.Write( line.sSubName );
f.Write("</p>");
f.Write("</td>");
}
else
{
f.Write("<td class='name'>");
f.Write( line.sName );
f.Write("</td>");
}
if( !line.sValue.empty() )
{
f.Write("<td>&nbsp;</td>");
f.Write("<td class='value'>");
f.Write( line.sValue );
f.Write("</td>");
}
f.Write( "\n" );
f.Write("</tr>");
@@ -129,9 +145,9 @@ inline void PrintTable(RageFile &f,Table &table)
void PrintStatistics( RageFile &f, const Profile *pProfile, CString sTitle, vector<Song*> &vpSongs, vector<Steps*> &vpAllSteps, vector<StepsType> &vStepsTypesToShow, map<Steps*,Song*> mapStepsToSong, vector<Course*> 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; i<NUM_STYLES; i++ )
@@ -179,7 +195,7 @@ void PrintStatistics( RageFile &f, const Profile *pProfile, CString sTitle, vect
PRINT_CLOSE(f);
PRINT_OPEN(f,"Num Songs Played by Difficulty",true);
PRINT_OPEN(f,"Num Songs Played by Difficulty");
{
BEGIN_TABLE(4);
FOREACH_Difficulty( dc )
@@ -188,7 +204,7 @@ void PrintStatistics( RageFile &f, const Profile *pProfile, CString sTitle, vect
}
PRINT_CLOSE(f);
PRINT_OPEN(f,"Num Songs Played by Meter",true);
PRINT_OPEN(f,"Num Songs Played by Meter");
{
BEGIN_TABLE(4);
for( int i=MIN_METER; i<=MAX_METER; i++ )
@@ -196,6 +212,32 @@ void PrintStatistics( RageFile &f, const Profile *pProfile, CString sTitle, vect
END_TABLE;
}
PRINT_CLOSE(f);
PRINT_OPEN(f,"Grade Count");
{
int iGradeCount[NUM_GRADES];
ZERO( iGradeCount );
for( int i=0; i<vpAllSteps.size(); i++ )
{
Steps* pSteps = vpAllSteps[i];
const HighScoreList &hsl = pProfile->GetStepsHighScoreList(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; g<PREFSMAN->m_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<asFiles.size(); i++ )
{
CString sFile = "Screenshots/"+asFiles[i];
CString sImgTag = ssprintf("<a href='%s' target='_new'><img class='screenshot' src='%s' width='160' height='120'></a>", 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\
<link rel='stylesheet' type='text/css' href='%s'>\n\
</head>\n\
<body>",
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(
"<table border='0' cellpadding='0' cellspacing='0' width='100%%' cellspacing='5'><tr><td><h1>%s</h1></td><td>%s %s<br>%s</td></tr></table>\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("<p class='footer'>%s</p>\n", STATS_FOOTER.c_str()) );
f.PutLine( ssprintf("<p class='footer'>%s</p>\n", FOOTER.c_str()) );
f.PutLine( "</body>" );
f.PutLine( "</html>" );
+9 -4
View File
@@ -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