using System; using System.Collections.Generic; using System.IO; using System.Linq; using BepInEx.Configuration; using Newtonsoft.Json.Linq; namespace MeidoPhotoStudio.Plugin { public static class Translation { private const string settingsHeader = "Translation"; private static readonly string[] props = { "ui", "props", "bg", "face" }; private static readonly ConfigEntry currentLanguage; private static readonly ConfigEntry suppressWarnings; private static Dictionary> Translations; private static bool forceSuppressWarnings; private static bool suppressWarningsCached; public static event EventHandler ReloadTranslationEvent; public static bool SuppressWarnings { get => suppressWarningsCached; set { suppressWarningsCached = value; suppressWarnings.Value = value; } } public static string CurrentLanguage { get => currentLanguage.Value; set => currentLanguage.Value = value; } static Translation() { currentLanguage = Configuration.Config.Bind( settingsHeader, "Language", "en", "Directory to pull translations from" + "\nTranslations are found in the 'Translations' folder" ); suppressWarnings = Configuration.Config.Bind( settingsHeader, "SuppressWarnings", false, "Suppress translation warnings from showing up in the console" ); suppressWarningsCached = !suppressWarnings.Value; } public static void Initialize(string language) { forceSuppressWarnings = false; var rootTranslationPath = Path.Combine(Constants.configPath, Constants.translationDirectory); var currentTranslationPath = Path.Combine(rootTranslationPath, language); Translations = new(StringComparer.InvariantCultureIgnoreCase); if (!Directory.Exists(currentTranslationPath)) { Utility.LogError($"No translations found for '{language}' in '{currentTranslationPath}'"); forceSuppressWarnings = true; return; } foreach (var prop in props) { var translationFile = $"translation.{prop}.json"; try { var translationPath = Path.Combine(currentTranslationPath, translationFile); var translationJson = File.ReadAllText(translationPath); var translation = JObject.Parse(translationJson); foreach (var translationProp in translation.AsJEnumerable().Cast()) { var token = translationProp.Value; Translations[translationProp.Path] = new( token.ToObject>(), StringComparer.InvariantCultureIgnoreCase ); } } catch { forceSuppressWarnings = true; Utility.LogError($"Could not find translation file '{translationFile}'"); } } } public static void ReinitializeTranslation() { Initialize(CurrentLanguage); ReloadTranslationEvent?.Invoke(null, EventArgs.Empty); } public static bool Has(string category, string text, bool warn = false) { warn = !forceSuppressWarnings && !SuppressWarnings && warn; if (!Translations.ContainsKey(category)) { if (warn) Utility.LogWarning($"Could not translate '{text}': category '{category}' was not found"); return false; } if (!Translations[category].ContainsKey(text)) { if (warn) { Utility.LogWarning( $"Could not translate '{text}': '{text}' was not found in category '{category}'" ); } return false; } return true; } public static string Get(string category, string text, bool warn = true) => Has(category, text, warn) ? Translations[category][text] : text; public static string[] GetArray(string category, IEnumerable list) => GetList(category, list).ToArray(); public static IEnumerable GetList(string category, IEnumerable list) => list.Select(uiName => Get(category, uiName)); } }