1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-06 09:09:40 +02:00

Provide encoding information to maps & campaigns loaders

This commit is contained in:
Ivan Savenko
2023-02-24 22:38:12 +02:00
parent bd70b6fabd
commit 4260726e4b
20 changed files with 121 additions and 68 deletions

View File

@@ -15,6 +15,7 @@
#include "../../lib/CGeneralTextHandler.h" #include "../../lib/CGeneralTextHandler.h"
#include "../../lib/StartInfo.h" #include "../../lib/StartInfo.h"
#include "../../lib/mapping/CMapInfo.h" #include "../../lib/mapping/CMapInfo.h"
#include "../../lib/mapping/CMap.h"
#include "../gui/CGuiHandler.h" #include "../gui/CGuiHandler.h"
#include "../CGameInfo.h" #include "../CGameInfo.h"
#include "../CPlayerInterface.h" #include "../CPlayerInterface.h"

View File

@@ -24,6 +24,7 @@
#include "../../lib/StartInfo.h" #include "../../lib/StartInfo.h"
#include "../../lib/filesystem/Filesystem.h" #include "../../lib/filesystem/Filesystem.h"
#include "../../lib/mapping/CMapInfo.h" #include "../../lib/mapping/CMapInfo.h"
#include "../../lib/mapping/CMap.h"
CSavingScreen::CSavingScreen() CSavingScreen::CSavingScreen()
: CSelectionBase(ESelectionScreen::saveGame) : CSelectionBase(ESelectionScreen::saveGame)

View File

@@ -25,6 +25,7 @@
#include "../../lib/CGeneralTextHandler.h" #include "../../lib/CGeneralTextHandler.h"
#include "../../lib/mapping/CMapInfo.h" #include "../../lib/mapping/CMapInfo.h"
#include "../../lib/mapping/CMap.h"
#include "../../lib/rmg/CMapGenOptions.h" #include "../../lib/rmg/CMapGenOptions.h"
#include "../../lib/CModHandler.h" #include "../../lib/CModHandler.h"
#include "../../lib/rmg/CRmgTemplateStorage.h" #include "../../lib/rmg/CRmgTemplateStorage.h"

View File

@@ -33,6 +33,8 @@
#include "../../lib/CModHandler.h" #include "../../lib/CModHandler.h"
#include "../../lib/filesystem/Filesystem.h" #include "../../lib/filesystem/Filesystem.h"
#include "../../lib/mapping/CMapInfo.h" #include "../../lib/mapping/CMapInfo.h"
#include "../../lib/mapping/CMap.h"
#include "../../lib/mapping/CCampaignHandler.h"
#include "../../lib/serializer/Connection.h" #include "../../lib/serializer/Connection.h"
bool mapSorter::operator()(const std::shared_ptr<CMapInfo> aaa, const std::shared_ptr<CMapInfo> bbb) bool mapSorter::operator()(const std::shared_ptr<CMapInfo> aaa, const std::shared_ptr<CMapInfo> bbb)

View File

