From 39c65eeaab90d29d894841fcbfaefde3925bd7f4 Mon Sep 17 00:00:00 2001
From: Tim Felgentreff <timfelgentreff@gmail.com>
Date: Sat, 19 Feb 2022 20:42:55 +0100
Subject: [PATCH] more debugging and sync hashing

---
 src/map/map_fog.cpp     | 27 ++++++++++++++++++++++++---
 src/network/network.cpp | 11 +++++++++++
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/src/map/map_fog.cpp b/src/map/map_fog.cpp
index c3879b3a7..2b2784f72 100644
--- a/src/map/map_fog.cpp
+++ b/src/map/map_fog.cpp
@@ -51,6 +51,13 @@
 #include "video.h"
 #include "../video/intern_video.h"
 
+#ifdef USE_STACKTRACE
+#include <stdexcept>
+#include <stacktrace/call_stack.hpp>
+#include <stacktrace/stack_exception.hpp>
+#else
+#include "st_backtrace.h"
+#endif
 
 /*----------------------------------------------------------------------------
 --  Variables
@@ -205,6 +212,7 @@ void MapMarkTileSight(const CPlayer &player, const unsigned int index)
 {
 	CMapField &mf = *Map.Field(index);
 	unsigned short *v = &(mf.playerInfo.Visible[player.Index]);
+
 	if (*v == 0 || *v == 1) { // Unexplored or unseen
 		// When there is no fog only unexplored tiles are marked.
 		if (!Map.NoFogOfWar || *v == 0) {
@@ -214,10 +222,23 @@ void MapMarkTileSight(const CPlayer &player, const unsigned int index)
 		if (mf.playerInfo.IsTeamVisible(*ThisPlayer)) {
 			Map.MarkSeenTile(mf);
 		}
-		return;
+	} else {
+		Assert(*v != 65535);
+		++*v;
+	}
+	if (EnableDebugPrint) {
+		fprintf(stderr, "Mapsight: GameCycle: %lud, SyncHash before: %x", GameCycle, SyncHash);
+	}
+	// Calculate some hash.
+	SyncHash = (SyncHash << 5) | (SyncHash >> 27);
+	SyncHash ^= (*v << 16) | *v;
+
+	if (EnableDebugPrint) {
+		fprintf(stderr, ", after: %x (mapfield: %d, player: %d, sight: %d)\n", SyncHash,
+							index, player.Index, *v);
+		print_backtrace(8);
+		fflush(stderr);
 	}
-	Assert(*v != 65535);
-	++*v;
 }
 
 void MapMarkTileSight(const CPlayer &player, const Vec2i &pos)
diff --git a/src/network/network.cpp b/src/network/network.cpp
index 034339eed..4519b93dc 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -250,6 +250,8 @@
 //  Declaration
 //----------------------------------------------------------------------------
 
+extern int SaveGame(const std::string &filename); /// Save game
+
 /**
 **  Network command input/output queue.
 */
@@ -930,6 +932,15 @@ static void NetworkExecCommand_Sync(const CNetworkCommandQueue &ncq)
 			SetMessage("%s", _("Network out of sync"));
 			gameInSync = false;
 			SetGamePaused(true);
+
+			time_t now;
+			time(&now);
+			std::string savefile = "desync_savegame_";
+			savefile += std::to_string(ThisPlayer->Index);
+			savefile += "_";
+			savefile += std::to_string((intmax_t)now);
+			savefile += ".sav";
+			SaveGame(savefile);
 		}
 		DebugPrint("\nNetwork out of sync seed: %X!=%X , hash: %X!=%X Cycle %lu\n\n" _C_
 				   syncSeed _C_ NetworkSyncSeeds[gameNetCycle & 0xFF] _C_