hdextractor.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * hdextractor.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "hdextractor.h"
  12. #include "../../lib/VCMIDirs.h"
  13. HdExtractor::HdExtractor(QWidget *p) :
  14. parent(p)
  15. {
  16. }
  17. HdExtractor::SubModType HdExtractor::archiveTypeToSubModType(ArchiveType v)
  18. {
  19. SubModType subModType = SubModType::X2;
  20. if(vstd::contains({ArchiveType::BITMAP_X2, ArchiveType::SPRITE_X2}, v))
  21. subModType = SubModType::X2;
  22. else if(vstd::contains({ArchiveType::BITMAP_X3, ArchiveType::SPRITE_X3}, v))
  23. subModType = SubModType::X3;
  24. else if(vstd::contains({ArchiveType::BITMAP_LOC_X2, ArchiveType::SPRITE_LOC_X2}, v))
  25. subModType = SubModType::LOC_X2;
  26. else if(vstd::contains({ArchiveType::BITMAP_LOC_X3, ArchiveType::SPRITE_LOC_X3}, v))
  27. subModType = SubModType::LOC_X3;
  28. return subModType;
  29. };
  30. void HdExtractor::installHd()
  31. {
  32. QString tmpDir = QFileDialog::getExistingDirectory(parent, tr("Select Directory with HD Edition (Steam folder)"), QDir::homePath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
  33. if(tmpDir.isEmpty())
  34. return;
  35. QDir dir(tmpDir);
  36. if(!dir.exists("HOMM3 2.0.exe"))
  37. {
  38. QMessageBox::critical(parent, tr("Invalid folder"), tr("The selected folder does not contain HOMM3 2.0.exe! Please select the HD Edition installation folder."));
  39. return;
  40. }
  41. QString language = "";
  42. auto folderList = QDir(QDir::cleanPath(dir.absolutePath() + QDir::separator() + "data/LOC")).entryList(QDir::Filter::Dirs);
  43. for(auto lng : languages.keys())
  44. for(auto folder : folderList)
  45. if(lng == folder)
  46. language = lng;
  47. QDir dst(pathToQString(VCMIDirs::get().userDataPath() / "Mods" / "hd-edition"));
  48. dst.mkpath(dst.path());
  49. createModJson(std::nullopt, dst, language);
  50. QDir dstData(dst.filePath("content/data"));
  51. dstData.mkpath(".");
  52. QFile::copy(dir.filePath("data/spriteFlagsInfo.txt"), dstData.filePath("spriteFlagsInfo.txt"));
  53. QDir dstDataFlags(dst.filePath("content/data/flags"));
  54. dstDataFlags.mkpath(".");
  55. for (const QFileInfo &fileInfo : QDir(dir.filePath("data/flags")).entryInfoList(QDir::Files))
  56. {
  57. QString srcFile = fileInfo.absoluteFilePath();
  58. QString destFile = dstDataFlags.filePath(fileInfo.fileName());
  59. QFile::copy(srcFile, destFile);
  60. }
  61. for(auto modType : {X2, X3, LOC_X2, LOC_X3})
  62. {
  63. QString suffix = (language.isEmpty() || modType == SubModType::X2 || modType == SubModType::X3) ? "" : "_" + language;
  64. QDir modPath = QDir(dst.filePath(QString("mods/") + submodnames.at(modType) + suffix));
  65. modPath.mkpath(modPath.path());
  66. createModJson(modType, modPath, languages[language]);
  67. QDir contentDataDir(modPath.filePath("content/data"));
  68. contentDataDir.mkpath(".");
  69. for(auto & type : {ArchiveType::BITMAP_X2, ArchiveType::BITMAP_X3, ArchiveType::SPRITE_X2, ArchiveType::SPRITE_X3, ArchiveType::BITMAP_LOC_X2, ArchiveType::BITMAP_LOC_X3, ArchiveType::SPRITE_LOC_X2, ArchiveType::SPRITE_LOC_X3})
  70. {
  71. if(archiveTypeToSubModType(type) != modType)
  72. continue;
  73. QFile fileName;
  74. if(vstd::contains({ArchiveType::BITMAP_LOC_X2, ArchiveType::BITMAP_LOC_X3, ArchiveType::SPRITE_LOC_X2, ArchiveType::SPRITE_LOC_X3}, type))
  75. fileName.setFileName(dir.filePath(QString("data/LOC/") + language + "/" + pakfiles.at(type)));
  76. else
  77. fileName.setFileName(dir.filePath(QString("data/") + pakfiles.at(type)));
  78. QString destPath = contentDataDir.filePath(QFileInfo(fileName).fileName());
  79. fileName.copy(contentDataDir.filePath(fileName.fileName()));
  80. if(!fileName.copy(destPath))
  81. QMessageBox::critical(parent, tr("Extraction error"), tr("Please delete mod and try again! Failed to copy file %1 to %2").arg(fileName.fileName(), destPath), QMessageBox::Ok, QMessageBox::Ok);
  82. }
  83. }
  84. }
  85. void HdExtractor::createModJson(std::optional<SubModType> submodType, QDir path, QString language)
  86. {
  87. if (auto result = submodType)
  88. {
  89. QString scale = (*result == SubModType::X2 || *result == SubModType::LOC_X2) ? "2" : "3";
  90. bool isTranslation = (*result == SubModType::LOC_X2 || *result == SubModType::LOC_X3);
  91. QJsonObject mod;
  92. if(isTranslation)
  93. {
  94. mod = QJsonObject({
  95. { "modType", "Translation" },
  96. { "name", "HD Localisation (" + language + ") (x" + scale + ")" },
  97. { "description", "Translated Resources (x" + scale + ")" },
  98. { "author", "Ubisoft" },
  99. { "version", "1.0" },
  100. { "contact", "vcmi.eu" },
  101. { "language", language },
  102. });
  103. }
  104. else
  105. {
  106. mod = QJsonObject({
  107. { "modType", "Graphical" },
  108. { "name", "HD (x" + scale + ")" },
  109. { "description", "Resources (x" + scale + ")" },
  110. { "author", "Ubisoft" },
  111. { "version", "1.0" },
  112. { "contact", "vcmi.eu" },
  113. });
  114. }
  115. QFile jsonFile(path.filePath("mod.json"));
  116. jsonFile.open(QFile::WriteOnly);
  117. jsonFile.write(QJsonDocument(mod).toJson());
  118. }
  119. else
  120. {
  121. QJsonObject mod
  122. {
  123. { "modType", "Graphical" },
  124. { "name", "Heroes III HD Edition" },
  125. { "description", "Extracted resources from official Heroes HD to make it usable on VCMI" },
  126. { "author", "Ubisoft" },
  127. { "version", "1.0" },
  128. { "contact", "vcmi.eu" },
  129. };
  130. QFile jsonFile(path.filePath("mod.json"));
  131. jsonFile.open(QFile::WriteOnly);
  132. jsonFile.write(QJsonDocument(mod).toJson());
  133. }
  134. }