mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-20 10:19:15 +01:00
2c268af0f9
*changed fat/ntfs/ext installer to use the header title as foldername instead of wiitdb title (this is the way it is in the wbfs managers) *Fixed language changing for wiitdb titles / coverdownload even without available .lang file which is loaded *Added reload of game titles on language change *Added check for valid config files. If config file is not valid it will not be used. Current valid configs are R1031 to all. (You configs will be reseted with this. If you want to save them, move them and merge them afterwards manually.) *Fixed possible crash on mounting *Changed default settings for device free space display to off, because fat32 partitions are very slow on that. Added a warning when on FAT partition and trying to enable this option. *Updated langauge files
330 lines
6.1 KiB
C++
330 lines
6.1 KiB
C++
#include <ogcsys.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#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)
|
|
{
|
|
if(!id)
|
|
return NULL;
|
|
|
|
for(u32 i = 0; i < GameList.size(); ++i)
|
|
{
|
|
if(strncmp(id, GameList[i].id, 6) == 0)
|
|
{
|
|
return &GameList[i];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool CGameStatistics::AddGame(const GameStatus & NewGame)
|
|
{
|
|
for(u32 i = 0; i < GameList.size(); ++i)
|
|
{
|
|
if(strncmp(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<GameStatus>().swap(GameList);
|
|
|
|
return Save();
|
|
}
|
|
|
|
bool CGameStatistics::Remove(const char * id)
|
|
{
|
|
if(!id)
|
|
return false;
|
|
|
|
for(u32 i = 0; i < GameList.size(); ++i)
|
|
{
|
|
if(strncmp(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;
|
|
}
|
|
#include "gecko.h"
|
|
void CGameStatistics::ParseLine(char *line)
|
|
{
|
|
char name[1024], value[1024];
|
|
char GameID[8];
|
|
|
|
if(!ReadGameID(line, GameID, 6))
|
|
return;
|
|
|
|
if(strlen(GameID) != 6)
|
|
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));
|
|
|
|
//gprintf("ID: %s, Name = %s, Value = %s\n", GameID, name, 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)
|
|
{
|
|
if(!id)
|
|
return 0;
|
|
|
|
GameStatus * game = GetGameStatus(id);
|
|
if(game)
|
|
return game->PlayCount;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CGameStatistics::GetFavoriteRank(const char * id)
|
|
{
|
|
if(!id)
|
|
return 0;
|
|
|
|
GameStatus * game = GetGameStatus(id);
|
|
if(game)
|
|
return game->FavoriteRank;
|
|
|
|
return 0;
|
|
}
|