diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/SMAPI/Framework/ContentCoordinator.cs | 41 | ||||
-rw-r--r-- | src/SMAPI/Framework/ContentManagers/BaseContentManager.cs | 17 | ||||
-rw-r--r-- | src/SMAPI/Framework/ContentManagers/GameContentManager.cs | 2 | ||||
-rw-r--r-- | src/SMAPI/Framework/SCore.cs | 4 |
4 files changed, 45 insertions, 19 deletions
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs index d0e759c2..b6f1669a 100644 --- a/src/SMAPI/Framework/ContentCoordinator.cs +++ b/src/SMAPI/Framework/ContentCoordinator.cs @@ -64,6 +64,9 @@ namespace StardewModdingAPI.Framework /// <summary>An unmodified content manager which doesn't intercept assets, used to compare asset data.</summary> private readonly LocalizedContentManager VanillaContentManager; + /// <summary>The language enum values indexed by locale code.</summary> + private Lazy<IDictionary<string, LocalizedContentManager.LanguageCode>> LocaleCodes; + /********* ** Accessors @@ -133,6 +136,7 @@ namespace StardewModdingAPI.Framework this.ContentManagers.Add(contentManagerForAssetPropagation); this.VanillaContentManager = new LocalizedContentManager(serviceProvider, rootDirectory); this.CoreAssets = new CoreAssetPropagator(this.MainContentManager, contentManagerForAssetPropagation, this.Monitor, reflection, aggressiveMemoryOptimizations); + this.LocaleCodes = new Lazy<IDictionary<string, LocalizedContentManager.LanguageCode>>(this.GetLocaleCodes); } /// <summary>Get a new content manager which handles reading files from the game content folder with support for interception.</summary> @@ -195,6 +199,10 @@ namespace StardewModdingAPI.Framework /// <summary>Perform any cleanup needed when the locale changes.</summary> public void OnLocaleChanged() { + // rebuild locale cache (which may change due to custom mod languages) + this.LocaleCodes = new Lazy<IDictionary<string, LocalizedContentManager.LanguageCode>>(this.GetLocaleCodes); + + // reload affected content this.ContentManagerLock.InReadLock(() => { foreach (IContentManager contentManager in this.ContentManagers) @@ -408,6 +416,25 @@ namespace StardewModdingAPI.Framework return tilesheets ?? new TilesheetReference[0]; } + /// <summary>Get the language enum which corresponds to a locale code (e.g. <see cref="LocalizedContentManager.LanguageCode.fr"/> given <c>fr-FR</c>).</summary> + /// <param name="locale">The locale code to search. This must exactly match the language; no fallback is performed.</param> + /// <param name="language">The matched language enum, if any.</param> + /// <returns>Returns whether a valid language was found.</returns> + public bool TryGetLanguageEnum(string locale, out LocalizedContentManager.LanguageCode language) + { + return this.LocaleCodes.Value.TryGetValue(locale, out language); + } + + /// <summary>Get the locale code which corresponds to a language enum (e.g. <c>fr-FR</c> given <see cref="LocalizedContentManager.LanguageCode.fr"/>).</summary> + /// <param name="language">The language enum to search.</param> + public string GetLocaleCode(LocalizedContentManager.LanguageCode language) + { + if (language == LocalizedContentManager.LanguageCode.mod && LocalizedContentManager.CurrentModLanguage == null) + return null; + + return Game1.content.LanguageCodeString(language); + } + /// <summary>Dispose held resources.</summary> public void Dispose() { @@ -457,5 +484,19 @@ namespace StardewModdingAPI.Framework return false; } } + + /// <summary>Get the language enums (like <see cref="LocalizedContentManager.LanguageCode.ja"/>) indexed by locale code (like <c>ja-JP</c>).</summary> + private IDictionary<string, LocalizedContentManager.LanguageCode> GetLocaleCodes() + { + IDictionary<string, LocalizedContentManager.LanguageCode> map = new Dictionary<string, LocalizedContentManager.LanguageCode>(); + foreach (LocalizedContentManager.LanguageCode code in Enum.GetValues(typeof(LocalizedContentManager.LanguageCode))) + { + string locale = this.GetLocaleCode(code); + if (locale != null) + map[locale] = code; + } + + return map; + } } } diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs index 7244a534..5645c0fa 100644 --- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs @@ -38,9 +38,6 @@ namespace StardewModdingAPI.Framework.ContentManagers /// <summary>A callback to invoke when the content manager is being disposed.</summary> private readonly Action<BaseContentManager> OnDisposing; - /// <summary>The language enum values indexed by locale code.</summary> - protected IDictionary<string, LanguageCode> LanguageCodes { get; } - /// <summary>A list of disposable assets.</summary> private readonly List<WeakReference<IDisposable>> Disposables = new List<WeakReference<IDisposable>>(); @@ -92,7 +89,6 @@ namespace StardewModdingAPI.Framework.ContentManagers this.AggressiveMemoryOptimizations = aggressiveMemoryOptimizations; // get asset data - this.LanguageCodes = this.GetKeyLocales().ToDictionary(p => p.Value, p => p.Key, StringComparer.OrdinalIgnoreCase); this.BaseDisposableReferences = reflection.GetField<List<IDisposable>>(this, "disposableAssets").GetValue(); } @@ -292,7 +288,7 @@ namespace StardewModdingAPI.Framework.ContentManagers if (lastSepIndex >= 0) { string suffix = cacheKey.Substring(lastSepIndex + 1, cacheKey.Length - lastSepIndex - 1); - if (this.LanguageCodes.ContainsKey(suffix)) + if (this.Coordinator.TryGetLanguageEnum(suffix, out _)) { assetName = cacheKey.Substring(0, lastSepIndex); localeCode = cacheKey.Substring(lastSepIndex + 1, cacheKey.Length - lastSepIndex - 1); @@ -311,17 +307,6 @@ namespace StardewModdingAPI.Framework.ContentManagers /// <param name="language">The language to check.</param> protected abstract bool IsNormalizedKeyLoaded(string normalizedAssetName, LanguageCode language); - /// <summary>Get the locale codes (like <c>ja-JP</c>) used in asset keys.</summary> - private IDictionary<LanguageCode, string> GetKeyLocales() - { - // create locale => code map - IDictionary<LanguageCode, string> map = new Dictionary<LanguageCode, string>(); - foreach (LanguageCode code in Enum.GetValues(typeof(LanguageCode))) - map[code] = this.GetLocale(code); - - return map; - } - /// <summary>Get the asset name from a cache key.</summary> /// <param name="cacheKey">The input cache key.</param> private string GetAssetName(string cacheKey) diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs index 38bcf153..7a49dd36 100644 --- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs @@ -249,7 +249,7 @@ namespace StardewModdingAPI.Framework.ContentManagers // extract language code int splitIndex = rawAsset.LastIndexOf('.'); - if (splitIndex != -1 && this.LanguageCodes.TryGetValue(rawAsset.Substring(splitIndex + 1), out language)) + if (splitIndex != -1 && this.Coordinator.TryGetLanguageEnum(rawAsset.Substring(splitIndex + 1), out language)) { assetName = rawAsset.Substring(0, splitIndex); return true; diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 947284a8..a0467daa 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -751,7 +751,7 @@ namespace StardewModdingAPI.Framework ** Locale changed events *********/ if (state.Locale.IsChanged) - this.Monitor.Log($"Context: locale set to {state.Locale.New}."); + this.Monitor.Log($"Context: locale set to {state.Locale.New} ({this.ContentCore.GetLocaleCode(state.Locale.New)})."); /********* ** Load / return-to-title events @@ -761,7 +761,7 @@ namespace StardewModdingAPI.Framework else if (Context.IsWorldReady && Context.LoadStage != LoadStage.Ready) { // print context - string context = $"Context: loaded save '{Constants.SaveFolderName}', starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}, locale set to {this.ContentCore.Language}."; + string context = $"Context: loaded save '{Constants.SaveFolderName}', starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}, locale set to {this.ContentCore.GetLocale()}."; if (Context.IsMultiplayer) { int onlineCount = Game1.getOnlineFarmers().Count(); |