Files
jaildoctors_dilemma/source/stats.cpp

335 lines
7.4 KiB
C++

#include "jail_engine/jscore.h"
#include "stats.h"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
// Constructor
Stats::Stats(std::string file, std::string buffer, options_t *options)
{
this->options = options;
bufferPath = buffer;
filePath = file;
bufferList.clear();
list.clear();
dictionary.clear();
}
// Destructor
Stats::~Stats()
{
// Vuelca los datos del buffer en la lista de estadisticas
updateListFromBuffer();
// Calcula cual es la habitación con más muertes
checkWorstNightmare();
// Guarda las estadísticas
saveToServer();
saveToFile(bufferPath, bufferList);
saveToFile(filePath, list);
bufferList.clear();
list.clear();
dictionary.clear();
}
// Inicializador
// Se debe llamar a este procediiento una vez se haya creado el diccionario numero-nombre
void Stats::init()
{
loadFromFile(bufferPath, bufferList);
loadFromFile(filePath, list);
if (options->online.enabled)
{
loadFromServer();
}
// Vuelca los datos del buffer en la lista de estadisticas
updateListFromBuffer();
}
// Añade una muerte a las estadisticas
void Stats::addDeath(std::string name)
{
// Normaliza el nombre
// std::replace(name.begin(), name.end(), ' ', '_');
// Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name, bufferList);
if (index != -1)
{
bufferList[index].died++;
}
// En caso contrario crea la entrada
else
{
stats_t item;
item.name = name;
item.visited = 0;
item.died = 1;
bufferList.push_back(item);
}
}
// Añade una visita a las estadisticas
void Stats::addVisit(std::string name)
{
// Normaliza el nombre
// std::replace(name.begin(), name.end(), ' ', '_');
// Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name, bufferList);
if (index != -1)
{
bufferList[index].visited++;
}
// En caso contrario crea la entrada
else
{
stats_t item;
item.name = name;
item.visited = 1;
item.died = 0;
bufferList.push_back(item);
}
}
// Busca una entrada en la lista por nombre
int Stats::findByName(std::string name, std::vector<stats_t> &list)
{
int i = 0;
for (auto l : list)
{
if (l.name == name)
{
return i;
}
i++;
}
return -1;
}
// Carga las estadisticas desde un fichero
bool Stats::loadFromFile(std::string filePath, std::vector<stats_t> &list)
{
list.clear();
// Indicador de éxito en la carga
bool success = true;
// Variables para manejar el fichero
std::string line;
std::ifstream file(filePath);
// Si el fichero se puede abrir
if (file.good())
{
// Procesa el fichero linea a linea
while (std::getline(file, line))
{
// Comprueba que la linea no sea un comentario
if (line.substr(0, 1) != "#")
{
stats_t stat;
std::stringstream ss(line);
std::string tmp;
// Obtiene el nombre
getline(ss, tmp, ';');
stat.name = tmp;
// Obtiene las visitas
getline(ss, tmp, ';');
stat.visited = std::stoi(tmp);
// Obtiene las muertes
getline(ss, tmp, ';');
stat.died = std::stoi(tmp);
list.push_back(stat);
}
}
// Cierra el fichero
file.close();
}
// El fichero no existe
else
{ // Crea el fichero con los valores por defecto
saveToFile(filePath, list);
}
return success;
}
// Carga las estadisticas desde un servidor
void Stats::loadFromServer()
{
// Limpia los datos del servidor
// eraseServerData();
list.clear();
std::string data;
if (options->online.enabled)
{
data = jscore::getUserData(options->online.gameID, options->online.jailerID);
}
std::stringstream ss(data);
std::string tmp;
int count = 0;
for (int i = 0; i < (int)data.size(); ++i)
{
if (data[i] == ';')
{
count++;
}
}
while (count > 0)
{
stats_t stat;
// Obtiene el nombre
getline(ss, tmp, ';');
stat.name = numberToName(tmp);
// Obtiene las visitas
getline(ss, tmp, ';');
stat.visited = std::stoi(tmp);
// Obtiene las muertes
getline(ss, tmp, ';');
stat.died = std::stoi(tmp);
list.push_back(stat);
count = count - 3;
}
}
// Guarda las estadisticas en un fichero
void Stats::saveToFile(std::string filePath, std::vector<stats_t> &list)
{
// Crea y abre el fichero de texto
std::ofstream file(filePath);
// Escribe en el fichero
file << "# ROOM NAME;VISITS;DEATHS" << std::endl;
for (auto item : list)
{
file << item.name << ";" << item.visited << ";" << item.died << std::endl;
}
// Cierra el fichero
file.close();
}
// Guarda las estadisticas en un servidor
void Stats::saveToServer()
{
std::string data = "";
if (options->online.enabled)
{
for (auto item : list)
{
data = data + nameToNumber(item.name) + ";" + std::to_string(item.visited) + ";" + std::to_string(item.died) + ";";
}
jscore::setUserData(options->online.gameID, options->online.jailerID, data);
}
}
// Calcula cual es la habitación con más muertes
void Stats::checkWorstNightmare()
{
int deaths = 0;
for (auto item : list)
{
if (item.died > deaths)
{
deaths = item.died;
options->stats.worstNightmare = item.name;
}
}
}
// Añade una entrada al diccionario
void Stats::addDictionary(std::string number, std::string name)
{
dictionary.push_back({number, name});
}
// Obtiene el nombre de una habitación a partir del número
std::string Stats::numberToName(std::string number)
{
for (auto l : dictionary)
{
if (l.number == number)
{
return l.name;
}
}
return "";
}
// Obtiene el número de una habitación a partir del nombre
std::string Stats::nameToNumber(std::string name)
{
for (auto l : dictionary)
{
if (l.name == name)
{
return l.number;
}
}
return "";
}
// Vuelca los datos del buffer en la lista de estadisticas
void Stats::updateListFromBuffer()
{
// Actualiza list desde bufferList
for (auto buffer : bufferList)
{
int index = findByName(buffer.name, list);
if (index != -1)
{ // Encontrado. Aumenta sus estadisticas
list[index].visited += buffer.visited;
list[index].died += buffer.died;
}
else
{ // En caso contrario crea la entrada
stats_t item;
item.name = buffer.name;
item.visited = buffer.visited;
item.died = buffer.died;
list.push_back(item);
}
}
// Sube los datos al servidor
if (options->online.enabled)
{
saveToServer();
bufferList.clear();
}
saveToFile(bufferPath, bufferList);
saveToFile(filePath, list);
}
// Limpia los datos del servidor
void Stats::eraseServerData()
{
jscore::setUserData(options->online.gameID, options->online.jailerID, "");
}