Ticket #3255: t3255_prevent_replay_overwrites_v5.patch
File t3255_prevent_replay_overwrites_v5.patch, 6.5 KB (added by , 8 years ago) |
---|
-
source/ps/Replay.cpp
28 28 #include "ps/Loader.h" 29 29 #include "ps/Mod.h" 30 30 #include "ps/Profile.h" 31 31 #include "ps/ProfileViewer.h" 32 32 #include "ps/Pyrogenesis.h" 33 #include "ps/VisualReplay.h" 33 34 #include "scriptinterface/ScriptInterface.h" 34 35 #include "scriptinterface/ScriptStats.h" 35 36 #include "simulation2/Simulation2.h" 36 37 #include "simulation2/helpers/SimulationCommand.h" 37 38 39 #include <ctime> 38 40 #include <sstream> 39 41 #include <fstream> 40 42 #include <iomanip> 41 43 42 #if MSC_VERSION43 #include <process.h>44 #define getpid _getpid // use the non-deprecated function name45 #endif46 47 44 static std::string Hexify(const std::string& s) 48 45 { 49 46 std::stringstream str; 50 47 str << std::hex; 51 48 for (size_t i = 0; i < s.size(); ++i) … … CReplayLogger::~CReplayLogger() 63 60 delete m_Stream; 64 61 } 65 62 66 63 void CReplayLogger::StartGame(JS::MutableHandleValue attribs) 67 64 { 65 const time_t timestamp = std::time(nullptr); 66 68 67 // Add timestamp, since the file-modification-date can change 69 m_ScriptInterface.SetProperty(attribs, "timestamp", std::to_string( std::time(nullptr)));68 m_ScriptInterface.SetProperty(attribs, "timestamp", std::to_string(timestamp)); 70 69 71 70 // Add engine version and currently loaded mods for sanity checks when replaying 72 71 m_ScriptInterface.SetProperty(attribs, "engine_version", CStr(engine_version)); 73 72 m_ScriptInterface.SetProperty(attribs, "mods", g_modsLoaded); 74 73 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 static int run = -1;74 // Construct directory name (for example 2015-11-02_0012) 75 const struct tm* now = localtime(×tamp); 76 char directory[256]; 77 int i = 0; 79 78 do 80 79 { 81 std::wstringstream name; 82 name << getpid(); 83 if (++run) 84 name << "-" << run; 85 86 m_Directory = psLogDir() / L"sim_log" / name.str(); 87 } while (DirectoryExists(m_Directory)); 80 const CStr directoryFormat = ++i < 10000 ? "%04d-%02d-%02d_%04d" : "%04d-%02d-%02d_%d"; 81 sprintf(directory, directoryFormat.c_str(), now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, i); 82 m_Directory = VisualReplay::GetDirectoryName() / CStr(directory); 83 } while (DirectoryExists(m_Directory) || FileExists(m_Directory)); 88 84 85 debug_printf("Writing replay to %s\n", m_Directory.string8().c_str()); 89 86 CreateDirectories(m_Directory, 0700); 90 87 91 88 m_Stream = new std::ofstream(OsString(m_Directory / L"commands.txt").c_str(), std::ofstream::out | std::ofstream::trunc); 92 89 *m_Stream << "start " << m_ScriptInterface.StringifyJSON(attribs, false) << "\n"; 93 90 } -
source/ps/VisualReplay.cpp
1 /* Copyright (C) 201 5Wildfire Games.1 /* Copyright (C) 2016 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 5 * it under the terms of the GNU General Public License as published by 6 6 * the Free Software Foundation, either version 2 of the License, or … … 25 25 #include "network/NetClient.h" 26 26 #include "network/NetServer.h" 27 27 #include "ps/CLogger.h" 28 28 #include "ps/Filesystem.h" 29 29 #include "ps/Game.h" 30 #include "ps/GameSetup/Paths.h" 31 #include "ps/Mod.h" 30 32 #include "ps/Pyrogenesis.h" 31 33 #include "ps/Replay.h" 32 34 #include "scriptinterface/ScriptInterface.h" 33 35 34 36 /** … … 36 38 */ 37 39 const u8 minimumReplayDuration = 3; 38 40 39 41 OsPath VisualReplay::GetDirectoryName() 40 42 { 41 return OsPath(psLogDir() / L"sim_log"); 43 const Paths paths(g_args); 44 return OsPath(paths.UserData() / "replays" / engine_version); 42 45 } 43 46 44 47 void VisualReplay::StartVisualReplay(const CStrW& directory) 45 48 { 46 49 ENSURE(!g_NetServer); -
source/simulation2/Simulation2.cpp
public: 77 77 if (CConfigDB::IsInitialised()) 78 78 { 79 79 CFG_GET_VAL("ooslog", m_EnableOOSLog); 80 80 CFG_GET_VAL("serializationtest", m_EnableSerializationTest); 81 81 } 82 83 std::stringstream pid; 84 pid << getpid(); 85 m_OOSLogPath = psLogDir() / "oos_logs" / pid.str(); 86 87 if (m_EnableOOSLog) 88 debug_printf("Writing ooslogs to %s\n", m_OOSLogPath.string8().c_str()); 82 89 } 83 90 84 91 ~CSimulation2Impl() 85 92 { 86 93 UnregisterFileReloadFunc(ReloadChangedFileCB, this); … … public: 130 137 std::set<VfsPath> m_LoadedScripts; 131 138 132 139 uint32_t m_TurnNumber; 133 140 134 141 bool m_EnableOOSLog; 135 142 OsPath m_OOSLogPath; 136 143 137 144 // Functions and data for the serialization test mode: (see Update() for relevant comments) 138 139 145 bool m_EnableSerializationTest; 140 146 141 147 struct SerializationTestState 142 148 { 143 149 std::stringstream state; … … void CSimulation2Impl::DumpSerialization 293 299 294 300 void CSimulation2Impl::ReportSerializationFailure( 295 301 SerializationTestState* primaryStateBefore, SerializationTestState* primaryStateAfter, 296 302 SerializationTestState* secondaryStateBefore, SerializationTestState* secondaryStateAfter) 297 303 { 298 OsPath path = psLogDir() / " oos_log";304 OsPath path = psLogDir() / "serializationtest"; 299 305 CreateDirectories(path, 0700); 300 306 307 debug_printf("Writing serializationtest-data to %s\n", path.string8().c_str()); 308 301 309 // Clean up obsolete files from previous runs 302 310 wunlink(path / "hash.before.a"); 303 311 wunlink(path / "hash.before.b"); 304 312 wunlink(path / "debug.before.a"); 305 313 wunlink(path / "debug.before.b"); … … void CSimulation2Impl::Interpolate(float 547 555 548 556 void CSimulation2Impl::DumpState() 549 557 { 550 558 PROFILE("DumpState"); 551 559 552 std::stringstream pid;553 pid << getpid();554 560 std::stringstream name;\ 555 561 name << std::setw(5) << std::setfill('0') << m_TurnNumber << ".txt"; 556 OsPath path = psLogDir() / "sim_log" / pid.str()/ name.str();562 OsPath path = m_OOSLogPath / name.str(); 557 563 CreateDirectories(path.Parent(), 0700); 558 564 std::ofstream file (OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc); 559 565 560 566 file << "State hash: " << std::hex; 561 567 std::string hashRaw; … … CSimulation2::~CSimulation2() 583 589 { 584 590 delete m; 585 591 } 586 592 587 593 // Forward all method calls to the appropriate CSimulation2Impl/CComponentManager methods: 588 589 594 void CSimulation2::EnableOOSLog() 590 595 { 591 596 m->m_EnableOOSLog = true; 597 debug_printf("Writing ooslogs to %s\n", m->m_OOSLogPath.string8().c_str()); 592 598 } 593 599 594 600 void CSimulation2::EnableSerializationTest() 595 601 { 596 602 m->m_EnableSerializationTest = true;