1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-27 22:49:25 +02:00
This commit is contained in:
Laserlicht
2024-08-01 21:30:53 +02:00
parent fb171ab3a2
commit 490f1bfee6
7 changed files with 63 additions and 28 deletions

View File

@@ -355,22 +355,6 @@ void ClientCommandManager::handleGetScriptsCommand()
#endif #endif
} }
void ClientCommandManager::handleGetStatistic()
{
printCommandMessage("Command accepted.\t");
const boost::filesystem::path outPath = VCMIDirs::get().userExtractedPath() / "statistic";
boost::filesystem::create_directories(outPath);
const boost::filesystem::path filePath = outPath / (vstd::getDateTimeISO8601Basic(std::time(nullptr)) + ".csv");
std::ofstream file(filePath.c_str());
std::string csv = CSH->client->gameState()->statistic.toCsv();
file << csv;
printCommandMessage("Writing statistic done :)\n");
printCommandMessage("Statistic files can be found in " + outPath.string() + " directory\n");
}
void ClientCommandManager::handleGetTextCommand() void ClientCommandManager::handleGetTextCommand()
{ {
printCommandMessage("Command accepted.\t"); printCommandMessage("Command accepted.\t");
@@ -613,9 +597,6 @@ void ClientCommandManager::processCommand(const std::string & message, bool call
else if(message=="get scripts") else if(message=="get scripts")
handleGetScriptsCommand(); handleGetScriptsCommand();
else if(message=="get statistic")
handleGetStatistic();
else if(message=="get txt") else if(message=="get txt")
handleGetTextCommand(); handleGetTextCommand();

View File

@@ -57,9 +57,6 @@ class ClientCommandManager //take mantis #2292 issue about account if thinking a
// Dumps all scripts in Extracted/Scripts // Dumps all scripts in Extracted/Scripts
void handleGetScriptsCommand(); void handleGetScriptsCommand();
// Dumps statistic in file
void handleGetStatistic();
// Dumps all .txt files from DATA into Extracted/DATA // Dumps all .txt files from DATA into Extracted/DATA
void handleGetTextCommand(); void handleGetTextCommand();

View File

@@ -9,6 +9,9 @@
*/ */
#include "StdInc.h" #include "StdInc.h"
#include "GameStatistics.h" #include "GameStatistics.h"
#include "../CPlayerState.h"
#include "../constants/StringConstants.h"
#include "CGameState.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
@@ -17,15 +20,37 @@ void StatisticDataSet::add(StatisticDataSetEntry entry)
data.push_back(entry); data.push_back(entry);
} }
StatisticDataSetEntry StatisticDataSet::createEntry(const PlayerState * ps, const CGameState * gs)
{
StatisticDataSetEntry data;
data.day = gs->getDate(Date::DAY);
data.player = ps->color;
data.team = ps->team;
data.resources = ps->resources;
data.heroesCount = ps->heroes.size();
data.townCount = ps->towns.size();
return data;
}
std::string StatisticDataSet::toCsv() std::string StatisticDataSet::toCsv()
{ {
std::stringstream ss; std::stringstream ss;
ss << "Day" << ";" << "Player" << "\r\n"; auto resources = std::vector<EGameResID>{EGameResID::GOLD, EGameResID::WOOD, EGameResID::MERCURY, EGameResID::ORE, EGameResID::SULFUR, EGameResID::CRYSTAL, EGameResID::GEMS};
ss << "Day" << ";" << "Player" << ";" << "Team" << ";" << "HeroesCount" << ";" << "TownCount";
for(auto & resource : resources)
ss << ";" << GameConstants::RESOURCE_NAMES[resource];
ss << "\r\n";
for(auto & entry : data) for(auto & entry : data)
{ {
ss << entry.day << ";" << entry.player.getNum() << "\r\n"; ss << entry.day << ";" << GameConstants::PLAYER_COLOR_NAMES[entry.player] << ";" << entry.team.getNum() << ";" << entry.heroesCount << ";" << entry.townCount;
for(auto & resource : resources)
ss << ";" << entry.resources[resource];
ss << "\r\n";
} }
return ss.str(); return ss.str();

View File

@@ -10,18 +10,30 @@
#pragma once #pragma once
#include "../GameConstants.h" #include "../GameConstants.h"
#include "../ResourceSet.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
struct PlayerState;
class CGameState;
struct DLL_LINKAGE StatisticDataSetEntry struct DLL_LINKAGE StatisticDataSetEntry
{ {
int day; int day;
PlayerColor player; PlayerColor player;
TeamID team;
TResources resources;
int heroesCount;
int townCount;
template <typename Handler> void serialize(Handler &h) template <typename Handler> void serialize(Handler &h)
{ {
h & day; h & day;
h & player; h & player;
h & team;
h & resources;
h & heroesCount;
h & townCount;
} }
}; };
@@ -31,6 +43,7 @@ class DLL_LINKAGE StatisticDataSet
public: public:
void add(StatisticDataSetEntry entry); void add(StatisticDataSetEntry entry);
static StatisticDataSetEntry createEntry(const PlayerState * ps, const CGameState * gs);
std::string toCsv(); std::string toCsv();
template <typename Handler> void serialize(Handler &h) template <typename Handler> void serialize(Handler &h)

View File

@@ -676,10 +676,7 @@ void CGameHandler::addStatistics()
if (elem.first == PlayerColor::NEUTRAL || !elem.first.isValidPlayer()) if (elem.first == PlayerColor::NEUTRAL || !elem.first.isValidPlayer())
continue; continue;
StatisticDataSetEntry data; auto data = StatisticDataSet::createEntry(&elem.second, gs);
data.day = getDate(Date::DAY);
data.player = elem.first;
gameState()->statistic.add(data); gameState()->statistic.add(data);
} }

View File

@@ -29,6 +29,7 @@
#include "../../lib/networkPacks/PacksForClient.h" #include "../../lib/networkPacks/PacksForClient.h"
#include "../../lib/networkPacks/StackLocation.h" #include "../../lib/networkPacks/StackLocation.h"
#include "../../lib/serializer/Connection.h" #include "../../lib/serializer/Connection.h"
#include "../lib/VCMIDirs.h"
PlayerMessageProcessor::PlayerMessageProcessor(CGameHandler * gameHandler) PlayerMessageProcessor::PlayerMessageProcessor(CGameHandler * gameHandler)
:gameHandler(gameHandler) :gameHandler(gameHandler)
@@ -133,12 +134,30 @@ void PlayerMessageProcessor::commandCheaters(PlayerColor player, const std::vect
broadcastSystemMessage("No cheaters registered!"); broadcastSystemMessage("No cheaters registered!");
} }
void PlayerMessageProcessor::commandStatistic(PlayerColor player, const std::vector<std::string> & words)
{
bool isHost = gameHandler->gameLobby()->isPlayerHost(player);
if(!isHost)
return;
const boost::filesystem::path outPath = VCMIDirs::get().userCachePath() / "statistic";
boost::filesystem::create_directories(outPath);
const boost::filesystem::path filePath = outPath / (vstd::getDateTimeISO8601Basic(std::time(nullptr)) + ".csv");
std::ofstream file(filePath.c_str());
std::string csv = gameHandler->gameState()->statistic.toCsv();
file << csv;
broadcastSystemMessage("Statistic files can be found in " + outPath.string() + " directory\n");
}
void PlayerMessageProcessor::commandHelp(PlayerColor player, const std::vector<std::string> & words) void PlayerMessageProcessor::commandHelp(PlayerColor player, const std::vector<std::string> & words)
{ {
broadcastSystemMessage("Available commands to host:"); broadcastSystemMessage("Available commands to host:");
broadcastSystemMessage("'!exit' - immediately ends current game"); broadcastSystemMessage("'!exit' - immediately ends current game");
broadcastSystemMessage("'!kick <player>' - kick specified player from the game"); broadcastSystemMessage("'!kick <player>' - kick specified player from the game");
broadcastSystemMessage("'!save <filename>' - save game under specified filename"); broadcastSystemMessage("'!save <filename>' - save game under specified filename");
broadcastSystemMessage("'!statistic' - save game statistics as csv file");
broadcastSystemMessage("Available commands to all players:"); broadcastSystemMessage("Available commands to all players:");
broadcastSystemMessage("'!help' - display this help"); broadcastSystemMessage("'!help' - display this help");
broadcastSystemMessage("'!cheaters' - list players that entered cheat command during game"); broadcastSystemMessage("'!cheaters' - list players that entered cheat command during game");
@@ -319,6 +338,8 @@ void PlayerMessageProcessor::handleCommand(PlayerColor player, const std::string
commandSave(player, words); commandSave(player, words);
if(words[0] == "!cheaters") if(words[0] == "!cheaters")
commandCheaters(player, words); commandCheaters(player, words);
if(words[0] == "!statistic")
commandStatistic(player, words);
} }
void PlayerMessageProcessor::cheatGiveSpells(PlayerColor player, const CGHeroInstance * hero) void PlayerMessageProcessor::cheatGiveSpells(PlayerColor player, const CGHeroInstance * hero)

View File

@@ -62,6 +62,7 @@ class PlayerMessageProcessor
void commandKick(PlayerColor player, const std::vector<std::string> & words); void commandKick(PlayerColor player, const std::vector<std::string> & words);
void commandSave(PlayerColor player, const std::vector<std::string> & words); void commandSave(PlayerColor player, const std::vector<std::string> & words);
void commandCheaters(PlayerColor player, const std::vector<std::string> & words); void commandCheaters(PlayerColor player, const std::vector<std::string> & words);
void commandStatistic(PlayerColor player, const std::vector<std::string> & words);
void commandHelp(PlayerColor player, const std::vector<std::string> & words); void commandHelp(PlayerColor player, const std::vector<std::string> & words);
void commandVote(PlayerColor player, const std::vector<std::string> & words); void commandVote(PlayerColor player, const std::vector<std::string> & words);