fix save folder constants not available during early load stages
This commit is contained in:
parent
79c6166005
commit
9240bdbf9b
|
@ -1,4 +1,9 @@
|
||||||
# Release notes
|
# Release notes
|
||||||
|
## Upcoming
|
||||||
|
|
||||||
|
* For modders:
|
||||||
|
* Fixed `Constants.SaveFolderName` and `CurrentSavePath` not available during early load stages when using `Specialised.LoadStageChanged` event.
|
||||||
|
|
||||||
## 2.10.1
|
## 2.10.1
|
||||||
Released 30 December 2018 for Stardew Valley 1.3.32.
|
Released 30 December 2018 for Stardew Valley 1.3.32.
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using StardewModdingAPI.Enums;
|
||||||
using StardewModdingAPI.Framework;
|
using StardewModdingAPI.Framework;
|
||||||
using StardewModdingAPI.Framework.ModLoading;
|
using StardewModdingAPI.Framework.ModLoading;
|
||||||
using StardewModdingAPI.Internal;
|
using StardewModdingAPI.Internal;
|
||||||
|
@ -12,16 +13,6 @@ namespace StardewModdingAPI
|
||||||
/// <summary>Contains SMAPI's constants and assumptions.</summary>
|
/// <summary>Contains SMAPI's constants and assumptions.</summary>
|
||||||
public static class Constants
|
public static class Constants
|
||||||
{
|
{
|
||||||
/*********
|
|
||||||
** Fields
|
|
||||||
*********/
|
|
||||||
/// <summary>The directory path containing the current save's data (if a save is loaded).</summary>
|
|
||||||
private static string RawSavePath => Context.IsSaveLoaded ? Path.Combine(Constants.SavesPath, Constants.GetSaveFolderName()) : null;
|
|
||||||
|
|
||||||
/// <summary>Whether the directory containing the current save's data exists on disk.</summary>
|
|
||||||
private static bool SavePathReady => Context.IsSaveLoaded && Directory.Exists(Constants.RawSavePath);
|
|
||||||
|
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
** Accessors
|
** Accessors
|
||||||
*********/
|
*********/
|
||||||
|
@ -52,11 +43,33 @@ namespace StardewModdingAPI
|
||||||
/// <summary>The directory path where all saves are stored.</summary>
|
/// <summary>The directory path where all saves are stored.</summary>
|
||||||
public static string SavesPath { get; } = Path.Combine(Constants.DataPath, "Saves");
|
public static string SavesPath { get; } = Path.Combine(Constants.DataPath, "Saves");
|
||||||
|
|
||||||
/// <summary>The directory name containing the current save's data (if a save is loaded and the directory exists).</summary>
|
/// <summary>The name of the current save folder (if save info is available, regardless of whether the save file exists yet).</summary>
|
||||||
public static string SaveFolderName => Context.IsSaveLoaded ? Constants.GetSaveFolderName() : "";
|
public static string SaveFolderName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Constants.GetSaveFolderName()
|
||||||
|
#if SMAPI_3_0_STRICT
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
?? "";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>The directory path containing the current save's data (if a save is loaded and the directory exists).</summary>
|
/// <summary>The absolute path to the current save folder (if save info is available and the save file exists).</summary>
|
||||||
public static string CurrentSavePath => Constants.SavePathReady ? Path.Combine(Constants.SavesPath, Constants.GetSaveFolderName()) : "";
|
public static string CurrentSavePath
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Constants.GetSaveFolderPathIfExists()
|
||||||
|
#if SMAPI_3_0_STRICT
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
?? "";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****
|
/****
|
||||||
** Internal
|
** Internal
|
||||||
|
@ -184,13 +197,6 @@ namespace StardewModdingAPI
|
||||||
/*********
|
/*********
|
||||||
** Private methods
|
** Private methods
|
||||||
*********/
|
*********/
|
||||||
/// <summary>Get the name of a save directory for the current player.</summary>
|
|
||||||
private static string GetSaveFolderName()
|
|
||||||
{
|
|
||||||
string prefix = new string(Game1.player.Name.Where(char.IsLetterOrDigit).ToArray());
|
|
||||||
return $"{prefix}_{Game1.uniqueIDForThisGame}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Get the game's current version string.</summary>
|
/// <summary>Get the game's current version string.</summary>
|
||||||
private static string GetGameVersion()
|
private static string GetGameVersion()
|
||||||
{
|
{
|
||||||
|
@ -200,5 +206,43 @@ namespace StardewModdingAPI
|
||||||
throw new InvalidOperationException($"The {nameof(Game1)}.{nameof(Game1.version)} field could not be found.");
|
throw new InvalidOperationException($"The {nameof(Game1)}.{nameof(Game1.version)} field could not be found.");
|
||||||
return (string)field.GetValue(null);
|
return (string)field.GetValue(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Get the name of the save folder, if any.</summary>
|
||||||
|
internal static string GetSaveFolderName()
|
||||||
|
{
|
||||||
|
// save not available
|
||||||
|
if (Context.LoadStage == LoadStage.None)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// get basic info
|
||||||
|
string playerName;
|
||||||
|
ulong saveID;
|
||||||
|
if (Context.LoadStage == LoadStage.SaveParsed)
|
||||||
|
{
|
||||||
|
playerName = SaveGame.loaded.player.Name;
|
||||||
|
saveID = SaveGame.loaded.uniqueIDForThisGame;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
playerName = Game1.player.Name;
|
||||||
|
saveID = Game1.uniqueIDForThisGame;
|
||||||
|
}
|
||||||
|
|
||||||
|
// build folder name
|
||||||
|
return $"{new string(playerName.Where(char.IsLetterOrDigit).ToArray())}_{saveID}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Get the path to the current save folder, if any.</summary>
|
||||||
|
internal static string GetSaveFolderPathIfExists()
|
||||||
|
{
|
||||||
|
string folderName = Constants.GetSaveFolderName();
|
||||||
|
if (folderName == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
string path = Path.Combine(Constants.SavesPath, folderName);
|
||||||
|
return Directory.Exists(path)
|
||||||
|
? path
|
||||||
|
: null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using StardewModdingAPI.Enums;
|
||||||
using StardewModdingAPI.Events;
|
using StardewModdingAPI.Events;
|
||||||
using StardewValley;
|
using StardewValley;
|
||||||
using StardewValley.Menus;
|
using StardewValley.Menus;
|
||||||
|
@ -39,5 +40,8 @@ namespace StardewModdingAPI
|
||||||
|
|
||||||
/// <summary>Whether the game is currently writing to the save file.</summary>
|
/// <summary>Whether the game is currently writing to the save file.</summary>
|
||||||
internal static bool IsSaving => Game1.activeClickableMenu is SaveGameMenu || Game1.activeClickableMenu is ShippingMenu; // saving is performed by SaveGameMenu, but it's wrapped by ShippingMenu on days when the player shipping something
|
internal static bool IsSaving => Game1.activeClickableMenu is SaveGameMenu || Game1.activeClickableMenu is ShippingMenu; // saving is performed by SaveGameMenu, but it's wrapped by ShippingMenu on days when the player shipping something
|
||||||
|
|
||||||
|
/// <summary>The current stage in the game's loading process.</summary>
|
||||||
|
internal static LoadStage LoadStage { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,9 +69,6 @@ namespace StardewModdingAPI.Framework
|
||||||
/// <remarks>Skipping a few frames ensures the game finishes initialising the world before mods try to change it.</remarks>
|
/// <remarks>Skipping a few frames ensures the game finishes initialising the world before mods try to change it.</remarks>
|
||||||
private readonly Countdown AfterLoadTimer = new Countdown(5);
|
private readonly Countdown AfterLoadTimer = new Countdown(5);
|
||||||
|
|
||||||
/// <summary>The current stage in the game's loading process.</summary>
|
|
||||||
private LoadStage LoadStage = LoadStage.None;
|
|
||||||
|
|
||||||
/// <summary>Whether the game is saving and SMAPI has already raised <see cref="IGameLoopEvents.Saving"/>.</summary>
|
/// <summary>Whether the game is saving and SMAPI has already raised <see cref="IGameLoopEvents.Saving"/>.</summary>
|
||||||
private bool IsBetweenSaveEvents;
|
private bool IsBetweenSaveEvents;
|
||||||
|
|
||||||
|
@ -215,12 +212,12 @@ namespace StardewModdingAPI.Framework
|
||||||
internal void OnLoadStageChanged(LoadStage newStage)
|
internal void OnLoadStageChanged(LoadStage newStage)
|
||||||
{
|
{
|
||||||
// nothing to do
|
// nothing to do
|
||||||
if (newStage == this.LoadStage)
|
if (newStage == Context.LoadStage)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// update data
|
// update data
|
||||||
LoadStage oldStage = this.LoadStage;
|
LoadStage oldStage = Context.LoadStage;
|
||||||
this.LoadStage = newStage;
|
Context.LoadStage = newStage;
|
||||||
if (newStage == LoadStage.None)
|
if (newStage == LoadStage.None)
|
||||||
{
|
{
|
||||||
this.Monitor.Log("Context: returned to title", LogLevel.Trace);
|
this.Monitor.Log("Context: returned to title", LogLevel.Trace);
|
||||||
|
@ -511,7 +508,7 @@ namespace StardewModdingAPI.Framework
|
||||||
*********/
|
*********/
|
||||||
if (wasWorldReady && !Context.IsWorldReady)
|
if (wasWorldReady && !Context.IsWorldReady)
|
||||||
this.OnLoadStageChanged(LoadStage.None);
|
this.OnLoadStageChanged(LoadStage.None);
|
||||||
else if (Context.IsWorldReady && this.LoadStage != LoadStage.Ready)
|
else if (Context.IsWorldReady && Context.LoadStage != LoadStage.Ready)
|
||||||
{
|
{
|
||||||
// print context
|
// print context
|
||||||
string context = $"Context: loaded saved game '{Constants.SaveFolderName}', starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.";
|
string context = $"Context: loaded saved game '{Constants.SaveFolderName}', starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.";
|
||||||
|
@ -884,7 +881,7 @@ namespace StardewModdingAPI.Framework
|
||||||
events.GameLaunched.Raise(new GameLaunchedEventArgs());
|
events.GameLaunched.Raise(new GameLaunchedEventArgs());
|
||||||
|
|
||||||
// preloaded
|
// preloaded
|
||||||
if (Context.IsSaveLoaded && this.LoadStage != LoadStage.Loaded && this.LoadStage != LoadStage.Ready)
|
if (Context.IsSaveLoaded && Context.LoadStage != LoadStage.Loaded && Context.LoadStage != LoadStage.Ready)
|
||||||
this.OnLoadStageChanged(LoadStage.Loaded);
|
this.OnLoadStageChanged(LoadStage.Loaded);
|
||||||
|
|
||||||
// update tick
|
// update tick
|
||||||
|
|
Loading…
Reference in New Issue