mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	#1228 - prevent second AI activation on AI defeat due to wrong EndTurn packet
This commit is contained in:
		| @@ -535,6 +535,7 @@ void AIGateway::yourTurn() | ||||
| 	LOG_TRACE(logAi); | ||||
| 	NET_EVENT_HANDLER; | ||||
| 	status.startedTurn(); | ||||
|  | ||||
| 	makingTurn = make_unique<boost::thread>(&AIGateway::makeTurn, this); | ||||
| } | ||||
|  | ||||
| @@ -1428,7 +1429,15 @@ void AIGateway::endTurn() | ||||
| 	{ | ||||
| 		logAi->error("Not having turn at the end of turn???"); | ||||
| 	} | ||||
|  | ||||
| 	logAi->debug("Resources at the end of turn: %s", cb->getResourceAmount().toString()); | ||||
|  | ||||
| 	if(cb->getPlayerStatus(playerID) != EPlayerStatus::INGAME) | ||||
| 	{ | ||||
| 		logAi->info("Ending turn is not needed because we already lost"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		cb->endTurn(); | ||||
| @@ -1601,7 +1610,7 @@ void AIStatus::waitTillFree() | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> lock(mx); | ||||
| 	while(battle != NO_BATTLE || !remainingQueries.empty() || !objectsBeingVisited.empty() || ongoingHeroMovement) | ||||
| 		cv.timed_wait(lock, boost::posix_time::milliseconds(100)); | ||||
| 		cv.timed_wait(lock, boost::posix_time::milliseconds(10)); | ||||
| } | ||||
|  | ||||
| bool AIStatus::haveTurn() | ||||
|   | ||||
| @@ -74,6 +74,8 @@ Goals::TTask Nullkiller::choseBestTask(Goals::TTaskVec & tasks) const | ||||
|  | ||||
| Goals::TTask Nullkiller::choseBestTask(Goals::TSubgoal behavior, int decompositionMaxDepth) const | ||||
| { | ||||
| 	boost::this_thread::interruption_point(); | ||||
|  | ||||
| 	logAi->debug("Checking behavior %s", behavior->toString()); | ||||
|  | ||||
| 	auto start = std::chrono::high_resolution_clock::now(); | ||||
| @@ -160,8 +162,12 @@ void Nullkiller::updateAiState(int pass, bool fast) | ||||
| 			cfg.mainTurnDistanceLimit = MAIN_TURN_DISTANCE_LIMIT * ((int)scanDepth + 1); | ||||
| 		} | ||||
|  | ||||
| 		boost::this_thread::interruption_point(); | ||||
|  | ||||
| 		pathfinder->updatePaths(activeHeroes, cfg); | ||||
|  | ||||
| 		boost::this_thread::interruption_point(); | ||||
|  | ||||
| 		objectClusterizer->clusterize(); | ||||
| 	} | ||||
|  | ||||
| @@ -212,6 +218,8 @@ HeroLockedReason Nullkiller::getHeroLockedReason(const CGHeroInstance * hero) co | ||||
|  | ||||
| void Nullkiller::makeTurn() | ||||
| { | ||||
| 	boost::lock_guard<boost::mutex> sharedStorageLock(AISharedStorage::locker); | ||||
|  | ||||
| 	const int MAX_DEPTH = 10; | ||||
|  | ||||
| 	resetAiState(); | ||||
|   | ||||
| @@ -23,6 +23,7 @@ namespace NKAI | ||||
| { | ||||
|  | ||||
| std::shared_ptr<boost::multi_array<AIPathNode, 5>> AISharedStorage::shared; | ||||
| boost::mutex AISharedStorage::locker; | ||||
| std::set<int3> commitedTiles; | ||||
| std::set<int3> commitedTilesInitial; | ||||
|  | ||||
|   | ||||
| @@ -135,6 +135,8 @@ class AISharedStorage | ||||
| 	static std::shared_ptr<boost::multi_array<AIPathNode, 5>> shared; | ||||
| 	std::shared_ptr<boost::multi_array<AIPathNode, 5>> nodes; | ||||
| public: | ||||
| 	static boost::mutex locker; | ||||
|  | ||||
| 	AISharedStorage(int3 mapSize); | ||||
| 	~AISharedStorage(); | ||||
|  | ||||
|   | ||||
| @@ -80,6 +80,8 @@ void AIPathfinder::updatePaths(std::map<const CGHeroInstance *, HeroRole> heroes | ||||
|  | ||||
| 		do | ||||
| 		{ | ||||
| 			boost::this_thread::interruption_point(); | ||||
|  | ||||
| 			while(storage->calculateHeroChain()) | ||||
| 			{ | ||||
| 				boost::this_thread::interruption_point(); | ||||
| @@ -91,6 +93,8 @@ void AIPathfinder::updatePaths(std::map<const CGHeroInstance *, HeroRole> heroes | ||||
| 			logAi->trace("Select next actor"); | ||||
| 		} while(storage->selectNextActor()); | ||||
|  | ||||
| 		boost::this_thread::interruption_point(); | ||||
|  | ||||
| 		if(storage->calculateHeroChainFinal()) | ||||
| 		{ | ||||
| 			boost::this_thread::interruption_point(); | ||||
|   | ||||
| @@ -89,7 +89,17 @@ bool SaveGame::applyGh(CGameHandler * gh) | ||||
|  | ||||
| bool EndTurn::applyGh(CGameHandler * gh) | ||||
| { | ||||
| 	PlayerColor player = GS(gh)->currentPlayer; | ||||
| 	PlayerColor currentPlayer = GS(gh)->currentPlayer; | ||||
| 	if(player != currentPlayer) | ||||
| 	{ | ||||
| 		if(gh->getPlayerStatus(player) == EPlayerStatus::INGAME) | ||||
| 			throwAndComplain(gh, "Player attempted to end turn for another player!"); | ||||
|  | ||||
| 		logGlobal->debug("Player attempted to end turn after game over. Ignoring this request."); | ||||
|  | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	throwOnWrongPlayer(gh, player); | ||||
| 	if(gh->queries.topQuery(player)) | ||||
| 		throwAndComplain(gh, "Cannot end turn before resolving queries!"); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user