mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Loading of translation mods is now skipped on language mismatch
This commit is contained in:
parent
a062e5e425
commit
369e925af8
@ -258,7 +258,7 @@ int main(int argc, char * argv[])
|
|||||||
|
|
||||||
// Init filesystem and settings
|
// Init filesystem and settings
|
||||||
preinitDLL(::console);
|
preinitDLL(::console);
|
||||||
settings.init();
|
|
||||||
Settings session = settings.write["session"];
|
Settings session = settings.write["session"];
|
||||||
auto setSettingBool = [](std::string key, std::string arg) {
|
auto setSettingBool = [](std::string key, std::string arg) {
|
||||||
Settings s = settings.write(vstd::split(key, "/"));
|
Settings s = settings.write(vstd::split(key, "/"));
|
||||||
|
@ -139,6 +139,11 @@ bool CModEntry::isValid() const
|
|||||||
return !localData.isEmpty() || !repository.isEmpty();
|
return !localData.isEmpty() || !repository.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CModEntry::isTranslation() const
|
||||||
|
{
|
||||||
|
return getBaseValue("modType").toString().toLower() == "translation";
|
||||||
|
}
|
||||||
|
|
||||||
int CModEntry::getModStatus() const
|
int CModEntry::getModStatus() const
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
@ -62,6 +62,8 @@ public:
|
|||||||
bool isCompatible() const;
|
bool isCompatible() const;
|
||||||
// returns if has any data
|
// returns if has any data
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
// installed and enabled
|
||||||
|
bool isTranslation() const;
|
||||||
|
|
||||||
// see ModStatus enum
|
// see ModStatus enum
|
||||||
int getModStatus() const;
|
int getModStatus() const;
|
||||||
|
@ -847,7 +847,7 @@ QString CModListView::getTranslationModName(const QString & language)
|
|||||||
{
|
{
|
||||||
auto mod = modModel->getMod(modName);
|
auto mod = modModel->getMod(modName);
|
||||||
|
|
||||||
if (mod.getBaseValue("modType").toString().toLower() != "translation")
|
if (!mod.isTranslation())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mod.getBaseValue("language").toString() != language)
|
if (mod.getBaseValue("language").toString() != language)
|
||||||
|
@ -387,8 +387,6 @@ CGeneralTextHandler::CGeneralTextHandler():
|
|||||||
znpc00 (*this, "vcmi.znpc00" ), // technically - wog
|
znpc00 (*this, "vcmi.znpc00" ), // technically - wog
|
||||||
qeModCommands (*this, "vcmi.quickExchange" )
|
qeModCommands (*this, "vcmi.quickExchange" )
|
||||||
{
|
{
|
||||||
detectInstallParameters();
|
|
||||||
|
|
||||||
readToVector("core.vcdesc", "DATA/VCDESC.TXT" );
|
readToVector("core.vcdesc", "DATA/VCDESC.TXT" );
|
||||||
readToVector("core.lcdesc", "DATA/LCDESC.TXT" );
|
readToVector("core.lcdesc", "DATA/LCDESC.TXT" );
|
||||||
readToVector("core.tcommand", "DATA/TCOMMAND.TXT" );
|
readToVector("core.tcommand", "DATA/TCOMMAND.TXT" );
|
||||||
@ -605,16 +603,19 @@ std::string CGeneralTextHandler::getModLanguage(const std::string & modContext)
|
|||||||
|
|
||||||
std::string CGeneralTextHandler::getPreferredLanguage()
|
std::string CGeneralTextHandler::getPreferredLanguage()
|
||||||
{
|
{
|
||||||
|
assert(!settings["general"]["language"].String().empty());
|
||||||
return settings["general"]["language"].String();
|
return settings["general"]["language"].String();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CGeneralTextHandler::getInstalledLanguage()
|
std::string CGeneralTextHandler::getInstalledLanguage()
|
||||||
{
|
{
|
||||||
|
assert(!settings["session"]["language"].String().empty());
|
||||||
return settings["session"]["language"].String();
|
return settings["session"]["language"].String();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CGeneralTextHandler::getInstalledEncoding()
|
std::string CGeneralTextHandler::getInstalledEncoding()
|
||||||
{
|
{
|
||||||
|
assert(!settings["session"]["encoding"].String().empty());
|
||||||
return settings["session"]["encoding"].String();
|
return settings["session"]["encoding"].String();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,7 +616,8 @@ bool CModInfo::Version::isNull() const
|
|||||||
|
|
||||||
CModInfo::CModInfo():
|
CModInfo::CModInfo():
|
||||||
checksum(0),
|
checksum(0),
|
||||||
enabled(false),
|
explicitlyEnabled(false),
|
||||||
|
implicitlyEnabled(true),
|
||||||
validation(PENDING)
|
validation(PENDING)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -629,7 +630,8 @@ CModInfo::CModInfo(std::string identifier,const JsonNode & local, const JsonNode
|
|||||||
dependencies(config["depends"].convertTo<std::set<std::string> >()),
|
dependencies(config["depends"].convertTo<std::set<std::string> >()),
|
||||||
conflicts(config["conflicts"].convertTo<std::set<std::string> >()),
|
conflicts(config["conflicts"].convertTo<std::set<std::string> >()),
|
||||||
checksum(0),
|
checksum(0),
|
||||||
enabled(false),
|
explicitlyEnabled(false),
|
||||||
|
implicitlyEnabled(true),
|
||||||
validation(PENDING),
|
validation(PENDING),
|
||||||
config(addMeta(config, identifier))
|
config(addMeta(config, identifier))
|
||||||
{
|
{
|
||||||
@ -654,7 +656,7 @@ JsonNode CModInfo::saveLocalData() const
|
|||||||
stream << std::noshowbase << std::hex << std::setw(8) << std::setfill('0') << checksum;
|
stream << std::noshowbase << std::hex << std::setw(8) << std::setfill('0') << checksum;
|
||||||
|
|
||||||
JsonNode conf;
|
JsonNode conf;
|
||||||
conf["active"].Bool() = enabled;
|
conf["active"].Bool() = explicitlyEnabled;
|
||||||
conf["validated"].Bool() = validation != FAILED;
|
conf["validated"].Bool() = validation != FAILED;
|
||||||
conf["checksum"].String() = stream.str();
|
conf["checksum"].String() = stream.str();
|
||||||
return conf;
|
return conf;
|
||||||
@ -683,33 +685,52 @@ void CModInfo::updateChecksum(ui32 newChecksum)
|
|||||||
void CModInfo::loadLocalData(const JsonNode & data)
|
void CModInfo::loadLocalData(const JsonNode & data)
|
||||||
{
|
{
|
||||||
bool validated = false;
|
bool validated = false;
|
||||||
enabled = true;
|
implicitlyEnabled = true;
|
||||||
|
explicitlyEnabled = true;
|
||||||
checksum = 0;
|
checksum = 0;
|
||||||
if (data.getType() == JsonNode::JsonType::DATA_BOOL)
|
if (data.getType() == JsonNode::JsonType::DATA_BOOL)
|
||||||
{
|
{
|
||||||
enabled = data.Bool();
|
explicitlyEnabled = data.Bool();
|
||||||
}
|
}
|
||||||
if (data.getType() == JsonNode::JsonType::DATA_STRUCT)
|
if (data.getType() == JsonNode::JsonType::DATA_STRUCT)
|
||||||
{
|
{
|
||||||
enabled = data["active"].Bool();
|
explicitlyEnabled = data["active"].Bool();
|
||||||
validated = data["validated"].Bool();
|
validated = data["validated"].Bool();
|
||||||
checksum = strtol(data["checksum"].String().c_str(), nullptr, 16);
|
checksum = strtol(data["checksum"].String().c_str(), nullptr, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
//check compatibility
|
//check compatibility
|
||||||
bool wasEnabled = enabled;
|
implicitlyEnabled &= (vcmiCompatibleMin.isNull() || Version::GameVersion().compatible(vcmiCompatibleMin));
|
||||||
enabled = enabled && (vcmiCompatibleMin.isNull() || Version::GameVersion().compatible(vcmiCompatibleMin));
|
implicitlyEnabled &= (vcmiCompatibleMax.isNull() || vcmiCompatibleMax.compatible(Version::GameVersion()));
|
||||||
enabled = enabled && (vcmiCompatibleMax.isNull() || vcmiCompatibleMax.compatible(Version::GameVersion()));
|
|
||||||
|
|
||||||
if(wasEnabled && !enabled)
|
if(!implicitlyEnabled)
|
||||||
logGlobal->warn("Mod %s is incompatible with current version of VCMI and cannot be enabled", name);
|
logGlobal->warn("Mod %s is incompatible with current version of VCMI and cannot be enabled", name);
|
||||||
|
|
||||||
if (enabled)
|
if (boost::iequals(config["modType"].String(), "translation")) // compatibility code - mods use "Translation" type at the moment
|
||||||
|
{
|
||||||
|
if (baseLanguage != VLC->generaltexth->getPreferredLanguage())
|
||||||
|
{
|
||||||
|
logGlobal->warn("Translation mod %s was not loaded: language mismatch!", name);
|
||||||
|
implicitlyEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEnabled())
|
||||||
validation = validated ? PASSED : PENDING;
|
validation = validated ? PASSED : PENDING;
|
||||||
else
|
else
|
||||||
validation = validated ? PASSED : FAILED;
|
validation = validated ? PASSED : FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CModInfo::isEnabled() const
|
||||||
|
{
|
||||||
|
return implicitlyEnabled && explicitlyEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CModInfo::setEnabled(bool on)
|
||||||
|
{
|
||||||
|
explicitlyEnabled = on;
|
||||||
|
}
|
||||||
|
|
||||||
CModHandler::CModHandler() : content(std::make_shared<CContentHandler>())
|
CModHandler::CModHandler() : content(std::make_shared<CContentHandler>())
|
||||||
{
|
{
|
||||||
modules.COMMANDERS = false;
|
modules.COMMANDERS = false;
|
||||||
@ -820,36 +841,6 @@ bool CModHandler::hasCircularDependency(TModID modID, std::set <TModID> currentL
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CModHandler::checkDependencies(const std::vector <TModID> & input) const
|
|
||||||
{
|
|
||||||
for(const TModID & id : input)
|
|
||||||
{
|
|
||||||
const CModInfo & mod = allMods.at(id);
|
|
||||||
|
|
||||||
for(const TModID & dep : mod.dependencies)
|
|
||||||
{
|
|
||||||
if(!vstd::contains(input, dep))
|
|
||||||
{
|
|
||||||
logMod->error("Error: Mod %s requires missing %s!", mod.name, dep);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(const TModID & conflicting : mod.conflicts)
|
|
||||||
{
|
|
||||||
if(vstd::contains(input, conflicting))
|
|
||||||
{
|
|
||||||
logMod->error("Error: Mod %s conflicts with %s!", mod.name, allMods.at(conflicting).name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hasCircularDependency(id))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returned vector affects the resource loaders call order (see CFilesystemList::load).
|
// Returned vector affects the resource loaders call order (see CFilesystemList::load).
|
||||||
// The loaders call order matters when dependent mod overrides resources in its dependencies.
|
// The loaders call order matters when dependent mod overrides resources in its dependencies.
|
||||||
std::vector <TModID> CModHandler::validateAndSortDependencies(std::vector <TModID> modsToResolve) const
|
std::vector <TModID> CModHandler::validateAndSortDependencies(std::vector <TModID> modsToResolve) const
|
||||||
@ -995,10 +986,10 @@ void CModHandler::loadOneMod(std::string modName, std::string parent, const Json
|
|||||||
mod.dependencies.insert(parent);
|
mod.dependencies.insert(parent);
|
||||||
|
|
||||||
allMods[modFullName] = mod;
|
allMods[modFullName] = mod;
|
||||||
if (mod.enabled && enableMods)
|
if (mod.isEnabled() && enableMods)
|
||||||
activeMods.push_back(modFullName);
|
activeMods.push_back(modFullName);
|
||||||
|
|
||||||
loadMods(CModInfo::getModDir(modFullName) + '/', modFullName, modSettings[modName]["mods"], enableMods && mod.enabled);
|
loadMods(CModInfo::getModDir(modFullName) + '/', modFullName, modSettings[modName]["mods"], enableMods && mod.isEnabled());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1087,6 +1078,8 @@ static ui32 calculateModChecksum(const std::string modName, ISimpleResourceLoade
|
|||||||
|
|
||||||
void CModHandler::loadModFilesystems()
|
void CModHandler::loadModFilesystems()
|
||||||
{
|
{
|
||||||
|
CGeneralTextHandler::detectInstallParameters();
|
||||||
|
|
||||||
activeMods = validateAndSortDependencies(activeMods);
|
activeMods = validateAndSortDependencies(activeMods);
|
||||||
|
|
||||||
coreMod.updateChecksum(calculateModChecksum(CModHandler::scopeBuiltin(), CResourceHandler::get(CModHandler::scopeBuiltin())));
|
coreMod.updateChecksum(calculateModChecksum(CModHandler::scopeBuiltin(), CResourceHandler::get(CModHandler::scopeBuiltin())));
|
||||||
@ -1109,6 +1102,9 @@ TModID CModHandler::findResourceOrigin(const ResourceID & name)
|
|||||||
if(CResourceHandler::get("core")->existsResource(name))
|
if(CResourceHandler::get("core")->existsResource(name))
|
||||||
return "core";
|
return "core";
|
||||||
|
|
||||||
|
if(CResourceHandler::get("mapEditor")->existsResource(name))
|
||||||
|
return "core"; // Workaround for loading maps via map editor
|
||||||
|
|
||||||
assert(0);
|
assert(0);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -236,9 +236,6 @@ public:
|
|||||||
/// CRC-32 checksum of the mod
|
/// CRC-32 checksum of the mod
|
||||||
ui32 checksum;
|
ui32 checksum;
|
||||||
|
|
||||||
/// true if mod is enabled
|
|
||||||
bool enabled;
|
|
||||||
|
|
||||||
EValidationStatus validation;
|
EValidationStatus validation;
|
||||||
|
|
||||||
JsonNode config;
|
JsonNode config;
|
||||||
@ -249,10 +246,19 @@ public:
|
|||||||
JsonNode saveLocalData() const;
|
JsonNode saveLocalData() const;
|
||||||
void updateChecksum(ui32 newChecksum);
|
void updateChecksum(ui32 newChecksum);
|
||||||
|
|
||||||
|
bool isEnabled() const;
|
||||||
|
void setEnabled(bool on);
|
||||||
|
|
||||||
static std::string getModDir(std::string name);
|
static std::string getModDir(std::string name);
|
||||||
static std::string getModFile(std::string name);
|
static std::string getModFile(std::string name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// true if mod is enabled by user, e.g. in Launcher UI
|
||||||
|
bool explicitlyEnabled;
|
||||||
|
|
||||||
|
/// true if mod can be loaded - compatible and has no missing deps
|
||||||
|
bool implicitlyEnabled;
|
||||||
|
|
||||||
void loadLocalData(const JsonNode & data);
|
void loadLocalData(const JsonNode & data);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -266,12 +272,6 @@ class DLL_LINKAGE CModHandler
|
|||||||
|
|
||||||
bool hasCircularDependency(TModID mod, std::set <TModID> currentList = std::set <TModID>()) const;
|
bool hasCircularDependency(TModID mod, std::set <TModID> currentList = std::set <TModID>()) const;
|
||||||
|
|
||||||
//returns false if mod list is incorrect and prints error to console. Possible errors are:
|
|
||||||
// - missing dependency mod
|
|
||||||
// - conflicting mod in load order
|
|
||||||
// - circular dependencies
|
|
||||||
bool checkDependencies(const std::vector <TModID> & input) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1. Set apart mods with resolved dependencies from mods which have unresolved dependencies
|
* 1. Set apart mods with resolved dependencies from mods which have unresolved dependencies
|
||||||
* 2. Sort resolved mods using topological algorithm
|
* 2. Sort resolved mods using topological algorithm
|
||||||
@ -449,7 +449,7 @@ public:
|
|||||||
h & mver;
|
h & mver;
|
||||||
|
|
||||||
if(allMods.count(m) && (allMods[m].version.isNull() || mver.isNull() || allMods[m].version.compatible(mver)))
|
if(allMods.count(m) && (allMods[m].version.isNull() || mver.isNull() || allMods[m].version.compatible(mver)))
|
||||||
allMods[m].enabled = true;
|
allMods[m].setEnabled(true);
|
||||||
else
|
else
|
||||||
missingMods.emplace_back(m, mver.toString());
|
missingMods.emplace_back(m, mver.toString());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "CHeroHandler.h"
|
#include "CHeroHandler.h"
|
||||||
#include "mapObjects/CObjectHandler.h"
|
#include "mapObjects/CObjectHandler.h"
|
||||||
#include "CTownHandler.h"
|
#include "CTownHandler.h"
|
||||||
|
#include "CConfigHandler.h"
|
||||||
#include "RoadHandler.h"
|
#include "RoadHandler.h"
|
||||||
#include "RiverHandler.h"
|
#include "RiverHandler.h"
|
||||||
#include "TerrainHandler.h"
|
#include "TerrainHandler.h"
|
||||||
@ -48,7 +49,9 @@ DLL_LINKAGE void preinitDLL(CConsoleHandler * Console, bool onlyEssential, bool
|
|||||||
VLC = new LibClasses();
|
VLC = new LibClasses();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
VLC->loadFilesystem(onlyEssential, extractArchives);
|
VLC->loadFilesystem(extractArchives);
|
||||||
|
settings.init();
|
||||||
|
VLC->loadModFilesystem(onlyEssential);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -160,9 +163,8 @@ void LibClasses::updateEntity(Metatype metatype, int32_t index, const JsonNode &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibClasses::loadFilesystem(bool onlyEssential, bool extractArchives)
|
void LibClasses::loadFilesystem(bool extractArchives)
|
||||||
{
|
{
|
||||||
CStopWatch totalTime;
|
|
||||||
CStopWatch loadTime;
|
CStopWatch loadTime;
|
||||||
|
|
||||||
CResourceHandler::initialize();
|
CResourceHandler::initialize();
|
||||||
@ -170,15 +172,17 @@ void LibClasses::loadFilesystem(bool onlyEssential, bool extractArchives)
|
|||||||
|
|
||||||
CResourceHandler::load("config/filesystem.json", extractArchives);
|
CResourceHandler::load("config/filesystem.json", extractArchives);
|
||||||
logGlobal->info("\tData loading: %d ms", loadTime.getDiff());
|
logGlobal->info("\tData loading: %d ms", loadTime.getDiff());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibClasses::loadModFilesystem(bool onlyEssential)
|
||||||
|
{
|
||||||
|
CStopWatch loadTime;
|
||||||
modh = new CModHandler();
|
modh = new CModHandler();
|
||||||
|
modh->loadMods(onlyEssential);
|
||||||
logGlobal->info("\tMod handler: %d ms", loadTime.getDiff());
|
logGlobal->info("\tMod handler: %d ms", loadTime.getDiff());
|
||||||
|
|
||||||
modh->loadMods(onlyEssential);
|
|
||||||
modh->loadModFilesystems();
|
modh->loadModFilesystems();
|
||||||
logGlobal->info("\tMod filesystems: %d ms", loadTime.getDiff());
|
logGlobal->info("\tMod filesystems: %d ms", loadTime.getDiff());
|
||||||
|
|
||||||
logGlobal->info("Basic initialization: %d ms", totalTime.getDiff());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void logHandlerLoaded(const std::string & name, CStopWatch & timer)
|
static void logHandlerLoaded(const std::string & name, CStopWatch & timer)
|
||||||
|
@ -107,7 +107,8 @@ public:
|
|||||||
void clear(); //deletes all handlers and its data
|
void clear(); //deletes all handlers and its data
|
||||||
|
|
||||||
// basic initialization. should be called before init(). Can also extract original H3 archives
|
// basic initialization. should be called before init(). Can also extract original H3 archives
|
||||||
void loadFilesystem(bool onlyEssential, bool extractArchives = false);
|
void loadFilesystem(bool extractArchives);
|
||||||
|
void loadModFilesystem(bool onlyEssential);
|
||||||
|
|
||||||
#if SCRIPTING_ENABLED
|
#if SCRIPTING_ENABLED
|
||||||
void scriptsLoaded();
|
void scriptsLoaded();
|
||||||
|
@ -170,7 +170,6 @@ MainWindow::MainWindow(QWidget* parent) :
|
|||||||
|
|
||||||
//init
|
//init
|
||||||
preinitDLL(::console, false, extractionOptions.extractArchives);
|
preinitDLL(::console, false, extractionOptions.extractArchives);
|
||||||
settings.init();
|
|
||||||
|
|
||||||
// Initialize logging based on settings
|
// Initialize logging based on settings
|
||||||
logConfig->configure();
|
logConfig->configure();
|
||||||
|
@ -1117,7 +1117,6 @@ int main(int argc, const char * argv[])
|
|||||||
boost::program_options::variables_map opts;
|
boost::program_options::variables_map opts;
|
||||||
handleCommandOptions(argc, argv, opts);
|
handleCommandOptions(argc, argv, opts);
|
||||||
preinitDLL(console);
|
preinitDLL(console);
|
||||||
settings.init();
|
|
||||||
logConfig.configure();
|
logConfig.configure();
|
||||||
|
|
||||||
loadDLLClasses();
|
loadDLLClasses();
|
||||||
|
Loading…
Reference in New Issue
Block a user