add XmlFile
working on moving high scores to XML
This commit is contained in:
@@ -67,7 +67,7 @@ ScoreKeeper.h ScoreKeeperMAX2.cpp ScoreKeeperMAX2.h ScoreKeeperRave.cpp ScoreKee
|
||||
Song.cpp song.h SongCacheIndex.cpp SongCacheIndex.h SongOptions.cpp SongOptions.h StageStats.cpp StageStats.h Steps.cpp Steps.h \
|
||||
Style.h StyleDef.cpp StyleDef.h StyleInput.h TimingData.cpp TimingData.h TitleSubstitution.cpp TitleSubstitution.h
|
||||
|
||||
FileTypes = IniFile.cpp IniFile.h MsdFile.cpp MsdFile.h
|
||||
FileTypes = IniFile.cpp IniFile.h MsdFile.cpp MsdFile.h XmlFile.cpp XmlFile.h
|
||||
|
||||
StepMania = StdString.h StepMania.cpp StepMania.h global.cpp global.h
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "Bookkeeper.h"
|
||||
#include <time.h>
|
||||
#include "MemoryCardManager.h"
|
||||
#include "XmlFile.h"
|
||||
|
||||
|
||||
ProfileManager* PROFILEMAN = NULL; // global and accessable from anywhere in our program
|
||||
@@ -220,6 +221,7 @@ bool ProfileManager::SaveProfile( PlayerNumber pn )
|
||||
|
||||
SaveCategoryScoresToDir( m_sProfileDir[pn], (ProfileSlot)pn );
|
||||
SaveSongScoresToDir( m_sProfileDir[pn], (ProfileSlot)pn );
|
||||
SaveSongScoresToDirXml( m_sProfileDir[pn], (ProfileSlot)pn );
|
||||
SaveCourseScoresToDir( m_sProfileDir[pn], (ProfileSlot)pn );
|
||||
SaveStatsWebPageToDir( m_sProfileDir[pn], (ProfileSlot)pn );
|
||||
|
||||
@@ -389,6 +391,7 @@ void ProfileManager::SaveMachineScoresToDisk()
|
||||
|
||||
SaveCategoryScoresToDir( MACHINE_PROFILE_DIR, PROFILE_SLOT_MACHINE );
|
||||
SaveSongScoresToDir( MACHINE_PROFILE_DIR, PROFILE_SLOT_MACHINE );
|
||||
SaveSongScoresToDirXml( MACHINE_PROFILE_DIR, PROFILE_SLOT_MACHINE );
|
||||
SaveCourseScoresToDir( MACHINE_PROFILE_DIR, PROFILE_SLOT_MACHINE );
|
||||
SaveStatsWebPageToDir( MACHINE_PROFILE_DIR, PROFILE_SLOT_MACHINE );
|
||||
}
|
||||
@@ -929,6 +932,86 @@ void ProfileManager::SaveSongScoresToDir( CString sDir, ProfileSlot slot )
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileManager::SaveSongScoresToDirXml( CString sDir, ProfileSlot slot )
|
||||
{
|
||||
Profile* pProfile = GetProfile( slot );
|
||||
ASSERT( pProfile );
|
||||
|
||||
CString fn = sDir + SONG_SCORES_FILE+".xml";
|
||||
|
||||
LOG->Trace("SongManager::SaveSongScoresToFile %s", fn.c_str());
|
||||
|
||||
RageFile f;
|
||||
if( !f.Open(fn, RageFile::WRITE) )
|
||||
{
|
||||
LOG->Warn( "Couldn't open file \"%s\" for writing: %s", fn.c_str(), f.GetError().c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
XNode xml;
|
||||
xml.name = "SongScores";
|
||||
|
||||
const vector<Song*> &vpSongs = SONGMAN->GetAllSongs();
|
||||
|
||||
for( unsigned s=0; s<vpSongs.size(); s++ ) // foreach song
|
||||
{
|
||||
Song* pSong = vpSongs[s];
|
||||
ASSERT(pSong);
|
||||
|
||||
/* If the song has never been played, don't write anything. This keeps
|
||||
* us from saving a dozen copies of each song for all autogen difficulties,
|
||||
* since most people only use a couple game modes. */
|
||||
vector<Steps*> vNotesToWrite;
|
||||
for( unsigned i=0; i<pSong->m_apNotes.size(); ++i )
|
||||
{
|
||||
Steps* pNotes = pSong->m_apNotes[i];
|
||||
HighScoreList &hsl = pProfile->GetStepsHighScoreList( pNotes );
|
||||
if( hsl.iNumTimesPlayed == 0 && hsl.vHighScores.empty() )
|
||||
continue;
|
||||
vNotesToWrite.push_back( pNotes );
|
||||
}
|
||||
|
||||
if( vNotesToWrite.empty() )
|
||||
continue;
|
||||
|
||||
LPXNode pSongNode = xml.AppendChild( "Song" );
|
||||
pSongNode->AppendChild( "Dir", pSong->GetSongDir() );
|
||||
|
||||
for( unsigned n=0; n<vNotesToWrite.size(); n++ )
|
||||
{
|
||||
LPXNode pStepsNode = pSongNode->AppendChild( "Steps" );
|
||||
|
||||
Steps* pNotes = vNotesToWrite[n];
|
||||
ASSERT(pNotes);
|
||||
|
||||
HighScoreList &hsl = pProfile->GetStepsHighScoreList( pNotes );
|
||||
|
||||
pStepsNode->AppendChild( "StepsType", pNotes->m_StepsType );
|
||||
pStepsNode->AppendChild( "Difficulty", pNotes->GetDifficulty() );
|
||||
pStepsNode->AppendChild( "Description", pNotes->GetDescription() );
|
||||
pStepsNode->AppendChild( "NumTimesPlayed", hsl.iNumTimesPlayed );
|
||||
|
||||
for( int l=0; l<(int)hsl.vHighScores.size(); l++ )
|
||||
{
|
||||
HighScore &hs = hsl.vHighScores[l];
|
||||
|
||||
LPXNode pHighScoreNode = pSongNode->AppendChild( "HighScore" );
|
||||
|
||||
// tricky: wipe out "name to fill in" markers
|
||||
if( IsRankingToFillIn(hs.sName) )
|
||||
hs.sName = "";
|
||||
|
||||
pHighScoreNode->AppendChild( "Name", hs.sName );
|
||||
pHighScoreNode->AppendChild( "Grade", hs.grade );
|
||||
pHighScoreNode->AppendChild( "Score", hs.iScore );
|
||||
pHighScoreNode->AppendChild( "Percent", hs.fPercentDP );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileWrite( f, xml.GetXML() );
|
||||
}
|
||||
|
||||
/* static CString HTMLQuoteDoubleQuotes( CString str )
|
||||
{
|
||||
str.Replace( "\"", """ );
|
||||
|
||||
@@ -98,6 +98,7 @@ public:
|
||||
void ReadCourseScoresFromDir( CString sDir, ProfileSlot slot );
|
||||
void ReadCategoryScoresFromDir( CString sDir, ProfileSlot slot );
|
||||
|
||||
void SaveSongScoresToDirXml( CString sDir, ProfileSlot slot );
|
||||
void SaveSongScoresToDir( CString sDir, ProfileSlot slot );
|
||||
void SaveCourseScoresToDir( CString sDir, ProfileSlot slot );
|
||||
void SaveCategoryScoresToDir( CString sDir, ProfileSlot slot );
|
||||
|
||||
@@ -65,7 +65,7 @@ IntDir=.\../Debug6
|
||||
TargetDir=\stepmania\stepmania\Program
|
||||
TargetName=StepMania-debug
|
||||
SOURCE="$(InputPath)"
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi
|
||||
# End Special Build Tool
|
||||
|
||||
@@ -103,8 +103,8 @@ IntDir=.\../Debug_Xbox
|
||||
TargetDir=\stepmania\stepmania
|
||||
TargetName=default
|
||||
SOURCE="$(InputPath)"
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c \
|
||||
verstub.cpp /Fo$(IntDir)\
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c \
|
||||
verstub.cpp /Fo$(IntDir)\
|
||||
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
|
||||
# End Special Build Tool
|
||||
|
||||
@@ -144,7 +144,7 @@ IntDir=.\../Release6
|
||||
TargetDir=\stepmania\stepmania\Program
|
||||
TargetName=StepMania
|
||||
SOURCE="$(InputPath)"
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi
|
||||
# End Special Build Tool
|
||||
|
||||
@@ -184,8 +184,8 @@ IntDir=.\../Release_Xbox
|
||||
TargetDir=\stepmania\stepmania
|
||||
TargetName=default
|
||||
SOURCE="$(InputPath)"
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c \
|
||||
verstub.cpp /Fo$(IntDir)\
|
||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c \
|
||||
verstub.cpp /Fo$(IntDir)\
|
||||
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
|
||||
# End Special Build Tool
|
||||
|
||||
@@ -1909,6 +1909,25 @@ SOURCE=.\MsdFile.cpp
|
||||
|
||||
SOURCE=.\MsdFile.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XmlFile.cpp
|
||||
|
||||
!IF "$(CFG)" == "StepMania - Win32 Debug"
|
||||
|
||||
!ELSEIF "$(CFG)" == "StepMania - Xbox Debug"
|
||||
|
||||
!ELSEIF "$(CFG)" == "StepMania - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "StepMania - Xbox Release"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XmlFile.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "StepMania"
|
||||
|
||||
|
||||
@@ -810,6 +810,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\
|
||||
<File
|
||||
RelativePath="MsdFile.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="XmlFile.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="XmlFile.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="StepMania"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,191 @@
|
||||
// XmlFile.h: interface for the XmlFile class.
|
||||
//
|
||||
// Adapted from http://www.codeproject.com/cpp/xmlite.asp
|
||||
// by Chris. The CodeProject FAQ says "all developers may freely
|
||||
// use the code in their own applications".
|
||||
//
|
||||
// XmlFile : XML Lite Parser Library
|
||||
// by bro ( Cho,Kyung Min: [email protected] ) 2002-10-30
|
||||
// History.
|
||||
// 2002-10-29 : First Coded. Parsing XMLElelement and Attributes.
|
||||
// get xml parsed string ( looks good )
|
||||
// 2002-10-30 : Get Node Functions, error handling ( not completed )
|
||||
// 2002-12-06 : Helper Funtion string to long
|
||||
// 2002-12-12 : Entity Helper Support
|
||||
// 2003-04-08 : Close,
|
||||
// 2003-07=23 : add property escape_value. (now no escape on default)
|
||||
// fix escape functions
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <vector>
|
||||
#include <RageUtil.h>
|
||||
|
||||
// TCHAR defines
|
||||
#define LPTSTR char*
|
||||
#define LPCTSTR const char*
|
||||
#define _tcschr strchr
|
||||
//#define FALSE false
|
||||
#define _istspace isspace
|
||||
#define _tcspbrk strpbrk
|
||||
#define IsEmpty empty
|
||||
#define _tcslen strlen
|
||||
#define _tcsecpy strlen
|
||||
|
||||
struct _tagXMLAttr;
|
||||
typedef _tagXMLAttr XAttr, *LPXAttr;
|
||||
typedef std::vector<LPXAttr> XAttrs;
|
||||
struct _tagXMLNode;
|
||||
typedef _tagXMLNode XNode, *LPXNode;
|
||||
typedef std::vector<LPXNode> XNodes, *LPXNodes;
|
||||
|
||||
// Entity Encode/Decode Support
|
||||
typedef struct _tagXmlEntity
|
||||
{
|
||||
TCHAR entity; // entity ( & " ' < > )
|
||||
TCHAR ref[10]; // entity reference ( & " etc )
|
||||
int ref_len; // entity reference length
|
||||
}XENTITY,*LPXENTITY;
|
||||
|
||||
typedef struct _tagXMLEntitys : public std::vector<XENTITY>
|
||||
{
|
||||
LPXENTITY GetEntity( int entity );
|
||||
LPXENTITY GetEntity( LPTSTR entity );
|
||||
int GetEntityCount( LPCTSTR str );
|
||||
int Ref2Entity( LPCTSTR estr, LPTSTR str, int strlen );
|
||||
int Entity2Ref( LPCTSTR str, LPTSTR estr, int estrlen );
|
||||
CString Ref2Entity( LPCTSTR estr );
|
||||
CString Entity2Ref( LPCTSTR str );
|
||||
|
||||
_tagXMLEntitys(){};
|
||||
_tagXMLEntitys( LPXENTITY entities, int count );
|
||||
}XENTITYS,*LPXENTITYS;
|
||||
extern XENTITYS entityDefault;
|
||||
CString XRef2Entity( LPCTSTR estr );
|
||||
CString XEntity2Ref( LPCTSTR str );
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PIE_PARSE_WELFORMED = 0,
|
||||
PIE_ALONE_NOT_CLOSED,
|
||||
PIE_NOT_CLOSED,
|
||||
PIE_NOT_NESTED,
|
||||
PIE_ATTR_NO_VALUE
|
||||
}PCODE;
|
||||
|
||||
// Parse info.
|
||||
typedef struct _tagParseInfo
|
||||
{
|
||||
bool trim_value; // [set] do trim when parse?
|
||||
bool entity_value; // [set] do convert from reference to entity? ( < -> < )
|
||||
LPXENTITYS entitys; // [set] entity table for entity decode
|
||||
TCHAR escape_value; // [set] escape value (default '\\')
|
||||
|
||||
LPTSTR xml; // [get] xml source
|
||||
bool erorr_occur; // [get] is occurance of error?
|
||||
LPTSTR error_pointer; // [get] error position of xml source
|
||||
PCODE error_code; // [get] error code
|
||||
CString error_string; // [get] error string
|
||||
|
||||
_tagParseInfo() { trim_value = true; entity_value = true; entitys = &entityDefault; xml = NULL; erorr_occur = false; error_pointer = NULL; error_code = PIE_PARSE_WELFORMED; escape_value = 0; }
|
||||
}PARSEINFO,*LPPARSEINFO;
|
||||
extern PARSEINFO piDefault;
|
||||
|
||||
// display optional environment
|
||||
typedef struct _tagDispOption
|
||||
{
|
||||
bool newline; // newline when new tag
|
||||
bool reference_value; // do convert from entity to reference ( < -> < )
|
||||
LPXENTITYS entitys; // entity table for entity encode
|
||||
|
||||
int tab_base; // internal usage
|
||||
_tagDispOption() { newline = true; reference_value = true; entitys = &entityDefault; tab_base = 0; }
|
||||
}DISP_OPT, *LPDISP_OPT;
|
||||
extern DISP_OPT optDefault;
|
||||
|
||||
// XAttr : Attribute Implementation
|
||||
typedef struct _tagXMLAttr
|
||||
{
|
||||
CString name;
|
||||
CString value;
|
||||
|
||||
_tagXMLNode* parent;
|
||||
|
||||
CString GetXML( LPDISP_OPT opt = &optDefault );
|
||||
}XAttr, *LPXAttr;
|
||||
|
||||
// XMLNode structure
|
||||
typedef struct _tagXMLNode
|
||||
{
|
||||
// name and value
|
||||
CString name;
|
||||
CString value;
|
||||
|
||||
// internal variables
|
||||
LPXNode parent; // parent node
|
||||
XNodes childs; // child node
|
||||
XAttrs attrs; // attributes
|
||||
|
||||
// Load/Save XML
|
||||
LPTSTR Load( LPCTSTR pszXml, LPPARSEINFO pi = &piDefault );
|
||||
LPTSTR LoadAttributes( LPCTSTR pszAttrs, LPPARSEINFO pi = &piDefault );
|
||||
CString GetXML( LPDISP_OPT opt = &optDefault );
|
||||
|
||||
// in own attribute list
|
||||
LPXAttr GetAttr( LPCTSTR attrname );
|
||||
LPCTSTR GetAttrValue( LPCTSTR attrname );
|
||||
XAttrs GetAttrs( LPCTSTR name );
|
||||
|
||||
// in one level child nodes
|
||||
LPXNode GetChild( LPCTSTR name );
|
||||
LPCTSTR GetChildValue( LPCTSTR name );
|
||||
XNodes GetChilds( LPCTSTR name );
|
||||
XNodes GetChilds();
|
||||
|
||||
LPXAttr GetChildAttr( LPCTSTR name, LPCTSTR attrname );
|
||||
LPCTSTR GetChildAttrValue( LPCTSTR name, LPCTSTR attrname );
|
||||
|
||||
// modify DOM
|
||||
int GetChildCount();
|
||||
LPXNode GetChild( int i );
|
||||
XNodes::iterator GetChildIterator( LPXNode node );
|
||||
LPXNode CreateNode( LPCTSTR name = NULL, LPCTSTR value = NULL );
|
||||
LPXNode AppendChild( LPCTSTR name = NULL, LPCTSTR value = NULL );
|
||||
LPXNode AppendChild( LPCTSTR name, float value );
|
||||
LPXNode AppendChild( LPCTSTR name, int value );
|
||||
LPXNode AppendChild( LPXNode node );
|
||||
bool RemoveChild( LPXNode node );
|
||||
LPXNode DetachChild( LPXNode node );
|
||||
|
||||
|
||||
LPXAttr GetAttr( int i );
|
||||
XAttrs::iterator GetAttrIterator( LPXAttr node );
|
||||
LPXAttr CreateAttr( LPCTSTR anem = NULL, LPCTSTR value = NULL );
|
||||
LPXAttr AppendAttr( LPCTSTR name = NULL, LPCTSTR value = NULL );
|
||||
LPXAttr AppendAttr( LPXAttr attr );
|
||||
bool RemoveAttr( LPXAttr attr );
|
||||
LPXAttr DetachAttr( LPXAttr attr );
|
||||
|
||||
// operator overloads
|
||||
LPXNode operator [] ( int i ) { return GetChild(i); }
|
||||
|
||||
_tagXMLNode() { parent = NULL; }
|
||||
~_tagXMLNode();
|
||||
|
||||
void Close();
|
||||
}XNode, *LPXNode;
|
||||
|
||||
// Helper Funtion
|
||||
inline long XStr2Int( LPCTSTR str, long default_value = 0 )
|
||||
{
|
||||
return str ? atol(str) : default_value;
|
||||
}
|
||||
|
||||
inline bool XIsEmptyString( LPCTSTR str )
|
||||
{
|
||||
CString s(str);
|
||||
TrimLeft( s );
|
||||
TrimRight( s );
|
||||
|
||||
return ( s.empty() || s == "" );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user