using System; using System.Collections.Generic; using System.IO; using System.Linq; using Cthangover.Core.Localization; using Godot; namespace Cthangover.Tools.Services { /// /// Texts of one mod's locale/*.properties for the editors that show a /// localized name instead of its key. A language's files are /// <lang>.properties and <anything>_<lang>.properties, /// as LocaleLoader reads them. /// /// A write goes into the file of the language that already declares the key; /// a new key goes into <lang>.properties, else the first non-scenario /// file of the language, else a new locale/<lang>.properties. /// Scenario string files (scenarios_*) never get entity texts. /// public static class LocaleFileService { private const string Dir = "locale"; /// Languages the mod has texts for, plus the game's current one; the current one first. public static List Languages(string modId) { var current = LanguageCode.Normalize(TranslationServer.GetLocale()) ?? "ru"; var languages = new List { current }; foreach (var file in ModFileService.ListFiles(modId, Dir, ".properties")) { var language = LanguageOf(file); if (language != null && !languages.Contains(language)) languages.Add(language); } return languages; } /// The mod's text of in , or null. public static string Read(string modId, string language, string key) { string found = null; foreach (var file in FilesOf(modId, language)) found = PropertiesText.Get(ModFileService.ReadText(modId, file), key) ?? found; return found; } /// Sets the text of in ; false when the mod is not writable. public static bool Write(string modId, string language, string key, string value) { var files = FilesOf(modId, language); var target = files.FirstOrDefault(f => PropertiesText.Keys(ModFileService.ReadText(modId, f)).Contains(key)) ?? files.FirstOrDefault(f => Path.GetFileName(f) == language + ".properties") ?? files.FirstOrDefault(f => !Path.GetFileName(f).StartsWith("scenarios_", StringComparison.Ordinal)) ?? $"{Dir}/{language}.properties"; return ModFileService.WriteText(modId, target, PropertiesText.Set(ModFileService.ReadText(modId, target), key, value)); } /// Reloads the game's texts of the current language, so a saved name shows at once. public static void ReloadGame() => LocaleLoader.LoadLocale(TranslationServer.GetLocale()); private static List FilesOf(string modId, string language) => ModFileService.ListFiles(modId, Dir, ".properties").Where(f => LanguageOf(f) == language && Path.GetDirectoryName(f)?.Replace('\\', '/') == Dir).ToList(); private static string LanguageOf(string file) { var name = Path.GetFileNameWithoutExtension(file); var language = name.Substring(name.LastIndexOf('_') + 1); return LanguageCode.Supported.Contains(language) ? language : null; } } }