335 lines
7.2 KiB
C++
335 lines
7.2 KiB
C++
#include "jail_engine/jscore.h"
|
|
#include "stats.h"
|
|
#include <algorithm>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
|
|
// Constructor
|
|
Stats::Stats(string file, 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(string name)
|
|
{
|
|
// Normaliza el nombre
|
|
// 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(string name)
|
|
{
|
|
// Normaliza el nombre
|
|
// 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(string name, 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(string filePath, vector<stats_t> &list)
|
|
{
|
|
list.clear();
|
|
|
|
// Indicador de éxito en la carga
|
|
bool success = true;
|
|
|
|
// Variables para manejar el fichero
|
|
string line;
|
|
ifstream file(filePath);
|
|
|
|
// Si el fichero se puede abrir
|
|
if (file.good())
|
|
{
|
|
// Procesa el fichero linea a linea
|
|
while (getline(file, line))
|
|
{
|
|
// Comprueba que la linea no sea un comentario
|
|
if (line.substr(0, 1) != "#")
|
|
{
|
|
stats_t stat;
|
|
stringstream ss(line);
|
|
string tmp;
|
|
|
|
// Obtiene el nombre
|
|
getline(ss, tmp, ';');
|
|
stat.name = tmp;
|
|
|
|
// Obtiene las visitas
|
|
getline(ss, tmp, ';');
|
|
stat.visited = stoi(tmp);
|
|
|
|
// Obtiene las muertes
|
|
getline(ss, tmp, ';');
|
|
stat.died = 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();
|
|
|
|
string data;
|
|
if (options->online.enabled)
|
|
{
|
|
data = jscore::getUserData(options->online.gameID, options->online.jailerID);
|
|
}
|
|
|
|
stringstream ss(data);
|
|
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 = stoi(tmp);
|
|
|
|
// Obtiene las muertes
|
|
getline(ss, tmp, ';');
|
|
stat.died = stoi(tmp);
|
|
|
|
list.push_back(stat);
|
|
count = count - 3;
|
|
}
|
|
}
|
|
|
|
// Guarda las estadisticas en un fichero
|
|
void Stats::saveToFile(string filePath, vector<stats_t> &list)
|
|
{
|
|
// Crea y abre el fichero de texto
|
|
ofstream file(filePath);
|
|
|
|
// Escribe en el fichero
|
|
file << "# ROOM NAME;VISITS;DEATHS" << endl;
|
|
for (auto item : list)
|
|
{
|
|
file << item.name << ";" << item.visited << ";" << item.died << endl;
|
|
}
|
|
|
|
// Cierra el fichero
|
|
file.close();
|
|
}
|
|
|
|
// Guarda las estadisticas en un servidor
|
|
void Stats::saveToServer()
|
|
{
|
|
string data = "";
|
|
if (options->online.enabled)
|
|
{
|
|
for (auto item : list)
|
|
{
|
|
data = data + nameToNumber(item.name) + ";" + to_string(item.visited) + ";" + 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(string number, string name)
|
|
{
|
|
dictionary.push_back({number, name});
|
|
}
|
|
|
|
// Obtiene el nombre de una habitación a partir del número
|
|
string Stats::numberToName(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
|
|
string Stats::nameToNumber(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, "");
|
|
} |