improve error when installer is pointed at a compatibility-branch game folder
This commit is contained in:
parent
cb9d6ae5ad
commit
98d01d522d
|
@ -4,7 +4,7 @@
|
||||||
## Upcoming version
|
## Upcoming version
|
||||||
* For players:
|
* For players:
|
||||||
* You no longer need .NET 5 installed to run SMAPI or the installer.
|
* You no longer need .NET 5 installed to run SMAPI or the installer.
|
||||||
* The installer now detects when the game folder contains an incompatible older game version.
|
* The installer now detects when the game folder contains an incompatible legacy game version.
|
||||||
* Updated for the latest Stardew Valley 1.5.5 hotfix.
|
* Updated for the latest Stardew Valley 1.5.5 hotfix.
|
||||||
|
|
||||||
* For SMAPI maintainers:
|
* For SMAPI maintainers:
|
||||||
|
|
|
@ -55,11 +55,11 @@ namespace StardewModdingAPI.Installer.Framework
|
||||||
return this.GameScanner.LooksLikeGameFolder(dir);
|
return this.GameScanner.LooksLikeGameFolder(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Get whether a folder seems to contain Stardew Valley 1.5.4 or earlier.</summary>
|
/// <summary>Get whether a folder seems to contain the game, and which version it contains if so.</summary>
|
||||||
/// <param name="dir">The folder to check.</param>
|
/// <param name="dir">The folder to check.</param>
|
||||||
public bool LooksLikeStardewValley154(DirectoryInfo dir)
|
public GameFolderType GetGameFolderType(DirectoryInfo dir)
|
||||||
{
|
{
|
||||||
return this.GameScanner.LooksLikeStardewValley154(dir);
|
return this.GameScanner.GetGameFolderType(dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ using StardewModdingAPI.Installer.Framework;
|
||||||
using StardewModdingAPI.Internal.ConsoleWriting;
|
using StardewModdingAPI.Internal.ConsoleWriting;
|
||||||
using StardewModdingAPI.Toolkit;
|
using StardewModdingAPI.Toolkit;
|
||||||
using StardewModdingAPI.Toolkit.Framework;
|
using StardewModdingAPI.Toolkit.Framework;
|
||||||
|
using StardewModdingAPI.Toolkit.Framework.GameScanning;
|
||||||
using StardewModdingAPI.Toolkit.Framework.ModScanning;
|
using StardewModdingAPI.Toolkit.Framework.ModScanning;
|
||||||
using StardewModdingAPI.Toolkit.Utilities;
|
using StardewModdingAPI.Toolkit.Utilities;
|
||||||
|
|
||||||
|
@ -633,18 +634,39 @@ namespace StardewModdingApi.Installer
|
||||||
// use specified path
|
// use specified path
|
||||||
if (specifiedPath != null)
|
if (specifiedPath != null)
|
||||||
{
|
{
|
||||||
|
string errorPrefix = $"You specified --game-path \"{specifiedPath}\", but";
|
||||||
|
|
||||||
var dir = new DirectoryInfo(specifiedPath);
|
var dir = new DirectoryInfo(specifiedPath);
|
||||||
if (!dir.Exists)
|
if (!dir.Exists)
|
||||||
{
|
{
|
||||||
this.PrintError($"You specified --game-path \"{specifiedPath}\", but that folder doesn't exist.");
|
this.PrintError($"{errorPrefix} that folder doesn't exist.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!context.LooksLikeGameFolder(dir))
|
|
||||||
|
switch (context.GetGameFolderType(dir))
|
||||||
{
|
{
|
||||||
this.PrintError($"You specified --game-path \"{specifiedPath}\", but that folder doesn't contain the Stardew Valley executable.");
|
case GameFolderType.Valid:
|
||||||
|
return dir;
|
||||||
|
|
||||||
|
case GameFolderType.Legacy154OrEarlier:
|
||||||
|
this.PrintWarning($"{errorPrefix} that directory seems to have Stardew Valley 1.5.4 or earlier.");
|
||||||
|
this.PrintWarning("Please update your game to the latest version to use SMAPI.");
|
||||||
|
return null;
|
||||||
|
|
||||||
|
case GameFolderType.LegacyCompatibilityBranch:
|
||||||
|
this.PrintWarning($"{errorPrefix} that directory seems to have the Stardew Valley legacy 'compatibility' branch.");
|
||||||
|
this.PrintWarning("Unfortunately SMAPI is only compatible with the full main version of the game.");
|
||||||
|
this.PrintWarning("Please update your game to the main branch to use SMAPI.");
|
||||||
|
return null;
|
||||||
|
|
||||||
|
case GameFolderType.NoGameFound:
|
||||||
|
this.PrintWarning($"{errorPrefix} that directory doesn't contain a Stardew Valley executable.");
|
||||||
|
return null;
|
||||||
|
|
||||||
|
default:
|
||||||
|
this.PrintWarning($"{errorPrefix} that directory doesn't seem to contain a valid game install.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return dir;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// let user choose detected path
|
// let user choose detected path
|
||||||
|
@ -702,23 +724,32 @@ namespace StardewModdingApi.Installer
|
||||||
this.PrintWarning("That directory doesn't seem to exist.");
|
this.PrintWarning("That directory doesn't seem to exist.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!context.LooksLikeGameFolder(directory))
|
|
||||||
{
|
|
||||||
if (context.LooksLikeStardewValley154(directory))
|
|
||||||
{
|
|
||||||
this.PrintWarning("That directory seems to have Stardew Valley 1.5.4 or earlier.");
|
|
||||||
this.PrintWarning("Please update your game to the latest version to use SMAPI.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.PrintWarning("That directory doesn't contain a Stardew Valley executable.");
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// looks OK
|
switch (context.GetGameFolderType(directory))
|
||||||
|
{
|
||||||
|
case GameFolderType.Valid:
|
||||||
this.PrintInfo(" OK!");
|
this.PrintInfo(" OK!");
|
||||||
return directory;
|
return directory;
|
||||||
|
|
||||||
|
case GameFolderType.Legacy154OrEarlier:
|
||||||
|
this.PrintWarning("That directory seems to have Stardew Valley 1.5.4 or earlier.");
|
||||||
|
this.PrintWarning("Please update your game to the latest version to use SMAPI.");
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case GameFolderType.LegacyCompatibilityBranch:
|
||||||
|
this.PrintWarning("That directory seems to have the Stardew Valley legacy 'compatibility' branch.");
|
||||||
|
this.PrintWarning("Unfortunately SMAPI is only compatible with the full main version of the game.");
|
||||||
|
this.PrintWarning("Please update your game to the main branch to use SMAPI.");
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case GameFolderType.NoGameFound:
|
||||||
|
this.PrintWarning("That directory doesn't contain a Stardew Valley executable.");
|
||||||
|
continue;
|
||||||
|
|
||||||
|
default:
|
||||||
|
this.PrintWarning("That directory doesn't seem to contain a valid game install.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
namespace StardewModdingAPI.Toolkit.Framework.GameScanning
|
||||||
|
{
|
||||||
|
/// <summary>The detected validity for a Stardew Valley game folder based on file structure heuristics.</summary>
|
||||||
|
public enum GameFolderType
|
||||||
|
{
|
||||||
|
/// <summary>The folder seems to contain a valid Stardew Valley 1.5.5+ install.</summary>
|
||||||
|
Valid,
|
||||||
|
|
||||||
|
/// <summary>The folder doesn't contain Stardew Valley.</summary>
|
||||||
|
NoGameFound,
|
||||||
|
|
||||||
|
/// <summary>The folder contains Stardew Valley 1.5.4 or earlier. This version uses XNA Framework and 32-bit .NET Framework 4.5.2 on Windows and Mono on Linux/macOS, and isn't compatible with current versions of SMAPI.</summary>
|
||||||
|
Legacy154OrEarlier,
|
||||||
|
|
||||||
|
/// <summary>The folder contains Stardew Valley from the game's legacy compatibility branch, which backports newer changes to the <see cref="Legacy154OrEarlier"/> format.</summary>
|
||||||
|
LegacyCompatibilityBranch,
|
||||||
|
|
||||||
|
/// <summary>The folder seems to contain Stardew Valley files, but they failed to load for unknown reasons (e.g. corrupted executable).</summary>
|
||||||
|
InvalidUnknown
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,36 +55,58 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning
|
||||||
/// <param name="dir">The folder to check.</param>
|
/// <param name="dir">The folder to check.</param>
|
||||||
public bool LooksLikeGameFolder(DirectoryInfo dir)
|
public bool LooksLikeGameFolder(DirectoryInfo dir)
|
||||||
{
|
{
|
||||||
return
|
return this.GetGameFolderType(dir) == GameFolderType.Valid;
|
||||||
dir.Exists
|
|
||||||
&& dir.EnumerateFiles("Stardew Valley.dll").Any();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Get whether a folder seems to contain Stardew Valley 1.5.4 or earlier.</summary>
|
/// <summary>Detect the validity of a game folder based on file structure heuristics.</summary>
|
||||||
/// <param name="dir">The folder to check.</param>
|
/// <param name="dir">The folder to check.</param>
|
||||||
public bool LooksLikeStardewValley154(DirectoryInfo dir)
|
public GameFolderType GetGameFolderType(DirectoryInfo dir)
|
||||||
{
|
{
|
||||||
if (!dir.Exists || this.LooksLikeGameFolder(dir))
|
// no such folder
|
||||||
return false;
|
if (!dir.Exists)
|
||||||
|
return GameFolderType.NoGameFound;
|
||||||
|
|
||||||
// get legacy executable
|
// apparently valid
|
||||||
FileInfo executable = new FileInfo(Path.Combine(dir.FullName, "Stardew Valley.exe"));
|
if (dir.EnumerateFiles("Stardew Valley.dll").Any())
|
||||||
if (!executable.Exists)
|
return GameFolderType.Valid;
|
||||||
executable = new FileInfo(Path.Combine(dir.FullName, "StardewValley.exe"));
|
|
||||||
if (!executable.Exists)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// check if it's a standard .NET assembly
|
// doesn't contain any version of Stardew Valley
|
||||||
// This will fail in Stardew Valley 1.5.5+, where it's a binary wrapper around Stardew Valley.dll.
|
FileInfo executable = new(Path.Combine(dir.FullName, "Stardew Valley.exe"));
|
||||||
|
if (!executable.Exists)
|
||||||
|
executable = new(Path.Combine(dir.FullName, "StardewValley.exe")); // pre-1.5.5 Linux/macOS executable
|
||||||
|
if (!executable.Exists)
|
||||||
|
return GameFolderType.NoGameFound;
|
||||||
|
|
||||||
|
// get assembly version
|
||||||
|
Version version;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Version version = AssemblyName.GetAssemblyName(executable.FullName).Version;
|
version = AssemblyName.GetAssemblyName(executable.FullName).Version;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return false;
|
// The executable exists but it doesn't seem to be a valid assembly. This would
|
||||||
|
// happen with Stardew Valley 1.5.5+, but that should have been flagged as a valid
|
||||||
|
// folder before this point.
|
||||||
|
return GameFolderType.InvalidUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore Stardew Valley 1.5.5+ at this point
|
||||||
|
if (version.Major == 1 && version.Minor == 3 && version.Build == 37)
|
||||||
|
return GameFolderType.InvalidUnknown;
|
||||||
|
|
||||||
|
// incompatible version
|
||||||
|
if (version.Major == 1 && version.Minor < 4)
|
||||||
|
{
|
||||||
|
// Stardew Valley 1.5.4 and earlier have assembly versions <= 1.3.7853.31734
|
||||||
|
if (version.Minor < 3 || version.Build <= 7853)
|
||||||
|
return GameFolderType.Legacy154OrEarlier;
|
||||||
|
|
||||||
|
// Stardew Valley 1.5.5+ legacy compatibility branch
|
||||||
|
return GameFolderType.LegacyCompatibilityBranch;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GameFolderType.InvalidUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
|
|
Loading…
Reference in New Issue