helper.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * helper.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 "helper.h"
  12. #include "mapcontroller.h"
  13. #include "../lib/filesystem/Filesystem.h"
  14. #include "../lib/filesystem/CMemoryBuffer.h"
  15. #include "../lib/filesystem/CFilesystemLoader.h"
  16. #include "../lib/filesystem/CZipSaver.h"
  17. #include "../lib/campaign/CampaignHandler.h"
  18. #include "../lib/mapping/CMapService.h"
  19. #include "../lib/mapping/CMap.h"
  20. #include "../lib/mapping/CMap.h"
  21. #include "../lib/mapping/MapFormatJson.h"
  22. #include "../lib/modding/ModIncompatibility.h"
  23. std::unique_ptr<CMap> Helper::openMapInternal(const QString & filenameSelect)
  24. {
  25. QFileInfo fi(filenameSelect);
  26. std::string fname = fi.fileName().toStdString();
  27. std::string fdir = fi.dir().path().toStdString();
  28. ResourcePath resId("MAPEDITOR/" + fname, EResType::MAP);
  29. //addFilesystem takes care about memory deallocation if case of failure, no memory leak here
  30. auto * mapEditorFilesystem = new CFilesystemLoader("MAPEDITOR/", fdir, 0);
  31. CResourceHandler::removeFilesystem("local", "mapEditor");
  32. CResourceHandler::addFilesystem("local", "mapEditor", mapEditorFilesystem);
  33. if(!CResourceHandler::get("mapEditor")->existsResource(resId))
  34. throw std::runtime_error("Cannot open map from this folder");
  35. CMapService mapService;
  36. if(auto header = mapService.loadMapHeader(resId))
  37. {
  38. auto missingMods = CMapService::verifyMapHeaderMods(*header);
  39. ModIncompatibility::ModList modList;
  40. for(const auto & m : missingMods)
  41. modList.push_back(m.second.name);
  42. if(!modList.empty())
  43. throw ModIncompatibility(modList);
  44. return mapService.loadMap(resId, nullptr);
  45. }
  46. else
  47. throw std::runtime_error("Corrupted map");
  48. }
  49. std::shared_ptr<CampaignState> Helper::openCampaignInternal(const QString & filenameSelect)
  50. {
  51. QFileInfo fi(filenameSelect);
  52. std::string fname = fi.fileName().toStdString();
  53. std::string fdir = fi.dir().path().toStdString();
  54. ResourcePath resId("MAPEDITOR/" + fname, EResType::CAMPAIGN);
  55. //addFilesystem takes care about memory deallocation if case of failure, no memory leak here
  56. auto * mapEditorFilesystem = new CFilesystemLoader("MAPEDITOR/", fdir, 0);
  57. CResourceHandler::removeFilesystem("local", "mapEditor");
  58. CResourceHandler::addFilesystem("local", "mapEditor", mapEditorFilesystem);
  59. if(!CResourceHandler::get("mapEditor")->existsResource(resId))
  60. throw std::runtime_error("Cannot open campaign from this folder");
  61. if(auto campaign = CampaignHandler::getCampaign(resId.getName()))
  62. return campaign;
  63. else
  64. throw std::runtime_error("Corrupted campaign");
  65. }
  66. void Helper::saveCampaign(std::shared_ptr<CampaignState> campaignState, const QString & filename)
  67. {
  68. auto jsonCampaign = CampaignHandler::writeHeaderToJson(*campaignState);
  69. std::shared_ptr<CIOApi> io(new CDefaultIOApi());
  70. auto saver = std::make_shared<CZipSaver>(io, filename.toStdString());
  71. for(auto & scenario : campaignState->allScenarios())
  72. {
  73. auto map = campaignState->getMap(scenario, nullptr);
  74. MapController::repairMap(map.get());
  75. CMemoryBuffer serializeBuffer;
  76. {
  77. CMapSaverJson jsonSaver(&serializeBuffer);
  78. jsonSaver.saveMap(map);
  79. }
  80. auto mapName = boost::algorithm::to_lower_copy(campaignState->scenario(scenario).mapName);
  81. if(!boost::ends_with(mapName, ".vmap"))
  82. mapName = boost::replace_all_copy(mapName, ".h3m", std::string("")) + ".vmap";
  83. auto stream = saver->addFile(mapName);
  84. stream->write(reinterpret_cast<const ui8 *>(serializeBuffer.getBuffer().data()), serializeBuffer.getSize());
  85. jsonCampaign["scenarios"].Vector().push_back(CampaignHandler::writeScenarioToJson(campaignState->scenario(scenario)));
  86. jsonCampaign["scenarios"].Vector().back()["map"].String() = mapName;
  87. }
  88. auto jsonCampaignStr = jsonCampaign.toString();
  89. saver->addFile("header.json")->write(reinterpret_cast<const ui8 *>(jsonCampaignStr.data()), jsonCampaignStr.length());
  90. }