private void LogDumpResults(string prefix, string output, TranslationCount before, TranslationCount after) { var delta = after - before; Logger.LogDebug( $"[TextDump] {DumpLevelCompleted + 1}/{DumpLevelMax} lines:{after.Lines,4:D} (new:{delta.Lines,4:D}) translations:{after.TranslatedLines,4:D} (new:{delta.TranslatedLines,4:D}) {prefix} {output}"); }
private void KKS_TextDumpComplete(BaseTextDumpPlugin sender, EventArgs eventArgs) { var delta = _total - _lastTotal; if (DumpLevelCompleted >= DumpLevelMax) { NotificationMessage = string.Empty; if (_total == _lastTotal) { _stableCount++; } else { _lastTotal = _total; if (_stableCount != 0) { _lastDelta = delta; } _stableCount = 0; } if (_stableCount < 3) { StartCoroutine(RetryDelay(10)); if (_stableCount == 0) { NotificationMessage = $"Number of translations found is continuing to change ({delta})"; } else { NotificationMessage = "Number of translations unchanged"; } NotificationMessage += $", will keep re-dumping until it's stable for {3 - _stableCount} more cycle(s)"; DumpLevelCompleted--; DumpLevelReady = DumpLevelCompleted; } } else if (DumpLevelCompleted > 0) { NotificationMessage = "Multiple brute-force dump attempts are required, please wait until you see a message saying files are available"; } }
private TranslationCount DumpLocalizations() { var origCount = new TranslationCount(_localizationTotal); InitHelpers(); var folderPath = LocalizationRoot; if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } foreach (var entry in LocalizationDumpHelper.GetLocalizations()) { var output = entry.Path; switch (entry) { case StringTranslationDumper stringDumper: { IDictionary <string, string> results; try { results = stringDumper.Collector(); } catch (Exception e) { results = new Dictionary <string, string>(); Logger.LogError( $"[TextDump] Localization {output}: Error executing {entry.Collector.Method.Name}(): {e.Message}"); } var filePath = Path.Combine(folderPath, $"{output}.txt"); var translations = GetTranslationsForPath(filePath); var beforeCount = new TranslationCount(translations); translations.Merge(results, TextResourceHelper); var afterCount = new TranslationCount(translations); LogDumpResults("Localization", output, beforeCount, afterCount); var delta = afterCount - beforeCount; _localizationTotal += delta; break; } case ResizerDumper resizeDumper: { IDictionary <string, List <string> > results; try { results = resizeDumper.Collector(); } catch (Exception e) { results = new Dictionary <string, List <string> >(); Logger.LogError( $"[TextDump] Localization {output}: Error executing {entry.Collector.Method.Name}(): {e.Message}"); } try { AssetLoader.UnloadBundles(); } catch { } var filePath = Path.Combine(folderPath, $"{output}_resizer.txt"); var resizers = GetResizersForPath(filePath); resizers.Merge(results); //var afterCount = new TranslationCount(translations); //LogDumpResults("Localization", output, beforeCount, afterCount); //_localizationTotal += afterCount - beforeCount; break; } default: Logger.LogError($"[TextDump] Localization {output}: {entry} is unsupported dumper type"); break; } } var totalDelta = _localizationTotal - origCount; Logger.LogInfo( $"[TextDump] Total Localization lines (translated): {_localizationTotal} (change {totalDelta})"); return(totalDelta); }
private TranslationCount DumpAssets() { var origCount = new TranslationCount(_assetTotal); InitHelpers(); var folderPath = AssetsRoot; if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } foreach (var assetDumper in AssetDumpHelper.GetAssetDumpers()) { var output = assetDumper.Path; switch (assetDumper) { case StringTranslationDumper stringDumper: { IDictionary <string, string> results; #pragma warning disable CA1031 // Do not catch general exception types try { results = stringDumper.Collector(); } catch (Exception e) { results = new Dictionary <string, string>(); Logger.LogError( $"[TextDump] Asset {output}: Error executing {assetDumper.Collector.Method.Name}(): {e.Message}"); Logger.LogDebug($"[TextDump] Asset {output}:\n{e.StackTrace}"); } try { AssetLoader.UnloadBundles(); } catch { } #pragma warning restore CA1031 // Do not catch general exception types var filePath = Path.Combine(folderPath, $"{output}.txt"); var translations = GetTranslationsForPath(filePath); var beforeCount = new TranslationCount(translations); translations.Merge(results, TextResourceHelper); var afterCount = new TranslationCount(translations); LogDumpResults("Asset", output, beforeCount, afterCount); var delta = afterCount - beforeCount; _assetTotal += delta; break; } #if RAW_DUMP_SUPPORT case RawTranslationDumper rawDumper: { var filePath = Path.Combine(folderPath, $"{output}.bytes"); Logger.LogFatal($"RawTranslationsDict[{filePath}] = {rawDumper.Collector}"); RawTranslationsDict[filePath] = new Func <IEnumerable <byte> >(rawDumper.Collector); break; } #endif default: Logger.LogError($"[TextDump] Asset {output}: {assetDumper} is unsupported dumper type"); break; } } var totalDelta = _assetTotal - origCount; Logger.LogInfo($"[TextDump] Total Asset lines (translated): {_assetTotal} (change {totalDelta})"); return(totalDelta); }
private void DumpText(string from) { if (string.IsNullOrEmpty(from)) { throw new ArgumentException("Value cannot be null or empty.", nameof(from)); } InitHelpers(); DumpStarted = true; LogWithMessage(BepInExLogLevel.Warning, $"[TextDump] Starting dump {DumpLevelCompleted + 1}/{DumpLevelMax} from {from}. Application may become unresponsive, please wait."); if (Directory.Exists(DumpRoot)) { Directory.Delete(DumpRoot, true); } // if using BeforeFirstLoad it's best not to try doing localizations (if we're dumping more than once). var skipLocalizations = CurrentExecutionMode == ExecutionMode.BeforeFirstLoad && DumpLevelCompleted == 0 && DumpLevelMax > 1; var dumpAssets = CurrentAssetDumpMode == AssetDumpMode.Always || DumpLevelCompleted < 1 && CurrentAssetDumpMode.HasFlag(AssetDumpMode.FirstOnly) || DumpLevelReady == DumpLevelMax && CurrentAssetDumpMode.HasFlag(AssetDumpMode.LastOnly) || CurrentAssetDumpMode == AssetDumpMode.CustomLevels && AssetDumpLevels != null && AssetDumpLevels.Contains(DumpLevelCompleted + 1); if (dumpAssets) { _total += DumpAssets(); } if (!skipLocalizations) { _total += DumpLocalizations(); } Logger.LogInfo($"[TextDump] Total lines (translated):{_assetTotal + _localizationTotal}"); DumpCompleted = true; DumpLevelCompleted++; LogWithMessage(BepInExLogLevel.Info, $"[TextDump] Dump {DumpLevelCompleted}/{DumpLevelMax} completed."); OnTextDumpLevelComplete(EventArgs.Empty); if (AreAllDumpsComplete()) { if (dumpAssets) { AssetDumpHelper.LogUnmatchedDumpers(); } try { AssetLoader.UnloadBundles(); } catch { } } if (!WriteAfterEachDump && (!WriteAfterFinalDump || !AreAllDumpsComplete())) { return; } if (WriteInProgress) { return; } StartCoroutine(WriteTranslations()); }