Bazaar developer reference

CvDllGameContext::RandomNumberGeneratorSyncCheck(PlayerTypes, ICvRandom1 *, bool)

Defined in
CvDllContext.cpp, line 905
Class
CvDllGameContext
Hook name
CivHooks::CvDllGameContext_RandomNumberGeneratorSyncCheck

Hooks

static bool BeforeCvDllGameContext_RandomNumberGeneratorSyncCheck(CvDllGameContext* self, PlayerTypes ePlayer, ICvRandom1* pRandom, bool bIsHost, bool& result);static void AfterCvDllGameContext_RandomNumberGeneratorSyncCheck(CvDllGameContext* self, PlayerTypes ePlayer, ICvRandom1* pRandom, bool bIsHost, bool& result);static bool ReplaceCvDllGameContext_RandomNumberGeneratorSyncCheck(bool (*original)(CvDllGameContext*, PlayerTypes, ICvRandom1*, bool), CvDllGameContext* self, PlayerTypes ePlayer, ICvRandom1* pRandom, bool bIsHost);// CivHooks.h gives this hook point no types, so nothing checks these hooks' parameters.host->RegisterHook(host->pluginIndex, CivHooks::CvDllGameContext_RandomNumberGeneratorSyncCheck::ID, CIV_HOOK_BEFORE, (void*)&BeforeCvDllGameContext_RandomNumberGeneratorSyncCheck);host->RegisterHook(host->pluginIndex, CivHooks::CvDllGameContext_RandomNumberGeneratorSyncCheck::ID, CIV_HOOK_AFTER, (void*)&AfterCvDllGameContext_RandomNumberGeneratorSyncCheck);host->RegisterHook(host->pluginIndex, CivHooks::CvDllGameContext_RandomNumberGeneratorSyncCheck::ID, CIV_HOOK_REPLACE, (void*)&ReplaceCvDllGameContext_RandomNumberGeneratorSyncCheck);

Code

