#include #include #include #include #include "CGameStatistics.h" #include "FileOperations/fileops.h" #include "svnrev.h" #define VALID_CONFIG_REV 1031 CGameStatistics GameStatistics; CGameStatistics::CGameStatistics() { } CGameStatistics::~CGameStatistics() { } GameStatus * CGameStatistics::GetGameStatus(const char * id) const { if(!id) return NULL; for(u32 i = 0; i < GameList.size(); ++i) { if(strncasecmp(id, GameList[i].id, 6) == 0) { return (GameStatus *) &GameList[i]; } } return NULL; } bool CGameStatistics::AddGame(const GameStatus & NewGame) { for(u32 i = 0; i < GameList.size(); ++i) { if(strncasecmp(NewGame.id, GameList[i].id, 6) == 0) { memcpy(&GameList[i], &NewGame, sizeof(GameStatus)); return true; } } GameList.push_back(NewGame); return true; } bool CGameStatistics::RemoveAll() { GameList.clear(); std::vector().swap(GameList); return Save(); } bool CGameStatistics::Remove(const char * id) { if(!id) return false; for(u32 i = 0; i < GameList.size(); ++i) { if(strncasecmp(id, GameList[i].id, 6) == 0) { GameList.erase(GameList.begin()+i); break; } } return true; } bool CGameStatistics::Load(const char * path) { char line[1024]; char filepath[300]; snprintf(filepath, sizeof(filepath), "%sGXGameStatistics.cfg", path); ConfigPath = filepath; FILE *file = fopen(filepath, "r"); if (!file) return false; if(!ValidVersion(file)) { fclose(file); return false; } while (fgets(line, sizeof(line), file)) { if (line[0] == '#') continue; this->ParseLine(line); } fclose(file); return true; } bool CGameStatistics::ValidVersion(FILE * file) { if(!file) return false; char line[255]; int revision = 0; while (fgets(line, sizeof(line), file)) { const char * ptr = strcasestr(line, "USB Loader GX R"); if(ptr) { ptr += strlen("USB Loader GX R"); revision = atoi(ptr); break; } } rewind(file); return revision >= VALID_CONFIG_REV; } bool CGameStatistics::Save() { char filepath[300]; strcpy(filepath, ConfigPath.c_str()); char * ptr = strrchr(filepath, '/'); if(ptr) ptr[0] = 0; if(!CreateSubfolder(filepath)) return false; FILE * f = fopen(ConfigPath.c_str(), "w"); if (!f) return false; fprintf(f, "# USB Loader GX R%s - Game statistics file\n", GetRev()); fprintf(f, "# note: this file is automatically generated\n"); fprintf(f, "# Num Games: %d\n", GameList.size()); for (u32 i = 0; i < GameList.size(); i++) { fprintf(f, "game:%s = ", GameList[i].id); fprintf(f, "FavoriteRank:%d; ", GameList[i].FavoriteRank); fprintf(f, "PlayCount:%d;\n", GameList[i].PlayCount); } fprintf(f, "# END\n"); fclose(f); return true; } bool CGameStatistics::SetSetting(GameStatus & game, char *name, char *value) { int i = 0; if(strcmp(name, "FavoriteRank") == 0) { if (sscanf(value, "%d", &i) == 1) { game.FavoriteRank = i; } return true; } else if(strcmp(name, "PlayCount") == 0) { if (sscanf(value, "%d", &i) == 1) { game.PlayCount = i; } return true; } return false; } bool CGameStatistics::ReadGameID(const char * src, char * GameID, int size) { if(strncasecmp(src, "game:", 5) != 0) return false; char * ptr = strchr(src, ':'); if(!ptr) return false; ptr++; int i = 0; for(i = 0; i < size; i++, ptr++) { if(*ptr == ' ' || *ptr == '\0') break; GameID[i] = *ptr; } GameID[i] = 0; return true; } void CGameStatistics::ParseLine(char *line) { char name[1024], value[1024]; char GameID[8]; if(!ReadGameID(line, GameID, 6)) return; if(strlen(GameID) != 6 && strlen(GameID) != 4) return; GameStatus NewGame; memset(&NewGame, 0, sizeof(GameStatus)); snprintf(NewGame.id, sizeof(NewGame.id), GameID); char * LinePtr = strchr(line, '='); while(LinePtr != NULL) { LinePtr++; char * eq = strchr(LinePtr, ':'); if (!eq) break; this->TrimLine(name, LinePtr, sizeof(name)); this->TrimLine(value, eq + 1, sizeof(value)); SetSetting(NewGame, name, value); LinePtr = strchr(LinePtr, ';'); } AddGame(NewGame); } void CGameStatistics::TrimLine(char *dest, const char *src, int size) { while (*src == ' ') src++; int i = 0; for(i = 0; i < size; i++, src++) { if(*src == ';' || *src == ':' || *src == '\n' || *src == '\r' || *src == '\0') break; dest[i] = *src; } dest[i] = '\0'; } void CGameStatistics::SetPlayCount(const char * id, int count) { if(!id) return; GameStatus NewStatus; snprintf(NewStatus.id, sizeof(NewStatus.id), id); NewStatus.FavoriteRank = 0; NewStatus.PlayCount = count; GameStatus * game = GetGameStatus(id); if(game) { NewStatus.FavoriteRank = game->FavoriteRank; } AddGame(NewStatus); } void CGameStatistics::SetFavoriteRank(const char * id, int rank) { if(!id) return; GameStatus NewStatus; snprintf(NewStatus.id, sizeof(NewStatus.id), id); NewStatus.FavoriteRank = rank; NewStatus.PlayCount = 0; GameStatus * game = GetGameStatus(id); if(game) { NewStatus.PlayCount = game->PlayCount; } AddGame(NewStatus); } int CGameStatistics::GetPlayCount(const char * id) const { if(!id) return 0; GameStatus * game = GetGameStatus(id); if(game) return game->PlayCount; return 0; } int CGameStatistics::GetFavoriteRank(const char * id) const { if(!id) return 0; GameStatus * game = GetGameStatus(id); if(game) return game->FavoriteRank; return 0; }