mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Minor refactoring of translations:
- removed unsuccessful and broken validation of translations - pass JsonNode when registering strings to provide information on mod source
This commit is contained in:
		| @@ -431,9 +431,9 @@ std::shared_ptr<CArtifact> CArtHandler::loadFromJson(const std::string & scope, | ||||
|  | ||||
| 	const JsonNode & text = node["text"]; | ||||
|  | ||||
| 	VLC->generaltexth->registerString(scope, art->getNameTextID(), text["name"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, art->getDescriptionTextID(), text["description"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, art->getEventTextID(), text["event"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, art->getNameTextID(), text["name"]); | ||||
| 	VLC->generaltexth->registerString(scope, art->getDescriptionTextID(), text["description"]); | ||||
| 	VLC->generaltexth->registerString(scope, art->getEventTextID(), text["event"]); | ||||
|  | ||||
| 	const JsonNode & graphics = node["graphics"]; | ||||
| 	art->image = graphics["image"].String(); | ||||
|   | ||||
| @@ -240,8 +240,8 @@ void CBonusTypeHandler::loadItem(const JsonNode & source, CBonusType & dest, con | ||||
|  | ||||
| 	if (!dest.hidden) | ||||
| 	{ | ||||
| 		VLC->generaltexth->registerString( "vcmi", dest.getNameTextID(), source["name"].String()); | ||||
| 		VLC->generaltexth->registerString( "vcmi", dest.getDescriptionTextID(), source["description"].String()); | ||||
| 		VLC->generaltexth->registerString( "vcmi", dest.getNameTextID(), source["name"]); | ||||
| 		VLC->generaltexth->registerString( "vcmi", dest.getDescriptionTextID(), source["description"]); | ||||
| 	} | ||||
|  | ||||
| 	const JsonNode & graphics = source["graphics"]; | ||||
|   | ||||
| @@ -617,9 +617,9 @@ std::shared_ptr<CCreature> CCreatureHandler::loadFromJson(const std::string & sc | ||||
|  | ||||
| 	cre->cost = ResourceSet(node["cost"]); | ||||
|  | ||||
| 	VLC->generaltexth->registerString(scope, cre->getNameSingularTextID(), node["name"]["singular"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, cre->getNamePluralTextID(), node["name"]["plural"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, cre->getDescriptionTextID(), node["description"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, cre->getNameSingularTextID(), node["name"]["singular"]); | ||||
| 	VLC->generaltexth->registerString(scope, cre->getNamePluralTextID(), node["name"]["plural"]); | ||||
| 	VLC->generaltexth->registerString(scope, cre->getDescriptionTextID(), node["description"]); | ||||
|  | ||||
| 	cre->addBonus(node["hitPoints"].Integer(), BonusType::STACK_HEALTH); | ||||
| 	cre->addBonus(node["speed"].Integer(), BonusType::STACKS_SPEED); | ||||
|   | ||||
| @@ -459,11 +459,11 @@ std::shared_ptr<CHero> CHeroHandler::loadFromJson(const std::string & scope, con | ||||
| 	hero->onlyOnWaterMap = node["onlyOnWaterMap"].Bool(); | ||||
| 	hero->onlyOnMapWithoutWater = node["onlyOnMapWithoutWater"].Bool(); | ||||
|  | ||||
| 	VLC->generaltexth->registerString(scope, hero->getNameTextID(), node["texts"]["name"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, hero->getBiographyTextID(), node["texts"]["biography"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, hero->getSpecialtyNameTextID(), node["texts"]["specialty"]["name"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, hero->getSpecialtyTooltipTextID(), node["texts"]["specialty"]["tooltip"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, hero->getSpecialtyDescriptionTextID(), node["texts"]["specialty"]["description"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, hero->getNameTextID(), node["texts"]["name"]); | ||||
| 	VLC->generaltexth->registerString(scope, hero->getBiographyTextID(), node["texts"]["biography"]); | ||||
| 	VLC->generaltexth->registerString(scope, hero->getSpecialtyNameTextID(), node["texts"]["specialty"]["name"]); | ||||
| 	VLC->generaltexth->registerString(scope, hero->getSpecialtyTooltipTextID(), node["texts"]["specialty"]["tooltip"]); | ||||
| 	VLC->generaltexth->registerString(scope, hero->getSpecialtyDescriptionTextID(), node["texts"]["specialty"]["description"]); | ||||
|  | ||||
| 	hero->iconSpecSmall = node["images"]["specialtySmall"].String(); | ||||
| 	hero->iconSpecLarge = node["images"]["specialtyLarge"].String(); | ||||
|   | ||||
| @@ -212,7 +212,7 @@ std::shared_ptr<CSkill> CSkillHandler::loadFromJson(const std::string & scope, c | ||||
|  | ||||
| 	skill->onlyOnWaterMap = json["onlyOnWaterMap"].Bool(); | ||||
|  | ||||
| 	VLC->generaltexth->registerString(scope, skill->getNameTextID(), json["name"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, skill->getNameTextID(), json["name"]); | ||||
| 	switch(json["gainChance"].getType()) | ||||
| 	{ | ||||
| 	case JsonNode::JsonType::DATA_INTEGER: | ||||
| @@ -237,7 +237,7 @@ std::shared_ptr<CSkill> CSkillHandler::loadFromJson(const std::string & scope, c | ||||
| 			skill->addNewBonus(bonus, level); | ||||
| 		} | ||||
| 		CSkill::LevelInfo & skillAtLevel = skill->at(level); | ||||
| 		VLC->generaltexth->registerString(scope, skill->getDescriptionTextID(level), levelNode["description"].String()); | ||||
| 		VLC->generaltexth->registerString(scope, skill->getDescriptionTextID(level), levelNode["description"]); | ||||
| 		skillAtLevel.iconSmall = levelNode["images"]["small"].String(); | ||||
| 		skillAtLevel.iconMedium = levelNode["images"]["medium"].String(); | ||||
| 		skillAtLevel.iconLarge = levelNode["images"]["large"].String(); | ||||
|   | ||||
| @@ -50,7 +50,7 @@ std::shared_ptr<RiverType> RiverTypeHandler::loadFromJson( | ||||
| 		info->paletteAnimation.push_back(element); | ||||
| 	} | ||||
|  | ||||
| 	VLC->generaltexth->registerString(scope, info->getNameTextID(), json["text"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, info->getNameTextID(), json["text"]); | ||||
|  | ||||
| 	return info; | ||||
| } | ||||
|   | ||||
| @@ -41,7 +41,7 @@ std::shared_ptr<RoadType> RoadTypeHandler::loadFromJson( | ||||
| 	info->shortIdentifier = json["shortIdentifier"].String(); | ||||
| 	info->movementCost    = json["moveCost"].Integer(); | ||||
|  | ||||
| 	VLC->generaltexth->registerString(scope,info->getNameTextID(), json["text"].String()); | ||||
| 	VLC->generaltexth->registerString(scope,info->getNameTextID(), json["text"]); | ||||
|  | ||||
| 	return info; | ||||
| } | ||||
|   | ||||
| @@ -45,7 +45,7 @@ std::shared_ptr<TerrainType> TerrainTypeHandler::loadFromJson( const std::string | ||||
| 	info->transitionRequired = json["transitionRequired"].Bool(); | ||||
| 	info->terrainViewPatterns = json["terrainViewPatterns"].String(); | ||||
|  | ||||
| 	VLC->generaltexth->registerString(scope, info->getNameTextID(), json["text"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, info->getNameTextID(), json["text"]); | ||||
|  | ||||
| 	const JsonVector & unblockedVec = json["minimapUnblocked"].Vector(); | ||||
| 	info->minimapUnblocked = | ||||
|   | ||||
| @@ -292,8 +292,8 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons | ||||
| 	ret->modScope = source.getModScope(); | ||||
| 	ret->town = town; | ||||
|  | ||||
| 	VLC->generaltexth->registerString(source.getModScope(), ret->getNameTextID(), source["name"].String()); | ||||
| 	VLC->generaltexth->registerString(source.getModScope(), ret->getDescriptionTextID(), source["description"].String()); | ||||
| 	VLC->generaltexth->registerString(source.getModScope(), ret->getNameTextID(), source["name"]); | ||||
| 	VLC->generaltexth->registerString(source.getModScope(), ret->getDescriptionTextID(), source["description"]); | ||||
|  | ||||
| 	ret->subId = vstd::find_or(MappedKeys::SPECIAL_BUILDINGS, source["type"].String(), BuildingSubID::NONE); | ||||
| 	ret->resources = TResources(source["cost"]); | ||||
| @@ -603,7 +603,7 @@ void CTownHandler::loadTown(CTown * town, const JsonNode & source) | ||||
| 	town->namesCount = 0; | ||||
| 	for(const auto & name : source["names"].Vector()) | ||||
| 	{ | ||||
| 		VLC->generaltexth->registerString(town->faction->modScope, town->getRandomNameTextID(town->namesCount), name.String()); | ||||
| 		VLC->generaltexth->registerString(town->faction->modScope, town->getRandomNameTextID(town->namesCount), name); | ||||
| 		town->namesCount += 1; | ||||
| 	} | ||||
|  | ||||
| @@ -718,8 +718,8 @@ std::shared_ptr<CFaction> CTownHandler::loadFromJson(const std::string & scope, | ||||
| 	faction->modScope = scope; | ||||
| 	faction->identifier = identifier; | ||||
|  | ||||
| 	VLC->generaltexth->registerString(scope, faction->getNameTextID(), source["name"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, faction->getDescriptionTextID(), source["description"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, faction->getNameTextID(), source["name"]); | ||||
| 	VLC->generaltexth->registerString(scope, faction->getDescriptionTextID(), source["description"]); | ||||
|  | ||||
| 	faction->creatureBg120 = ImagePath::fromJson(source["creatureBackground"]["120px"]); | ||||
| 	faction->creatureBg130 = ImagePath::fromJson(source["creatureBackground"]["130px"]); | ||||
|   | ||||
| @@ -28,7 +28,7 @@ void CBankInstanceConstructor::initTypeData(const JsonNode & input) | ||||
| 	if (input.Struct().count("name") == 0) | ||||
| 		logMod->warn("Bank %s missing name!", getJsonKey()); | ||||
|  | ||||
| 	VLC->generaltexth->registerString(input.getModScope(), getNameTextID(), input["name"].String()); | ||||
| 	VLC->generaltexth->registerString(input.getModScope(), getNameTextID(), input["name"]); | ||||
|  | ||||
| 	levels = input["levels"].Vector(); | ||||
| 	bankResetDuration = static_cast<si32>(input["resetDuration"].Float()); | ||||
|   | ||||
| @@ -278,7 +278,7 @@ std::unique_ptr<ObjectClass> CObjectClassesHandler::loadFromJson(const std::stri | ||||
| 	newObject->base = json["base"]; | ||||
| 	newObject->id = index; | ||||
|  | ||||
| 	VLC->generaltexth->registerString(scope, newObject->getNameTextID(), json["name"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, newObject->getNameTextID(), json["name"]); | ||||
|  | ||||
| 	newObject->objectTypeHandlers.resize(json["lastReservedIndex"].Float() + 1); | ||||
|  | ||||
|   | ||||
| @@ -23,7 +23,7 @@ void CRewardableConstructor::initTypeData(const JsonNode & config) | ||||
| 	blockVisit = config["blockedVisitable"].Bool(); | ||||
|  | ||||
| 	if (!config["name"].isNull()) | ||||
| 		VLC->generaltexth->registerString( config.getModScope(), getNameTextID(), config["name"].String()); | ||||
| 		VLC->generaltexth->registerString( config.getModScope(), getNameTextID(), config["name"]); | ||||
|  | ||||
| 	JsonUtils::validate(config, "vcmi:rewardable", getJsonKey()); | ||||
| 	 | ||||
|   | ||||
| @@ -29,7 +29,7 @@ void DwellingInstanceConstructor::initTypeData(const JsonNode & input) | ||||
| 	if (input.Struct().count("name") == 0) | ||||
| 		logMod->warn("Dwelling %s missing name!", getJsonKey()); | ||||
|  | ||||
| 	VLC->generaltexth->registerString( input.getModScope(), getNameTextID(), input["name"].String()); | ||||
| 	VLC->generaltexth->registerString( input.getModScope(), getNameTextID(), input["name"]); | ||||
|  | ||||
| 	const JsonVector & levels = input["creatures"].Vector(); | ||||
| 	const auto totalLevels = levels.size(); | ||||
|   | ||||
| @@ -401,33 +401,6 @@ CModVersion CModHandler::getModVersion(TModID modName) const | ||||
| 	return {}; | ||||
| } | ||||
|  | ||||
| bool CModHandler::validateTranslations(TModID modName) const | ||||
| { | ||||
| 	bool result = true; | ||||
| 	const auto & mod = allMods.at(modName); | ||||
|  | ||||
| 	{ | ||||
| 		auto fileList = mod.config["translations"].convertTo<std::vector<std::string> >(); | ||||
| 		JsonNode json = JsonUtils::assembleFromFiles(fileList); | ||||
| 		result |= VLC->generaltexth->validateTranslation(mod.baseLanguage, modName, json); | ||||
| 	} | ||||
|  | ||||
| 	for(const auto & language : Languages::getLanguageList()) | ||||
| 	{ | ||||
| 		if (mod.config[language.identifier].isNull()) | ||||
| 			continue; | ||||
|  | ||||
| 		if (mod.config[language.identifier]["skipValidation"].Bool()) | ||||
| 			continue; | ||||
|  | ||||
| 		auto fileList = mod.config[language.identifier]["translations"].convertTo<std::vector<std::string> >(); | ||||
| 		JsonNode json = JsonUtils::assembleFromFiles(fileList); | ||||
| 		result |= VLC->generaltexth->validateTranslation(language.identifier, modName, json); | ||||
| 	} | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| void CModHandler::loadTranslation(const TModID & modName) | ||||
| { | ||||
| 	const auto & mod = allMods[modName]; | ||||
| @@ -441,8 +414,8 @@ void CModHandler::loadTranslation(const TModID & modName) | ||||
| 	JsonNode baseTranslation = JsonUtils::assembleFromFiles(baseTranslationList); | ||||
| 	JsonNode extraTranslation = JsonUtils::assembleFromFiles(extraTranslationList); | ||||
|  | ||||
| 	VLC->generaltexth->loadTranslationOverrides(modBaseLanguage, modName, baseTranslation); | ||||
| 	VLC->generaltexth->loadTranslationOverrides(preferredLanguage, modName, extraTranslation); | ||||
| 	VLC->generaltexth->loadTranslationOverrides(modName, baseTranslation); | ||||
| 	VLC->generaltexth->loadTranslationOverrides(modName, extraTranslation); | ||||
| } | ||||
|  | ||||
| void CModHandler::load() | ||||
| @@ -480,12 +453,6 @@ void CModHandler::load() | ||||
| 	for(const TModID & modName : activeMods) | ||||
| 		loadTranslation(modName); | ||||
|  | ||||
| #if 0 | ||||
| 	for(const TModID & modName : activeMods) | ||||
| 		if (!validateTranslations(modName)) | ||||
| 			allMods[modName].validation = CModInfo::FAILED; | ||||
| #endif | ||||
|  | ||||
| 	logMod->info("\tLoading mod data: %d ms", timer.getDiff()); | ||||
| 	VLC->creh->loadCrExpMod(); | ||||
| 	VLC->identifiersHandler->finalize(); | ||||
|   | ||||
| @@ -49,8 +49,6 @@ class DLL_LINKAGE CModHandler final : boost::noncopyable | ||||
| 	void loadOneMod(std::string modName, const std::string & parent, const JsonNode & modSettings, bool enableMods); | ||||
| 	void loadTranslation(const TModID & modName); | ||||
|  | ||||
| 	bool validateTranslations(TModID modName) const; | ||||
|  | ||||
| 	CModVersion getModVersion(TModID modName) const; | ||||
|  | ||||
| public: | ||||
|   | ||||
| @@ -76,7 +76,7 @@ void Rewardable::Info::init(const JsonNode & objectConfig, const std::string & o | ||||
|  | ||||
| 	auto loadString = [&](const JsonNode & entry, const TextIdentifier & textID){ | ||||
| 		if (entry.isString() && !entry.String().empty() && entry.String()[0] != '@') | ||||
| 			VLC->generaltexth->registerString(entry.getModScope(), textID, entry.String()); | ||||
| 			VLC->generaltexth->registerString(entry.getModScope(), textID, entry); | ||||
| 	}; | ||||
|  | ||||
| 	parameters = objectConfig; | ||||
|   | ||||
| @@ -783,7 +783,7 @@ std::shared_ptr<CSpell> CSpellHandler::loadFromJson(const std::string & scope, c | ||||
| 		spell->combat = type == "combat"; | ||||
| 	} | ||||
|  | ||||
| 	VLC->generaltexth->registerString(scope, spell->getNameTextID(), json["name"].String()); | ||||
| 	VLC->generaltexth->registerString(scope, spell->getNameTextID(), json["name"]); | ||||
|  | ||||
| 	logMod->trace("%s: loading spell %s", __FUNCTION__, spell->getNameTranslated()); | ||||
|  | ||||
| @@ -1005,7 +1005,7 @@ std::shared_ptr<CSpell> CSpellHandler::loadFromJson(const std::string & scope, c | ||||
| 		const si32 levelPower     = levelObject.power = static_cast<si32>(levelNode["power"].Integer()); | ||||
|  | ||||
| 		if (!spell->isCreatureAbility()) | ||||
| 			VLC->generaltexth->registerString(scope, spell->getDescriptionTextID(levelIndex), levelNode["description"].String()); | ||||
| 			VLC->generaltexth->registerString(scope, spell->getDescriptionTextID(levelIndex), levelNode["description"]); | ||||
|  | ||||
| 		levelObject.cost          = static_cast<si32>(levelNode["cost"].Integer()); | ||||
| 		levelObject.AIValue       = static_cast<si32>(levelNode["aiValue"].Integer()); | ||||
|   | ||||
| @@ -22,17 +22,15 @@ VCMI_LIB_NAMESPACE_BEGIN | ||||
|  | ||||
| std::recursive_mutex TextLocalizationContainer::globalTextMutex; | ||||
|  | ||||
| void TextLocalizationContainer::registerStringOverride(const std::string & modContext, const std::string & language, const TextIdentifier & UID, const std::string & localized) | ||||
| void TextLocalizationContainer::registerStringOverride(const std::string & modContext, const TextIdentifier & UID, const std::string & localized) | ||||
| { | ||||
| 	std::lock_guard globalLock(globalTextMutex); | ||||
|  | ||||
| 	assert(!modContext.empty()); | ||||
| 	assert(!language.empty()); | ||||
|  | ||||
| 	// NOTE: implicitly creates entry, intended - strings added by maps, campaigns, vcmi and potentially - UI mods are not registered anywhere at the moment | ||||
| 	auto & entry = stringsLocalizations[UID.get()]; | ||||
|  | ||||
| 	entry.overrideLanguage = language; | ||||
| 	entry.overrideValue = localized; | ||||
| 	if (entry.modContext.empty()) | ||||
| 		entry.modContext = modContext; | ||||
| @@ -76,6 +74,15 @@ const std::string & TextLocalizationContainer::deserialize(const TextIdentifier | ||||
| 	return entry.baseValue; | ||||
| } | ||||
|  | ||||
| void TextLocalizationContainer::registerString(const std::string & modContext, const TextIdentifier & inputUID, const JsonNode & localized) | ||||
| { | ||||
| 	assert(!localized.getModScope().empty()); | ||||
| 	assert(!getModLanguage(localized.getModScope()).empty()); | ||||
|  | ||||
| 	std::lock_guard globalLock(globalTextMutex); | ||||
| 	registerString(modContext, inputUID, localized.String(), getModLanguage(modContext)); | ||||
| } | ||||
|  | ||||
| void TextLocalizationContainer::registerString(const std::string & modContext, const TextIdentifier & UID, const std::string & localized, const std::string & language) | ||||
| { | ||||
| 	std::lock_guard globalLock(globalTextMutex); | ||||
| @@ -88,13 +95,11 @@ void TextLocalizationContainer::registerString(const std::string & modContext, c | ||||
| 	if(stringsLocalizations.count(UID.get()) > 0) | ||||
| 	{ | ||||
| 		auto & value = stringsLocalizations[UID.get()]; | ||||
| 		value.baseLanguage = language; | ||||
| 		value.baseValue = localized; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		StringState value; | ||||
| 		value.baseLanguage = language; | ||||
| 		value.baseValue = localized; | ||||
| 		value.modContext = modContext; | ||||
|  | ||||
| @@ -108,63 +113,10 @@ void TextLocalizationContainer::registerString(const std::string & modContext, c | ||||
| 	registerString(modContext, UID, localized, getModLanguage(modContext)); | ||||
| } | ||||
|  | ||||
| bool TextLocalizationContainer::validateTranslation(const std::string & language, const std::string & modContext, const JsonNode & config) const | ||||
| { | ||||
| 	std::lock_guard globalLock(globalTextMutex); | ||||
|  | ||||
| 	bool allPresent = true; | ||||
|  | ||||
| 	for(const auto & string : stringsLocalizations) | ||||
| 	{ | ||||
| 		if (string.second.modContext != modContext) | ||||
| 			continue; // Not our mod | ||||
|  | ||||
| 		if (string.second.overrideLanguage == language) | ||||
| 			continue; // Already translated | ||||
|  | ||||
| 		if (string.second.baseLanguage == language && !string.second.baseValue.empty()) | ||||
| 			continue; // Base string already uses our language | ||||
|  | ||||
| 		if (string.second.baseLanguage.empty()) | ||||
| 			continue; // String added in localization, not present in base language (e.g. maps/campaigns) | ||||
|  | ||||
| 		if (config.Struct().count(string.first) > 0) | ||||
| 			continue; | ||||
|  | ||||
| 		if (allPresent) | ||||
| 			logMod->warn("Translation into language '%s' in mod '%s' is incomplete! Missing lines:", language, modContext); | ||||
|  | ||||
| 		std::string currentText; | ||||
| 		if (string.second.overrideValue.empty()) | ||||
| 			currentText = string.second.baseValue; | ||||
| 		else | ||||
| 			currentText = string.second.overrideValue; | ||||
|  | ||||
| 		logMod->warn(R"(    "%s" : "%s",)", string.first, TextOperations::escapeString(currentText)); | ||||
| 		allPresent = false; | ||||
| 	} | ||||
|  | ||||
| 	bool allFound = true; | ||||
|  | ||||
| 	//	for(const auto & string : config.Struct()) | ||||
| 	//	{ | ||||
| 	//		if (stringsLocalizations.count(string.first) > 0) | ||||
| 	//			continue; | ||||
| 	// | ||||
| 	//		if (allFound) | ||||
| 	//			logMod->warn("Translation into language '%s' in mod '%s' has unused lines:", language, modContext); | ||||
| 	// | ||||
| 	//		logMod->warn(R"(    "%s" : "%s",)", string.first, TextOperations::escapeString(string.second.String())); | ||||
| 	//		allFound = false; | ||||
| 	//	} | ||||
|  | ||||
| 	return allPresent && allFound; | ||||
| } | ||||
|  | ||||
| void TextLocalizationContainer::loadTranslationOverrides(const std::string & language, const std::string & modContext, const JsonNode & config) | ||||
| void TextLocalizationContainer::loadTranslationOverrides(const std::string & modContext, const JsonNode & config) | ||||
| { | ||||
| 	for(const auto & node : config.Struct()) | ||||
| 		registerStringOverride(modContext, language, node.first, node.second.String()); | ||||
| 		registerStringOverride(modContext, node.first, node.second.String()); | ||||
| } | ||||
|  | ||||
| bool TextLocalizationContainer::identifierExists(const TextIdentifier & UID) const | ||||
|   | ||||
| @@ -25,15 +25,9 @@ protected: | ||||
| 		/// Human-readable string that was added on registration | ||||
| 		std::string baseValue; | ||||
|  | ||||
| 		/// Language of base string | ||||
| 		std::string baseLanguage; | ||||
|  | ||||
| 		/// Translated human-readable string | ||||
| 		std::string overrideValue; | ||||
|  | ||||
| 		/// Language of the override string | ||||
| 		std::string overrideLanguage; | ||||
|  | ||||
| 		/// ID of mod that created this string | ||||
| 		std::string modContext; | ||||
|  | ||||
| @@ -41,7 +35,7 @@ protected: | ||||
| 		void serialize(Handler & h) | ||||
| 		{ | ||||
| 			h & baseValue; | ||||
| 			h & baseLanguage; | ||||
| 			//h & baseLanguage; | ||||
| 			h & modContext; | ||||
| 		} | ||||
| 	}; | ||||
| @@ -52,7 +46,7 @@ protected: | ||||
| 	std::vector<const TextLocalizationContainer *> subContainers; | ||||
|  | ||||
| 	/// add selected string to internal storage as high-priority strings | ||||
| 	void registerStringOverride(const std::string & modContext, const std::string & language, const TextIdentifier & UID, const std::string & localized); | ||||
| 	void registerStringOverride(const std::string & modContext, const TextIdentifier & UID, const std::string & localized); | ||||
|  | ||||
| 	std::string getModLanguage(const std::string & modContext); | ||||
|  | ||||
| @@ -60,16 +54,12 @@ protected: | ||||
| 	bool identifierExists(const TextIdentifier & UID) const; | ||||
|  | ||||
| public: | ||||
| 	/// validates translation of specified language for specified mod | ||||
| 	/// returns true if localization is valid and complete | ||||
| 	/// any error messages will be written to log file | ||||
| 	bool validateTranslation(const std::string & language, const std::string & modContext, JsonNode const & file) const; | ||||
|  | ||||
| 	/// Loads translation from provided json | ||||
| 	/// Any entries loaded by this will have priority over texts registered normally | ||||
| 	void loadTranslationOverrides(const std::string & language, const std::string & modContext, JsonNode const & file); | ||||
| 	void loadTranslationOverrides(const std::string & modContext, JsonNode const & file); | ||||
|  | ||||
| 	/// add selected string to internal storage | ||||
| 	void registerString(const std::string & modContext, const TextIdentifier & UID, const JsonNode & localized); | ||||
| 	void registerString(const std::string & modContext, const TextIdentifier & UID, const std::string & localized); | ||||
| 	void registerString(const std::string & modContext, const TextIdentifier & UID, const std::string & localized, const std::string & language); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user