Browse Source

Better detection of invalid mod data to avoid crash and notify modders

Ivan Savenko 1 year ago
parent
commit
2265890f69
3 changed files with 13 additions and 6 deletions
  1. 4 1
      lib/CCreatureHandler.cpp
  2. 5 1
      lib/CHeroHandler.cpp
  3. 4 4
      lib/mapObjects/CGHeroInstance.cpp

+ 4 - 1
lib/CCreatureHandler.cpp

@@ -397,7 +397,10 @@ void CCreature::serializeJson(JsonSerializeFormat & handler)
 	if(!handler.saving)
 	{
 		if(ammMin > ammMax)
+		{
 			logMod->error("Invalid creature '%s' configuration, advMapAmount.min > advMapAmount.max", identifier);
+			std::swap(ammMin, ammMax);
+		}
 	}
 }
 
@@ -622,7 +625,7 @@ CCreature * CCreatureHandler::loadFromJson(const std::string & scope, const Json
 	}
 	else
 	{
-		logGlobal->error("Mod %s: creature %s has minimal damage (%d) greater than maximal damage (%d)!", scope, identifier, minDamage, maxDamage);
+		logMod->error("Mod %s: creature %s has minimal damage (%d) greater than maximal damage (%d)!", scope, identifier, minDamage, maxDamage);
 		cre->addBonus(maxDamage, BonusType::CREATURE_DAMAGE, BonusCustomSubtype::creatureDamageMin);
 		cre->addBonus(minDamage, BonusType::CREATURE_DAMAGE, BonusCustomSubtype::creatureDamageMax);
 	}

+ 5 - 1
lib/CHeroHandler.cpp

@@ -473,7 +473,11 @@ void CHeroHandler::loadHeroArmy(CHero * hero, const JsonNode & node) const
 		hero->initialArmy[i].minAmount = static_cast<ui32>(source["min"].Float());
 		hero->initialArmy[i].maxAmount = static_cast<ui32>(source["max"].Float());
 
-		assert(hero->initialArmy[i].minAmount <= hero->initialArmy[i].maxAmount);
+		if (hero->initialArmy[i].minAmount > hero->initialArmy[i].maxAmount)
+		{
+			logMod->error("Hero %s has minimal army size (%d) greater than maximal size (%d)!", hero->getJsonKey(), hero->initialArmy[i].minAmount, hero->initialArmy[i].maxAmount);
+			std::swap(hero->initialArmy[i].minAmount, hero->initialArmy[i].maxAmount);
+		}
 
 		VLC->identifiers()->requestIdentifier("creature", source["creature"], [=](si32 creature)
 		{

+ 4 - 4
lib/mapObjects/CGHeroInstance.cpp

@@ -436,14 +436,14 @@ void CGHeroInstance::initArmy(CRandomGenerator & rand, IArmyDescriptor * dst)
 
 		int count = rand.nextInt(stack.minAmount, stack.maxAmount);
 
-		const CCreature * creature = stack.creature.toCreature();
-
-		if(creature == nullptr)
+		if(stack.creature == CreatureID::NONE)
 		{
-			logGlobal->error("Hero %s has invalid creature with id %d in initial army", getNameTranslated(), stack.creature.toEnum());
+			logGlobal->error("Hero %s has invalid creature in initial army", getNameTranslated());
 			continue;
 		}
 
+		const CCreature * creature = stack.creature.toCreature();
+
 		if(creature->warMachine != ArtifactID::NONE) //war machine
 		{
 			warMachinesGiven++;