1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-08 22:26:51 +02:00

support chronicles aoi installer

This commit is contained in:
Laserlicht
2025-02-07 22:30:01 +01:00
parent d8ee343800
commit 4f1a91c2bd
3 changed files with 39 additions and 10 deletions

View File

@@ -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

View File

@@ -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();

View File

@@ -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);