From 333766ef1b42689ec5f386c7759adaa4ea46a460 Mon Sep 17 00:00:00 2001 From: elexis Date: Tue, 29 May 2018 02:14:38 +0000 Subject: [PATCH] Test all full hashes in non-visual replaymode by default and keep skipping quick-hash by default. The previous code only tested quick hashes every 100 turns and could not be used to confirm replay hashes matching. The option can become used for visual replays too. Differential Revision: https://code.wildfiregames.com/D1538 Refs #5162 Reviewed By: temple This was SVN commit r21829. --- binaries/system/readme.txt | 2 ++ source/main.cpp | 4 +++- source/ps/Replay.cpp | 35 ++++++++++++++++++++--------------- source/ps/Replay.h | 5 +++-- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/binaries/system/readme.txt b/binaries/system/readme.txt index 4cfba3c08e..d2a41d4e99 100644 --- a/binaries/system/readme.txt +++ b/binaries/system/readme.txt @@ -78,6 +78,8 @@ Advanced / diagnostic: less complete. It should be enough for debugging most rejoin OOSes. -unique-logs adds unix timestamp and process id to the filename of mainlog.html, interestinglog.html and oos_dump.txt to prevent these files from becoming overwritten by another pyrogenesis process. +-hashtest-full=X whether to enable computation of full hashes in replaymode (default true). Can be disabled to improve performance. +-hashtest-quick=X whether to enable computation of quick hashes in replaymode (default false). Can be enabled for debugging purposes. Windows-specific: -wQpcTscSafe allow timing via QueryPerformanceCounter despite the fact diff --git a/source/main.cpp b/source/main.cpp index a2b01cad0c..bd00fd3903 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -554,7 +554,9 @@ static void RunGameOrAtlas(int argc, const char* argv[]) replay.Replay( args.Has("serializationtest"), args.Has("rejointest") ? args.Get("rejointest").ToInt() : -1, - args.Has("ooslog")); + args.Has("ooslog"), + !args.Has("hashtest-full") || args.Get("hashtest-full") == "true", + args.Has("hashtest-quick") && args.Get("hashtest-quick") == "true"); } g_VFS.reset(); diff --git a/source/ps/Replay.cpp b/source/ps/Replay.cpp index 2f91cda777..3d65474b99 100644 --- a/source/ps/Replay.cpp +++ b/source/ps/Replay.cpp @@ -167,7 +167,8 @@ void CReplayPlayer::CheckReplayMods(const ScriptInterface& scriptInterface, JS:: if (!warn.empty()) LOGWARNING("%s\nThe mods of the replay are:\n%s\nThese mods are enabled:\n%s", warn, ModListToString(replayMods), ModListToString(enabledMods)); } -void CReplayPlayer::Replay(bool serializationtest, int rejointestturn, bool ooslog) + +void CReplayPlayer::Replay(const bool serializationtest, const int rejointestturn, const bool ooslog, const bool testHashFull, const bool testHashQuick) { ENSURE(m_Stream); @@ -247,20 +248,7 @@ void CReplayPlayer::Replay(bool serializationtest, int rejointestturn, bool oosl { std::string replayHash; *m_Stream >> replayHash; - - bool quick = (type == "hash-quick"); - - if (turn % 100 == 0) - { - std::string hash; - bool ok = g_Game->GetSimulation2()->ComputeStateHash(hash, quick); - ENSURE(ok); - std::string hexHash = Hexify(hash); - if (hexHash == replayHash) - debug_printf("hash ok (%s)\n", hexHash.c_str()); - else - debug_printf("HASH MISMATCH (%s != %s)\n", hexHash.c_str(), replayHash.c_str()); - } + TestHash(type, replayHash, testHashFull, testHashQuick); } else if (type == "end") { @@ -307,3 +295,20 @@ void CReplayPlayer::Replay(bool serializationtest, int rejointestturn, bool oosl delete &g_ProfileViewer; SAFE_DELETE(g_ScriptStatsTable); } + +void CReplayPlayer::TestHash(const std::string& hashType, const std::string& replayHash, const bool testHashFull, const bool testHashQuick) +{ + bool quick = (hashType == "hash-quick"); + if ((quick && !testHashQuick) || (!quick && !testHashFull)) + return; + + std::string hash; + ENSURE(g_Game->GetSimulation2()->ComputeStateHash(hash, quick)); + + std::string hexHash = Hexify(hash); + + if (hexHash == replayHash) + debug_printf("%s ok (%s)\n", hashType.c_str(), hexHash.c_str()); + else + debug_printf("%s MISMATCH (%s != %s)\n", hashType.c_str(), hexHash.c_str(), replayHash.c_str()); +} diff --git a/source/ps/Replay.h b/source/ps/Replay.h index fc36d9d549..7902edbe1e 100644 --- a/source/ps/Replay.h +++ b/source/ps/Replay.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -98,12 +98,13 @@ public: ~CReplayPlayer(); void Load(const OsPath& path); - void Replay(bool serializationtest, int rejointestturn, bool ooslog); + void Replay(const bool serializationtest, const int rejointestturn, const bool ooslog, const bool testHashFull, const bool testHashQuick); private: std::istream* m_Stream; CStr ModListToString(const std::vector>& list) const; void CheckReplayMods(const ScriptInterface& scriptInterface, JS::HandleValue attribs) const; + void TestHash(const std::string& hashType, const std::string& replayHash, const bool testHashFull, const bool testHashQuick); }; #endif // INCLUDED_REPLAY