فهرست منبع

support chronicles aoi installer

Laserlicht 8 ماه پیش
والد
کامیت
4f1a91c2bd
3فایلهای تغییر یافته به همراه39 افزوده شده و 10 حذف شده
  1. 1 0
      launcher/innoextract.cpp
  2. 37 9
      launcher/modManager/chroniclesextractor.cpp
  3. 1 1
      launcher/modManager/chroniclesextractor.h

+ 1 - 0
launcher/innoextract.cpp

@@ -93,6 +93,7 @@ QString Innoextract::getHashError(QString exeFile, QString binFile, QString exeF
 		{ H3_COMPLETE, "french",     822688,  998540653, "fbb300eeef52f5d81a571a178723b19313e3856d", "4f4d90ff2f60968616766237664744bc54754500" }, // setup_heroes_of_might_and_magic_3_complete_4.0_(3.2)_gog_0.1_(french)_(77075).exe
 		{ H3_COMPLETE, "polish",     819904,  851750601, "a413b0b9f3d5ca3e1a57e84a42de28c67d77b1a7", "fd9fe58bcbb8b442e8cfc299d90f1d503f281d40" }, // setup_heroes_of_might_and_magic_3_complete_4.0_(3.2)_gog_0.1_(polish)_(77075).exe
 		{ H3_COMPLETE, "russian",    819416,  981633128, "e84eedf62fe2e5f9171a7e1ce6e99315a09ce41f", "49cc683395c0cf80830bfa66e42bb5dfdb7aa124" }, // setup_heroes_of_might_and_magic_3_complete_4.0_(3.2)_gog_0.1_(russian)_(77075).exe
+		{ CHR,         "english", 689384280,          0, "81f6e306103cca7dd413c4476eeda65eb790e9e6", ""                                         }, // setup_heroes_chronicles_2.0.0.38.exe
 		{ CHR,         "english", 485694752,          0, "44e4fc2c38261a1c2a57d5198f44493210e8fc1a", ""                                         }, // setup_heroes_chronicles_chapter1_2.1.0.42.exe
 		{ CHR,         "english", 493102840,          0, "b479a3272cf4b57a6b7fc499df5eafb624dcd6de", ""                                         }, // setup_heroes_chronicles_chapter2_2.1.0.43.exe
 		{ CHR,         "english", 470364128,          0, "5ad36d822e1700c9ecf93b78652900a52518146b", ""                                         }, // setup_heroes_chronicles_chapter3_2.1.0.41.exe

+ 37 - 9
launcher/modManager/chroniclesextractor.cpp

@@ -42,9 +42,11 @@ void ChroniclesExtractor::removeTempDir()
 	tempDir.removeRecursively();
 }
 
-int ChroniclesExtractor::getChronicleNo()
+std::vector<int> ChroniclesExtractor::getChronicleNo()
 {
+	// supports "All in one" and seperate installers
 	QStringList appDirCandidates = tempDir.entryList({"app"}, QDir::Filter::Dirs);
+	std::vector<int> tmp;
 
 	if (!appDirCandidates.empty())
 	{
@@ -56,11 +58,12 @@ int ChroniclesExtractor::getChronicleNo()
 			QStringList chroniclesDirCandidates = appDir.entryList({chronicleName}, QDir::Filter::Dirs);
 
 			if (!chroniclesDirCandidates.empty())
-				return i;
+				tmp.push_back(i);
 		}
 	}
-	QMessageBox::critical(parent, tr("Invalid file selected"), tr("You have to select a Heroes Chronicles installer file!"));
-	return 0;
+	if(tmp.empty())
+		QMessageBox::critical(parent, tr("Invalid file selected"), tr("You have to select a Heroes Chronicles installer file!"));
+	return tmp;
 }
 
 bool ChroniclesExtractor::extractGogInstaller(QString file)
@@ -179,6 +182,9 @@ void ChroniclesExtractor::extractFiles(int no) const
 	QDir outDirMaps(pathToQString(basePath / "Maps" / "Chronicles"));
 
 	auto extract = [](QDir scrDir, QDir dest, QString file, std::vector<std::string> files = {}){
+		if(scrDir.entryList({file}).isEmpty())
+			return; // file does not exists (needed for "All in one" installer)
+
 		CArchiveLoader archive("", scrDir.filePath(scrDir.entryList({file}).front()).toStdString(), false);
 		for(auto & entry : archive.getEntries())
 			if(files.empty())
@@ -212,6 +218,25 @@ void ChroniclesExtractor::extractFiles(int no) const
 	extract(tmpDirData, outDirDataPortraits, "bitmap.lod", tarnumPortraits);
 	extract(tmpDirData, outDirData, "lbitmap.lod", std::vector<std::string>{"INTRORIM"});
 
+	// special case - "All in one" installer
+	{
+		tmpDir.cdUp();
+		auto mapping = std::map<std::string, int>{{ {"Intro", 1}, {"Intr2", 2}, {"Intr3", 3}, {"Intr4", 4}, {"Intro5", 7}, {"Intro6", 8} }};
+		std::vector<std::string> videoFiles;
+		for(auto & elem : mapping)
+			for(auto & ending : {".bik", ".smk"})
+				videoFiles.push_back(elem.first + ending);
+		extract(tmpDirData, tmpDir, "Hchron.vid", videoFiles);
+		for(auto & ending : {".bik", ".smk"})
+		{
+			if(!vstd::reverseMap(mapping).count(no))
+				continue;
+			auto srcName = vstd::reverseMap(mapping).at(no);
+			auto dstName = (no == 7 || no == 8) ? srcName : "Intro";
+			QFile::copy(tmpDir.filePath(QString::fromStdString(srcName + ending)), outDirVideo.filePath(QString::fromStdString(dstName + ending)));
+		}
+	}
+
 	if(!outDirMaps.exists())
 		outDirMaps.mkpath(".");
 	QString campaignFileName = "Hc" + QString::number(no) + "_Main.h3c";
@@ -247,16 +272,19 @@ void ChroniclesExtractor::installChronicles(QStringList exe)
 		if(!extractGogInstaller(filepath))
 			continue;
 
-		logGlobal->info("Detecting Chronicle");
-		int chronicleNo = getChronicleNo();
-		if(!chronicleNo)
+		logGlobal->info("Detecting Chronicles");
+		auto chronicleNo = getChronicleNo();
+		if(chronicleNo.empty())
 			continue;
 
 		logGlobal->info("Creating base Chronicle mod");
 		createBaseMod();
 
-		logGlobal->info("Creating Chronicle mod");
-		createChronicleMod(chronicleNo);
+		for(auto & no : chronicleNo)
+		{
+			logGlobal->info("Creating Chronicle mod (%i)", no);
+			createChronicleMod(no);
+		}
 
 		logGlobal->info("Removing temporary directory");
 		removeTempDir();

+ 1 - 1
launcher/modManager/chroniclesextractor.h

@@ -24,7 +24,7 @@ class ChroniclesExtractor : public QObject
 
 	bool createTempDir();
 	void removeTempDir();
-	int getChronicleNo();
+	std::vector<int> getChronicleNo();
 	bool extractGogInstaller(QString filePath);
 	void createBaseMod() const;
 	void createChronicleMod(int no);