diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-05-06 18:05:40 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-05-06 18:05:40 -0400 |
commit | 87d5288287520f750651667839ebbe7bbeb97bba (patch) | |
tree | 80afbe8f2ccd1bc828d52af0f964acaeb15d0db6 | |
parent | 295ad29b8d60fdbae0c0030e8d887a2adab779a3 (diff) | |
download | SMAPI-87d5288287520f750651667839ebbe7bbeb97bba.tar.gz SMAPI-87d5288287520f750651667839ebbe7bbeb97bba.tar.bz2 SMAPI-87d5288287520f750651667839ebbe7bbeb97bba.zip |
fix content managers' LoadBaseString not recognizing localized mod assets
-rw-r--r-- | docs/release-notes.md | 1 | ||||
-rw-r--r-- | src/SMAPI/Framework/ContentManagers/BaseContentManager.cs | 49 |
2 files changed, 50 insertions, 0 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md index 2fff0c58..99269bc6 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -7,6 +7,7 @@ _You can enable them by editing `smapi-internal/config.json` if needed. They'll be re-enabled in a later version after they're reworked to reduce performance impact._ * Removed experimental 'aggressive memory optimizations' option. _This was disabled by default and is no longer needed in most cases. Memory usage will be better reduced by reworked asset propagation in the upcoming SMAPI 4.0.0._ + * Fixed 'content file was not found' error when the game tries to load unlocalized text from a localizable mod data asset. * Updated compatibility list. ## 3.14.0 diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs index db2934a0..e4695588 100644 --- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs @@ -111,6 +111,26 @@ namespace StardewModdingAPI.Framework.ContentManagers } /// <inheritdoc /> + [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse", Justification = "Copied as-is from game code")] + public sealed override string LoadBaseString(string path) + { + try + { + // copied as-is from LocalizedContentManager.LoadBaseString + // This is only changed to call this.Load instead of base.Load, to support mod assets + this.ParseStringPath(path, out string assetName, out string key); + Dictionary<string, string> strings = this.Load<Dictionary<string, string>>(assetName, LanguageCode.en); + return strings != null && strings.ContainsKey(key) + ? this.GetString(strings, key) + : path; + } + catch (Exception ex) + { + throw new InvalidOperationException($"Failed loading string path '{path}' from '{this.Name}'.", ex); + } + } + + /// <inheritdoc /> public sealed override T Load<T>(string assetName) { return this.Load<T>(assetName, this.Language); @@ -331,5 +351,34 @@ namespace StardewModdingAPI.Framework.ContentManagers // avoid hard disposable references; see remarks on the field this.BaseDisposableReferences.Clear(); } + + /**** + ** Private methods copied from the game code + ****/ +#pragma warning disable CS1574 // <see cref /> can't be resolved: the reference is valid but private + /// <summary>Parse a string path like <c>assetName:key</c>.</summary> + /// <param name="path">The string path.</param> + /// <param name="assetName">The extracted asset name.</param> + /// <param name="key">The extracted entry key.</param> + /// <exception cref="ContentLoadException">The string path is not in a valid format.</exception> + /// <remarks>This is copied as-is from <see cref="LocalizedContentManager.parseStringPath"/>.</remarks> + private void ParseStringPath(string path, out string assetName, out string key) + { + int length = path.IndexOf(':'); + assetName = length != -1 ? path.Substring(0, length) : throw new ContentLoadException("Unable to parse string path: " + path); + key = path.Substring(length + 1, path.Length - length - 1); + } + + /// <summary>Get a string value from a dictionary asset.</summary> + /// <param name="strings">The asset to read.</param> + /// <param name="key">The string key to find.</param> + /// <remarks>This is copied as-is from <see cref="LocalizedContentManager.GetString"/>.</remarks> + private string GetString(Dictionary<string, string> strings, string key) + { + return strings.TryGetValue(key + ".desktop", out string? str) + ? str + : strings[key]; + } +#pragma warning restore CS1574 } } |