From 141c1a985408cebd3ecd3d636d14f869c7f0be5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20W=2E=20Urba=C5=84czyk?= Date: Sat, 7 Sep 2013 16:57:31 +0000 Subject: [PATCH] Not crash when asking callback about requirements for not existing building, fixing #1444 corrupted saves (for testing). --- lib/CTownHandler.h | 9 +++++++++ lib/IGameCallback.cpp | 6 ++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/CTownHandler.h b/lib/CTownHandler.h index 29623fb4e..73b766a8e 100644 --- a/lib/CTownHandler.h +++ b/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> &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); + } + } }; diff --git a/lib/IGameCallback.cpp b/lib/IGameCallback.cpp index cafd91ed6..7929982c8 100644 --- a/lib/IGameCallback.cpp +++ b/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 CGameInfoCallback::getBuildingRequiments( const CGTownInstance *t, BuildingID ID ) { ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", std::set()); + ERROR_RET_VAL_IF(!t->town->buildings.count(ID), "No such building!", std::set()); std::set used; used.insert(ID);