Ticket #3255: t3255_prevent_replay_overwrites_v3.patch

File t3255_prevent_replay_overwrites_v3.patch, 3.5 KB (added by elexis, 9 years ago)
  • source/ps/Replay.cpp

     
    3333#include "scriptinterface/ScriptInterface.h"
    3434#include "scriptinterface/ScriptStats.h"
    3535#include "simulation2/Simulation2.h"
    3636#include "simulation2/helpers/SimulationCommand.h"
    3737
     38#include <ctime>
    3839#include <sstream>
    3940#include <fstream>
    4041#include <iomanip>
    4142
    42 #if MSC_VERSION
    43 #include <process.h>
    44 #define getpid _getpid // use the non-deprecated function name
    45 #endif
    46 
    4743static std::string Hexify(const std::string& s)
    4844{
    4945    std::stringstream str;
    5046    str << std::hex;
    5147    for (size_t i = 0; i < s.size(); ++i)
    CReplayLogger::~CReplayLogger()  
    6359    delete m_Stream;
    6460}
    6561
    6662void CReplayLogger::StartGame(JS::MutableHandleValue attribs)
    6763{
    68     // Add timestamp, since the file-modification-date can change
     64    // Add timestamp to the header, since the file-modification-date can change
    6965    m_ScriptInterface.SetProperty(attribs, "timestamp", std::to_string(std::time(nullptr)));
    7066
    71     // Add engine version and currently loaded mods for sanity checks when replaying
     67    // Add engine version and currently loaded mods to the header for a compatibility check when replaying
    7268    m_ScriptInterface.SetProperty(attribs, "engine_version", CStr(engine_version));
    7369    m_ScriptInterface.SetProperty(attribs, "mods", g_modsLoaded);
    7470
    75     // Construct the directory name based on the PID, to be relatively unique.
    76     // Append "-1", "-2" etc if we run multiple matches in a single session,
    77     // to avoid accidentally overwriting earlier logs.
    78     std::wstringstream name;
    79     name << getpid();
    80 
    81     static int run = -1;
    82     if (++run)
    83         name << "-" << run;
     71    // Get current date
     72    const time_t t = time(nullptr);
     73    const struct tm* now = localtime(&t);
     74
     75    // Construct directory name based on date and sequential number per date
     76    const CStr subDirectoryFormat = "%04d-%02d-%02d_replay_%03d";
     77    char subDirectory[subDirectoryFormat.length()];
     78    OsPath fullPath;
     79    int i = 1;
     80    do {
     81        sprintf(subDirectory, subDirectoryFormat.c_str(), 1900+now->tm_year, 1+now->tm_mon, now->tm_mday, i++);
     82        fullPath = psLogDir() / L"sim_log" / wstring_from_utf8(CStr(subDirectory));
     83    } while (DirectoryExists(fullPath) || FileExists(fullPath));
    8484
    85     m_Directory = psLogDir() / L"sim_log" / name.str();
     85    // Create directory
     86    m_Directory = fullPath;
    8687    CreateDirectories(m_Directory, 0700);
    8788
     89    // Open commands.txt
    8890    m_Stream = new std::ofstream(OsString(m_Directory / L"commands.txt").c_str(), std::ofstream::out | std::ofstream::trunc);
     91
     92    // Write header
    8993    *m_Stream << "start " << m_ScriptInterface.StringifyJSON(attribs, false) << "\n";
    9094}
    9195
    9296void CReplayLogger::Turn(u32 n, u32 turnLength, std::vector<SimulationCommand>& commands)
    9397{
  • source/simulation2/Simulation2.cpp

    void CSimulation2Impl::DumpState()  
    553553
    554554    std::stringstream pid;
    555555    pid << getpid();
    556556    std::stringstream name;\
    557557    name << std::setw(5) << std::setfill('0') << m_TurnNumber << ".txt";
    558     OsPath path = psLogDir() / "sim_log" / pid.str() / name.str();
     558    OsPath path = psLogDir() / "oos_log" / name.str();
    559559    CreateDirectories(path.Parent(), 0700);
    560560    std::ofstream file (OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc);
    561561
    562562    file << "State hash: " << std::hex;
    563563    std::string hashRaw;