protected override bool DumpAsset(string calculatedModificationPath, ExcelData asset, IAssetOrResourceLoadedContext context) { var defaultTranslationFile = Path.Combine(calculatedModificationPath, "translation.txt"); var cache = new SimpleTextTranslationCache( defaultTranslationFile, false); var columnsToDump = new HashSet <int>(TextResourceHelper.GetSupportedExcelColumns(calculatedModificationPath, asset)); for (var i = 1; i < asset.list.Count; i++) { var row = asset.GetRow(i); var rowColumns = Enumerable.Range(0, row.Count); if (columnsToDump.Count > 0) { rowColumns = rowColumns.Where(columnsToDump.Contains); } foreach (var key in rowColumns.Select(j => row[j]) .Where(k => !k.IsNullOrEmpty() && LanguageHelper.IsTranslatable(k))) { cache.AddTranslationToCache(key, key); } } return(true); }
public override bool UpdateParam(string calculatedModificationPath, SimpleTextTranslationCache cache, EventInfo.Param param) { var key = TextResourceHelper.GetSpecializedKey(param, param.Name); if (string.IsNullOrEmpty(key)) { return(false); } var result = false; if (cache.TryGetTranslation(key, true, out var translated)) { param.Name = translated; TrackReplacement(calculatedModificationPath, key, translated); TranslationHelper.RegisterRedirectedResourceTextToPath(translated, calculatedModificationPath); result = true; } else if (AutoTranslatorSettings.IsDumpingRedirectedResourcesEnabled && LanguageHelper.IsTranslatable(key)) { cache.AddTranslationToCache(key, !string.IsNullOrEmpty(param.Name) ? param.Name : string.Empty); } return(result); }
private IEnumerator StudioDump <T>(string currentRoot, string topLevelFileName, Dictionary <int, T> infoList) where T : LoadCommonInfo { yield return(new WaitUntilStable(infoList, infoList.Count > 0 ? 1 : 3)); var groupResults = GetTranslationsForPath(CombinePaths(currentRoot, topLevelFileName)); foreach (var grouping in infoList.Where(e => IsMod(e.Key)).Select(e => e.Value) .GroupBy(GetStudioGrouping).OrderBy(g => g.Key, StringComparer.OrdinalIgnoreCase)) { var names = grouping.Select(i => i.name).Where(n => !groupResults.ContainsKey(n)).Select( origName => { var shouldInclude = ShouldIncludeEntry(origName, out var translatedName); var result = new { origName, translatedName }; return(new { shouldInclude, result }); }).Where(r => r.shouldInclude && r.result.origName != r.result.translatedName) .Select(r => r.result) .OrderBy(n => n.origName, StringComparer.OrdinalIgnoreCase) .ToList(); if (names.Count < 1) { continue; } TextResourceHelper.AddLocalizationToResults(groupResults, $"{FilePattern}{grouping.Key}", FilePattern); foreach (var entry in names) { TextResourceHelper.AddLocalizationToResults(groupResults, entry.origName, entry.translatedName); } } }
public override bool UpdateParam(string calculatedModificationPath, SimpleTextTranslationCache cache, EventInfo.Param param) { var result = false; var origKey = param.Name; foreach (var key in TextResourceHelper.GetTranslationKeys(param, origKey)) { if (string.IsNullOrEmpty(key)) { continue; } if (cache.TryGetTranslation(key, true, out var translated)) { param.Name = translated; TrackReplacement(calculatedModificationPath, origKey, translated); TranslationHelper.RegisterRedirectedResourceTextToPath(translated, calculatedModificationPath); result = true; break; } if (AutoTranslatorSettings.IsDumpingRedirectedResourcesEnabled && LanguageHelper.IsTranslatable(origKey)) { cache.AddTranslationToCache(key, !string.IsNullOrEmpty(param.Name) ? param.Name : string.Empty); } } return(result); }
private bool TryRegisterTranslation(SimpleTextTranslationCache cache, ScenarioData.Param param, int i, string calculatedModificationPath) { var key = TextResourceHelper.GetSpecializedKey(param, i, out var value); if (!string.IsNullOrEmpty(key)) { if (cache.TryGetTranslation(key, true, out var translated)) { var result = TextResourceHelper.GetSpecializedTranslation(param, i, translated); TranslationHelper.RegisterRedirectedResourceTextToPath(result, calculatedModificationPath); param.Args[i] = result; Logger.DebugLogDebug($"{GetType()} handled {calculatedModificationPath}"); return(true); } if (LanguageHelper.IsTranslatable(key)) { TranslationHelper.RegisterRedirectedResourceTextToPath(key, calculatedModificationPath); if (AutoTranslatorSettings.IsDumpingRedirectedResourcesEnabled) { cache.AddTranslationToCache(key, value); } } } return(false); }
private IEnumerator StudioDump <T>(string currentRoot, string topLevelFileName, Dictionary <int, Dictionary <int, Dictionary <int, T> > > nestedInfoList, Dictionary <int, GroupInfo> groupInfoList) where T : LoadCommonInfo { var jobs = new List <Coroutine> { StartCoroutine(WaitForStableDictionary(nestedInfoList)), StartCoroutine(WaitForStableDictionary(groupInfoList)) }; foreach (var job in jobs) { yield return(job); } jobs.Clear(); var groupResults = GetTranslationsForPath(CombinePaths(currentRoot, topLevelFileName)); foreach (var group in nestedInfoList.Select(group => { var groupRoot = CombinePaths(currentRoot, $"group_{group.Key:D10}"); var groupInfo = GetStudioGroupInfo(groupInfoList, group.Key); var groupName = groupInfo?.name ?? string.Empty; return(new { group, groupRoot, groupInfo, groupName }); }).OrderBy(g => g.groupRoot, StringComparer.OrdinalIgnoreCase)) { var categoryResults = GetTranslationsForPath(CombinePaths(group.groupRoot, "category_names.txt")); if (ShouldIncludeEntry(group.groupName, out var groupNameTrans)) { TextResourceHelper.AddLocalizationToResults(groupResults, group.groupName, groupNameTrans); } foreach (var category in group.group.Value.Select(category => { var categoryName = GetStudioGroupCategoryName(group.groupInfo, category.Key); var categoryFileName = $"category_{category.Key:D10}.txt"; return(new { category, categoryName, categoryFileName }); }).OrderBy(c => c.categoryFileName, StringComparer.OrdinalIgnoreCase)) { if (ShouldIncludeEntry(category.categoryName, out var categoryNameTrans)) { TextResourceHelper.AddLocalizationToResults(categoryResults, category.categoryName, categoryNameTrans); } jobs.Add(StartCoroutine(StudioDump(group.groupRoot, category.categoryFileName, category.category.Value))); } } foreach (var job in jobs) { yield return(job); } }
/// <summary> /// Caches forward and reverse translation of assets as they're loaded, but does not apply them. /// to avoid breaking code that relies on original names being present. /// </summary> protected override bool ReplaceOrUpdateAsset(string calculatedModificationPath, ref MapInfo asset, IAssetOrResourceLoadedContext context) { var result = false; var start = Time.realtimeSinceStartup; try { // updating the MapInfo assets directly breaks places that are doing lookups by mapName // instead of id, so we just register this as a place to lookup MapInfo translations and // return true so it appears handled Hooks.Init(); // register new translations with helper without replacing var cache = GetTranslationCache(calculatedModificationPath, asset, context); if (cache.IsEmpty) { return(result = true); } var shouldTrack = IsTranslationRegistrationAllowed(calculatedModificationPath); // register with helper or dump without translating here foreach (var key in asset.param .Select(entry => TextResourceHelper.GetSpecializedKey(entry, GetMapName(entry))) .Where(k => !string.IsNullOrEmpty(k))) { if (cache.TryGetTranslation(key, true, out var translated)) { if (string.IsNullOrEmpty(translated)) { continue; } _mapLookup[key] = translated; _reverseMapLookup[translated] = key; if (shouldTrack) { TrackReplacement(calculatedModificationPath, key, translated); } TranslationHelper.RegisterRedirectedResourceTextToPath(translated, calculatedModificationPath); } else if (AutoTranslatorSettings.IsDumpingRedirectedResourcesEnabled && !string.IsNullOrEmpty(key) && LanguageHelper.IsTranslatable(key)) { cache.AddTranslationToCache(key, key); } } GameSpecificReplaceOrUpdateAsset(calculatedModificationPath, ref asset, context, cache, shouldTrack); return(result = true); } finally { Logger.DebugLogDebug("{0}.{1}: {2} => {3} ({4} seconds)", GetType(), nameof(ReplaceOrUpdateAsset), calculatedModificationPath, result, Time.realtimeSinceStartup - start); } }
protected override string CalculateModificationFilePath(TextAsset asset, IAssetOrResourceLoadedContext context) { var path = asset.DefaultCalculateModificationFilePath(context); if (AllowTranslationRegistration && TextResourceHelper.IsRandomNameListAsset(asset.name)) { ExcludePathFromTranslationRegistration(path); } return(path); }
protected virtual bool DefaultDumpParam(SimpleTextTranslationCache cache, TParam param, string value) { var key = TextResourceHelper.GetSpecializedKey(param, value); if (string.IsNullOrEmpty(key) || !LanguageHelper.IsTranslatable(value)) { return(false); } cache.AddTranslationToCache(key, string.Empty); return(true); }
public override bool DumpParam(SimpleTextTranslationCache cache, EventInfo.Param param) { var key = TextResourceHelper.GetSpecializedKey(param, param.Name); var value = !string.IsNullOrEmpty(key) ? key : string.Empty; if (string.IsNullOrEmpty(key) || !LanguageHelper.IsTranslatable(key)) { return(false); } cache.AddTranslationToCache(key, value); return(true); }
/// <summary> /// Caches forward and reverse translation of assets as they're loaded, but does not apply them. /// to avoid breaking code that relies on original names being present. /// </summary> protected override bool ReplaceOrUpdateAsset(string calculatedModificationPath, ref MapInfo asset, IAssetOrResourceLoadedContext context) { // updating the MapInfo assets directly breaks places that are doing lookups by mapName // instead of id, so we just register this as a place to lookup MapInfo translations and // return true so it appears handled Hooks.Init(); // register new translations with helper without replacing var defaultTranslationFile = Path.Combine(calculatedModificationPath, "translation.txt"); var redirectedResources = RedirectedDirectory.GetFilesInDirectory(calculatedModificationPath, ".txt"); var streams = redirectedResources.Select(x => x.OpenStream()); var cache = new SimpleTextTranslationCache( defaultTranslationFile, streams, false, true); if (cache.IsEmpty) { return(true); } var shouldTrack = IsTranslationRegistrationAllowed(calculatedModificationPath); // register with helper or dump without translating here foreach (var key in asset.param .Select(entry => TextResourceHelper.GetSpecializedKey(entry, GetMapName(entry))) .Where(k => !string.IsNullOrEmpty(k))) { if (cache.TryGetTranslation(key, true, out var translated)) { if (string.IsNullOrEmpty(translated)) { continue; } _mapLookup[key] = translated; _reverseMapLookup[translated] = key; if (shouldTrack) { TrackReplacement(calculatedModificationPath, key, translated); } TranslationHelper.RegisterRedirectedResourceTextToPath(translated, calculatedModificationPath); } else if (AutoTranslatorSettings.IsDumpingRedirectedResourcesEnabled && !string.IsNullOrEmpty(key) && LanguageHelper.IsTranslatable(key)) { cache.AddTranslationToCache(key, key); } } return(true); }
protected override bool DumpAsset(string calculatedModificationPath, ScenarioData asset, IAssetOrResourceLoadedContext context) { var cache = GetDumpCache(calculatedModificationPath, asset, context); foreach (var param in asset.list) { TextResourceHelper.DumpScenarioParam(param, cache); } return(true); }
public override bool DumpParam(SimpleTextTranslationCache cache, TitleSkillName.Param param) { var key = TextResourceHelper.GetSpecializedKey(param, param.name0); if (string.IsNullOrEmpty(key) || !LanguageHelper.IsTranslatable(key)) { return(false); } var value = !string.IsNullOrEmpty(param.name1) ? param.name1 : key; cache.AddTranslationToCache(key, value); return(true); }
protected override bool DumpAsset(string calculatedModificationPath, NickName asset, IAssetOrResourceLoadedContext context) { var cache = GetDumpCache(calculatedModificationPath, asset, context); foreach (var entry in asset.param) { var key = TextResourceHelper.GetSpecializedKey(entry, entry.Name); if (!string.IsNullOrEmpty(key) && LanguageHelper.IsTranslatable(key)) { cache.AddTranslationToCache(key, entry.Name); } } return(true); }
protected override bool DumpAsset(string calculatedModificationPath, MapInfo asset, IAssetOrResourceLoadedContext context) { var cache = GetDumpCache(calculatedModificationPath, asset, context); var result = false; foreach (var entry in asset.param) { var key = TextResourceHelper.GetSpecializedKey(entry, GetMapName(entry)); if (string.IsNullOrEmpty(key) || !LanguageHelper.IsTranslatable(key)) { continue; } cache.AddTranslationToCache(key, GetMapNameTranslation(entry)); result = true; } return(result); }
internal void Awake() { _instance = this; Logger = Logger ?? base.Logger; TextResourceHelper = GetTextResourceHelper(); ExcelDataHandler = new ExcelDataHandler(this); ScenarioDataHandler = new ScenarioDataHandler(this); TextAssetTableHandler = new TextAssetTableHandler(this); #if RAW_DUMP_SUPPORT TextAssetRawBytesHandler = new TextAssetRawBytesHandler(this); #endif enabled = false; #if !HS ChaListDataHandler = new ChaListDataHandler(this); #endif XuaHooks.Init(); OnTextResourceRedirectorAwake(EventArgs.Empty); }
protected override bool DumpAsset(string calculatedModificationPath, NickName asset, IAssetOrResourceLoadedContext context) { var defaultTranslationFile = Path.Combine(calculatedModificationPath, "translation.txt"); var cache = new SimpleTextTranslationCache( defaultTranslationFile, false); foreach (var entry in asset.param) { if (!entry.isSpecial) { continue; } var key = TextResourceHelper.GetSpecializedKey(entry, entry.Name); if (!string.IsNullOrEmpty(key) && LanguageHelper.IsTranslatable(key)) { cache.AddTranslationToCache(key, entry.Name); } } return(true); }
public bool IsRandomNameListAsset(string assetName) { return(TextResourceHelper.IsRandomNameListAsset(assetName)); }
protected override bool DumpAsset(string calculatedModificationPath, ScenarioData asset, IAssetOrResourceLoadedContext context) { var defaultTranslationFile = Path.Combine(calculatedModificationPath, "translation.txt"); var cache = new SimpleTextTranslationCache( defaultTranslationFile, false); foreach (var param in asset.list) { if (!TextResourceHelper.IsSupportedCommand(param.Command)) { continue; } if (param.Command == Command.Text) { foreach (var key in param.Args) { if (!string.IsNullOrEmpty(key) && !TextResourceHelper.TextKeysBlacklist.Contains(key) && LanguageHelper.IsTranslatable(key)) { cache.AddTranslationToCache(key, key); } } } else if (param.Command == Command.Calc) { if (param.Args.Length >= 3 && TextResourceHelper.CalcKeys.Contains(param.Args[0])) { cache.AddTranslationToCache(param.Args[2], param.Args[2]); } } else if (param.Command == Command.Format) { if (param.Args.Length >= 2 && TextResourceHelper.FormatKeys.Contains(param.Args[0])) { cache.AddTranslationToCache(param.Args[1], param.Args[1]); } } else if (param.Command == Command.Choice) { for (var i = 0; i < param.Args.Length; i++) { var key = TextResourceHelper.GetSpecializedKey(param, i, out var value); if (!key.IsNullOrEmpty()) { cache.AddTranslationToCache(key, value); } } } #if false else if (param.Command == ADV.Command.Switch) { for (int i = 1; i < param.Args.Length; i += 1) { cache.AddTokenTranslationToCache(param.Args[i], param.Args[i]); } } #endif #if false else if (param.Command == ADV.Command.InfoText) { for (int i = 1; i < param.Args.Length; i += 1) { cache.AddTokenTranslationToCache(param.Args[i], param.Args[i]); } } #endif #if false else if (param.Command == ADV.Command.Jump) { // TODO: detect if should be dumped if (param.Args.Length >= 1) { cache.AddTokenTranslationToCache(param.Args[0], param.Args[0]); } } #endif } return(true); }
protected override bool ReplaceOrUpdateAsset(string calculatedModificationPath, ref ScenarioData asset, IAssetOrResourceLoadedContext context) { Logger.DebugLogDebug($"{GetType()} attempt to handle {calculatedModificationPath}"); var defaultTranslationFile = Path.Combine(calculatedModificationPath, "translation.txt"); var redirectedResources = RedirectedDirectory.GetFilesInDirectory(calculatedModificationPath, ".txt"); var streams = redirectedResources.Select(x => x.OpenStream()); var cache = new SimpleTextTranslationCache( defaultTranslationFile, streams, false, true); if (cache.IsEmpty) { Logger.DebugLogDebug($"{GetType()} unable to handle {calculatedModificationPath} (no cache)"); return(false); } var result = false; foreach (var param in asset.list) { if (!TextResourceHelper.IsSupportedCommand(param.Command)) { Logger.DebugLogDebug($"{GetType()} skipping unsupported command: {param.Command}"); continue; } switch (param.Command) { case Command.Text: // Text: 0 - jp speaker (if present), 1 - text for (var i = 0; i < param.Args.Length && i < 2; i++) { var key = param.Args[i]; if (key.IsNullOrEmpty() || TextResourceHelper.TextKeysBlacklist.Contains(key) || StringIsSingleReplacement(key)) { continue; } if (TryRegisterTranslation(cache, param, i, calculatedModificationPath)) { result = true; } } break; case Command.Calc: { if (param.Args.Length >= 3 && TextResourceHelper.CalcKeys.Contains(param.Args[0])) { if (TryRegisterTranslation(cache, param, 2, calculatedModificationPath)) { result = true; } } break; } case Command.Format: { if (param.Args.Length >= 2 && TextResourceHelper.FormatKeys.Contains(param.Args[0])) { if (TryRegisterTranslation(cache, param, 1, calculatedModificationPath)) { result = true; } } break; } case Command.Choice: { for (var i = 0; i < param.Args.Length; i++) { if (TryRegisterTranslation(cache, param, i, calculatedModificationPath)) { result = true; } } break; } #if false case ADV.Command.Switch: // TODO break; #if AI case ADV.Command.InfoText: // TODO break; #endif case ADV.Command.Jump: // TODO break; #endif default: { Logger.LogWarning( $"{GetType()} expected to handle {param.Command}, but support not implemented"); break; } } } Logger.DebugLogDebug(result ? $"{GetType()} handled {calculatedModificationPath}" : $"{GetType()} unable to handle {calculatedModificationPath}"); return(result); }
/// <inheritdoc /> /// <remarks>Always returns <c>true</c> to signal nothing else should handle these.</remarks> protected override bool ReplaceOrUpdateAsset(string calculatedModificationPath, ref NickName asset, IAssetOrResourceLoadedContext context) { // updating the NickName assets directly causes issues, but after SaveData.LoadNickNameParam() they // are safe to manipulate InitHooks(); var defaultTranslationFile = Path.Combine(calculatedModificationPath, "translation.txt"); var redirectedResources = RedirectedDirectory.GetFilesInDirectory(calculatedModificationPath, ".txt"); var streams = redirectedResources.Select(x => x.OpenStream()); var cache = new SimpleTextTranslationCache( defaultTranslationFile, streams, false, true); if (cache.IsEmpty) { return(true); } var replacementKey = calculatedModificationPath .Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) .LastOrDefault(); // don't touch "player" entry if (string.IsNullOrEmpty(replacementKey) || replacementKey.Equals("player", StringComparison.OrdinalIgnoreCase)) { return(true); } if (!_replacements.TryGetValue(replacementKey, out var replacements)) { _replacements[replacementKey] = replacements = new Dictionary <string, string>(); } foreach (var entry in asset.param) { if (!entry.isSpecial) { continue; } var key = TextResourceHelper.GetSpecializedKey(entry, entry.Name); if (string.IsNullOrEmpty(key)) { continue; } if (cache.TryGetTranslation(key, true, out var translated)) { replacements[key] = translated; TranslationHelper.RegisterRedirectedResourceTextToPath(translated, calculatedModificationPath); } else if (AutoTranslatorSettings.IsDumpingRedirectedResourcesEnabled && LanguageHelper.IsTranslatable(key)) { cache.AddTranslationToCache(key, entry.Name); } } return(true); }
private IEnumerator MakerDump() { NotificationMessage = "Collecting Maker Mod Strings, please wait..."; ChaListControl chaListCtrl = null; while (chaListCtrl == null) { yield return(null); #if !KKS Character.Instance.SafeProc(i => chaListCtrl = i.chaListCtrl); #else if (Character.Instance == null || !Character.Instance.isActiveAndEnabled) { continue; } chaListCtrl = Character.chaListCtrl; #endif } var categories = Enum.GetValues(typeof(ChaListDefine.CategoryNo)).Cast <ChaListDefine.CategoryNo>(); foreach (var category in categories) { try { var results = GetTranslationsForPath(CombinePaths(MakerRoot, $"{category}.txt")); var categoryInfo = chaListCtrl.GetCategoryInfo(category); foreach (var grouping in categoryInfo.Values.Where(IsMod).GroupBy(GetMakerGrouping) .OrderBy(g => g.Key, StringComparer.OrdinalIgnoreCase)) { try { var names = grouping.Select(i => i.Name).Where(n => !results.ContainsKey(n)).Select( origName => { var shouldInclude = ShouldIncludeEntry(origName, out var translatedName); var result = new { origName, translatedName }; return(new { shouldInclude, result }); }).Where(r => r.shouldInclude && r.result.origName != r.result.translatedName) .Select(r => r.result) .OrderBy(n => n.origName, StringComparer.OrdinalIgnoreCase) .ToList(); if (names.Count < 1) { continue; } TextResourceHelper.AddLocalizationToResults(results, $"{FilePattern}{grouping.Key}", FilePattern); foreach (var entry in names) { TextResourceHelper.AddLocalizationToResults(results, entry.origName, entry.translatedName); } } catch (Exception err) { Logger.LogError($"Looping {grouping}: {err.Message}"); UnityDebug.LogException(err); } } } catch (Exception err) { Logger.LogError($"Looping {category}: {err.Message}"); UnityDebug.LogException(err); } } DumpCompleted = true; }
/// <inheritdoc /> /// <remarks>Always returns <c>true</c> to signal nothing else should handle these.</remarks> protected override bool ReplaceOrUpdateAsset(string calculatedModificationPath, ref NickName asset, IAssetOrResourceLoadedContext context) { var result = false; var start = UnityEngine.Time.realtimeSinceStartup; try { // updating the NickName assets directly causes issues, save off a lookup table. var cache = GetTranslationCache(calculatedModificationPath, asset, context); if (cache.IsEmpty) { return(false); } var personalityKey = calculatedModificationPath .Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) .LastOrDefault(); if (string.IsNullOrEmpty(personalityKey)) { return(false); } var replacements = _replacements.GetOrInit(personalityKey); foreach (var entry in asset.param) { // nicknames should not fall back on undecorated keys, so don't loop var key = TextResourceHelper.GetSpecializedKey(entry, entry.Name); if (string.IsNullOrEmpty(key)) { continue; } if (cache.TryGetTranslation(key, true, out var translated)) { replacements[key] = translated; result = true; // use entry.Name here to avoid tracking with key // Scope 15 for the class nickname editor TrackReplacement(calculatedModificationPath, entry.Name, translated, 15, -1); TranslationHelper.RegisterRedirectedResourceTextToPath(translated, calculatedModificationPath); Logger.DebugLogDebug("{0}.{1}: {2}: {3} => {4}", GetType().FullName, nameof(ReplaceOrUpdateAsset), personalityKey, key, translated); } else if (AutoTranslatorSettings.IsDumpingRedirectedResourcesEnabled && LanguageHelper.IsTranslatable(key)) { cache.AddTranslationToCache(key, entry.Name); } } return(result); } finally { Logger.DebugLogDebug("{0}.{1}: {2} => {3} (4 seconds)", GetType().Name, nameof(ReplaceOrUpdateAsset), calculatedModificationPath, result, Time.realtimeSinceStartup - start); } }
public TextAssetRawBytesHandler(TextResourceHelper textResourceHelper) { CheckDirectory = true; _textResourceHelper = textResourceHelper; Logger.LogInfo($"{GetType()} {(Enabled ? "enabled" : "disabled")}"); }
protected override bool ReplaceOrUpdateAsset(string calculatedModificationPath, ref ExcelData asset, IAssetOrResourceLoadedContext context) { Logger.DebugLogDebug($"{GetType()} attempt to handle {calculatedModificationPath}"); var defaultTranslationFile = Path.Combine(calculatedModificationPath, "translation.txt"); var redirectedResources = RedirectedDirectory.GetFilesInDirectory(calculatedModificationPath, ".txt"); var streams = redirectedResources.Select(x => x.OpenStream()); var cache = new SimpleTextTranslationCache( defaultTranslationFile, streams, false, true); var result = false; if (cache.IsEmpty) { Logger.DebugLogDebug($"{GetType()} unable to handle {calculatedModificationPath} (no cache)"); return(false); } var columnsToTranslate = new HashSet <int>(TextResourceHelper.GetSupportedExcelColumns(calculatedModificationPath, asset)); var filter = columnsToTranslate.Count > 0; var row = -1; var shouldTrack = IsTranslationRegistrationAllowed(calculatedModificationPath); foreach (var param in asset.list) { row++; if (param.list == null || param.list.Count < 1 || param.list[0] == "no") { continue; } for (var i = 0; i < param.list.Count; i++) { if (filter && !columnsToTranslate.Contains(i)) { continue; } foreach (var key in TextResourceHelper.GetExcelRowTranslationKeys(asset.name, param.list, i)) { if (string.IsNullOrEmpty(key)) { continue; } Logger.DebugLogDebug( $"Attempting excel replacement [{row}, {i}]: Searching for replacement key={key}"); if (cache.TryGetTranslation(key, true, out var translated)) { result = true; translated = TextResourceHelper.PrepareTranslationForReplacement(asset, translated); if (shouldTrack) { TrackReplacement(calculatedModificationPath, key, translated); } TranslationHelper.RegisterRedirectedResourceTextToPath(translated, calculatedModificationPath); Logger.DebugLogDebug( $"Replacing [{row}, {i}]: key={key}: {param.list[i]} => {translated}"); param.list[i] = translated; break; } if (!LanguageHelper.IsTranslatable(key)) { continue; } TranslationHelper.RegisterRedirectedResourceTextToPath(key, calculatedModificationPath); if (AutoTranslatorSettings.IsDumpingRedirectedResourcesEnabled) { cache.AddTranslationToCache(key, key); } } } } Logger.DebugLogDebug(result ? $"{GetType()} handled {calculatedModificationPath}" : $"{GetType()} unable to handle {calculatedModificationPath}"); return(result); }
protected override bool ReplaceOrUpdateAsset(string calculatedModificationPath, ref ExcelData asset, IAssetOrResourceLoadedContext context) { var result = false; var start = Time.realtimeSinceStartup; try { Logger.DebugLogDebug("{0}.{1} attempt to handle {2}", GetType(), nameof(ReplaceOrUpdateAsset), calculatedModificationPath); var cache = GetTranslationCache(calculatedModificationPath, asset, context); if (cache.IsEmpty) { Logger.DebugLogDebug("{0}.{1} unable to handle {2} (no cache)", GetType(), nameof(ReplaceOrUpdateAsset), calculatedModificationPath); return(false); } var columnsToTranslate = new HashSet <int>(TextResourceHelper.GetSupportedExcelColumns(calculatedModificationPath, asset, out var firstRow)); var filter = columnsToTranslate.Count > 0; var row = -1; var shouldTrack = IsTranslationRegistrationAllowed(calculatedModificationPath); foreach (var param in asset.list) { row++; if (row < firstRow) { continue; } if (param.list == null || param.list.Count < 1 || param.list[0] == "no") { continue; } for (var i = 0; i < param.list.Count; i++) { if (filter && !columnsToTranslate.Contains(i)) { continue; } foreach (var key in TextResourceHelper.GetExcelRowTranslationKeys(asset.name, param.list, i)) { if (string.IsNullOrEmpty(key)) { continue; } Logger.DebugLogDebug( "Attempting excel replacement [{0}, {1}]: Searching for replacement key={2}", row, i, key); if (cache.TryGetTranslation(key, true, out var translated)) { result = true; translated = TextResourceHelper.PrepareTranslationForReplacement(asset, translated); if (shouldTrack) { TrackReplacement(calculatedModificationPath, key, translated); } TranslationHelper.RegisterRedirectedResourceTextToPath(translated, calculatedModificationPath); Logger.DebugLogDebug( "Replacing [{0}, {1}]: key={2}: {3} => {4}", row, i, key, param.list[i], translated); param.list[i] = translated; break; } if (!LanguageHelper.IsTranslatable(key)) { continue; } TranslationHelper.RegisterRedirectedResourceTextToPath(key, calculatedModificationPath); if (AutoTranslatorSettings.IsDumpingRedirectedResourcesEnabled) { cache.AddTranslationToCache(key, key); } } } } return(result); } finally { Logger.DebugLogDebug("{0}.{1}: {2} => {3} ({4} seconds)", GetType(), nameof(ReplaceOrUpdateAsset), calculatedModificationPath, result, Time.realtimeSinceStartup - start); } }