@@ -217,7 +217,7 @@ std::vector<CIdentifierStorage::ObjectData> CIdentifierStorage::getPossibleIdent
// special scope that should have access to all in-game objects // special scope that should have access to all in-game objects
if (request.localScope == CModHandler::scopeGame()) if (request.localScope == CModHandler::scopeGame())
{ {
for (auto const & modName : VLC->modh->getActiveMods()) for(const auto & modName : VLC->modh->getActiveMods())
allowedScopes.insert(modName); allowedScopes.insert(modName);
} }
@@ -943,8 +943,9 @@ std::vector<std::string> CModHandler::getModList(std::string path)
bool CModHandler::isScopeReserved(const TModID & scope) bool CModHandler::isScopeReserved(const TModID & scope)
{ {
static const std::array<TModID, 6> reservedScopes = { //following scopes are reserved - either in use by mod system or by filesystem
"core", "map", "game", "root", "saves", "config" static const std::array<TModID, 9> reservedScopes = {
"core", "map", "game", "root", "saves", "config", "local", "initial", "mapEditor"
}; };
return std::find(reservedScopes.begin(), reservedScopes.end(), scope) != reservedScopes.end(); return std::find(reservedScopes.begin(), reservedScopes.end(), scope) != reservedScopes.end();
@@ -1097,8 +1098,22 @@ void CModHandler::loadModFilesystems()
} }
} }
std::string CModHandler::getModLanguage(TModID modId) const TModID CModHandler::findResourceOrigin(const ResourceID & name)
{ {
for(const auto & modID : boost::adaptors::reverse(activeMods))
{
if(CResourceHandler::get(modID)->existsResource(name))
return modID;
}
assert(0);
return "";
}
std::string CModHandler::getModLanguage(const TModID& modId) const
{
if ( modId == "core")
return VLC->generaltexth->getInstalledLanguage();
return allMods.at(modId).baseLanguage; return allMods.at(modId).baseLanguage;
} }
@@ -1130,7 +1145,7 @@ bool CModHandler::validateTranslations(TModID modName) const
result |= VLC->generaltexth->validateTranslation(mod.baseLanguage, modName, json); result |= VLC->generaltexth->validateTranslation(mod.baseLanguage, modName, json);
} }
for (auto const & language : Languages::getLanguageList()) for(const auto & language : Languages::getLanguageList())
{ {
if (!language.hasTranslation) if (!language.hasTranslation)
continue; continue;
@@ -1148,7 +1163,7 @@ bool CModHandler::validateTranslations(TModID modName) const
void CModHandler::loadTranslation(TModID modName) void CModHandler::loadTranslation(TModID modName)
{ {
auto const & mod = allMods[modName]; const auto & mod = allMods[modName];
std::string preferredLanguage = VLC->generaltexth->getPreferredLanguage(); std::string preferredLanguage = VLC->generaltexth->getPreferredLanguage();
std::string modBaseLanguage = allMods[modName].baseLanguage; std::string modBaseLanguage = allMods[modName].baseLanguage;

View File

@@ -339,7 +339,10 @@ public:
void loadMods(bool onlyEssential = false); void loadMods(bool onlyEssential = false);
void loadModFilesystems(); void loadModFilesystems();
std::string getModLanguage(TModID modId) const; /// returns ID of mod that provides selected file resource
TModID findResourceOrigin(const ResourceID & name);
std::string getModLanguage(const TModID& modId) const;
std::set<TModID> getModDependencies(TModID modId, bool & isModFound) const; std::set<TModID> getModDependencies(TModID modId, bool & isModFound) const;

View File

@@ -28,6 +28,8 @@
#include "StartInfo.h" #include "StartInfo.h"
#include "CPlayerState.h" #include "CPlayerState.h"
#include "TerrainHandler.h" #include "TerrainHandler.h"
#include "mapping/CCampaignHandler.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN

View File

@@ -13,6 +13,8 @@
#include "CGeneralTextHandler.h" #include "CGeneralTextHandler.h"
#include "rmg/CMapGenOptions.h" #include "rmg/CMapGenOptions.h"
#include "mapping/CMapInfo.h" #include "mapping/CMapInfo.h"
#include "mapping/CCampaignHandler.h"
#include "mapping/CMap.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN

View File

@@ -17,10 +17,13 @@
#include "../VCMI_Lib.h" #include "../VCMI_Lib.h"
#include "../vcmi_endian.h" #include "../vcmi_endian.h"
#include "../CGeneralTextHandler.h" #include "../CGeneralTextHandler.h"
#include "../TextOperations.h"
#include "../StartInfo.h" #include "../StartInfo.h"
#include "../CModHandler.h"
#include "../CArtHandler.h" //for hero crossover #include "../CArtHandler.h" //for hero crossover
#include "../mapObjects/CGHeroInstance.h"//for hero crossover #include "../mapObjects/CGHeroInstance.h"//for hero crossover
#include "../CHeroHandler.h" #include "../CHeroHandler.h"
#include "../Languages.h"
#include "CMapService.h" #include "CMapService.h"
#include "CMap.h" #include "CMap.h"
#include "CMapInfo.h" #include "CMapInfo.h"
@@ -40,31 +43,41 @@ bool CScenarioTravel::STravelBonus::isBonusForHero() const
CCampaignHeader CCampaignHandler::getHeader( const std::string & name) CCampaignHeader CCampaignHandler::getHeader( const std::string & name)
{ {
std::vector<ui8> cmpgn = getFile(name, true)[0]; ResourceID resourceID(name, EResType::CAMPAIGN);
std::string modName = VLC->modh->findResourceOrigin(resourceID);
std::string language = VLC->modh->getModLanguage(modName);
std::string encoding = Languages::getLanguageOptions(language).encoding;
auto fileStream = CResourceHandler::get(modName)->load(resourceID);
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); CCampaignHeader ret = readHeaderFromMemory(reader, name, encoding);
ret.filename = name;
return ret; return ret;
} }
std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & name ) std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & name )
{ {
ResourceID resourceID(name, EResType::CAMPAIGN);
std::string modName = VLC->modh->findResourceOrigin(resourceID);
std::string language = VLC->modh->getModLanguage(modName);
std::string encoding = Languages::getLanguageOptions(language).encoding;
auto fileStream = CResourceHandler::get(modName)->load(resourceID);
auto ret = std::make_unique<CCampaign>(); auto ret = std::make_unique<CCampaign>();
std::vector<std::vector<ui8>> file = getFile(name, false); std::vector<std::vector<ui8>> file = getFile(std::move(fileStream), false);
CMemoryStream stream(file[0].data(), file[0].size()); CMemoryStream stream(file[0].data(), file[0].size());
CBinaryReader reader(&stream); CBinaryReader reader(&stream);
ret->header = readHeaderFromMemory(reader); ret->header = readHeaderFromMemory(reader, name, encoding);
ret->header.filename = name;
int howManyScenarios = static_cast<int>(VLC->generaltexth->getCampaignLength(ret->header.mapVersion)); int howManyScenarios = static_cast<int>(VLC->generaltexth->getCampaignLength(ret->header.mapVersion));
for(int g=0; g<howManyScenarios; ++g) for(int g=0; g<howManyScenarios; ++g)
{ {
CCampaignScenario sc = readScenarioFromMemory(reader, ret->header.version, ret->header.mapVersion); CCampaignScenario sc = readScenarioFromMemory(reader, name, encoding, ret->header.version, ret->header.mapVersion);
ret->scenarios.push_back(sc); ret->scenarios.push_back(sc);
} }
@@ -88,7 +101,8 @@ std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & na
auto hdr = mapService.loadMapHeader( auto hdr = mapService.loadMapHeader(
reinterpret_cast<const ui8 *>(ret->mapPieces[scenarioID].c_str()), reinterpret_cast<const ui8 *>(ret->mapPieces[scenarioID].c_str()),
static_cast<int>(ret->mapPieces[scenarioID].size()), static_cast<int>(ret->mapPieces[scenarioID].size()),
scenarioName); scenarioName,
"(unknown)");
ret->scenarios[scenarioID].scenarioName = hdr->name; ret->scenarios[scenarioID].scenarioName = hdr->name;
scenarioID++; scenarioID++;
} }
@@ -110,28 +124,30 @@ std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & na
return ret; return ret;
} }
std::string CCampaignHandler::readLocalizedString(CBinaryReader & reader) std::string CCampaignHandler::readLocalizedString(CBinaryReader & reader, std::string encoding)
{ {
return reader.readBaseString(); return TextOperations::toUnicode(reader.readBaseString(), encoding);
} }
CCampaignHeader CCampaignHandler::readHeaderFromMemory( CBinaryReader & reader ) CCampaignHeader CCampaignHandler::readHeaderFromMemory( CBinaryReader & reader, std::string filename, std::string encoding )
{ {
CCampaignHeader ret; CCampaignHeader ret;
ret.version = reader.readUInt32(); ret.version = reader.readUInt32();
ret.mapVersion = reader.readUInt8() - 1;//change range of it from [1, 20] to [0, 19] ret.mapVersion = reader.readUInt8() - 1;//change range of it from [1, 20] to [0, 19]
ret.name = readLocalizedString(reader); ret.name = readLocalizedString(reader, encoding);
ret.description = readLocalizedString(reader); ret.description = readLocalizedString(reader, encoding);
if (ret.version > CampaignVersion::RoE) if (ret.version > CampaignVersion::RoE)
ret.difficultyChoosenByPlayer = reader.readInt8(); ret.difficultyChoosenByPlayer = reader.readInt8();
else else
ret.difficultyChoosenByPlayer = 0; ret.difficultyChoosenByPlayer = 0;
ret.music = reader.readInt8(); ret.music = reader.readInt8();
ret.filename = filename;
ret.encoding = encoding;
return ret; return ret;
} }
CCampaignScenario CCampaignHandler::readScenarioFromMemory( CBinaryReader & reader, int version, int mapVersion ) CCampaignScenario CCampaignHandler::readScenarioFromMemory( CBinaryReader & reader, std::string filename, std::string encoding, int version, int mapVersion )
{ {
auto prologEpilogReader = [&]() -> CCampaignScenario::SScenarioPrologEpilog auto prologEpilogReader = [&]() -> CCampaignScenario::SScenarioPrologEpilog
{ {
@@ -141,14 +157,14 @@ CCampaignScenario CCampaignHandler::readScenarioFromMemory( CBinaryReader & read
{ {
ret.prologVideo = reader.readUInt8(); ret.prologVideo = reader.readUInt8();
ret.prologMusic = reader.readUInt8(); ret.prologMusic = reader.readUInt8();
ret.prologText = readLocalizedString(reader); ret.prologText = readLocalizedString(reader, encoding);
} }
return ret; return ret;
}; };
CCampaignScenario ret; CCampaignScenario ret;
ret.conquered = false; ret.conquered = false;
ret.mapName = readLocalizedString(reader); ret.mapName = readLocalizedString(reader, encoding);
ret.packedMapSize = reader.readUInt32(); ret.packedMapSize = reader.readUInt32();
if(mapVersion == 18)//unholy alliance if(mapVersion == 18)//unholy alliance
{ {
@@ -160,7 +176,7 @@ CCampaignScenario CCampaignHandler::readScenarioFromMemory( CBinaryReader & read
} }
ret.regionColor = reader.readUInt8(); ret.regionColor = reader.readUInt8();
ret.difficulty = reader.readUInt8(); ret.difficulty = reader.readUInt8();
ret.regionText = readLocalizedString(reader); ret.regionText = readLocalizedString(reader, encoding);
ret.prolog = prologEpilogReader(); ret.prolog = prologEpilogReader();
ret.epilog = prologEpilogReader(); ret.epilog = prologEpilogReader();
@@ -310,9 +326,9 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory(CBinaryReader & r
return ret; return ret;
} }
std::vector< std::vector<ui8> > CCampaignHandler::getFile(const std::string & name, bool headerOnly) std::vector< std::vector<ui8> > CCampaignHandler::getFile(std::unique_ptr<CInputStream> file, bool headerOnly)
{ {
CCompressedStream stream(CResourceHandler::get()->load(ResourceID(name, EResType::CAMPAIGN)), true); CCompressedStream stream(std::move(file), true);
std::vector< std::vector<ui8> > ret; std::vector< std::vector<ui8> > ret;
do do
@@ -457,7 +473,7 @@ CMap * CCampaignState::getMap(int scenarioId) const
std::string & mapContent = camp->mapPieces.find(scenarioId)->second; std::string & mapContent = camp->mapPieces.find(scenarioId)->second;
const auto * buffer = reinterpret_cast<const ui8 *>(mapContent.data()); const auto * buffer = reinterpret_cast<const ui8 *>(mapContent.data());
CMapService mapService; CMapService mapService;
return mapService.loadMap(buffer, static_cast<int>(mapContent.size()), scenarioName).release(); return mapService.loadMap(buffer, static_cast<int>(mapContent.size()), scenarioName, "(unknown)").release();
} }
std::unique_ptr<CMapHeader> CCampaignState::getHeader(int scenarioId) const std::unique_ptr<CMapHeader> CCampaignState::getHeader(int scenarioId) const
@@ -471,7 +487,7 @@ std::unique_ptr<CMapHeader> CCampaignState::getHeader(int scenarioId) const
std::string & mapContent = camp->mapPieces.find(scenarioId)->second; std::string & mapContent = camp->mapPieces.find(scenarioId)->second;
const auto * buffer = reinterpret_cast<const ui8 *>(mapContent.data()); const auto * buffer = reinterpret_cast<const ui8 *>(mapContent.data());
CMapService mapService; CMapService mapService;
return mapService.loadMapHeader(buffer, static_cast<int>(mapContent.size()), scenarioName); return mapService.loadMapHeader(buffer, static_cast<int>(mapContent.size()), scenarioName, "(unknown)");
} }
std::shared_ptr<CMapInfo> CCampaignState::getMapInfo(int scenarioId) const std::shared_ptr<CMapInfo> CCampaignState::getMapInfo(int scenarioId) const
@@ -527,7 +543,4 @@ std::string CCampaignHandler::prologVoiceName(ui8 index)
return ""; return "";
} }
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@@ -16,6 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN
struct StartInfo; struct StartInfo;
class CGHeroInstance; class CGHeroInstance;
class CBinaryReader; class CBinaryReader;
class CInputStream;
class CMap; class CMap;
class CMapHeader; class CMapHeader;
class CMapInfo; class CMapInfo;
@@ -42,7 +43,7 @@ public:
ui8 music = 0; //CmpMusic.txt, start from 0 ui8 music = 0; //CmpMusic.txt, start from 0
std::string filename; std::string filename;
ui8 loadFromLod = 0; //if true, this campaign must be loaded fro, .lod file std::string encoding;
template <typename Handler> void serialize(Handler &h, const int formatVersion) template <typename Handler> void serialize(Handler &h, const int formatVersion)
{ {
@@ -53,7 +54,7 @@ public:
h & difficultyChoosenByPlayer; h & difficultyChoosenByPlayer;
h & music; h & music;
h & filename; h & filename;
h & loadFromLod; h & encoding;
} }
}; };
@@ -181,7 +182,7 @@ class DLL_LINKAGE CCampaignState
{ {
public: public:
std::unique_ptr<CCampaign> camp; std::unique_ptr<CCampaign> camp;
std::string campaignName; std::string fileEncoding;
std::vector<ui8> mapsConquered, mapsRemaining; std::vector<ui8> mapsConquered, mapsRemaining;
boost::optional<si32> currentMap; boost::optional<si32> currentMap;
@@ -206,7 +207,6 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & camp; h & camp;
h & campaignName;
h & mapsRemaining; h & mapsRemaining;
h & mapsConquered; h & mapsConquered;
h & currentMap; h & currentMap;
@@ -218,14 +218,15 @@ class DLL_LINKAGE CCampaignHandler
{ {
std::vector<size_t> scenariosCountPerCampaign; std::vector<size_t> scenariosCountPerCampaign;
static std::string readLocalizedString(CBinaryReader & reader); static std::string readLocalizedString(CBinaryReader & reader, std::string encoding);
static CCampaignHeader readHeaderFromMemory(CBinaryReader & reader); static CCampaignHeader readHeaderFromMemory(CBinaryReader & reader, std::string filename, std::string encoding);
static CCampaignScenario readScenarioFromMemory(CBinaryReader & reader, int version, int mapVersion ); static CCampaignScenario readScenarioFromMemory(CBinaryReader & reader, std::string filename, std::string encoding, int version, int mapVersion );
static CScenarioTravel readScenarioTravelFromMemory(CBinaryReader & reader, int version); static CScenarioTravel readScenarioTravelFromMemory(CBinaryReader & reader, int version);
/// returns h3c split in parts. 0 = h3c header, 1-end - maps (binary h3m) /// returns h3c split in parts. 0 = h3c header, 1-end - maps (binary h3m)
/// headerOnly - only header will be decompressed, returned vector wont have any maps /// headerOnly - only header will be decompressed, returned vector wont have any maps
static std::vector< std::vector<ui8> > getFile(const std::string & name, bool headerOnly); static std::vector<std::vector<ui8>> getFile(std::unique_ptr<CInputStream> file, bool headerOnly);
public: public:
static std::string prologVideoName(ui8 index); static std::string prologVideoName(ui8 index);
static std::string prologMusicName(ui8 index); static std::string prologMusicName(ui8 index);

View File

@@ -14,6 +14,8 @@
#include "../StartInfo.h" #include "../StartInfo.h"
#include "../GameConstants.h" #include "../GameConstants.h"
#include "CMapService.h" #include "CMapService.h"
#include "CMap.h"
#include "CCampaignHandler.h"
#include "../filesystem/Filesystem.h" #include "../filesystem/Filesystem.h"
#include "../serializer/CMemorySerializer.h" #include "../serializer/CMemorySerializer.h"

View File

@@ -9,21 +9,14 @@
*/ */
#pragma once #pragma once
// Forward class declarations aren't enough here. The compiler
// generated CMapInfo d-tor, generates the std::unique_ptr d-tor as well here
// as a inline method. The std::unique_ptr d-tor requires a complete type. Defining
// the CMapInfo d-tor to let the compiler add the d-tor stuff in the .cpp file
// would work with one exception. It prevents the generation of the move
// constructor which is needed. (Writing such a c-tor is nasty.) With the
// new c++11 keyword "default" for constructors this problem could be solved. But it isn't
// available for Visual Studio for now. (Empty d-tor in .cpp would be required anyway)
#include "CMap.h"
#include "CCampaignHandler.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
struct StartInfo; struct StartInfo;
class CMapHeader;
class CCampaignHeader;
class ResourceID;
/** /**
* A class which stores the count of human players and all players, the filename, * A class which stores the count of human players and all players, the filename,
* scenario options, the map header information,... * scenario options, the map header information,...
@@ -44,7 +37,11 @@ public:
CMapInfo(); CMapInfo();
virtual ~CMapInfo(); virtual ~CMapInfo();
CMapInfo &operator=(CMapInfo &&other); CMapInfo(CMapInfo &&other) = delete;
CMapInfo(const CMapInfo &other) = delete;
CMapInfo &operator=(CMapInfo &&other) = delete;
CMapInfo &operator=(const CMapInfo &other) = delete;
void mapInit(const std::string & fname); void mapInit(const std::string & fname);
void saveInit(const ResourceID & file); void saveInit(const ResourceID & file);

View File

@@ -15,6 +15,8 @@
#include "../filesystem/CCompressedStream.h" #include "../filesystem/CCompressedStream.h"
#include "../filesystem/CMemoryStream.h" #include "../filesystem/CMemoryStream.h"
#include "../filesystem/CMemoryBuffer.h" #include "../filesystem/CMemoryBuffer.h"
#include "../CModHandler.h"
#include "../Languages.h"
#include "CMap.h" #include "CMap.h"
@@ -26,20 +28,28 @@ VCMI_LIB_NAMESPACE_BEGIN
std::unique_ptr<CMap> CMapService::loadMap(const ResourceID & name) const std::unique_ptr<CMap> CMapService::loadMap(const ResourceID & name) const
{ {
std::string modName = VLC->modh->findResourceOrigin(name);
std::string language = VLC->modh->getModLanguage(modName);
std::string encoding = Languages::getLanguageOptions(language).encoding;
auto stream = getStreamFromFS(name); auto stream = getStreamFromFS(name);
return getMapLoader(stream)->loadMap(); return getMapLoader(stream, name.getName(), encoding)->loadMap();
} }
std::unique_ptr<CMapHeader> CMapService::loadMapHeader(const ResourceID & name) const std::unique_ptr<CMapHeader> CMapService::loadMapHeader(const ResourceID & name) const
{ {
std::string modName = VLC->modh->findResourceOrigin(name);
std::string language = VLC->modh->getModLanguage(modName);
std::string encoding = Languages::getLanguageOptions(language).encoding;
auto stream = getStreamFromFS(name); auto stream = getStreamFromFS(name);
return getMapLoader(stream)->loadMapHeader(); return getMapLoader(stream, name.getName(), encoding)->loadMapHeader();
} }
std::unique_ptr<CMap> CMapService::loadMap(const ui8 * buffer, int size, const std::string & name) const std::unique_ptr<CMap> CMapService::loadMap(const ui8 * buffer, int size, const std::string & name, const std::string & encoding) const
{ {
auto stream = getStreamFromMem(buffer, size); auto stream = getStreamFromMem(buffer, size);
std::unique_ptr<CMap> map(getMapLoader(stream)->loadMap()); std::unique_ptr<CMap> map(getMapLoader(stream, name, encoding)->loadMap());
std::unique_ptr<CMapHeader> header(map.get()); std::unique_ptr<CMapHeader> header(map.get());
//might be original campaign and require patch //might be original campaign and require patch
@@ -49,10 +59,10 @@ std::unique_ptr<CMap> CMapService::loadMap(const ui8 * buffer, int size, const s
return map; return map;
} }
std::unique_ptr<CMapHeader> CMapService::loadMapHeader(const ui8 * buffer, int size, const std::string & name) const std::unique_ptr<CMapHeader> CMapService::loadMapHeader(const ui8 * buffer, int size, const std::string & name, const std::string & encoding) const
{ {
auto stream = getStreamFromMem(buffer, size); auto stream = getStreamFromMem(buffer, size);
std::unique_ptr<CMapHeader> header = getMapLoader(stream)->loadMapHeader(); std::unique_ptr<CMapHeader> header = getMapLoader(stream, name, encoding)->loadMapHeader();
//might be original campaign and require patch //might be original campaign and require patch
getMapPatcher(name)->patchMapHeader(header); getMapPatcher(name)->patchMapHeader(header);
@@ -86,7 +96,7 @@ std::unique_ptr<CInputStream> CMapService::getStreamFromMem(const ui8 * buffer,
return std::unique_ptr<CInputStream>(new CMemoryStream(buffer, size)); return std::unique_ptr<CInputStream>(new CMemoryStream(buffer, size));
} }
std::unique_ptr<IMapLoader> CMapService::getMapLoader(std::unique_ptr<CInputStream> & stream) std::unique_ptr<IMapLoader> CMapService::getMapLoader(std::unique_ptr<CInputStream> & stream, std::string mapName, std::string encoding)
{ {
// Read map header // Read map header
CBinaryReader reader(stream.get()); CBinaryReader reader(stream.get());
@@ -109,12 +119,12 @@ std::unique_ptr<IMapLoader> CMapService::getMapLoader(std::unique_ptr<CInputStre
// gzip header magic number, reversed for LE // gzip header magic number, reversed for LE
case 0x00088B1F: case 0x00088B1F:
stream = std::unique_ptr<CInputStream>(new CCompressedStream(std::move(stream), true)); stream = std::unique_ptr<CInputStream>(new CCompressedStream(std::move(stream), true));
return std::unique_ptr<IMapLoader>(new CMapLoaderH3M(stream.get())); return std::unique_ptr<IMapLoader>(new CMapLoaderH3M(mapName, encoding, stream.get()));
case EMapFormat::WOG : case EMapFormat::WOG :
case EMapFormat::AB : case EMapFormat::AB :
case EMapFormat::ROE : case EMapFormat::ROE :
case EMapFormat::SOD : case EMapFormat::SOD :
return std::unique_ptr<IMapLoader>(new CMapLoaderH3M(stream.get())); return std::unique_ptr<IMapLoader>(new CMapLoaderH3M(mapName, encoding, stream.get()));
default : default :
throw std::runtime_error("Unknown map format"); throw std::runtime_error("Unknown map format");
} }

View File

@@ -58,7 +58,7 @@ public:
* @param name indicates name of file that will be used during map header patching * @param name indicates name of file that will be used during map header patching
* @return a unique ptr to the loaded map class * @return a unique ptr to the loaded map class
*/ */
virtual std::unique_ptr<CMap> loadMap(const ui8 * buffer, int size, const std::string & name) const = 0; virtual std::unique_ptr<CMap> loadMap(const ui8 * buffer, int size, const std::string & name, const std::string & encoding) const = 0;
/** /**
* Loads the VCMI/H3 map header from a buffer. This method is temporarily * Loads the VCMI/H3 map header from a buffer. This method is temporarily
@@ -72,7 +72,7 @@ public:
* @param name indicates name of file that will be used during map header patching * @param name indicates name of file that will be used during map header patching
* @return a unique ptr to the loaded map class * @return a unique ptr to the loaded map class
*/ */
virtual std::unique_ptr<CMapHeader> loadMapHeader(const ui8 * buffer, int size, const std::string & name) const = 0; virtual std::unique_ptr<CMapHeader> loadMapHeader(const ui8 * buffer, int size, const std::string & name, const std::string & encoding) const = 0;
virtual void saveMap(const std::unique_ptr<CMap> & map, boost::filesystem::path fullPath) const = 0; virtual void saveMap(const std::unique_ptr<CMap> & map, boost::filesystem::path fullPath) const = 0;
}; };
@@ -85,8 +85,8 @@ public:
std::unique_ptr<CMap> loadMap(const ResourceID & name) const override; std::unique_ptr<CMap> loadMap(const ResourceID & name) const override;
std::unique_ptr<CMapHeader> loadMapHeader(const ResourceID & name) const override; std::unique_ptr<CMapHeader> loadMapHeader(const ResourceID & name) const override;
std::unique_ptr<CMap> loadMap(const ui8 * buffer, int size, const std::string & name) const override; std::unique_ptr<CMap> loadMap(const ui8 * buffer, int size, const std::string & name, const std::string & encoding) const override;
std::unique_ptr<CMapHeader> loadMapHeader(const ui8 * buffer, int size, const std::string & name) const override; std::unique_ptr<CMapHeader> loadMapHeader(const ui8 * buffer, int size, const std::string & name, const std::string & encoding) const override;
void saveMap(const std::unique_ptr<CMap> & map, boost::filesystem::path fullPath) const override; void saveMap(const std::unique_ptr<CMap> & map, boost::filesystem::path fullPath) const override;
private: private:
/** /**
@@ -113,7 +113,7 @@ private:
* @param stream the input map stream * @param stream the input map stream
* @return the constructed map loader * @return the constructed map loader
*/ */
static std::unique_ptr<IMapLoader> getMapLoader(std::unique_ptr<CInputStream> & stream); static std::unique_ptr<IMapLoader> getMapLoader(std::unique_ptr<CInputStream> & stream, std::string mapName, std::string encoding);
/** /**
* Gets a map patcher for specified scenario * Gets a map patcher for specified scenario

View File

@@ -34,7 +34,7 @@ VCMI_LIB_NAMESPACE_BEGIN
const bool CMapLoaderH3M::IS_PROFILING_ENABLED = false; const bool CMapLoaderH3M::IS_PROFILING_ENABLED = false;
CMapLoaderH3M::CMapLoaderH3M(CInputStream * stream) CMapLoaderH3M::CMapLoaderH3M(const std::string & mapName, const std::string & encodingName, CInputStream * stream)
: map(nullptr) : map(nullptr)
, reader(new CBinaryReader(stream)) , reader(new CBinaryReader(stream))
, inputStream(stream) , inputStream(stream)

View File

@@ -39,7 +39,7 @@ public:
* *
* @param stream a stream containing the map data * @param stream a stream containing the map data
*/ */
CMapLoaderH3M(CInputStream * stream); CMapLoaderH3M(const std::string & mapName, const std::string & encodingName, CInputStream * stream);
/** /**
* Destructor. * Destructor.

View File

@@ -23,6 +23,7 @@
#include "../CRandomGenerator.h" #include "../CRandomGenerator.h"
#include "Functions.h" #include "Functions.h"
#include "../mapping/CMapEditManager.h" #include "../mapping/CMapEditManager.h"
#include "../mapping/CMap.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN

View File

@@ -14,6 +14,7 @@
#include "CMapGenOptions.h" #include "CMapGenOptions.h"
#include "Zone.h" #include "Zone.h"
#include "../mapping/CMapEditManager.h" #include "../mapping/CMapEditManager.h"
#include "../mapping/CMap.h"
#include "../CTownHandler.h" #include "../CTownHandler.h"
#include "ObjectManager.h" #include "ObjectManager.h"
#include "RoadPlacer.h" #include "RoadPlacer.h"

View File

@@ -11,10 +11,10 @@
#pragma once #pragma once
#include "../int3.h" #include "../int3.h"
#include "../GameConstants.h" #include "../GameConstants.h"
#include "../mapping/CMap.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
class CMap;
class CMapEditManager; class CMapEditManager;
class TileInfo; class TileInfo;
class CMapGenOptions; class CMapGenOptions;

View File

@@ -20,6 +20,7 @@
#include "../TerrainHandler.h" #include "../TerrainHandler.h"
#include "../CRandomGenerator.h" #include "../CRandomGenerator.h"
#include "../mapping/CMapEditManager.h" #include "../mapping/CMapEditManager.h"
#include "../mapping/CMap.h"
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN