Răsfoiți Sursa

Not crash when asking callback about requirements for not existing building, fixing #1444 corrupted saves (for testing).

Michał W. Urbańczyk 12 ani în urmă
părinte
comite
141c1a9854
2 a modificat fișierele cu 13 adăugiri și 2 ștergeri
  1. 9 0
      lib/CTownHandler.h
  2. 4 2
      lib/IGameCallback.cpp

+ 9 - 0
lib/CTownHandler.h

@@ -198,6 +198,15 @@ public:
 	{
 		h & names & faction & creatures & dwellings & dwellingNames & buildings & hordeLvl & mageLevel
 			& primaryRes & warMachine & clientInfo & moatDamage;
+
+		//Fix #1444 corrupted save
+		while(auto badElem = vstd::tryFindIf(buildings, [](const std::pair<BuildingID, ConstTransitivePtr<CBuilding>> &building)
+														{ return building.second == nullptr; }))
+		{
+			std::cout << "#1444-like bug encountered, fixing buildings list by removing bogus entry " << badElem->first << " from " << faction->name << std::endl;
+			buildings.erase(badElem->first);
+		}
+
 	}
 };
 

+ 4 - 2
lib/IGameCallback.cpp

@@ -567,10 +567,11 @@ EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTow
 {
 	ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", EBuildingState::TOWN_NOT_OWNED);
 
+	if(!t->town->buildings.count(ID))
+		return EBuildingState::BUILDING_ERROR;
+
 	const CBuilding * pom = t->town->buildings[ID];
 
-	if(!pom)
-		return EBuildingState::BUILDING_ERROR;
 
 	if(t->hasBuilt(ID))	//already built
 		return EBuildingState::ALREADY_PRESENT;
@@ -632,6 +633,7 @@ EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTow
 std::set<BuildingID> CGameInfoCallback::getBuildingRequiments( const CGTownInstance *t, BuildingID ID )
 {
 	ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", std::set<BuildingID>());
+	ERROR_RET_VAL_IF(!t->town->buildings.count(ID), "No such building!", std::set<BuildingID>());
 
 	std::set<int> used;
 	used.insert(ID);