diff options
| author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-07-06 22:26:09 -0400 |
|---|---|---|
| committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-07-06 22:26:09 -0400 |
| commit | d51ffe58f7b7450cd4c4a7ee3d8b4da1cf55e7e4 (patch) | |
| tree | ec19cdd7567125e47cfd49c7c044fc09f09f6b2f /src/SMAPI/Framework | |
| parent | 8e9237bdd7ec179975c9be5e28c811b42007e707 (diff) | |
| parent | bcb9e25d8666d2c1384515063ffbf987c36b8b0e (diff) | |
| download | SMAPI-d51ffe58f7b7450cd4c4a7ee3d8b4da1cf55e7e4.tar.gz SMAPI-d51ffe58f7b7450cd4c4a7ee3d8b4da1cf55e7e4.tar.bz2 SMAPI-d51ffe58f7b7450cd4c4a7ee3d8b4da1cf55e7e4.zip | |
Merge branch 'develop' into stable
Diffstat (limited to 'src/SMAPI/Framework')
25 files changed, 247 insertions, 122 deletions
diff --git a/src/SMAPI/Framework/CommandQueue.cs b/src/SMAPI/Framework/CommandQueue.cs new file mode 100644 index 00000000..c51016ad --- /dev/null +++ b/src/SMAPI/Framework/CommandQueue.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace StardewModdingAPI.Framework +{ + /// <summary>A thread-safe command queue optimized for infrequent changes.</summary> + internal class CommandQueue + { + /******** + ** Fields + ********/ + /// <summary>The underlying list of queued commands to parse and execute.</summary> + private readonly List<string> RawCommandQueue = new(); + + + /******** + ** Public methods + ********/ + /// <summary>Add a command to the queue.</summary> + /// <param name="command">The command to add.</param> + public void Add(string command) + { + lock (this.RawCommandQueue) + this.RawCommandQueue.Add(command); + } + + /// <summary>Remove and return all queued commands, if any.</summary> + /// <param name="queued">The commands that were dequeued, in the order they were originally queued.</param> + /// <returns>Returns whether any values were dequeued.</returns> + [SuppressMessage("ReSharper", "InconsistentlySynchronizedField", Justification = "Deliberately check if it's empty before locking unnecessarily.")] + public bool TryDequeue([NotNullWhen(true)] out string[]? queued) + { + if (this.RawCommandQueue.Count is 0) + { + queued = null; + return false; + } + + lock (this.RawCommandQueue) + { + queued = this.RawCommandQueue.ToArray(); + this.RawCommandQueue.Clear(); + return queued.Length > 0; + } + } + } +} diff --git a/src/SMAPI/Framework/Content/AssetInfo.cs b/src/SMAPI/Framework/Content/AssetInfo.cs index 773e3126..43feed27 100644 --- a/src/SMAPI/Framework/Content/AssetInfo.cs +++ b/src/SMAPI/Framework/Content/AssetInfo.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using Microsoft.Xna.Framework.Graphics; +#if SMAPI_DEPRECATED using StardewModdingAPI.Framework.Deprecations; +#endif namespace StardewModdingAPI.Framework.Content { @@ -30,6 +32,10 @@ namespace StardewModdingAPI.Framework.Content public IAssetName NameWithoutLocale => this.NameWithoutLocaleImpl ??= this.Name.GetBaseAssetName(); /// <inheritdoc /> + public Type DataType { get; } + +#if SMAPI_DEPRECATED + /// <inheritdoc /> [Obsolete($"Use {nameof(AssetInfo.Name)} or {nameof(AssetInfo.NameWithoutLocale)} instead. This property will be removed in SMAPI 4.0.0.")] public string AssetName { @@ -50,9 +56,7 @@ namespace StardewModdingAPI.Framework.Content return this.NameWithoutLocale.Name; } } - - /// <inheritdoc /> - public Type DataType { get; } +#endif /********* @@ -71,6 +75,7 @@ namespace StardewModdingAPI.Framework.Content this.GetNormalizedPath = getNormalizedPath; } +#if SMAPI_DEPRECATED /// <inheritdoc /> [Obsolete($"Use {nameof(Name)}.{nameof(IAssetName.IsEquivalentTo)} or {nameof(AssetInfo.NameWithoutLocale)}.{nameof(IAssetName.IsEquivalentTo)} instead. This method will be removed in SMAPI 4.0.0.")] public bool AssetNameEquals(string path) @@ -90,6 +95,7 @@ namespace StardewModdingAPI.Framework.Content return this.NameWithoutLocale.IsEquivalentTo(path); } +#endif /********* diff --git a/src/SMAPI/Framework/Content/AssetInterceptorChange.cs b/src/SMAPI/Framework/Content/AssetInterceptorChange.cs index f3d4f3f4..3b5068dc 100644 --- a/src/SMAPI/Framework/Content/AssetInterceptorChange.cs +++ b/src/SMAPI/Framework/Content/AssetInterceptorChange.cs @@ -1,8 +1,8 @@ +#if SMAPI_DEPRECATED using System; using System.Reflection; using StardewModdingAPI.Internal; -#pragma warning disable CS0618 // obsolete asset interceptors deliberately supported here namespace StardewModdingAPI.Framework.Content { /// <summary>A wrapper for <see cref="IAssetEditor"/> and <see cref="IAssetLoader"/> for internal cache invalidation.</summary> @@ -103,3 +103,4 @@ namespace StardewModdingAPI.Framework.Content } } } +#endif diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs index 3e09ac62..9e044b44 100644 --- a/src/SMAPI/Framework/ContentCoordinator.cs +++ b/src/SMAPI/Framework/ContentCoordinator.cs @@ -12,7 +12,9 @@ using StardewModdingAPI.Framework.Content; using StardewModdingAPI.Framework.ContentManagers; using StardewModdingAPI.Framework.Reflection; using StardewModdingAPI.Framework.Utilities; +#if SMAPI_DEPRECATED using StardewModdingAPI.Internal; +#endif using StardewModdingAPI.Metadata; using StardewModdingAPI.Toolkit.Serialization; using StardewModdingAPI.Toolkit.Utilities.PathLookups; @@ -84,6 +86,7 @@ namespace StardewModdingAPI.Framework /// <summary>The cached asset load/edit operations to apply, indexed by asset name.</summary> private readonly TickCacheDictionary<IAssetName, AssetOperationGroup?> AssetOperationsByKey = new(); +#if SMAPI_DEPRECATED /// <summary>A cache of asset operation groups created for legacy <see cref="IAssetLoader"/> implementations.</summary> [Obsolete("This only exists to support legacy code and will be removed in SMAPI 4.0.0.")] private readonly Dictionary<IAssetLoader, Dictionary<Type, AssetLoadOperation>> LegacyLoaderCache = new(ReferenceEqualityComparer.Instance); @@ -91,6 +94,7 @@ namespace StardewModdingAPI.Framework /// <summary>A cache of asset operation groups created for legacy <see cref="IAssetEditor"/> implementations.</summary> [Obsolete("This only exists to support legacy code and will be removed in SMAPI 4.0.0.")] private readonly Dictionary<IAssetEditor, Dictionary<Type, AssetEditOperation>> LegacyEditorCache = new(ReferenceEqualityComparer.Instance); +#endif /********* @@ -102,6 +106,7 @@ namespace StardewModdingAPI.Framework /// <summary>The current language as a constant.</summary> public LocalizedContentManager.LanguageCode Language => this.MainContentManager.Language; +#if SMAPI_DEPRECATED /// <summary>Interceptors which provide the initial versions of matching assets.</summary> [Obsolete("This only exists to support legacy code and will be removed in SMAPI 4.0.0.")] public IList<ModLinked<IAssetLoader>> Loaders { get; } = new List<ModLinked<IAssetLoader>>(); @@ -109,6 +114,7 @@ namespace StardewModdingAPI.Framework /// <summary>Interceptors which edit matching assets after they're loaded.</summary> [Obsolete("This only exists to support legacy code and will be removed in SMAPI 4.0.0.")] public IList<ModLinked<IAssetEditor>> Editors { get; } = new List<ModLinked<IAssetEditor>>(); +#endif /// <summary>The absolute path to the <see cref="ContentManager.RootDirectory"/>.</summary> public string FullRootDirectory { get; } @@ -498,15 +504,25 @@ namespace StardewModdingAPI.Framework return invalidatedAssets.Keys; } +#if SMAPI_DEPRECATED /// <summary>Get the asset load and edit operations to apply to a given asset if it's (re)loaded now.</summary> /// <typeparam name="T">The asset type.</typeparam> /// <param name="info">The asset info to load or edit.</param> public AssetOperationGroup? GetAssetOperations<T>(IAssetInfo info) where T : notnull +#else + /// <summary>Get the asset load and edit operations to apply to a given asset if it's (re)loaded now.</summary> + /// <param name="info">The asset info to load or edit.</param> + public AssetOperationGroup? GetAssetOperations(IAssetInfo info) +#endif { return this.AssetOperationsByKey.GetOrSet( info.Name, +#if SMAPI_DEPRECATED () => this.GetAssetOperationsWithoutCache<T>(info) +#else + () => this.RequestAssetOperations(info) +#endif ); } @@ -629,6 +645,7 @@ namespace StardewModdingAPI.Framework return map; } +#if SMAPI_DEPRECATED /// <summary>Get the asset load and edit operations to apply to a given asset if it's (re)loaded now, ignoring the <see cref="AssetOperationsByKey"/> cache.</summary> /// <typeparam name="T">The asset type.</typeparam> /// <param name="info">The asset info to load or edit.</param> @@ -639,7 +656,6 @@ namespace StardewModdingAPI.Framework AssetOperationGroup? group = this.RequestAssetOperations(info); // legacy load operations -#pragma warning disable CS0612, CS0618 // deprecated code if (this.Editors.Count > 0 || this.Loaders.Count > 0) { IAssetInfo legacyInfo = this.GetLegacyAssetInfo(info); @@ -738,7 +754,6 @@ namespace StardewModdingAPI.Framework ); } } -#pragma warning restore CS0612, CS0618 return group; } @@ -818,5 +833,6 @@ namespace StardewModdingAPI.Framework // else no change needed return asset; } +#endif } } diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs index d7be0c37..54f8e2a2 100644 --- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs @@ -111,7 +111,6 @@ namespace StardewModdingAPI.Framework.ContentManagers } /// <inheritdoc /> - [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse", Justification = "Copied as-is from game code")] public sealed override string LoadBaseString(string path) { try @@ -119,7 +118,7 @@ namespace StardewModdingAPI.Framework.ContentManagers // 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); + Dictionary<string, string>? strings = this.Load<Dictionary<string, string>?>(assetName, LanguageCode.en); return strings != null && strings.ContainsKey(key) ? this.GetString(strings, key) : path; diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs index 446f4a67..df7bdc59 100644 --- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs @@ -76,7 +76,11 @@ namespace StardewModdingAPI.Framework.ContentManagers // custom asset from a loader string locale = this.GetLocale(); IAssetInfo info = new AssetInfo(locale, assetName, typeof(T), this.AssertAndNormalizeAssetName); - AssetOperationGroup? operations = this.Coordinator.GetAssetOperations<T>(info); + AssetOperationGroup? operations = this.Coordinator.GetAssetOperations +#if SMAPI_DEPRECATED + <T> +#endif + (info); if (operations?.LoadOperations.Count > 0) { if (!this.AssertMaxOneRequiredLoader(info, operations.LoadOperations, out string? error)) @@ -129,7 +133,11 @@ namespace StardewModdingAPI.Framework.ContentManagers data = this.AssetsBeingLoaded.Track(assetName.Name, () => { IAssetInfo info = new AssetInfo(assetName.LocaleCode, assetName, typeof(T), this.AssertAndNormalizeAssetName); - AssetOperationGroup? operations = this.Coordinator.GetAssetOperations<T>(info); + AssetOperationGroup? operations = this.Coordinator.GetAssetOperations +#if SMAPI_DEPRECATED + <T> +#endif + (info); IAssetData asset = this.ApplyLoader<T>(info, operations?.LoadOperations) ?? new AssetDataForObject(info, this.RawLoad<T>(assetName, useCache), this.AssertAndNormalizeAssetName, this.Reflection); @@ -294,7 +302,11 @@ namespace StardewModdingAPI.Framework.ContentManagers ? $"Multiple mods want to provide the '{info.Name}' asset: {string.Join(", ", loaderNames)}" : $"The '{loaderNames[0]}' mod wants to provide the '{info.Name}' asset multiple times"; - error = $"{errorPhrase}. An asset can't be loaded multiple times, so SMAPI will use the default asset instead. Uninstall one of the mods to fix this. (Message for modders: you should avoid {nameof(AssetLoadPriority)}.{nameof(AssetLoadPriority.Exclusive)} and {nameof(IAssetLoader)} if possible to avoid conflicts.)"; + error = $"{errorPhrase}. An asset can't be loaded multiple times, so SMAPI will use the default asset instead. Uninstall one of the mods to fix this. (Message for modders: you should avoid {nameof(AssetLoadPriority)}.{nameof(AssetLoadPriority.Exclusive)}" +#if SMAPI_DEPRECATED + + " and {nameof(IAssetLoader)}" +#endif + + " if possible to avoid conflicts.)"; return false; } @@ -349,6 +361,7 @@ namespace StardewModdingAPI.Framework.ContentManagers // handle mismatch if (loadedMap.TileSheets.Count <= vanillaSheet.Index || loadedMap.TileSheets[vanillaSheet.Index].Id != vanillaSheet.Id) { +#if SMAPI_DEPRECATED // only show warning if not farm map // This is temporary: mods shouldn't do this for any vanilla map, but these are the ones we know will crash. Showing a warning for others instead gives modders time to update their mods, while still simplifying troubleshooting. bool isFarmMap = info.Name.IsEquivalentTo("Maps/Farm") || info.Name.IsEquivalentTo("Maps/Farm_Combat") || info.Name.IsEquivalentTo("Maps/Farm_Fishing") || info.Name.IsEquivalentTo("Maps/Farm_Foraging") || info.Name.IsEquivalentTo("Maps/Farm_FourCorners") || info.Name.IsEquivalentTo("Maps/Farm_Island") || info.Name.IsEquivalentTo("Maps/Farm_Mining"); @@ -361,7 +374,12 @@ namespace StardewModdingAPI.Framework.ContentManagers mod.LogAsMod($"SMAPI blocked a '{info.Name}' map load: {reason}", LogLevel.Error); return false; } + mod.LogAsMod($"SMAPI found an issue with a '{info.Name}' map load: {reason}", LogLevel.Warn); +#else + mod.LogAsMod($"SMAPI found an issue with a '{info.Name}' map load: {this.GetOnBehalfOfLabel(loader.OnBehalfOf, parenthetical: false) ?? "mod"} reordered the original tilesheets, which often causes crashes.\nTechnical details for mod author: Expected order: {string.Join(", ", vanillaTilesheetRefs.Select(p => p.Id))}. See https://stardewvalleywiki.com/Modding:Maps#Tilesheet_order for help.", LogLevel.Error); + return false; +#endif } } } diff --git a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs index 8c5d0f84..f3cf05d9 100644 --- a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; @@ -47,9 +46,6 @@ namespace StardewModdingAPI.Framework.ContentManagers /// <summary>If a map tilesheet's image source has no file extensions, the file extensions to check for in the local mod folder.</summary> private static readonly string[] LocalTilesheetExtensions = { ".png", ".xnb" }; - /// <summary>A lookup of image file paths to whether they have PyTK scaling information.</summary> - private static readonly Dictionary<string, bool> IsPyTkScaled = new(StringComparer.OrdinalIgnoreCase); - /********* ** Accessors @@ -211,24 +207,13 @@ namespace StardewModdingAPI.Framework.ContentManagers { if (ModContentManager.EnablePyTkLegacyMode) { - if (!ModContentManager.IsPyTkScaled.TryGetValue(file.FullName, out bool isScaled)) - { - string? dirPath = file.DirectoryName; - string fileName = $"{Path.GetFileNameWithoutExtension(file.Name)}.pytk.json"; - - string path = dirPath is not null - ? Path.Combine(dirPath, fileName) - : fileName; - - ModContentManager.IsPyTkScaled[file.FullName] = isScaled = File.Exists(path); - } - - asRawData = !isScaled; - if (!asRawData) - this.Monitor.LogOnce("Enabled compatibility mode for PyTK scaled textures. This won't cause any issues, but may impact performance.", LogLevel.Warn); + // PyTK intercepts Texture2D file loads to rescale them (e.g. for HD portraits), + // but doesn't support IRawTextureData loads yet. We can't just check if the + // current file has a '.pytk.json' rescale file though, since PyTK may still + // rescale it if the original asset or another edit gets rescaled. + asRawData = false; + this.Monitor.LogOnce("Enabled compatibility mode for PyTK 1.23.0 or earlier. This won't cause any issues, but may impact performance.", LogLevel.Warn); } - else - asRawData = true; } // load diff --git a/src/SMAPI/Framework/ContentPack.cs b/src/SMAPI/Framework/ContentPack.cs index 70fe51f8..a1d977e4 100644 --- a/src/SMAPI/Framework/ContentPack.cs +++ b/src/SMAPI/Framework/ContentPack.cs @@ -96,6 +96,7 @@ namespace StardewModdingAPI.Framework } } +#if SMAPI_DEPRECATED /// <inheritdoc /> [Obsolete($"Use {nameof(IContentPack.ModContent)}.{nameof(IModContentHelper.Load)} instead. This method will be removed in SMAPI 4.0.0.")] public T LoadAsset<T>(string key) @@ -110,6 +111,7 @@ namespace StardewModdingAPI.Framework { return this.ModContent.GetInternalAssetName(key).Name; } +#endif /********* diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index d811ed5c..c0b7c0ba 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -400,7 +400,7 @@ namespace StardewModdingAPI.Framework.Logging /// <param name="mods">The loaded mods.</param> /// <param name="skippedMods">The mods which could not be loaded.</param> /// <param name="logParanoidWarnings">Whether to log issues for mods which directly use potentially sensitive .NET APIs like file or shell access.</param> - [SuppressMessage("ReSharper", "ConstantConditionalAccessQualifier", Justification = "Manifests aren't guaranteed non-null at this point in the loading process.")] + [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "Manifests aren't guaranteed non-null at this point in the loading process.")] private void LogModWarnings(IEnumerable<IModMetadata> mods, IModMetadata[] skippedMods, bool logParanoidWarnings) { // get mods with warnings diff --git a/src/SMAPI/Framework/ModHelpers/CommandHelper.cs b/src/SMAPI/Framework/ModHelpers/CommandHelper.cs index ddbd618a..21435f62 100644 --- a/src/SMAPI/Framework/ModHelpers/CommandHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/CommandHelper.cs @@ -1,5 +1,7 @@ using System; +#if SMAPI_DEPRECATED using StardewModdingAPI.Framework.Deprecations; +#endif namespace StardewModdingAPI.Framework.ModHelpers { @@ -32,6 +34,7 @@ namespace StardewModdingAPI.Framework.ModHelpers return this; } +#if SMAPI_DEPRECATED /// <inheritdoc /> [Obsolete("Use mod-provided APIs to integrate with mods instead. This method will be removed in SMAPI 4.0.0.")] public bool Trigger(string name, string[] arguments) @@ -45,5 +48,6 @@ namespace StardewModdingAPI.Framework.ModHelpers return this.CommandManager.Trigger(name, arguments); } +#endif } } diff --git a/src/SMAPI/Framework/ModHelpers/ContentHelper.cs b/src/SMAPI/Framework/ModHelpers/ContentHelper.cs index 427adac2..9992cb52 100644 --- a/src/SMAPI/Framework/ModHelpers/ContentHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ContentHelper.cs @@ -1,3 +1,4 @@ +#if SMAPI_DEPRECATED using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -249,3 +250,4 @@ namespace StardewModdingAPI.Framework.ModHelpers } } } +#endif diff --git a/src/SMAPI/Framework/ModHelpers/ModHelper.cs b/src/SMAPI/Framework/ModHelpers/ModHelper.cs index 48973691..caa66bad 100644 --- a/src/SMAPI/Framework/ModHelpers/ModHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ModHelper.cs @@ -1,7 +1,9 @@ using System; using System.IO; using StardewModdingAPI.Events; +#if SMAPI_DEPRECATED using StardewModdingAPI.Framework.Deprecations; +#endif using StardewModdingAPI.Framework.Input; namespace StardewModdingAPI.Framework.ModHelpers @@ -9,12 +11,14 @@ namespace StardewModdingAPI.Framework.ModHelpers /// <summary>Provides simplified APIs for writing mods.</summary> internal class ModHelper : BaseHelper, IModHelper, IDisposable { +#if SMAPI_DEPRECATED /********* ** Fields *********/ /// <summary>The backing field for <see cref="Content"/>.</summary> [Obsolete("This only exists to support legacy code and will be removed in SMAPI 4.0.0.")] private readonly ContentHelper ContentImpl; +#endif /********* @@ -26,6 +30,7 @@ namespace StardewModdingAPI.Framework.ModHelpers /// <inheritdoc /> public IModEvents Events { get; } +#if SMAPI_DEPRECATED /// <inheritdoc /> [Obsolete($"Use {nameof(IGameContentHelper)} or {nameof(IModContentHelper)} instead.")] public IContentHelper Content @@ -42,6 +47,7 @@ namespace StardewModdingAPI.Framework.ModHelpers return this.ContentImpl; } } +#endif /// <inheritdoc /> public IGameContentHelper GameContent { get; } @@ -96,9 +102,9 @@ namespace StardewModdingAPI.Framework.ModHelpers /// <exception cref="InvalidOperationException">The <paramref name="modDirectory"/> path does not exist on disk.</exception> public ModHelper( IModMetadata mod, string modDirectory, Func<SInputState> currentInputState, IModEvents events, -#pragma warning disable CS0612 // deprecated code +#if SMAPI_DEPRECATED ContentHelper contentHelper, -#pragma warning restore CS0612 +#endif IGameContentHelper gameContentHelper, IModContentHelper modContentHelper, IContentPackHelper contentPackHelper, ICommandHelper commandHelper, IDataHelper dataHelper, IModRegistry modRegistry, IReflectionHelper reflectionHelper, IMultiplayerHelper multiplayer, ITranslationHelper translationHelper ) : base(mod) @@ -111,9 +117,9 @@ namespace StardewModdingAPI.Framework.ModHelpers // initialize this.DirectoryPath = modDirectory; -#pragma warning disable CS0612 // deprecated code +#if SMAPI_DEPRECATED this.ContentImpl = contentHelper ?? throw new ArgumentNullException(nameof(contentHelper)); -#pragma warning restore CS0612 +#endif this.GameContent = gameContentHelper ?? throw new ArgumentNullException(nameof(gameContentHelper)); this.ModContent = modContentHelper ?? throw new ArgumentNullException(nameof(modContentHelper)); this.ContentPacks = contentPackHelper ?? throw new ArgumentNullException(nameof(contentPackHelper)); @@ -127,12 +133,14 @@ namespace StardewModdingAPI.Framework.ModHelpers this.Events = events; } +#if SMAPI_DEPRECATED /// <summary>Get the underlying instance for <see cref="IContentHelper"/>.</summary> [Obsolete("This only exists to support legacy code and will be removed in SMAPI 4.0.0.")] public ContentHelper GetLegacyContentHelper() { return this.ContentImpl; } +#endif /**** ** Mod config file diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index e5aaa8ee..eb940c41 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -163,6 +163,7 @@ namespace StardewModdingAPI.Framework.ModLoading this.AssemblyDefinitionResolver.Add(assembly.Definition); } +#if SMAPI_DEPRECATED // special case: clear legacy-DLL warnings if the mod bundles a copy if (mod.Warnings.HasFlag(ModWarning.DetectedLegacyCachingDll)) { @@ -185,6 +186,7 @@ namespace StardewModdingAPI.Framework.ModLoading if (File.Exists(Path.Combine(mod.DirectoryPath, "System.Security.Permissions.dll"))) mod.RemoveWarning(ModWarning.DetectedLegacyPermissionsDll); } +#endif // throw if incompatibilities detected if (!assumeCompatible && mod.Warnings.HasFlag(ModWarning.BrokenCodeLoaded)) @@ -452,6 +454,7 @@ namespace StardewModdingAPI.Framework.ModLoading mod.SetWarning(ModWarning.AccessesShell); break; +#if SMAPI_DEPRECATED case InstructionHandleResult.DetectedLegacyCachingDll: template = $"{logPrefix}Detected reference to System.Runtime.Caching.dll, which will be removed in SMAPI 4.0.0."; mod.SetWarning(ModWarning.DetectedLegacyCachingDll); @@ -466,6 +469,7 @@ namespace StardewModdingAPI.Framework.ModLoading template = $"{logPrefix}Detected reference to System.Security.Permissions.dll, which will be removed in SMAPI 4.0.0."; mod.SetWarning(ModWarning.DetectedLegacyPermissionsDll); break; +#endif case InstructionHandleResult.None: break; diff --git a/src/SMAPI/Framework/ModLoading/Finders/LegacyAssemblyFinder.cs b/src/SMAPI/Framework/ModLoading/Finders/LegacyAssemblyFinder.cs index d3437b05..77380907 100644 --- a/src/SMAPI/Framework/ModLoading/Finders/LegacyAssemblyFinder.cs +++ b/src/SMAPI/Framework/ModLoading/Finders/LegacyAssemblyFinder.cs @@ -1,3 +1,4 @@ +#if SMAPI_DEPRECATED using Mono.Cecil; using StardewModdingAPI.Framework.ModLoading.Framework; @@ -47,3 +48,4 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders } } } +#endif diff --git a/src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs b/src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs index 476c30d0..189ca64e 100644 --- a/src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs +++ b/src/SMAPI/Framework/ModLoading/InstructionHandleResult.cs @@ -32,6 +32,7 @@ namespace StardewModdingAPI.Framework.ModLoading /// <summary>The instruction accesses the OS shell or processes directly.</summary> DetectedShellAccess, +#if SMAPI_DEPRECATED /// <summary>The module references the legacy <c>System.Configuration.ConfigurationManager</c> assembly and doesn't include a copy in the mod folder, so it'll break in SMAPI 4.0.0.</summary> DetectedLegacyConfigurationDll, @@ -40,5 +41,6 @@ namespace StardewModdingAPI.Framework.ModLoading /// <summary>The module references the legacy <c>System.Security.Permissions</c> assembly and doesn't include a copy in the mod folder, so it'll break in SMAPI 4.0.0.</summary> DetectedLegacyPermissionsDll +#endif } } diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index aa4d2d8c..ac7a6bbd 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -83,7 +83,7 @@ namespace StardewModdingAPI.Framework.ModLoading /// <inheritdoc /> [MemberNotNullWhen(true, nameof(ModMetadata.ContentPack))] - [SuppressMessage("ReSharper", "ConstantConditionalAccessQualifier", Justification = "The manifest may be null for broken mods while loading.")] + [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "The manifest may be null for broken mods while loading.")] public bool IsContentPack => this.Manifest?.ContentPackFor != null; /// <summary>The fake c |
