diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2021-09-01 20:58:21 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2021-09-01 20:58:21 -0400 |
commit | 1240cb21024c3b715a6dacb2bec170a588a08791 (patch) | |
tree | 271c007b8a4dd533064af38fa2c125c0566e17b9 | |
parent | 8bfab94213e86c4245961150bd3423ee85213c5d (diff) | |
download | SMAPI-1240cb21024c3b715a6dacb2bec170a588a08791.tar.gz SMAPI-1240cb21024c3b715a6dacb2bec170a588a08791.tar.bz2 SMAPI-1240cb21024c3b715a6dacb2bec170a588a08791.zip |
fix translations not initialized for temporary content packs
-rw-r--r-- | docs/release-notes.md | 3 | ||||
-rw-r--r-- | src/SMAPI/Framework/ContentPack.cs | 10 | ||||
-rw-r--r-- | src/SMAPI/Framework/IModMetadata.cs | 7 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModLoading/ModMetadata.cs | 18 | ||||
-rw-r--r-- | src/SMAPI/Framework/SCore.cs | 50 |
5 files changed, 77 insertions, 11 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md index a8db9cbd..1db50e26 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -6,6 +6,9 @@ * Improved mod compatibility in 64-bit mode (thanks to spacechase0!). * Reducing load time when scanning/rewriting many mods for compatibility. +* For mod authors: + * Fixed content packs created via `helper.ContentPacks.CreateFake` or `CreateTemporary` not initializing translations correctly. + * For console commands: * Added `hurry_all` command which immediately warps all NPCs to their scheduled positions. diff --git a/src/SMAPI/Framework/ContentPack.cs b/src/SMAPI/Framework/ContentPack.cs index 0660a367..b6add7b5 100644 --- a/src/SMAPI/Framework/ContentPack.cs +++ b/src/SMAPI/Framework/ContentPack.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using StardewModdingAPI.Framework.ModHelpers; using StardewModdingAPI.Toolkit.Serialization; using StardewModdingAPI.Toolkit.Utilities; @@ -32,7 +33,10 @@ namespace StardewModdingAPI.Framework public IManifest Manifest { get; } /// <inheritdoc /> - public ITranslationHelper Translation { get; } + public ITranslationHelper Translation => this.TranslationImpl; + + /// <summary>The underlying translation helper.</summary> + internal TranslationHelper TranslationImpl { get; set; } /********* @@ -44,12 +48,12 @@ namespace StardewModdingAPI.Framework /// <param name="content">Provides an API for loading content assets.</param> /// <param name="translation">Provides translations stored in the content pack's <c>i18n</c> folder.</param> /// <param name="jsonHelper">Encapsulates SMAPI's JSON file parsing.</param> - public ContentPack(string directoryPath, IManifest manifest, IContentHelper content, ITranslationHelper translation, JsonHelper jsonHelper) + public ContentPack(string directoryPath, IManifest manifest, IContentHelper content, TranslationHelper translation, JsonHelper jsonHelper) { this.DirectoryPath = directoryPath; this.Manifest = manifest; this.Content = content; - this.Translation = translation; + this.TranslationImpl = translation; this.JsonHelper = jsonHelper; foreach (string path in Directory.EnumerateFiles(this.DirectoryPath, "*", SearchOption.AllDirectories)) diff --git a/src/SMAPI/Framework/IModMetadata.cs b/src/SMAPI/Framework/IModMetadata.cs index f5babafb..cb876ee4 100644 --- a/src/SMAPI/Framework/IModMetadata.cs +++ b/src/SMAPI/Framework/IModMetadata.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using StardewModdingAPI.Framework.ModHelpers; using StardewModdingAPI.Framework.ModLoading; @@ -64,6 +65,9 @@ namespace StardewModdingAPI.Framework /// <summary>The update-check metadata for this mod (if any).</summary> ModEntryModel UpdateCheckData { get; } + /// <summary>The fake content packs created by this mod, if any.</summary> + ISet<WeakReference<ContentPack>> FakeContentPacks { get; } + /********* ** Public methods @@ -135,5 +139,8 @@ namespace StardewModdingAPI.Framework /// <summary>Get a relative path which includes the root folder name.</summary> string GetRelativePathWithRoot(); + + /// <summary>Get the currently live fake content packs created by this mod.</summary> + IEnumerable<ContentPack> GetFakeContentPacks(); } } diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index 0ace084f..9e6bc61f 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -83,6 +83,9 @@ namespace StardewModdingAPI.Framework.ModLoading /// <inheritdoc /> public bool IsContentPack => this.Manifest?.ContentPackFor != null; + /// <summary>The fake content packs created by this mod, if any.</summary> + public ISet<WeakReference<ContentPack>> FakeContentPacks { get; } = new HashSet<WeakReference<ContentPack>>(); + /********* ** Public methods @@ -244,6 +247,21 @@ namespace StardewModdingAPI.Framework.ModLoading return Path.Combine(rootFolderName, this.RelativeDirectoryPath); } + /// <summary>Get the currently live fake content packs created by this mod.</summary> + public IEnumerable<ContentPack> GetFakeContentPacks() + { + foreach (var reference in this.FakeContentPacks.ToArray()) + { + if (!reference.TryGetTarget(out ContentPack pack)) + { + this.FakeContentPacks.Remove(reference); + continue; + } + + yield return pack; + } + } + /********* ** Private methods diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 61fb77b2..f7efc89e 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -49,6 +49,7 @@ using StardewModdingAPI.Utilities; using StardewValley; using xTile.Display; using MiniMonoModHotfix = MonoMod.Utils.MiniMonoModHotfix; +using PathUtilities = StardewModdingAPI.Toolkit.Utilities.PathUtilities; using SObject = StardewValley.Object; namespace StardewModdingAPI.Framework @@ -1060,7 +1061,12 @@ namespace StardewModdingAPI.Framework // update mod translation helpers foreach (IModMetadata mod in this.ModRegistry.GetAll()) + { mod.Translations.SetLocale(locale, languageCode); + + foreach (ContentPack contentPack in mod.GetFakeContentPacks()) + contentPack.TranslationImpl.SetLocale(locale, languageCode); + } } /// <summary>Raised when the low-level stage while loading a save changes.</summary> @@ -1772,8 +1778,12 @@ namespace StardewModdingAPI.Framework { IMonitor packMonitor = this.LogManager.GetMonitor(packManifest.Name); IContentHelper packContentHelper = new ContentHelper(contentCore, packDirPath, packManifest.UniqueID, packManifest.Name, packMonitor); - ITranslationHelper packTranslationHelper = new TranslationHelper(packManifest.UniqueID, contentCore.GetLocale(), contentCore.Language); - return new ContentPack(packDirPath, packManifest, packContentHelper, packTranslationHelper, this.Toolkit.JsonHelper); + TranslationHelper packTranslationHelper = new TranslationHelper(packManifest.UniqueID, contentCore.GetLocale(), contentCore.Language); + + ContentPack contentPack = new ContentPack(packDirPath, packManifest, packContentHelper, packTranslationHelper, this.Toolkit.JsonHelper); + this.ReloadTranslationsForTemporaryContentPack(mod, contentPack); + mod.FakeContentPacks.Add(new WeakReference<ContentPack>(contentPack)); + return contentPack; } IModEvents events = new ModEvents(mod, this.EventManager); @@ -1867,17 +1877,41 @@ namespace StardewModdingAPI.Framework // mod translations foreach (IModMetadata metadata in mods) { - var translations = this.ReadTranslationFiles(Path.Combine(metadata.DirectoryPath, "i18n"), out IList<string> errors); - if (errors.Any()) + // top-level mod { - metadata.LogAsMod("Mod couldn't load some translation files:", LogLevel.Warn); - foreach (string error in errors) - metadata.LogAsMod($" - {error}", LogLevel.Warn); + var translations = this.ReadTranslationFiles(Path.Combine(metadata.DirectoryPath, "i18n"), out IList<string> errors); + if (errors.Any()) + { + metadata.LogAsMod("Mod couldn't load some translation files:", LogLevel.Warn); + foreach (string error in errors) + metadata.LogAsMod($" - {error}", LogLevel.Warn); + } + + metadata.Translations.SetTranslations(translations); } - metadata.Translations.SetTranslations(translations); + + // fake content packs + foreach (ContentPack pack in metadata.GetFakeContentPacks()) + this.ReloadTranslationsForTemporaryContentPack(metadata, pack); } } + /// <summary>Load or reload translations for a temporary content pack created by a mod.</summary> + /// <param name="parentMod">The parent mod which created the content pack.</param> + /// <param name="contentPack">The content pack instance.</param> + private void ReloadTranslationsForTemporaryContentPack(IModMetadata parentMod, ContentPack contentPack) + { + var translations = this.ReadTranslationFiles(Path.Combine(contentPack.DirectoryPath, "i18n"), out IList<string> errors); + if (errors.Any()) + { + parentMod.LogAsMod($"Generated content pack at '{PathUtilities.GetRelativePath(Constants.ModsPath, contentPack.DirectoryPath)}' couldn't load some translation files:", LogLevel.Warn); + foreach (string error in errors) + parentMod.LogAsMod($" - {error}", LogLevel.Warn); + } + + contentPack.TranslationImpl.SetTranslations(translations); + } + /// <summary>Read translations from a directory containing JSON translation files.</summary> /// <param name="folderPath">The folder path to search.</param> /// <param name="errors">The errors indicating why translation files couldn't be parsed, indexed by translation filename.</param> |