From 944c03737e7f7d7788f4321224a4e59a4f04717d Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 28 Feb 2021 12:01:11 -0500 Subject: add load stages immediately after game adds initial locations --- docs/release-notes.md | 4 +++ src/SMAPI/Enums/LoadStage.cs | 6 ++++ src/SMAPI/Patches/LoadContextPatch.cs | 53 +++++++++++++++++++++++++++++++---- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index fb67d8dc..e7401910 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -7,6 +7,10 @@ * Migrated to Harmony 2.0 (see [_migrate to Harmony 2.0_](https://stardewvalleywiki.com/Modding:Migrate_to_Harmony_2.0) for more info). --> +## Upcoming release +* For mod authors: + * Added two stages to the `LoadStageChanged` event: `CreatedInitialLocations` and `SaveAddedLocations`, raised immediately after the game adds its vanilla locations but before they're initialized. + ## 3.9.2 Released 21 February 2021 for Stardew Valley 1.5.4 or later. diff --git a/src/SMAPI/Enums/LoadStage.cs b/src/SMAPI/Enums/LoadStage.cs index 5c2b0412..aa95d201 100644 --- a/src/SMAPI/Enums/LoadStage.cs +++ b/src/SMAPI/Enums/LoadStage.cs @@ -9,6 +9,9 @@ namespace StardewModdingAPI.Enums /// The game is creating a new save slot, and has initialized the basic save info. CreatedBasicInfo, + /// The game is creating a new save slot, and has added the location instances but hasn't fully initialized them yet. + CreatedInitialLocations, + /// The game is creating a new save slot, and has initialized the in-game locations. CreatedLocations, @@ -21,6 +24,9 @@ namespace StardewModdingAPI.Enums /// The game is loading a save slot, and has applied the basic save info (including player data). Not applicable when connecting to a multiplayer host. Note that some basic info (like daily luck) is not initialized at this point. This is equivalent to value 36. SaveLoadedBasicInfo, + /// The game is loading a save slot and has added the location instances, but hasn't applied the data yet. Not applicable when connecting to a multiplayer host. + SaveAddedLocations, + /// The game is loading a save slot, and has applied the in-game location data. Not applicable when connecting to a multiplayer host. This is equivalent to value 50. SaveLoadedLocations, diff --git a/src/SMAPI/Patches/LoadContextPatch.cs b/src/SMAPI/Patches/LoadContextPatch.cs index ceda061b..9fddcc50 100644 --- a/src/SMAPI/Patches/LoadContextPatch.cs +++ b/src/SMAPI/Patches/LoadContextPatch.cs @@ -29,6 +29,9 @@ namespace StardewModdingAPI.Patches /// A callback to invoke when the load stage changes. private static Action OnStageChanged; + /// Whether the game is running running the code in . + private static bool IsInLoadForNewGame; + /********* ** Accessors @@ -62,9 +65,16 @@ namespace StardewModdingAPI.Patches prefix: new HarmonyMethod(this.GetType(), nameof(LoadContextPatch.Before_TitleMenu_CreatedNewCharacter)) ); - // detect CreatedLocations + // detect CreatedInitialLocations and SaveAddedLocations + harmony.Patch( + original: AccessTools.Method(typeof(Game1), nameof(Game1.AddModNPCs)), + prefix: new HarmonyMethod(this.GetType(), nameof(LoadContextPatch.Before_Game1_AddModNPCs)) + ); + + // detect CreatedLocations, and track IsInLoadForNewGame harmony.Patch( original: AccessTools.Method(typeof(Game1), nameof(Game1.loadForNewGame)), + prefix: new HarmonyMethod(this.GetType(), nameof(LoadContextPatch.Before_Game1_LoadForNewGame)), postfix: new HarmonyMethod(this.GetType(), nameof(LoadContextPatch.After_Game1_LoadForNewGame)) ); } @@ -82,16 +92,49 @@ namespace StardewModdingAPI.Patches return true; } + /// Called before . + /// Returns whether to execute the original method. + /// This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments. + private static bool Before_Game1_AddModNPCs() + { + // When this method is called from Game1.loadForNewGame, it happens right after adding the vanilla + // locations but before initializing them. + if (LoadContextPatch.IsInLoadForNewGame) + { + LoadContextPatch.OnStageChanged(LoadContextPatch.IsCreating() + ? LoadStage.CreatedInitialLocations + : LoadStage.SaveAddedLocations + ); + } + + return true; + } + + /// Called before . + /// Returns whether to execute the original method. + /// This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments. + private static bool Before_Game1_LoadForNewGame() + { + LoadContextPatch.IsInLoadForNewGame = true; + return true; + } + /// Called after . /// This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments. private static void After_Game1_LoadForNewGame() { - bool creating = - (Game1.currentMinigame is Intro) // creating save with intro - || (Game1.activeClickableMenu is TitleMenu menu && LoadContextPatch.Reflection.GetField(menu, "transitioningCharacterCreationMenu").GetValue()); // creating save, skipped intro + LoadContextPatch.IsInLoadForNewGame = false; - if (creating) + if (LoadContextPatch.IsCreating()) LoadContextPatch.OnStageChanged(LoadStage.CreatedLocations); } + + /// Get whether the save file is currently being created. + private static bool IsCreating() + { + return + (Game1.currentMinigame is Intro) // creating save with intro + || (Game1.activeClickableMenu is TitleMenu menu && LoadContextPatch.Reflection.GetField(menu, "transitioningCharacterCreationMenu").GetValue()); // creating save, skipped intro + } } } -- cgit From 403616b07c6da6479ce77fd45b41f622e9972915 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 28 Feb 2021 12:39:37 -0500 Subject: fix mods with suppressed warnings counted for showing the log section --- docs/release-notes.md | 3 +++ src/SMAPI/Framework/IModMetadata.cs | 6 +++--- src/SMAPI/Framework/Logging/LogManager.cs | 10 +++++----- src/SMAPI/Framework/ModLoading/ModMetadata.cs | 19 ++++++++++++------- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index e7401910..d3b0698f 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -8,6 +8,9 @@ --> ## Upcoming release +* For players: + * Fixed console showing _found 1 mod with warnings_ with no mods listed. + * For mod authors: * Added two stages to the `LoadStageChanged` event: `CreatedInitialLocations` and `SaveAddedLocations`, raised immediately after the game adds its vanilla locations but before they're initialized. diff --git a/src/SMAPI/Framework/IModMetadata.cs b/src/SMAPI/Framework/IModMetadata.cs index 70cf0036..5d2f352d 100644 --- a/src/SMAPI/Framework/IModMetadata.cs +++ b/src/SMAPI/Framework/IModMetadata.cs @@ -34,7 +34,7 @@ namespace StardewModdingAPI.Framework /// The reason the mod failed to load, if applicable. ModFailReason? FailReason { get; } - /// Indicates non-error issues with the mod. + /// The non-error issues with the mod, ignoring those suppressed via . ModWarning Warnings { get; } /// The reason the metadata is invalid, if any. @@ -124,9 +124,9 @@ namespace StardewModdingAPI.Framework /// Whether the mod has at least one valid update key set. bool HasValidUpdateKeys(); - /// Get whether the mod has any of the given warnings which haven't been suppressed in the . + /// Get whether the mod has any of the given warnings, ignoring those suppressed via . /// The warnings to check. - bool HasUnsuppressedWarnings(params ModWarning[] warnings); + bool HasWarnings(params ModWarning[] warnings); /// Get a relative path which includes the root folder name. string GetRelativePathWithRoot(); diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index 2c7be399..f3656886 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -505,7 +505,7 @@ namespace StardewModdingAPI.Framework.Logging { this.LogModWarningGroup( modsWithWarnings, - match: mod => mod.HasUnsuppressedWarnings(ModWarning.AccessesConsole, ModWarning.AccessesFilesystem, ModWarning.AccessesShell), + match: mod => mod.HasWarnings(ModWarning.AccessesConsole, ModWarning.AccessesFilesystem, ModWarning.AccessesShell), level: LogLevel.Debug, heading: "Direct system access", blurb: new[] @@ -517,11 +517,11 @@ namespace StardewModdingAPI.Framework.Logging modLabel: mod => { List labels = new List(); - if (mod.HasUnsuppressedWarnings(ModWarning.AccessesConsole)) + if (mod.HasWarnings(ModWarning.AccessesConsole)) labels.Add("console"); - if (mod.HasUnsuppressedWarnings(ModWarning.AccessesFilesystem)) + if (mod.HasWarnings(ModWarning.AccessesFilesystem)) labels.Add("files"); - if (mod.HasUnsuppressedWarnings(ModWarning.AccessesShell)) + if (mod.HasWarnings(ModWarning.AccessesShell)) labels.Add("shells/processes"); return $"{mod.DisplayName} ({string.Join(", ", labels)})"; @@ -582,7 +582,7 @@ namespace StardewModdingAPI.Framework.Logging /// A detailed explanation of the warning, split into lines. private void LogModWarningGroup(IModMetadata[] mods, ModWarning warning, LogLevel level, string heading, params string[] blurb) { - this.LogModWarningGroup(mods, mod => mod.HasUnsuppressedWarnings(warning), level, heading, blurb); + this.LogModWarningGroup(mods, mod => mod.HasWarnings(warning), level, heading, blurb); } diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index 18d2b112..b4de3d6c 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -13,6 +13,13 @@ namespace StardewModdingAPI.Framework.ModLoading /// Metadata for a mod. internal class ModMetadata : IModMetadata { + /********* + ** Fields + *********/ + /// The non-error issues with the mod, including warnings suppressed by the data record. + private ModWarning ActualWarnings = ModWarning.None; + + /********* ** Accessors *********/ @@ -41,7 +48,7 @@ namespace StardewModdingAPI.Framework.ModLoading public ModFailReason? FailReason { get; private set; } /// - public ModWarning Warnings { get; private set; } + public ModWarning Warnings => this.ActualWarnings & ~(this.DataRecord?.DataRecord.SuppressWarnings ?? ModWarning.None); /// public string Error { get; private set; } @@ -116,7 +123,7 @@ namespace StardewModdingAPI.Framework.ModLoading /// public IModMetadata SetWarning(ModWarning warning) { - this.Warnings |= warning; + this.ActualWarnings |= warning; return this; } @@ -218,12 +225,10 @@ namespace StardewModdingAPI.Framework.ModLoading } /// - public bool HasUnsuppressedWarnings(params ModWarning[] warnings) + public bool HasWarnings(params ModWarning[] warnings) { - return warnings.Any(warning => - this.Warnings.HasFlag(warning) - && (this.DataRecord?.DataRecord == null || !this.DataRecord.DataRecord.SuppressWarnings.HasFlag(warning)) - ); + ModWarning curWarnings = this.Warnings; + return warnings.Any(warning => curWarnings.HasFlag(warning)); } /// -- cgit From b2d47e29ffe58142efd0a5084f33fefffd87a460 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 28 Feb 2021 14:17:41 -0500 Subject: add ReturningToTitle stage --- docs/release-notes.md | 2 +- src/SMAPI/Enums/LoadStage.cs | 5 ++++- src/SMAPI/Patches/LoadContextPatch.cs | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index d3b0698f..833e2130 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -12,7 +12,7 @@ * Fixed console showing _found 1 mod with warnings_ with no mods listed. * For mod authors: - * Added two stages to the `LoadStageChanged` event: `CreatedInitialLocations` and `SaveAddedLocations`, raised immediately after the game adds its vanilla locations but before they're initialized. + * Added three stages to the `LoadStageChanged` event: `CreatedInitialLocations`/`SaveAddedLocations` (raised immediately after the game adds locations but before they're initialized), and `ReturningToTitle` (raised before exiting to the title screen). ## 3.9.2 Released 21 February 2021 for Stardew Valley 1.5.4 or later. diff --git a/src/SMAPI/Enums/LoadStage.cs b/src/SMAPI/Enums/LoadStage.cs index aa95d201..250c88e9 100644 --- a/src/SMAPI/Enums/LoadStage.cs +++ b/src/SMAPI/Enums/LoadStage.cs @@ -37,6 +37,9 @@ namespace StardewModdingAPI.Enums Loaded, /// The save is fully loaded, the world has been initialized, and is now true. - Ready + Ready, + + /// The game is exiting the loaded save and returning to the title screen. This happens before it returns to title; see after it returns. + ReturningToTitle } } diff --git a/src/SMAPI/Patches/LoadContextPatch.cs b/src/SMAPI/Patches/LoadContextPatch.cs index 9fddcc50..28bc23b6 100644 --- a/src/SMAPI/Patches/LoadContextPatch.cs +++ b/src/SMAPI/Patches/LoadContextPatch.cs @@ -77,6 +77,12 @@ namespace StardewModdingAPI.Patches prefix: new HarmonyMethod(this.GetType(), nameof(LoadContextPatch.Before_Game1_LoadForNewGame)), postfix: new HarmonyMethod(this.GetType(), nameof(LoadContextPatch.After_Game1_LoadForNewGame)) ); + + // detect ReturningToTitle + harmony.Patch( + original: AccessTools.Method(typeof(Game1), nameof(Game1.CleanupReturningToTitle)), + prefix: new HarmonyMethod(this.GetType(), nameof(LoadContextPatch.Before_Game1_CleanupReturningToTitle)) + ); } @@ -110,6 +116,15 @@ namespace StardewModdingAPI.Patches return true; } + /// Called before . + /// Returns whether to execute the original method. + /// This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments. + private static bool Before_Game1_CleanupReturningToTitle() + { + LoadContextPatch.OnStageChanged(LoadStage.ReturningToTitle); + return true; + } + /// Called before . /// Returns whether to execute the original method. /// This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments. -- cgit From 5ce096c89a15e74102c2741672a4a75afed47ddb Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 28 Feb 2021 14:22:30 -0500 Subject: fix edge case for non-English farmhands where content coordinator handled return to title too late --- docs/release-notes.md | 1 + src/SMAPI/Framework/SCore.cs | 30 ++++++++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index 833e2130..6f69479e 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -13,6 +13,7 @@ * For mod authors: * Added three stages to the `LoadStageChanged` event: `CreatedInitialLocations`/`SaveAddedLocations` (raised immediately after the game adds locations but before they're initialized), and `ReturningToTitle` (raised before exiting to the title screen). + * Fixed edge case when playing as a farmhand in non-English where translatable assets loaded via `IAssetLoader` weren't reapplied immediately when the server disconnects. ## 3.9.2 Released 21 February 2021 for Stardew Valley 1.5.4 or later. diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 2d783eb2..5df4b61b 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -1054,17 +1054,24 @@ namespace StardewModdingAPI.Framework LoadStage oldStage = Context.LoadStage; Context.LoadStage = newStage; this.Monitor.VerboseLog($"Context: load stage changed to {newStage}"); - if (newStage == LoadStage.None) - { - this.Monitor.Log("Context: returned to title"); - this.OnReturnedToTitle(); - } - // override chatbox - if (newStage == LoadStage.Loaded) + // handle stages + switch (newStage) { - Game1.onScreenMenus.Remove(Game1.chatBox); - Game1.onScreenMenus.Add(Game1.chatBox = new SChatBox(this.LogManager.MonitorForGame)); + case LoadStage.ReturningToTitle: + this.Monitor.Log("Context: returning to title"); + this.OnReturningToTitle(); + break; + + case LoadStage.None: + this.JustReturnedToTitle = true; + break; + + case LoadStage.Loaded: + // override chatbox + Game1.onScreenMenus.Remove(Game1.chatBox); + Game1.onScreenMenus.Add(Game1.chatBox = new SChatBox(this.LogManager.MonitorForGame)); + break; } // raise events @@ -1113,13 +1120,12 @@ namespace StardewModdingAPI.Framework this.EventManager.DayEnding.RaiseEmpty(); } - /// Raised after the player returns to the title screen. - private void OnReturnedToTitle() + /// Raised immediately before the player returns to the title screen. + private void OnReturningToTitle() { // perform cleanup this.Multiplayer.CleanupOnMultiplayerExit(); this.ContentCore.OnReturningToTitleScreen(); - this.JustReturnedToTitle = true; } /// Raised before the game exits. -- cgit From 699a07ecf718ee60a1225ff910a73aa4898ef908 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 28 Feb 2021 20:12:39 -0500 Subject: fix broken references to LoadStage enum in previously compiled mods --- src/SMAPI/Enums/LoadStage.cs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/SMAPI/Enums/LoadStage.cs b/src/SMAPI/Enums/LoadStage.cs index 250c88e9..bf103576 100644 --- a/src/SMAPI/Enums/LoadStage.cs +++ b/src/SMAPI/Enums/LoadStage.cs @@ -4,42 +4,42 @@ namespace StardewModdingAPI.Enums public enum LoadStage { /// A save is not loaded or loading. - None, + None = 0, /// The game is creating a new save slot, and has initialized the basic save info. - CreatedBasicInfo, + CreatedBasicInfo = 1, /// The game is creating a new save slot, and has added the location instances but hasn't fully initialized them yet. - CreatedInitialLocations, + CreatedInitialLocations = 10, /// The game is creating a new save slot, and has initialized the in-game locations. - CreatedLocations, + CreatedLocations = 2, /// The game is creating a new save slot, and has created the physical save files. - CreatedSaveFile, + CreatedSaveFile = 3, /// The game is loading a save slot, and has read the raw save data into . Not applicable when connecting to a multiplayer host. This is equivalent to value 20. - SaveParsed, + SaveParsed = 4, /// The game is loading a save slot, and has applied the basic save info (including player data). Not applicable when connecting to a multiplayer host. Note that some basic info (like daily luck) is not initialized at this point. This is equivalent to value 36. - SaveLoadedBasicInfo, + SaveLoadedBasicInfo = 5, /// The game is loading a save slot and has added the location instances, but hasn't applied the data yet. Not applicable when connecting to a multiplayer host. - SaveAddedLocations, + SaveAddedLocations = 11, /// The game is loading a save slot, and has applied the in-game location data. Not applicable when connecting to a multiplayer host. This is equivalent to value 50. - SaveLoadedLocations, + SaveLoadedLocations = 6, /// The final metadata has been loaded from the save file. This happens before the game applies problem fixes, checks for achievements, starts music, etc. Not applicable when connecting to a multiplayer host. - Preloaded, + Preloaded = 7, /// The save is fully loaded, but the world may not be fully initialized yet. - Loaded, + Loaded = 8, /// The save is fully loaded, the world has been initialized, and is now true. - Ready, + Ready = 9, /// The game is exiting the loaded save and returning to the title screen. This happens before it returns to title; see after it returns. - ReturningToTitle + ReturningToTitle = 12 } } -- cgit From 5a2258f4194986df3dea7dca9b17cdc96b3e63d5 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 4 Mar 2021 21:59:49 -0500 Subject: fix RewriteMods option ignored when rewriting mod for OS --- docs/release-notes.md | 1 + src/SMAPI/Framework/ModLoading/AssemblyLoader.cs | 51 +++++++++++++----------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index 6f69479e..7a4a0409 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -13,6 +13,7 @@ * For mod authors: * Added three stages to the `LoadStageChanged` event: `CreatedInitialLocations`/`SaveAddedLocations` (raised immediately after the game adds locations but before they're initialized), and `ReturningToTitle` (raised before exiting to the title screen). + * Fixed `RewriteMods` option in `smapi-internal/config.json` ignored when rewriting mod for OS compatibility. * Fixed edge case when playing as a farmhand in non-English where translatable assets loaded via `IAssetLoader` weren't reapplied immediately when the server disconnects. ## 3.9.2 diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index 4fae0f44..69535aa5 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -276,37 +276,40 @@ namespace StardewModdingAPI.Framework.ModLoading // swap assembly references if needed (e.g. XNA => MonoGame) bool platformChanged = false; - for (int i = 0; i < module.AssemblyReferences.Count; i++) + if (this.RewriteMods) { - // remove old assembly reference - if (this.AssemblyMap.RemoveNames.Any(name => module.AssemblyReferences[i].Name == name)) + for (int i = 0; i < module.AssemblyReferences.Count; i++) { - this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Rewriting {filename} for OS..."); - platformChanged = true; - module.AssemblyReferences.RemoveAt(i); - i--; + // remove old assembly reference + if (this.AssemblyMap.RemoveNames.Any(name => module.AssemblyReferences[i].Name == name)) + { + this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Rewriting {filename} for OS..."); + platformChanged = true; + module.AssemblyReferences.RemoveAt(i); + i--; + } } - } - if (platformChanged) - { - // add target assembly references - foreach (AssemblyNameReference target in this.AssemblyMap.TargetReferences.Values) - module.AssemblyReferences.Add(target); + if (platformChanged) + { + // add target assembly references + foreach (AssemblyNameReference target in this.AssemblyMap.TargetReferences.Values) + module.AssemblyReferences.Add(target); - // rewrite type scopes to use target assemblies - IEnumerable typeReferences = module.GetTypeReferences().OrderBy(p => p.FullName); - foreach (TypeReference type in typeReferences) - this.ChangeTypeScope(type); + // rewrite type scopes to use target assemblies + IEnumerable typeReferences = module.GetTypeReferences().OrderBy(p => p.FullName); + foreach (TypeReference type in typeReferences) + this.ChangeTypeScope(type); - // rewrite types using custom attributes - foreach (TypeDefinition type in module.GetTypes()) - { - foreach (var attr in type.CustomAttributes) + // rewrite types using custom attributes + foreach (TypeDefinition type in module.GetTypes()) { - foreach (var conField in attr.ConstructorArguments) + foreach (var attr in type.CustomAttributes) { - if (conField.Value is TypeReference typeRef) - this.ChangeTypeScope(typeRef); + foreach (var conField in attr.ConstructorArguments) + { + if (conField.Value is TypeReference typeRef) + this.ChangeTypeScope(typeRef); + } } } } -- cgit From 36cb8e8fcb8afd2965ffe26e7755eb11838264d7 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 7 Mar 2021 17:42:55 -0500 Subject: keep window open when installer crashes --- docs/release-notes.md | 1 + src/SMAPI.Installer/Program.cs | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index 7a4a0409..ebe44f09 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -10,6 +10,7 @@ ## Upcoming release * For players: * Fixed console showing _found 1 mod with warnings_ with no mods listed. + * If the installer crashes, the window now stays open if possible so you can read the error and ask for help. * For mod authors: * Added three stages to the `LoadStageChanged` event: `CreatedInitialLocations`/`SaveAddedLocations` (raised immediately after the game adds locations but before they're initialized), and `ReturningToTitle` (raised before exiting to the title screen). diff --git a/src/SMAPI.Installer/Program.cs b/src/SMAPI.Installer/Program.cs index 6c479621..d9c31dd6 100644 --- a/src/SMAPI.Installer/Program.cs +++ b/src/SMAPI.Installer/Program.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.IO.Compression; using System.Reflection; +using System.Threading; namespace StardewModdingApi.Installer { @@ -49,7 +50,15 @@ namespace StardewModdingApi.Installer // launch installer var installer = new InteractiveInstaller(bundleDir.FullName); - installer.Run(args); + + try + { + installer.Run(args); + } + catch (Exception ex) + { + Program.PrintErrorAndExit($"The installer failed with an unexpected exception.\nIf you need help fixing this error, see https://smapi.io/help\n\n{ex}"); + } } /********* @@ -76,5 +85,19 @@ namespace StardewModdingApi.Installer return null; } } + + /// Write an error directly to the console and exit. + /// The error message to display. + private static void PrintErrorAndExit(string message) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(message); + Console.ResetColor(); + + Console.WriteLine("Game has ended. Press any key to exit."); + Thread.Sleep(100); + Console.ReadKey(); + Environment.Exit(0); + } } } -- cgit From 0ed46c09104b823a5784690fa50e7022efc12c8f Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 7 Mar 2021 18:04:48 -0500 Subject: add descriptive error for PathTooLongException which crashes SMAPI or the installer --- docs/release-notes.md | 3 ++- src/SMAPI.Installer/InteractiveInstaller.cs | 12 ++++++++++++ src/SMAPI.Toolkit/Properties/AssemblyInfo.cs | 1 + src/SMAPI.Toolkit/Utilities/PathUtilities.cs | 25 +++++++++++++++++++++++++ src/SMAPI/Framework/Logging/LogManager.cs | 13 ++++++++++++- 5 files changed, 52 insertions(+), 2 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index ebe44f09..39e33305 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -9,8 +9,9 @@ ## Upcoming release * For players: - * Fixed console showing _found 1 mod with warnings_ with no mods listed. * If the installer crashes, the window now stays open if possible so you can read the error and ask for help. + * Added descriptive error if possible when a `PathTooLongException` crashes SMAPI or the installer. + * Fixed console showing _found 1 mod with warnings_ with no mods listed. * For mod authors: * Added three stages to the `LoadStageChanged` event: `CreatedInitialLocations`/`SaveAddedLocations` (raised immediately after the game adds locations but before they're initialized), and `ReturningToTitle` (raised before exiting to the title screen). diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index ff74a659..3d673719 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -279,6 +279,7 @@ namespace StardewModdingApi.Installer /********* ** Step 4: validate assumptions *********/ + // executable exists if (!File.Exists(paths.ExecutablePath)) { this.PrintError("The detected game install path doesn't contain a Stardew Valley executable."); @@ -286,6 +287,17 @@ namespace StardewModdingApi.Installer return; } + // game folder doesn't contain paths beyond the max limit + { + string[] tooLongPaths = PathUtilities.GetTooLongPaths(Path.Combine(paths.GamePath, "Mods")).ToArray(); + if (tooLongPaths.Any()) + { + this.PrintError($"SMAPI can't install to the detected game folder, because some of its files exceed the maximum {context.Platform} path length.\nIf you need help fixing this error, see https://smapi.io/help\n\nAffected paths:\n {string.Join("\n ", tooLongPaths)}"); + Console.ReadLine(); + return; + } + } + /********* ** Step 5: ask what to do diff --git a/src/SMAPI.Toolkit/Properties/AssemblyInfo.cs b/src/SMAPI.Toolkit/Properties/AssemblyInfo.cs index 233e680b..eede4562 100644 --- a/src/SMAPI.Toolkit/Properties/AssemblyInfo.cs +++ b/src/SMAPI.Toolkit/Properties/AssemblyInfo.cs @@ -1,4 +1,5 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("StardewModdingAPI")] +[assembly: InternalsVisibleTo("SMAPI.Installer")] [assembly: InternalsVisibleTo("SMAPI.Web")] diff --git a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs index c9fb6213..a394edba 100644 --- a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs +++ b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics.Contracts; using System.IO; using System.Linq; @@ -133,5 +134,29 @@ namespace StardewModdingAPI.Toolkit.Utilities { return !Regex.IsMatch(str, "[^a-z0-9_.-]", RegexOptions.IgnoreCase); } + + /// Get the paths which exceed the OS length limit. + /// The root path to search. + internal static IEnumerable GetTooLongPaths(string rootPath) + { + return Directory + .EnumerateFileSystemEntries(rootPath, "*.*", SearchOption.AllDirectories) + .Where(PathUtilities.IsPathTooLong); + } + + /// Get whether a file or directory path exceeds the OS path length limit. + /// The path to test. + internal static bool IsPathTooLong(string path) + { + try + { + _ = Path.GetFullPath(path); + return false; + } + catch (PathTooLongException) + { + return true; + } + } } } diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index f3656886..0dd45355 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -252,11 +252,22 @@ namespace StardewModdingAPI.Framework.Logging break; // missing content folder exception - case FileNotFoundException ex when ex.Message == "Could not find file 'C:\\Program Files (x86)\\Steam\\SteamApps\\common\\Stardew Valley\\Content\\XACT\\FarmerSounds.xgs'.": // path in error is hardcoded regardless of install path + case FileNotFoundException ex when ex.Message == "Couldn't find file 'C:\\Program Files (x86)\\Steam\\SteamApps\\common\\Stardew Valley\\Content\\XACT\\FarmerSounds.xgs'.": // path in error is hardcoded regardless of install path this.Monitor.Log("The game can't find its Content\\XACT\\FarmerSounds.xgs file. You can usually fix this by resetting your content files (see https://smapi.io/troubleshoot#reset-content ), or by uninstalling and reinstalling the game.", LogLevel.Error); this.Monitor.Log($"Technical details: {ex.GetLogSummary()}"); break; + // path too long exception + case PathTooLongException: + { + string[] affectedPaths = PathUtilities.GetTooLongPaths(Constants.ModsPath).ToArray(); + string message = affectedPaths.Any() + ? $"SMAPI can't launch because some of your mod files exceed the maximum path length on {Constants.Platform}.\nIf you need help fixing this error, see https://smapi.io/help\n\nAffected paths:\n {string.Join("\n ", affectedPaths)}" + : $"The game failed to launch: {exception.GetLogSummary()}"; + this.MonitorForGame.Log(message, LogLevel.Error); + } + break; + // generic exception default: this.MonitorForGame.Log($"The game failed to launch: {exception.GetLogSummary()}", LogLevel.Error); -- cgit From 7914734375df7b4c94e9119611a0eb85cc2caac9 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 7 Mar 2021 19:48:47 -0500 Subject: get patcher names automatically if needed --- src/SMAPI.Mods.ErrorHandler/Patches/DialogueErrorPatch.cs | 7 ------- src/SMAPI.Mods.ErrorHandler/Patches/EventPatches.cs | 7 ------- src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatches.cs | 7 ------- src/SMAPI.Mods.ErrorHandler/Patches/LoadErrorPatch.cs | 7 ------- src/SMAPI.Mods.ErrorHandler/Patches/ObjectErrorPatch.cs | 7 ------- src/SMAPI.Mods.ErrorHandler/Patches/ScheduleErrorPatch.cs | 7 ------- .../Patches/SpriteBatchValidationPatches.cs | 7 ------- src/SMAPI.Mods.ErrorHandler/Patches/UtilityErrorPatches.cs | 7 ------- src/SMAPI/Framework/Patching/GamePatcher.cs | 2 +- src/SMAPI/Framework/Patching/IHarmonyPatch.cs | 6 +++--- src/SMAPI/Patches/LoadContextPatch.cs | 7 ------- 11 files changed, 4 insertions(+), 67 deletions(-) diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/DialogueErrorPatch.cs b/src/SMAPI.Mods.ErrorHandler/Patches/DialogueErrorPatch.cs index ba0ca582..cce13064 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/DialogueErrorPatch.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/DialogueErrorPatch.cs @@ -29,13 +29,6 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches private static IReflectionHelper Reflection; - /********* - ** Accessors - *********/ - /// - public string Name => nameof(DialogueErrorPatch); - - /********* ** Public methods *********/ diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/EventPatches.cs b/src/SMAPI.Mods.ErrorHandler/Patches/EventPatches.cs index a15c1d32..72863d17 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/EventPatches.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/EventPatches.cs @@ -23,13 +23,6 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches private static IMonitor MonitorForGame; - /********* - ** Accessors - *********/ - /// - public string Name => nameof(EventPatches); - - /********* ** Public methods *********/ diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatches.cs b/src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatches.cs index c10f2de7..1edf2d6a 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatches.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatches.cs @@ -24,13 +24,6 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches private static IMonitor MonitorForGame; - /********* - ** Accessors - *********/ - /// - public string Name => nameof(GameLocationPatches); - - /********* ** Public methods *********/ diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/LoadErrorPatch.cs b/src/SMAPI.Mods.ErrorHandler/Patches/LoadErrorPatch.cs index 2227ea07..52d5f5a1 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/LoadErrorPatch.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/LoadErrorPatch.cs @@ -31,13 +31,6 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches private static Action OnContentRemoved; - /********* - ** Accessors - *********/ - /// - public string Name => nameof(LoadErrorPatch); - - /********* ** Public methods *********/ diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/ObjectErrorPatch.cs b/src/SMAPI.Mods.ErrorHandler/Patches/ObjectErrorPatch.cs index 70f054cd..9f8a98cd 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/ObjectErrorPatch.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/ObjectErrorPatch.cs @@ -20,13 +20,6 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches [SuppressMessage("ReSharper", "IdentifierTypo", Justification = "Argument names are defined by Harmony and methods are named for clarity.")] internal class ObjectErrorPatch : IHarmonyPatch { - /********* - ** Accessors - *********/ - /// - public string Name => nameof(ObjectErrorPatch); - - /********* ** Public methods *********/ diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/ScheduleErrorPatch.cs b/src/SMAPI.Mods.ErrorHandler/Patches/ScheduleErrorPatch.cs index abbd1a8f..d2a5e988 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/ScheduleErrorPatch.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/ScheduleErrorPatch.cs @@ -26,13 +26,6 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches private static IMonitor MonitorForGame; - /********* - ** Accessors - *********/ - /// - public string Name => nameof(ScheduleErrorPatch); - - /********* ** Public methods *********/ diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchValidationPatches.cs b/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchValidationPatches.cs index 0211cfb1..95e4f5ef 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchValidationPatches.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchValidationPatches.cs @@ -16,13 +16,6 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches [SuppressMessage("ReSharper", "IdentifierTypo", Justification = "Argument names are defined by Harmony and methods are named for clarity.")] internal class SpriteBatchValidationPatches : IHarmonyPatch { - /********* - ** Accessors - *********/ - /// - public string Name => nameof(SpriteBatchValidationPatches); - - /********* ** Public methods *********/ diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/UtilityErrorPatches.cs b/src/SMAPI.Mods.ErrorHandler/Patches/UtilityErrorPatches.cs index 481c881e..1ddd407c 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/UtilityErrorPatches.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/UtilityErrorPatches.cs @@ -18,13 +18,6 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches [SuppressMessage("ReSharper", "IdentifierTypo", Justification = "Argument names are defined by Harmony and methods are named for clarity.")] internal class UtilityErrorPatches : IHarmonyPatch { - /********* - ** Accessors - *********/ - /// - public string Name => nameof(UtilityErrorPatches); - - /********* ** Public methods *********/ diff --git a/src/SMAPI/Framework/Patching/GamePatcher.cs b/src/SMAPI/Framework/Patching/GamePatcher.cs index 82d7b9c8..ddecda08 100644 --- a/src/SMAPI/Framework/Patching/GamePatcher.cs +++ b/src/SMAPI/Framework/Patching/GamePatcher.cs @@ -44,7 +44,7 @@ namespace StardewModdingAPI.Framework.Patching } catch (Exception ex) { - this.Monitor.Log($"Couldn't apply runtime patch '{patch.Name}' to the game. Some SMAPI features may not work correctly. See log file for details.", LogLevel.Error); + this.Monitor.Log($"Couldn't apply runtime patch '{patch.GetType().Name}' to the game. Some SMAPI features may not work correctly. See log file for details.", LogLevel.Error); this.Monitor.Log(ex.GetLogSummary(), LogLevel.Trace); } } diff --git a/src/SMAPI/Framework/Patching/IHarmonyPatch.cs b/src/SMAPI/Framework/Patching/IHarmonyPatch.cs index 922243fa..38d30ab2 100644 --- a/src/SMAPI/Framework/Patching/IHarmonyPatch.cs +++ b/src/SMAPI/Framework/Patching/IHarmonyPatch.cs @@ -9,9 +9,9 @@ namespace StardewModdingAPI.Framework.Patching /// A Harmony patch to apply. internal interface IHarmonyPatch { - /// A unique name for this patch. - string Name { get; } - + /********* + ** Methods + *********/ /// Apply the Harmony patch. /// The Harmony instance. #if HARMONY_2 diff --git a/src/SMAPI/Patches/LoadContextPatch.cs b/src/SMAPI/Patches/LoadContextPatch.cs index 28bc23b6..c43d7071 100644 --- a/src/SMAPI/Patches/LoadContextPatch.cs +++ b/src/SMAPI/Patches/LoadContextPatch.cs @@ -33,13 +33,6 @@ namespace StardewModdingAPI.Patches private static bool IsInLoadForNewGame; - /********* - ** Accessors - *********/ - /// - public string Name => nameof(LoadContextPatch); - - /********* ** Public methods *********/ -- cgit From a571f459f59a6ecfdd53e3158ba8d29157598920 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 7 Mar 2021 20:02:25 -0500 Subject: prepare for release --- build/common.targets | 2 +- docs/release-notes.md | 12 +++++++----- src/SMAPI.Mods.ConsoleCommands/manifest.json | 4 ++-- src/SMAPI.Mods.ErrorHandler/manifest.json | 4 ++-- src/SMAPI.Mods.SaveBackup/manifest.json | 4 ++-- src/SMAPI/Constants.cs | 2 +- src/SMAPI/Enums/LoadStage.cs | 4 ++-- 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/build/common.targets b/build/common.targets index 29acbb56..50c839e1 100644 --- a/build/common.targets +++ b/build/common.targets @@ -4,7 +4,7 @@ - 3.9.2 + 3.9.3 SMAPI latest diff --git a/docs/release-notes.md b/docs/release-notes.md index 39e33305..36351f34 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -7,15 +7,17 @@ * Migrated to Harmony 2.0 (see [_migrate to Harmony 2.0_](https://stardewvalleywiki.com/Modding:Migrate_to_Harmony_2.0) for more info). --> -## Upcoming release +## 3.9.3 +Released 07 March 2021 for Stardew Valley 1.5.4 or later. + * For players: - * If the installer crashes, the window now stays open if possible so you can read the error and ask for help. * Added descriptive error if possible when a `PathTooLongException` crashes SMAPI or the installer. - * Fixed console showing _found 1 mod with warnings_ with no mods listed. + * The installer window now tries to stay open if it crashed, so you can read the error and ask for help. + * Fixed console showing _found 1 mod with warnings_ with no mods listed in some cases. * For mod authors: - * Added three stages to the `LoadStageChanged` event: `CreatedInitialLocations`/`SaveAddedLocations` (raised immediately after the game adds locations but before they're initialized), and `ReturningToTitle` (raised before exiting to the title screen). - * Fixed `RewriteMods` option in `smapi-internal/config.json` ignored when rewriting mod for OS compatibility. + * Added three stages to the specialised [`LoadStageChanged` event](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Events#Specialised): `CreatedInitialLocations`, `SaveAddedLocations`, and `ReturningToTitle`. + * Fixed `RewriteMods` option ignored when rewriting for OS compatibility. * Fixed edge case when playing as a farmhand in non-English where translatable assets loaded via `IAssetLoader` weren't reapplied immediately when the server disconnects. ## 3.9.2 diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json index aa3d6ceb..58692de1 100644 --- a/src/SMAPI.Mods.ConsoleCommands/manifest.json +++ b/src/SMAPI.Mods.ConsoleCommands/manifest.json @@ -1,9 +1,9 @@ { "Name": "Console Commands", "Author": "SMAPI", - "Version": "3.9.2", + "Version": "3.9.3", "Description": "Adds SMAPI console commands that let you manipulate the game.", "UniqueID": "SMAPI.ConsoleCommands", "EntryDll": "ConsoleCommands.dll", - "MinimumApiVersion": "3.9.2" + "MinimumApiVersion": "3.9.3" } diff --git a/src/SMAPI.Mods.ErrorHandler/manifest.json b/src/SMAPI.Mods.ErrorHandler/manifest.json index b6df0f49..962b27f8 100644 --- a/src/SMAPI.Mods.ErrorHandler/manifest.json +++ b/src/SMAPI.Mods.ErrorHandler/manifest.json @@ -1,9 +1,9 @@ { "Name": "Error Handler", "Author": "SMAPI", - "Version": "3.9.2", + "Version": "3.9.3", "Description": "Handles some common vanilla errors to log more useful info or avoid breaking the game.", "UniqueID": "SMAPI.ErrorHandler", "EntryDll": "ErrorHandler.dll", - "MinimumApiVersion": "3.9.2" + "MinimumApiVersion": "3.9.3" } diff --git a/src/SMAPI.Mods.SaveBackup/manifest.json b/src/SMAPI.Mods.SaveBackup/manifest.json index 4d2003e2..d51bc5d9 100644 --- a/src/SMAPI.Mods.SaveBackup/manifest.json +++ b/src/SMAPI.Mods.SaveBackup/manifest.json @@ -1,9 +1,9 @@ { "Name": "Save Backup", "Author": "SMAPI", - "Version": "3.9.2", + "Version": "3.9.3", "Description": "Automatically backs up all your saves once per day into its folder.", "UniqueID": "SMAPI.SaveBackup", "EntryDll": "SaveBackup.dll", - "MinimumApiVersion": "3.9.2" + "MinimumApiVersion": "3.9.3" } diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 54fb54ab..a81a6bc9 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -54,7 +54,7 @@ namespace StardewModdingAPI ** Public ****/ /// SMAPI's current semantic version. - public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.9.2"); + public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.9.3"); /// The minimum supported version of Stardew Valley. public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.5.4"); diff --git a/src/SMAPI/Enums/LoadStage.cs b/src/SMAPI/Enums/LoadStage.cs index bf103576..302c263b 100644 --- a/src/SMAPI/Enums/LoadStage.cs +++ b/src/SMAPI/Enums/LoadStage.cs @@ -24,10 +24,10 @@ namespace StardewModdingAPI.Enums /// The game is loading a save slot, and has applied the basic save info (including player data). Not applicable when connecting to a multiplayer host. Note that some basic info (like daily luck) is not initialized at this point. This is equivalent to value 36. SaveLoadedBasicInfo = 5, - /// The game is loading a save slot and has added the location instances, but hasn't applied the data yet. Not applicable when connecting to a multiplayer host. + /// The game is loading a save slot and has added the location instances, but hasn't restored their save data yet. Not applicable when connecting to a multiplayer host. SaveAddedLocations = 11, - /// The game is loading a save slot, and has applied the in-game location data. Not applicable when connecting to a multiplayer host. This is equivalent to value 50. + /// The game is loading a save slot, and has restored the in-game location data. Not applicable when connecting to a multiplayer host. This is equivalent to value 50. SaveLoadedLocations = 6, /// The final metadata has been loaded from the save file. This happens before the game applies problem fixes, checks for achievements, starts music, etc. Not applicable when connecting to a multiplayer host. -- cgit