Browse Source

Fixed use-after-free crash with quests registration in RMG.
* code taken from PR #200

AlexVinS 9 years ago
parent
commit
6dc47a2de0
4 changed files with 26 additions and 26 deletions
  1. 23 16
      lib/mapping/CMap.cpp
  2. 1 1
      lib/mapping/CMap.h
  3. 0 4
      lib/mapping/MapFormatH3M.cpp
  4. 2 5
      lib/rmg/CRmgTemplateZone.cpp

+ 23 - 16
lib/mapping/CMap.cpp

@@ -556,16 +556,9 @@ void CMap::eraseArtifactInstance(CArtifactInstance * art)
 	artInstances[art->id.getNum()].dellNull();
 }
 
-void CMap::addQuest(CGObjectInstance * quest)
-{
-	auto q = dynamic_cast<IQuestObject *>(quest);
-	q->quest->qid = quests.size();
-	quests.push_back(q->quest);
-}
-
 void CMap::addNewObject(CGObjectInstance * obj)
 {
-    if(obj->id != ObjectInstanceID(objects.size()))
+	if(obj->id != ObjectInstanceID(objects.size()))
 		throw std::runtime_error("Invalid object instance id");
 
 	if(obj->instanceName == "")
@@ -573,19 +566,33 @@ void CMap::addNewObject(CGObjectInstance * obj)
 
 	auto it = instanceNames.find(obj->instanceName);
 	if(it != instanceNames.end())
-		throw std::runtime_error("Object instance name duplicated:"+obj->instanceName);
+		throw std::runtime_error("Object instance name duplicated: "+obj->instanceName);
 
-    objects.push_back(obj);
-    instanceNames[obj->instanceName] = obj;
-    addBlockVisTiles(obj);
+	objects.push_back(obj);
+	instanceNames[obj->instanceName] = obj;
+	addBlockVisTiles(obj);
 
-	if(obj->ID == Obj::TOWN)
+	//todo: make this virtual method of CGObjectInstance
+	switch (obj->ID)
 	{
+	case Obj::TOWN:
 		towns.push_back(static_cast<CGTownInstance *>(obj));
-	}
-	if(obj->ID == Obj::HERO)
-	{
+		break;
+	case Obj::HERO:
 		heroesOnMap.push_back(static_cast<CGHeroInstance*>(obj));
+		break;
+	case Obj::SEER_HUT:
+	case Obj::QUEST_GUARD:
+	case Obj::BORDERGUARD:
+	case Obj::BORDER_GATE:
+		{
+			auto q = dynamic_cast<IQuestObject *>(obj);
+			q->quest->qid = quests.size();
+			quests.push_back(q->quest);
+		}
+		break;
+	default:
+		break;
 	}
 }
 

+ 1 - 1
lib/mapping/CMap.h

@@ -313,7 +313,7 @@ public:
 
 	void addNewArtifactInstance(CArtifactInstance * art);
 	void eraseArtifactInstance(CArtifactInstance * art);
-	void addQuest(CGObjectInstance * quest);
+
 	void addNewObject(CGObjectInstance * obj);
 
 	/// Gets object of specified type on requested position

+ 0 - 4
lib/mapping/MapFormatH3M.cpp

@@ -1112,7 +1112,6 @@ void CMapLoaderH3M::readObjects()
 		case Obj::SEER_HUT:
 			{
 				nobj = readSeerHut();
-				map->addQuest(nobj);
 				break;
 			}
 		case Obj::WITCH_HUT:
@@ -1363,7 +1362,6 @@ void CMapLoaderH3M::readObjects()
 		case Obj::QUEST_GUARD:
 			{
 				auto  guard = new CGQuestGuard();
-				map->addQuest(guard);
 				readQuest(guard);
 				nobj = guard;
 				break;
@@ -1400,13 +1398,11 @@ void CMapLoaderH3M::readObjects()
 		case Obj::BORDERGUARD:
 			{
 				nobj = new CGBorderGuard();
-				map->addQuest(nobj);
 				break;
 			}
 		case Obj::BORDER_GATE:
 			{
 				nobj = new CGBorderGate();
-				map->addQuest (nobj);
 				break;
 			}
 		case Obj::PYRAMID: //Pyramid of WoG object

+ 2 - 5
lib/rmg/CRmgTemplateZone.cpp

@@ -451,7 +451,7 @@ void CRmgTemplateZone::createBorder(CMapGenerator* gen)
 					if (gen->isPossible(nearbyPos))
 						gen->setOccupied(nearbyPos, ETileType::BLOCKED);
 				});
-				edge = true; 
+				edge = true;
 			}
 		});
 	}
@@ -2328,7 +2328,7 @@ ObjectInfo CRmgTemplateZone::getRandomObject(CMapGenerator* gen, CTreasurePileIn
 				continue;
 
 			total += oi.probability;
-			
+
 			thresholds.push_back (std::make_pair (total, &oi));
 		}
 	}
@@ -2760,7 +2760,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen)
 				obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false;
 
 				gen->banQuestArt(artid);
-				gen->map->addQuest(obj);
 
 				this->questArtZone->possibleObjects.push_back (generateArtInfo(artid));
 
@@ -2799,7 +2798,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen)
 				obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false;
 
 				gen->banQuestArt(artid);
-				gen->map->addQuest(obj);
 
 				this->questArtZone->possibleObjects.push_back(generateArtInfo(artid));
 
@@ -2823,7 +2821,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen)
 				obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false;
 
 				gen->banQuestArt(artid);
-				gen->map->addQuest(obj);
 
 				this->questArtZone->possibleObjects.push_back(generateArtInfo(artid));