1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Load custom campaigns from gzip

This commit is contained in:
nordsoft
2023-04-20 19:22:27 +04:00
parent be6667acf5
commit db33558abc

View File

@@ -90,21 +90,19 @@ CCampaignHeader CCampaignHandler::getHeader( const std::string & name)
std::string language = VLC->modh->getModLanguage(modName); std::string language = VLC->modh->getModLanguage(modName);
std::string encoding = Languages::getLanguageOptions(language).encoding; std::string encoding = Languages::getLanguageOptions(language).encoding;
JsonNode jsonCampaign(resourceID); auto fileStream = CResourceHandler::get(modName)->load(resourceID);
std::vector<ui8> cmpgn = getFile(std::move(fileStream), true)[0];
JsonNode jsonCampaign((const char*)cmpgn.data(), cmpgn.size());
if(jsonCampaign.isNull()) if(jsonCampaign.isNull())
{ {
auto fileStream = CResourceHandler::get(modName)->load(resourceID); //legacy OH3 campaign (*.h3c)
std::vector<ui8> cmpgn = getFile(std::move(fileStream), true)[0];
CMemoryStream stream(cmpgn.data(), cmpgn.size()); CMemoryStream stream(cmpgn.data(), cmpgn.size());
CBinaryReader reader(&stream); CBinaryReader reader(&stream);
CCampaignHeader ret = readHeaderFromMemory(reader, resourceID.getName(), modName, encoding); return readHeaderFromMemory(reader, resourceID.getName(), modName, encoding);
return ret;
}
else
{
CCampaignHeader ret = readHeaderFromJson(jsonCampaign, resourceID.getName(), modName, encoding);
return ret;
} }
//VCMI (*.vcmp)
return readHeaderFromJson(jsonCampaign, resourceID.getName(), modName, encoding);
} }
std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & name ) std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & name )
@@ -116,66 +114,48 @@ std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & na
auto ret = std::make_unique<CCampaign>(); auto ret = std::make_unique<CCampaign>();
JsonNode jsonCampaign(resourceID); auto fileStream = CResourceHandler::get(modName)->load(resourceID);
std::vector<std::vector<ui8>> files = getFile(std::move(fileStream), false);
JsonNode jsonCampaign((const char*)files[0].data(), files[0].size());
if(jsonCampaign.isNull()) if(jsonCampaign.isNull())
{ {
auto fileStream = CResourceHandler::get(modName)->load(resourceID); CMemoryStream stream(files[0].data(), files[0].size());
std::vector<std::vector<ui8>> file = getFile(std::move(fileStream), false);
CMemoryStream stream(file[0].data(), file[0].size());
CBinaryReader reader(&stream); CBinaryReader reader(&stream);
ret->header = readHeaderFromMemory(reader, resourceID.getName(), modName, encoding); ret->header = readHeaderFromMemory(reader, resourceID.getName(), modName, encoding);
int howManyScenarios = ret->header.numberOfScenarios;
for(int g = 0; g < howManyScenarios; ++g)
{
CCampaignScenario sc = readScenarioFromMemory(reader, ret->header);
ret->scenarios.push_back(sc);
}
int scenarioID = 0; for(int g = 0; g < ret->header.numberOfScenarios; ++g)
ret->scenarios.emplace_back(readScenarioFromMemory(reader, ret->header));
//first entry is campaign header. start loop from 1
for (int g=1; g<file.size() && scenarioID<howManyScenarios; ++g)
{
while(!ret->scenarios[scenarioID].isNotVoid()) //skip void scenarios
{
scenarioID++;
}
std::string scenarioName = resourceID.getName();
boost::to_lower(scenarioName);
scenarioName += ':' + std::to_string(g - 1);
//set map piece appropriately, convert vector to string
ret->mapPieces[scenarioID].assign(reinterpret_cast< const char* >(file[g].data()), file[g].size());
CMapService mapService;
auto hdr = mapService.loadMapHeader(
reinterpret_cast<const ui8 *>(ret->mapPieces[scenarioID].c_str()),
static_cast<int>(ret->mapPieces[scenarioID].size()),
scenarioName,
modName,
encoding);
ret->scenarios[scenarioID].scenarioName = hdr->name;
scenarioID++;
}
} }
else else
{ {
ret->header = readHeaderFromJson(jsonCampaign, resourceID.getName(), modName, encoding); ret->header = readHeaderFromJson(jsonCampaign, resourceID.getName(), modName, encoding);
for(auto & scenario : jsonCampaign["scenarios"].Vector()) for(auto & scenario : jsonCampaign["scenarios"].Vector())
{ ret->scenarios.emplace_back(readScenarioFromJson(scenario));
CCampaignScenario sc = readScenarioFromJson(scenario); }
if(sc.isNotVoid())
{ //first entry is campaign header. start loop from 1
CMapService mapService; for(int scenarioID = 0, g = 1; g < files.size() && scenarioID < ret->header.numberOfScenarios; ++g)
if(auto hdr = mapService.loadMapHeader(ResourceID(sc.mapName, EResType::MAP))) {
sc.scenarioName = hdr->name; while(!ret->scenarios[scenarioID].isNotVoid()) //skip void scenarios
} scenarioID++;
ret->scenarios.push_back(sc);
} std::string scenarioName = resourceID.getName();
boost::to_lower(scenarioName);
scenarioName += ':' + std::to_string(g - 1);
//set map piece appropriately, convert vector to string
ret->mapPieces[scenarioID].assign(reinterpret_cast<const char*>(files[g].data()), files[g].size());
CMapService mapService;
auto hdr = mapService.loadMapHeader(
reinterpret_cast<const ui8 *>(ret->mapPieces[scenarioID].c_str()),
static_cast<int>(ret->mapPieces[scenarioID].size()),
scenarioName,
modName,
encoding);
ret->scenarios[scenarioID].scenarioName = hdr->name;
scenarioID++;
} }
// handle campaign specific discrepancies // handle campaign specific discrepancies
@@ -817,10 +797,7 @@ CMap * CCampaignState::getMap(int scenarioId) const
if(scenarioId == -1) if(scenarioId == -1)
scenarioId = currentMap.value(); scenarioId = currentMap.value();
CMapService mapService; CMapService mapService;
if(camp->header.version == CampaignVersion::Version::VCMI)
return mapService.loadMap(ResourceID(camp->scenarios.at(scenarioId).mapName, EResType::MAP)).release();
std::string scenarioName = camp->header.filename.substr(0, camp->header.filename.find('.')); std::string scenarioName = camp->header.filename.substr(0, camp->header.filename.find('.'));
boost::to_lower(scenarioName); boost::to_lower(scenarioName);
scenarioName += ':' + std::to_string(scenarioId); scenarioName += ':' + std::to_string(scenarioId);