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:
@@ -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
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user