905bool CvDllGameContext::RandomNumberGeneratorSyncCheck(PlayerTypes ePlayer, ICvRandom1* pRandom, bool bIsHost)906{907	// uh oh! Check the Random number generator!908	const CvRandom& localSimRandomNumberGenerator = GC.getGame().getJonRand();909	CvRandom* pkRandom = GC.UnwrapRandomPointer(pRandom);910911	if(localSimRandomNumberGenerator != *pkRandom)912	{913		FILogFile* logFile = LOGFILEMGR.GetLog("net_message_debug.log", 0);914915		char formatBuf[128] = {"\0"};916		std::string rngLogMessage = "Game Random Number Generators are out of sync : local.seed=";917		rngLogMessage += _itoa_s(localSimRandomNumberGenerator.getSeed(), formatBuf, 10);918		rngLogMessage += ", remote.seed=";919		rngLogMessage += _itoa_s(pkRandom->getSeed(), formatBuf, 10);920		rngLogMessage += "\n\tlocal.callCount=";921		rngLogMessage += _itoa_s(localSimRandomNumberGenerator.getCallCount(), formatBuf, 10);922		rngLogMessage += ", remote.callCount=";923		rngLogMessage += _itoa_s(pkRandom->getCallCount(), formatBuf, 10);924		rngLogMessage += "\n\tlocal.resetCount=";925		rngLogMessage += _itoa_s(localSimRandomNumberGenerator.getResetCount(), formatBuf, 10);926		rngLogMessage += ", remote.resetCount=";927		rngLogMessage += _itoa_s(pkRandom->getResetCount(), formatBuf, 10);928		rngLogMessage += "\n";929930		if(localSimRandomNumberGenerator.callStackDebuggingEnabled() && pkRandom->callStackDebuggingEnabled())931		{932			std::string localCallStack("");933			std::string remoteCallStack("");934			localSimRandomNumberGenerator.resolveCallStacks();935			const std::vector<std::string>& localCallStacks = localSimRandomNumberGenerator.getResolvedCallStacks();936			const std::vector<std::string>& remoteCallStacks =  pkRandom->getResolvedCallStacks();937			const std::vector<unsigned long>& localSeedHistory = localSimRandomNumberGenerator.getSeedHistory();938			const std::vector<unsigned long>& remoteSeedHistory = pkRandom->getSeedHistory();939			std::vector<unsigned long>::const_iterator localSeedIterator = localSeedHistory.begin();940			std::vector<unsigned long>::const_iterator remoteSeedIterator = remoteSeedHistory.begin();941			unsigned int callNumber = 0;942			for(localSeedIterator = localSeedHistory.begin(), remoteSeedIterator = remoteSeedHistory.begin(); localSeedIterator != localSeedHistory.end() && remoteSeedIterator != remoteSeedHistory.end(); ++localSeedIterator, ++remoteSeedIterator, ++callNumber)943			{944				if(*localSeedIterator != *remoteSeedIterator)945				{946					if(callNumber < localCallStacks.size() && callNumber < remoteCallStacks.size())947					{948						rngLogMessage += "At Call #";949						rngLogMessage += _itoa_s(callNumber, formatBuf, 10);950						rngLogMessage += " random number seeds are different.\n";951						if(callNumber > 0)952						{953							rngLogMessage += "Call #";954							rngLogMessage += _itoa_s(callNumber - 1, formatBuf, 10);955							rngLogMessage += "\nLocal:\n";956							rngLogMessage += localCallStacks[callNumber - 1];957							rngLogMessage += "\nRemote:\n";958							rngLogMessage += remoteCallStacks[callNumber - 1];959						}960						rngLogMessage += "Call #";961						rngLogMessage += _itoa_s(callNumber, formatBuf, 10);962						rngLogMessage += "\nLocal:\n";963						rngLogMessage += localCallStacks[callNumber];964						rngLogMessage += "\nRemote:\n";965						rngLogMessage += remoteCallStacks[callNumber];966						break;967					}968				}969			}970			if(localSeedIterator != localSeedHistory.end() && remoteSeedIterator == remoteSeedHistory.end())971			{972				rngLogMessage += "\nLocal random number generator called more than remote at call #";973				rngLogMessage += _itoa_s(callNumber, formatBuf, 10);974				rngLogMessage += "\n";975				if(callNumber < localSeedHistory.size())976				{977					rngLogMessage += "Local CallStack:\n";978					rngLogMessage += localCallStacks[callNumber];979				}980			}981			else if(remoteSeedIterator != remoteSeedHistory.end() && localSeedIterator == localSeedHistory.end())982			{983				rngLogMessage += "\nremote random number generator called more than local at call #";984				rngLogMessage += _itoa_s(callNumber, formatBuf, 10);985				rngLogMessage += "\n";986				if(callNumber < remoteSeedHistory.size())987				{988					rngLogMessage += "remote CallStack:\n";989					rngLogMessage += remoteCallStacks[callNumber];990				}991			}992993			// find first different call994			std::vector<std::string>::const_iterator localCallStackIterator;995			std::vector<std::string>::const_iterator remoteCallStackIterator;996			for(localCallStackIterator = localCallStacks.begin(), remoteCallStackIterator = remoteCallStacks.begin(), callNumber = 0; localCallStackIterator != localCallStacks.end() && remoteCallStackIterator != remoteCallStacks.end(); ++localCallStackIterator, ++remoteCallStackIterator, ++callNumber)997			{998				if(*localCallStackIterator != *remoteCallStackIterator)999				{1000					rngLogMessage += "\nFirst different callstack at call #";1001					rngLogMessage += _itoa_s(callNumber, formatBuf, 10);1002					rngLogMessage += "\n";1003					rngLogMessage += "Local :\n";1004					rngLogMessage += *localCallStackIterator;1005					rngLogMessage += "Remote :\n";1006					rngLogMessage += *remoteCallStackIterator;1007					break;1008				}1009			}10101011			if(logFile)1012			{1013				logFile->DebugMsg(rngLogMessage.c_str());1014			}10151016			CvAssertMsg(false, rngLogMessage.c_str());10171018			if(logFile)1019			{1020				rngLogMessage = "\nDebug dump:\n";102110221023				// add full history1024				rngLogMessage += "Seed History -\n";1025				localSeedIterator = localSeedHistory.begin();1026				remoteSeedIterator = remoteSeedHistory.begin();1027				callNumber = 0;1028				while(localSeedIterator != localSeedHistory.end() || remoteSeedIterator != remoteSeedHistory.end())1029				{1030					++callNumber;1031					rngLogMessage += "\t Call #";1032					rngLogMessage += _itoa_s(callNumber, formatBuf, 10);1033					rngLogMessage += " LOCAL=";1034					if(localSeedIterator != localSeedHistory.end())1035					{1036						rngLogMessage += _itoa_s(*localSeedIterator, formatBuf, 10);1037						++localSeedIterator;1038					}1039					rngLogMessage += "\tREMOTE=";1040					if(remoteSeedIterator != remoteSeedHistory.end())1041					{1042						rngLogMessage += _itoa_s(*remoteSeedIterator, formatBuf, 10);1043						++remoteSeedIterator;1044					}1045					rngLogMessage += "\n";1046				}10471048				rngLogMessage += "\nLocal callstack history\n";1049				callNumber = 0;1050				std::string lastCallStackLogged;1051				unsigned int repeatCount = 0;1052				std::vector<std::string>::const_iterator i;1053				for(i = localCallStacks.begin(); i != localCallStacks.end(); ++i)1054				{1055					if(lastCallStackLogged != *i)1056					{1057						if(repeatCount > 0)1058						{1059							rngLogMessage += "Last message repeated ";1060							rngLogMessage += _itoa_s(repeatCount, formatBuf, 10);1061							rngLogMessage += " times\n";1062						}1063						rngLogMessage += "Call #";1064						rngLogMessage += _itoa_s(callNumber, formatBuf, 10);1065						rngLogMessage += "\n";1066						rngLogMessage += *i;1067						lastCallStackLogged = *i;1068						repeatCount = 0;1069					}1070					else1071					{1072						repeatCount++;1073					}1074					++callNumber;1075				}10761077				rngLogMessage += "\nRemote callstack history\n";1078				callNumber = 0;1079				repeatCount = 0;1080				for(i = remoteCallStacks.begin(); i != remoteCallStacks.end(); ++i)1081				{1082					if(lastCallStackLogged != *i)1083					{1084						if(repeatCount > 0)1085						{1086							rngLogMessage += "Last message repeated ";1087							rngLogMessage += _itoa_s(repeatCount, formatBuf, 10);1088							rngLogMessage += " times\n";1089						}1090						rngLogMessage += "Call #";1091						rngLogMessage += _itoa_s(callNumber, formatBuf, 10);1092						rngLogMessage += "\n";1093						rngLogMessage += *i;1094						lastCallStackLogged = *i;1095						repeatCount = 0;1096					}1097					else1098					{1099						repeatCount++;1100					}1101					++callNumber;1102				}1103				logFile->DebugMsg(rngLogMessage.c_str());1104			}11051106		}1107		else1108		{1109			if(logFile)1110			{1111				logFile->DebugMsg(rngLogMessage.c_str());1112			}1113			CvAssertMsg(false, rngLogMessage.c_str());1114		}111511161117		/* If this point has been reached, the OOS may be nearly unrecoverable1118		// attempt to recover1119		if(m_isHost)1120		{1121			CvRandom & rng = auto_ptr<ICvGame1> pGame = GameCore::GetGame();\n.getJonRand();1122			rng.reset(m_simRandomNumberGenerator.getSeed());1123		}1124		// brute force approach1125		// JAR : todo - this is the solution of last resort if1126		// loadDelta() doesn't work out1127		*/1128		return false;1129	}11301131	return true;1132}

Calls