update to .NET 5 and official 64-bit

This commit is contained in:
Jesse Plamondon-Willard 2021-08-12 21:26:10 -04:00
parent 40b74398ac
commit 727d75ae72
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
33 changed files with 192 additions and 341 deletions

View File

@ -7,7 +7,7 @@
<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
<!--set platform-->
<DefineConstants Condition="$(OS) == 'Windows_NT'">$(DefineConstants);SMAPI_FOR_WINDOWS;SMAPI_FOR_XNA</DefineConstants>
<DefineConstants Condition="$(OS) == 'Windows_NT'">$(DefineConstants);SMAPI_FOR_WINDOWS</DefineConstants>
</PropertyGroup>
<!--find game folder-->
@ -27,20 +27,31 @@
<TranslationFiles Include="$(TargetDir)\i18n\*.json" />
</ItemGroup>
<Copy SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFolder="$(GamePath)" />
<!-- SMAPI -->
<Copy SourceFiles="$(TargetDir)\$(TargetName).dll" DestinationFolder="$(GamePath)" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFolder="$(GamePath)" Condition="$(OS) == 'Windows_NT'" />
<Copy SourceFiles="$(TargetDir)\$(TargetName)" DestinationFolder="$(GamePath)" Condition="$(OS) != 'Windows_NT'" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).pdb" DestinationFolder="$(GamePath)" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).xml" DestinationFolder="$(GamePath)" />
<Copy SourceFiles="$(TargetDir)\SMAPI.config.json" DestinationFiles="$(GamePath)\smapi-internal\config.json" />
<Copy SourceFiles="$(TargetDir)\SMAPI.metadata.json" DestinationFiles="$(GamePath)\smapi-internal\metadata.json" />
<Copy SourceFiles="$(TargetDir)\Newtonsoft.Json.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\TMXTile.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="@(TranslationFiles)" DestinationFolder="$(GamePath)\smapi-internal\i18n" />
<!-- Harmony + dependencies -->
<Copy SourceFiles="$(TargetDir)\0Harmony.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\0Harmony.xml" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\Mono.Cecil.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\Mono.Cecil.Mdb.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\Mono.Cecil.Pdb.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\MonoMod.Common.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\Newtonsoft.Json.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\TMXTile.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="@(TranslationFiles)" DestinationFolder="$(GamePath)\smapi-internal\i18n" />
<!-- .NET dependencies -->
<Copy SourceFiles="$(TargetDir)\System.Configuration.ConfigurationManager.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\System.Management.dll" DestinationFolder="$(GamePath)\smapi-internal" Condition="$(OS) == 'Windows_NT'" />
<Copy SourceFiles="$(TargetDir)\System.Runtime.Caching.dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\System.Security.Permissions.dll" DestinationFolder="$(GamePath)\smapi-internal" />
</Target>
<Target Name="CopyDefaultMods" Condition="'$(MSBuildProjectName)' == 'SMAPI.Mods.ConsoleCommands' OR '$(MSBuildProjectName)' == 'SMAPI.Mods.ErrorHandler' OR '$(MSBuildProjectName)' == 'SMAPI.Mods.SaveBackup'">
@ -54,13 +65,13 @@
<Copy SourceFiles="@(TranslationFiles)" DestinationFolder="$(GamePath)\Mods\$(AssemblyName)\i18n" />
</Target>
<Target Name="CopyToolkit" Condition="'$(MSBuildProjectName)' == 'SMAPI.Toolkit' AND $(TargetFramework) == 'net452'" AfterTargets="PostBuildEvent">
<Target Name="CopyToolkit" Condition="'$(MSBuildProjectName)' == 'SMAPI.Toolkit'" AfterTargets="PostBuildEvent">
<Copy SourceFiles="$(TargetDir)\$(TargetName).dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).pdb" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).xml" DestinationFolder="$(GamePath)\smapi-internal" />
</Target>
<Target Name="CopyToolkitCoreInterfaces" Condition="'$(MSBuildProjectName)' == 'SMAPI.Toolkit.CoreInterfaces' AND $(TargetFramework) == 'net452'" AfterTargets="PostBuildEvent">
<Target Name="CopyToolkitCoreInterfaces" Condition="'$(MSBuildProjectName)' == 'SMAPI.Toolkit.CoreInterfaces'" AfterTargets="PostBuildEvent">
<Copy SourceFiles="$(TargetDir)\$(TargetName).dll" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).pdb" DestinationFolder="$(GamePath)\smapi-internal" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).xml" DestinationFolder="$(GamePath)\smapi-internal" />

View File

@ -14,7 +14,7 @@
<OutRootPath>$(SolutionDir)\..\bin</OutRootPath>
<SmapiBin>$(BuildRootPath)\SMAPI\bin\$(Configuration)</SmapiBin>
<ToolkitBin>$(BuildRootPath)\SMAPI.Toolkit\bin\$(Configuration)\net452</ToolkitBin>
<ToolkitBin>$(BuildRootPath)\SMAPI.Toolkit\bin\$(Configuration)\net5.0</ToolkitBin>
<ConsoleCommandsBin>$(BuildRootPath)\SMAPI.Mods.ConsoleCommands\bin\$(Configuration)</ConsoleCommandsBin>
<ErrorHandlerBin>$(BuildRootPath)\SMAPI.Mods.ErrorHandler\bin\$(Configuration)</ErrorHandlerBin>
<SaveBackupBin>$(BuildRootPath)\SMAPI.Mods.SaveBackup\bin\$(Configuration)</SaveBackupBin>
@ -35,12 +35,17 @@
<Copy SourceFiles="$(TargetDir)\assets\unix-install.sh" DestinationFiles="$(PackagePath)\install on Linux.sh" />
<Copy SourceFiles="$(TargetDir)\assets\unix-install.sh" DestinationFiles="$(PackagePath)\install on macOS.command" />
<Copy SourceFiles="$(TargetDir)\assets\windows-install.bat" DestinationFiles="$(PackagePath)\install on Windows.bat" />
<Copy SourceFiles="$(TargetDir)\assets\README.txt" DestinationFiles="$(PackagePath)\README.txt" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFiles="$(PackagePath)\internal\$(PlatformName)-install.exe" />
<Copy Condition="$(PlatformName) == 'windows'" SourceFiles="$(TargetDir)\assets\windows-exe-config.xml" DestinationFiles="$(PackagePath)\internal\$(PlatformName)-install.exe.config" />
<Copy SourceFiles="$(TargetDir)\assets\README.txt" DestinationFolder="$(PackagePath)" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).dll" DestinationFolder="$(PackagePath)\internal" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFiles="$(PackagePath)\internal\$(PlatformName)-install.exe" Condition="$(PlatformName) == 'windows'" />
<Copy SourceFiles="$(TargetDir)\$(TargetName)" DestinationFiles="$(PackagePath)\internal\$(PlatformName)-install" Condition="$(PlatformName) != 'windows'" />
<Copy SourceFiles="$(TargetDir)\$(TargetName).runtimeconfig.json" DestinationFolder="$(PackagePath)\internal" />
<Copy SourceFiles="$(TargetDir)\assets\windows-exe-config.xml" DestinationFiles="$(PackagePath)\internal\$(PlatformName)-install.exe.config" Condition="$(PlatformName) == 'windows'" />
<!--copy bundle files-->
<Copy SourceFiles="$(SmapiBin)\StardewModdingAPI.exe" DestinationFolder="$(PackagePath)\bundle" />
<Copy SourceFiles="$(SmapiBin)\StardewModdingAPI.dll" DestinationFolder="$(PackagePath)\bundle" />
<Copy SourceFiles="$(SmapiBin)\StardewModdingAPI.exe" DestinationFolder="$(PackagePath)\bundle" Condition="$(PlatformName) == 'windows'" />
<Copy SourceFiles="$(SmapiBin)\StardewModdingAPI" DestinationFolder="$(PackagePath)\bundle" Condition="$(PlatformName) != 'windows'" />
<Copy SourceFiles="$(SmapiBin)\StardewModdingAPI.pdb" DestinationFolder="$(PackagePath)\bundle" />
<Copy SourceFiles="$(SmapiBin)\StardewModdingAPI.xml" DestinationFolder="$(PackagePath)\bundle" />
<Copy SourceFiles="$(SmapiBin)\steam_appid.txt" DestinationFolder="$(PackagePath)\bundle" />
@ -61,11 +66,16 @@
<Copy SourceFiles="$(ToolkitBin)\SMAPI.Toolkit.CoreInterfaces.pdb" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
<Copy SourceFiles="$(ToolkitBin)\SMAPI.Toolkit.CoreInterfaces.xml" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
<Copy SourceFiles="@(TranslationFiles)" DestinationFolder="$(PackagePath)\bundle\smapi-internal\i18n" />
<Copy Condition="$(PlatformName) == 'unix'" SourceFiles="$(TargetDir)\assets\unix-launcher.sh" DestinationFiles="$(PackagePath)\bundle\StardewModdingAPI" />
<Copy Condition="$(PlatformName) == 'unix'" SourceFiles="$(SmapiBin)\System.Numerics.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
<Copy Condition="$(PlatformName) == 'unix'" SourceFiles="$(TargetDir)\assets\unix-launcher.sh" DestinationFolder="$(PackagePath)\bundle" />
<Copy Condition="$(PlatformName) == 'unix'" SourceFiles="$(SmapiBin)\System.Runtime.Caching.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
<Copy Condition="$(PlatformName) == 'windows'" SourceFiles="$(TargetDir)\assets\windows-exe-config.xml" DestinationFiles="$(PackagePath)\bundle\StardewModdingAPI.exe.config" />
<!-- copy .NET dependencies -->
<Copy SourceFiles="$(SmapiBin)\System.Configuration.ConfigurationManager.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
<Copy SourceFiles="$(SmapiBin)\System.Management.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" Condition="$(PlatformName) == 'windows'" />
<Copy SourceFiles="$(SmapiBin)\System.Runtime.Caching.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
<Copy SourceFiles="$(SmapiBin)\System.Security.Permissions.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
<!--copy bundled mods-->
<Copy SourceFiles="$(ConsoleCommandsBin)\ConsoleCommands.dll" DestinationFolder="$(PackagePath)\bundle\Mods\ConsoleCommands" />
<Copy SourceFiles="$(ConsoleCommandsBin)\ConsoleCommands.pdb" DestinationFolder="$(PackagePath)\bundle\Mods\ConsoleCommands" />
@ -78,63 +88,33 @@
<Copy SourceFiles="$(SaveBackupBin)\SaveBackup.pdb" DestinationFolder="$(PackagePath)\bundle\Mods\SaveBackup" />
<Copy SourceFiles="$(SaveBackupBin)\manifest.json" DestinationFolder="$(PackagePath)\bundle\Mods\SaveBackup" />
<!-- fix errors on Linux/macOS (sample: https://smapi.io/log/mMdFUpgB) -->
<Copy Condition="$(PlatformName) == 'unix'" SourceFiles="$(TargetDir)\assets\System.Numerics.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
<Copy Condition="$(PlatformName) == 'unix'" SourceFiles="$(TargetDir)\assets\System.Runtime.Caching.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
<!-- fix Linux/macOS permissions -->
<Exec Condition="$(PlatformName) == 'unix'" Command="chmod 755 &quot;$(PackagePath)\install on Linux.sh&quot;" />
<Exec Condition="$(PlatformName) == 'unix'" Command="chmod 755 &quot;$(PackagePath)\install on macOS.command&quot;" />
<Exec Condition="$(PlatformName) == 'unix'" Command="chmod 755 &quot;$(PackagePath)/install on Linux.sh&quot;" />
<Exec Condition="$(PlatformName) == 'unix'" Command="chmod 755 &quot;$(PackagePath)/install on macOS.command&quot;" />
<Exec Condition="$(PlatformName) == 'unix'" Command="chmod 755 &quot;$(PackagePath)/bundle/unix-launcher.sh&quot;" />
<!-- finalise 'for developers' installer -->
<ItemGroup>
<PackageFiles Include="$(PackagePath)\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(PackageFiles)" DestinationFolder="$(PackageDevPath)\%(RecursiveDir)" />
<ZipDirectory FromDirPath="$(PackageDevPath)\bundle" ToFilePath="$(PackageDevPath)\internal\$(PlatformName)-install.dat" />
<ZipDirectory SourceDirectory="$(PackageDevPath)\bundle" DestinationFile="$(PackageDevPath)\internal\$(PlatformName)-install.dat" />
<RemoveDir Directories="$(PackageDevPath)\bundle" />
<!-- finalise normal installer -->
<ReplaceFileText FilePath="$(PackagePath)\bundle\smapi-internal\config.json" Search="&quot;DeveloperMode&quot;: true" Replace="&quot;DeveloperMode&quot;: false" />
<ZipDirectory FromDirPath="$(PackagePath)\bundle" ToFilePath="$(PackagePath)\internal\$(PlatformName)-install.dat" />
<ZipDirectory SourceDirectory="$(PackagePath)\bundle" DestinationFile="$(PackagePath)\internal\$(PlatformName)-install.dat" />
<RemoveDir Directories="$(PackagePath)\bundle" />
</Target>
<!-- Create a zip file with the contents of a given folder path. Derived from https://stackoverflow.com/a/38127938/262123. -->
<UsingTask TaskName="ZipDirectory" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
<ParameterGroup>
<FromDirPath ParameterType="System.String" Required="true" />
<ToFilePath ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Reference Include="System.IO.Compression.FileSystem" />
<Using Namespace="System.IO.Compression" />
<Code Type="Fragment" Language="cs">
<![CDATA[
try
{
ZipFile.CreateFromDirectory(FromDirPath, ToFilePath);
return true;
}
catch(Exception ex)
{
Log.LogErrorFromException(ex);
return false;
}
]]>
</Code>
</Task>
</UsingTask>
<!-- Replace text in a file based on a regex pattern. Derived from https://stackoverflow.com/a/22571621/262123. -->
<UsingTask TaskName="ReplaceFileText" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<UsingTask TaskName="ReplaceFileText" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<FilePath ParameterType="System.String" Required="true" />
<Search ParameterType="System.String" Required="true" />
<Replace ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Reference Include="System.Core" />
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Using Namespace="System.Text.RegularExpressions" />

View File

@ -3,8 +3,22 @@
# Release notes
## Upcoming release
* For players:
* Updated for Stardew Valley 1.5.5.
* Added `set_farm_type` [console command](https://stardewvalleywiki.com/Modding:Console_commands#Console_commands) to change the current farm type.
* For mod authors:
* Migrated to 64-bit MonoGame and .NET 5 on all platforms (see [migration guide for mod authors](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5)).
**Update note for players with older systems:**
The game now has two branches: the _main branch_ which you'll get by default, and an optional
_compatibility branch_ for [older systems](https://www.stardewvalley.net/compatibility/). The two
branches have identical content, but use [different technologies](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5#Stardew_Valley_compatibility_branch).
Unfortunately **SMAPI only supports the main branch of the game**. There are formidable difficulties
across all mods in supporting all three variations, the [Steam hardware stats](https://store.steampowered.com/hwsurvey)
show that 99.69% of players have 64-bit, and 32-bit imposes significant restrictions on what mods
can do.
* For the web UI:
* Updated the JSON validator/schema for Content Patcher 1.24.0.

View File

@ -366,6 +366,7 @@ when you compile it.
## Release notes
## Upcoming release
* Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. **The older versions are no longer supported.**
* Improved analyzer performance by enabling parallel execution.
## 3.3.0

View File

@ -367,7 +367,7 @@ accordingly.
Initial setup:
1. Create an Azure Blob storage account for uploaded files.
2. Create an Azure App Services environment running the latest .NET Core on Linux or Windows.
2. Create an Azure App Services environment running the latest .NET on Linux or Windows.
3. Add these application settings in the new App Services environment:
property name | description

View File

@ -1,6 +1,4 @@
using System;
using System.IO;
using Microsoft.Win32;
using StardewModdingAPI.Toolkit;
using StardewModdingAPI.Toolkit.Framework.GameScanning;
using StardewModdingAPI.Toolkit.Utilities;
@ -13,9 +11,6 @@ namespace StardewModdingAPI.Installer.Framework
/*********
** Fields
*********/
/// <summary>The <see cref="Environment.OSVersion"/> value that represents Windows 7.</summary>
private readonly Version Windows7Version = new Version(6, 1);
/// <summary>The underlying toolkit game scanner.</summary>
private readonly GameScanner GameScanner = new GameScanner();
@ -29,9 +24,6 @@ namespace StardewModdingAPI.Installer.Framework
/// <summary>The human-readable OS name and version.</summary>
public string PlatformName { get; }
/// <summary>The name of the Stardew Valley executable.</summary>
public string ExecutableName { get; }
/// <summary>Whether the installer is running on Windows.</summary>
public bool IsWindows => this.Platform == Platform.Windows;
@ -47,7 +39,6 @@ namespace StardewModdingAPI.Installer.Framework
{
this.Platform = EnvironmentUtility.DetectPlatform();
this.PlatformName = EnvironmentUtility.GetFriendlyPlatformName(this.Platform);
this.ExecutableName = EnvironmentUtility.GetExecutableName(this.Platform);
}
/// <summary>Get the installer's version number.</summary>
@ -57,42 +48,6 @@ namespace StardewModdingAPI.Installer.Framework
return new SemanticVersion(raw);
}
/// <summary>Get whether the current system has .NET Framework 4.5 or later installed. This only applies on Windows.</summary>
/// <exception cref="NotSupportedException">The current platform is not Windows.</exception>
public bool HasNetFramework45()
{
switch (this.Platform)
{
case Platform.Windows:
using (RegistryKey versionKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"))
return versionKey?.GetValue("Release") != null; // .NET Framework 4.5+
default:
throw new NotSupportedException("The installed .NET Framework version can only be checked on Windows.");
}
}
/// <summary>Get whether the current system has XNA Framework installed. This only applies on Windows.</summary>
/// <exception cref="NotSupportedException">The current platform is not Windows.</exception>
public bool HasXna()
{
switch (this.Platform)
{
case Platform.Windows:
using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(@"SOFTWARE\Microsoft\XNA\Framework"))
return key != null; // XNA Framework 4.0+
default:
throw new NotSupportedException("The installed XNA Framework version can only be checked on Windows.");
}
}
/// <summary>Whether the current OS supports newer versions of .NET Framework.</summary>
public bool CanInstallLatestNetFramework()
{
return Environment.OSVersion.Version >= this.Windows7Version; // Windows 7+
}
/// <summary>Get whether a folder seems to contain the game files.</summary>
/// <param name="dir">The folder to check.</param>
public bool LooksLikeGameFolder(DirectoryInfo dir)

View File

@ -1,4 +1,5 @@
using System.IO;
using StardewModdingAPI.Toolkit.Framework;
namespace StardewModdingAPI.Installer.Framework
{
@ -44,17 +45,20 @@ namespace StardewModdingAPI.Installer.Framework
/// <summary>The full path to the user's config overrides file.</summary>
public string ApiUserConfigPath { get; }
/// <summary>The full path to the installed game executable file.</summary>
public string ExecutablePath { get; private set; }
/// <summary>The full path to the installed game DLL.</summary>
public string GameDllPath { get; }
/// <summary>The full path to the vanilla game launcher on Linux/macOS.</summary>
public string UnixLauncherPath { get; }
/// <summary>The full path to the installed SMAPI executable file.</summary>
public string UnixSmapiExecutablePath { get; }
/// <summary>The full path to the installed SMAPI launcher on Linux/macOS before it's renamed.</summary>
public string UnixSmapiLauncherPath { get; }
/// <summary>The full path to the vanilla game launch script on Linux/macOS.</summary>
public string VanillaLaunchScriptPath { get; }
/// <summary>The full path to the vanilla game launcher on Linux/macOS after SMAPI is installed.</summary>
public string UnixBackupLauncherPath { get; }
/// <summary>The full path to the installed SMAPI launch script on Linux/macOS before it's renamed.</summary>
public string NewLaunchScriptPath { get; }
/// <summary>The full path to the backed up game launch script on Linux/macOS after SMAPI is installed.</summary>
public string BackupLaunchScriptPath { get; }
/*********
@ -63,28 +67,24 @@ namespace StardewModdingAPI.Installer.Framework
/// <summary>Construct an instance.</summary>
/// <param name="bundleDir">The directory path containing the files to copy into the game folder.</param>
/// <param name="gameDir">The directory path for the installed game.</param>
/// <param name="gameExecutableName">The name of the game's executable file for the current platform.</param>
public InstallerPaths(DirectoryInfo bundleDir, DirectoryInfo gameDir, string gameExecutableName)
public InstallerPaths(DirectoryInfo bundleDir, DirectoryInfo gameDir)
{
// base paths
this.BundleDir = bundleDir;
this.GameDir = gameDir;
this.ModsDir = new DirectoryInfo(Path.Combine(gameDir.FullName, "Mods"));
this.GameDllPath = Path.Combine(gameDir.FullName, Constants.GameDllName);
// launch scripts
this.VanillaLaunchScriptPath = Path.Combine(gameDir.FullName, "StardewValley");
this.NewLaunchScriptPath = Path.Combine(gameDir.FullName, "unix-launcher.sh");
this.BackupLaunchScriptPath = Path.Combine(gameDir.FullName, "StardewValley-original");
this.UnixSmapiExecutablePath = Path.Combine(gameDir.FullName, "StardewModdingAPI");
// internal files
this.BundleApiUserConfigPath = Path.Combine(bundleDir.FullName, "smapi-internal", "config.user.json");
this.ExecutablePath = Path.Combine(gameDir.FullName, gameExecutableName);
this.UnixLauncherPath = Path.Combine(gameDir.FullName, "StardewValley");
this.UnixSmapiLauncherPath = Path.Combine(gameDir.FullName, "StardewModdingAPI");
this.UnixBackupLauncherPath = Path.Combine(gameDir.FullName, "StardewValley-original");
this.ApiConfigPath = Path.Combine(gameDir.FullName, "smapi-internal", "config.json");
this.ApiUserConfigPath = Path.Combine(gameDir.FullName, "smapi-internal", "config.user.json");
}
/// <summary>Override the filename for the <see cref="ExecutablePath"/>.</summary>
/// <param name="filename">the file name.</param>
public void SetExecutableFileName(string filename)
{
this.ExecutablePath = Path.Combine(this.GamePath, filename);
}
}
}

View File

@ -41,12 +41,13 @@ namespace StardewModdingApi.Installer
// current files
yield return GetInstallPath("libgdiplus.dylib"); // Linux/macOS only
yield return GetInstallPath("StardewModdingAPI"); // Linux/macOS only
yield return GetInstallPath("StardewModdingAPI.dll");
yield return GetInstallPath("StardewModdingAPI.exe");
yield return GetInstallPath("StardewModdingAPI.exe.config");
yield return GetInstallPath("StardewModdingAPI.exe.mdb"); // Linux/macOS only
yield return GetInstallPath("StardewModdingAPI.pdb"); // Windows only
yield return GetInstallPath("StardewModdingAPI.runtimeconfig.json");
yield return GetInstallPath("StardewModdingAPI.xml");
yield return GetInstallPath("StardewModdingAPI-x64.exe"); // not normally added to game folder, but may be mistakenly added by a manual install
yield return GetInstallPath("smapi-internal");
yield return GetInstallPath("steam_appid.txt");
@ -70,9 +71,7 @@ namespace StardewModdingApi.Installer
yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.dll"); // moved in 2.8
yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.pdb"); // moved in 2.8
yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.xml"); // moved in 2.8
yield return GetInstallPath("System.Numerics.dll"); // moved in 2.8
yield return GetInstallPath("System.Runtime.Caching.dll"); // moved in 2.8
yield return GetInstallPath("System.ValueTuple.dll"); // moved in 2.8
yield return GetInstallPath("StardewModdingAPI-x64.exe"); // 3.13
if (modsDir.Exists)
{
@ -149,30 +148,6 @@ namespace StardewModdingApi.Installer
}
#endif
/****
** Check Windows dependencies
****/
if (context.IsWindows)
{
// .NET Framework 4.5+
if (!context.HasNetFramework45())
{
this.PrintError(context.CanInstallLatestNetFramework()
? "Please install the latest version of .NET Framework before installing SMAPI."
: "Please install .NET Framework 4.5 before installing SMAPI."
);
this.PrintError("See the download page at https://www.microsoft.com/net/download/framework for details.");
Console.ReadLine();
return;
}
if (!context.HasXna())
{
this.PrintError("You don't seem to have XNA Framework installed. Please run the game at least once before installing SMAPI, so it can perform its first-time setup.");
Console.ReadLine();
return;
}
}
/****
** read command-line arguments
****/
@ -270,7 +245,7 @@ namespace StardewModdingApi.Installer
// get folders
DirectoryInfo bundleDir = new DirectoryInfo(this.BundlePath);
paths = new InstallerPaths(bundleDir, installDir, context.ExecutableName);
paths = new InstallerPaths(bundleDir, installDir);
}
@ -278,7 +253,7 @@ namespace StardewModdingApi.Installer
** Step 4: validate assumptions
*********/
// executable exists
if (!File.Exists(paths.ExecutablePath))
if (!File.Exists(paths.GameDllPath))
{
this.PrintError("The detected game install path doesn't contain a Stardew Valley executable.");
Console.ReadLine();
@ -367,11 +342,11 @@ namespace StardewModdingApi.Installer
** Always uninstall old files
****/
// restore game launcher
if (context.IsUnix && File.Exists(paths.UnixBackupLauncherPath))
if (context.IsUnix && File.Exists(paths.BackupLaunchScriptPath))
{
this.PrintDebug("Removing SMAPI launcher...");
this.InteractivelyDelete(paths.UnixLauncherPath);
File.Move(paths.UnixBackupLauncherPath, paths.UnixLauncherPath);
this.InteractivelyDelete(paths.VanillaLaunchScriptPath);
File.Move(paths.BackupLaunchScriptPath, paths.VanillaLaunchScriptPath);
}
// remove old files
@ -419,28 +394,31 @@ namespace StardewModdingApi.Installer
this.PrintDebug("Safely replacing game launcher...");
// back up & remove current launcher
if (File.Exists(paths.UnixLauncherPath))
if (File.Exists(paths.VanillaLaunchScriptPath))
{
if (!File.Exists(paths.UnixBackupLauncherPath))
File.Move(paths.UnixLauncherPath, paths.UnixBackupLauncherPath);
if (!File.Exists(paths.BackupLaunchScriptPath))
File.Move(paths.VanillaLaunchScriptPath, paths.BackupLaunchScriptPath);
else
this.InteractivelyDelete(paths.UnixLauncherPath);
this.InteractivelyDelete(paths.VanillaLaunchScriptPath);
}
// add new launcher
File.Move(paths.UnixSmapiLauncherPath, paths.UnixLauncherPath);
File.Move(paths.NewLaunchScriptPath, paths.VanillaLaunchScriptPath);
// mark file executable
// mark files executable
// (MSBuild doesn't keep permission flags for files zipped in a build task.)
new Process
foreach (string path in new[] { paths.VanillaLaunchScriptPath, paths.UnixSmapiExecutablePath })
{
StartInfo = new ProcessStartInfo
new Process
{
FileName = "chmod",
Arguments = $"755 \"{paths.UnixLauncherPath}\"",
CreateNoWindow = true
}
}.Start();
StartInfo = new ProcessStartInfo
{
FileName = "chmod",
Arguments = $"755 \"{path}\"",
CreateNoWindow = true
}
}.Start();
}
}
// create mods directory (if needed)
@ -507,7 +485,7 @@ namespace StardewModdingApi.Installer
/*********
** Step 6: final instructions
** Step 7: final instructions
*********/
if (context.IsWindows)
{
@ -536,13 +514,6 @@ namespace StardewModdingApi.Installer
/*********
** Private methods
*********/
/// <summary>Get whether an executable is 64-bit.</summary>
/// <param name="executablePath">The absolute path to the executable file.</param>
private bool Is64Bit(string executablePath)
{
return LowLevelEnvironmentUtility.Is64BitAssembly(executablePath);
}
/// <summary>Get the display text for a color scheme.</summary>
/// <param name="scheme">The color scheme.</param>
private string GetDisplayText(MonitorColorScheme scheme)
@ -705,7 +676,7 @@ namespace StardewModdingApi.Installer
{
// get path from user
Console.WriteLine();
this.PrintInfo($"Type the file path to the game directory (the one containing '{context.ExecutableName}'), then press enter.");
this.PrintInfo($"Type the file path to the game directory (the one containing '{Constants.GameDllName}'), then press enter.");
string path = Console.ReadLine()?.Trim();
if (string.IsNullOrWhiteSpace(path))
{

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<RootNamespace>StardewModdingAPI.Installer</RootNamespace>
<Description>The SMAPI installer for players.</Description>
<TargetFramework>net452</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<OutputType>Exe</OutputType>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>

View File

@ -1,24 +1,10 @@
#!/bin/bash
# Run the SMAPI installer through Mono on Linux or macOS.
# Move to script's directory
cd "`dirname "$0"`"
# get cross-distro version of POSIX command
COMMAND=""
if command -v command >/dev/null 2>&1; then
COMMAND="command -v"
elif type type >/dev/null 2>&1; then
COMMAND="type"
fi
# if $TERM is not set to xterm, mono will bail out when attempting to write to the console.
export TERM=xterm
# validate Mono & run installer
if $COMMAND mono >/dev/null 2>&1; then
mono internal/unix-install.exe
else
echo "Oops! Looks like Mono isn't installed. Please install Mono from https://mono-project.com, reboot, and run this installer again."
read
fi
# run installer
./internal/unix-install

View File

@ -1,34 +1,17 @@
#!/usr/bin/env bash
# MonoKickstart Shell Script
# Written by Ethan "flibitijibibo" Lee
# Modified for SMAPI by various contributors
# Move to script's directory
cd "$(dirname "$0")" || exit $?
# Get the system architecture
UNAME=$(uname)
ARCH=$(uname -m)
# validate script is being run from the game folder
if [ ! -f "Stardew Valley.dll" ]; then
echo "Oops! SMAPI must be placed in the Stardew Valley game folder.\nSee instructions: https://stardewvalleywiki.com/Modding:Player_Guide";
read
exit 1
fi
# MonoKickstart picks the right libfolder, so just execute the right binary.
# macOS
if [ "$UNAME" == "Darwin" ]; then
# ... Except on OSX.
export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:./osx/
# El Capitan is a total idiot and wipes this variable out, making the
# Steam overlay disappear. This sidesteps "System Integrity Protection"
# and resets the variable with Valve's own variable (they provided this
# fix by the way, thanks Valve!). Note that you will need to update your
# launch configuration to the script location, NOT just the app location
# (i.e. Kick.app/Contents/MacOS/Kick, not just Kick.app).
# -flibit
if [ "$STEAM_DYLD_INSERT_LIBRARIES" != "" ] && [ "$DYLD_INSERT_LIBRARIES" == "" ]; then
export DYLD_INSERT_LIBRARIES="$STEAM_DYLD_INSERT_LIBRARIES"
fi
# this was here before
ln -sf mcs.bin.osx mcs
# fix "DllNotFoundException: libgdiplus.dylib" errors when loading images in SMAPI
if [ -f libgdiplus.dylib ]; then
rm libgdiplus.dylib
@ -37,52 +20,13 @@ if [ "$UNAME" == "Darwin" ]; then
ln -s /Library/Frameworks/Mono.framework/Versions/Current/lib/libgdiplus.dylib libgdiplus.dylib
fi
# create bin file
# Note: don't overwrite if it's identical, to avoid resetting permission flags
if [ ! -x StardewModdingAPI.bin.osx ] || ! cmp StardewValley.bin.osx StardewModdingAPI.bin.osx >/dev/null 2>&1; then
cp -p StardewValley.bin.osx StardewModdingAPI.bin.osx
fi
# launch smapi
open -a Terminal ./StardewModdingAPI "$@"
# Make sure we're running in Terminal (so the user can see errors/warnings/update alerts).
# Previously we would just use `open -a Terminal` to launch the .bin.osx file, but that
# doesn't let us set environment variables.
if [ ! -t 1 ]; then # https://stackoverflow.com/q/911168/262123
# sanity check to make sure we don't have an infinite loop of opening windows
SKIP_TERMINAL=false
for argument in "$@"; do
if [ "$argument" == "--no-reopen-terminal" ]; then
SKIP_TERMINAL=true
break
fi
done
# reopen in Terminal if needed
# https://stackoverflow.com/a/29511052/262123
if [ "$SKIP_TERMINAL" == "false" ]; then
echo "Reopening in the Terminal app..."
echo "\"$0\" $@ --no-reopen-terminal" > /tmp/open-smapi-terminal.sh
chmod +x /tmp/open-smapi-terminal.sh
cat /tmp/open-smapi-terminal.sh
open -W -a Terminal /tmp/open-smapi-terminal.sh
rm /tmp/open-smapi-terminal.sh
exit 0
fi
fi
# launch SMAPI
LC_ALL="C" ./StardewModdingAPI.bin.osx "$@"
# Linux
else
# choose binary file to launch
LAUNCH_FILE=""
if [ "$ARCH" == "x86_64" ]; then
ln -sf mcs.bin.x86_64 mcs
cp StardewValley.bin.x86_64 StardewModdingAPI.bin.x86_64
LAUNCH_FILE="./StardewModdingAPI.bin.x86_64"
else
ln -sf mcs.bin.x86 mcs
cp StardewValley.bin.x86 StardewModdingAPI.bin.x86
LAUNCH_FILE="./StardewModdingAPI.bin.x86"
fi
LAUNCH_FILE="./StardewModdingAPI"
export LAUNCH_FILE
# select terminal (prefer xterm for best compatibility, then known supported terminals)
@ -105,44 +49,44 @@ else
terminal|termite)
# consumes only one argument after -e
# options containing space characters are unsupported
exec $TERMINAL_NAME -e "env TERM=xterm LC_ALL=\"C\" $LAUNCH_FILE $@"
exec $TERMINAL_NAME -e "env TERM=xterm $LAUNCH_FILE $@"
;;
xterm|konsole|alacritty)
# consumes all arguments after -e
exec $TERMINAL_NAME -e env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@"
exec $TERMINAL_NAME -e env TERM=xterm $LAUNCH_FILE "$@"
;;
terminator|xfce4-terminal|mate-terminal)
# consumes all arguments after -x
exec $TERMINAL_NAME -x env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@"
exec $TERMINAL_NAME -x env TERM=xterm $LAUNCH_FILE "$@"
;;
gnome-terminal)
# consumes all arguments after --
exec $TERMINAL_NAME -- env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@"
exec $TERMINAL_NAME -- env TERM=xterm $LAUNCH_FILE "$@"
;;
kitty)
# consumes all trailing arguments
exec $TERMINAL_NAME env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@"
exec $TERMINAL_NAME env TERM=xterm $LAUNCH_FILE "$@"
;;
*)
# If we don't know the terminal, just try to run it in the current shell.
# If THAT fails, launch with no output.
env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@"
env TERM=xterm $LAUNCH_FILE "$@"
if [ $? -eq 127 ]; then
exec LC_ALL="C" $LAUNCH_FILE --no-terminal "$@"
exec $LAUNCH_FILE --no-terminal "$@"
fi
esac
## terminal isn't executable; fallback to current shell or no terminal
else
echo "The '$TERMINAL_NAME' terminal isn't executable. SMAPI might be running in a sandbox or the system might be misconfigured? Falling back to current shell."
env TERM=xterm LC_ALL="C" $LAUNCH_FILE "$@"
env TERM=xterm $LAUNCH_FILE "$@"
if [ $? -eq 127 ]; then
exec LC_ALL="C" $LAUNCH_FILE --no-terminal "$@"
exec $LAUNCH_FILE --no-terminal "$@"
fi
fi
fi

View File

@ -1,18 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="2.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>
<ItemGroup>
@ -20,5 +16,4 @@
</ItemGroup>
<Import Project="..\..\build\common.targets" />
</Project>

View File

@ -9,8 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="2.10.0" PrivateAssets="all" />
<PackageReference Update="NETStandard.Library" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.10.0" />
</ItemGroup>
<ItemGroup>

View File

@ -2,28 +2,28 @@
<PropertyGroup>
<!--build-->
<RootNamespace>StardewModdingAPI.ModBuildConfig</RootNamespace>
<TargetFramework>net452</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<!--NuGet package-->
<PackageId>Pathoschild.Stardew.ModBuildConfig</PackageId>
<Title>Build package for SMAPI mods</Title>
<Version>3.3.0</Version>
<Version>3.4.0</Version>
<Authors>Pathoschild</Authors>
<Description>Automates the build configuration for crossplatform Stardew Valley SMAPI mods. For SMAPI 3.0 or later.</Description>
<Description>Automates the build configuration for crossplatform Stardew Valley SMAPI mods. For SMAPI 3.13.0 or later.</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIcon>images/icon.png</PackageIcon>
<PackageProjectUrl>https://smapi.io/package/readme</PackageProjectUrl>
<IncludeBuildOutput>false</IncludeBuildOutput>
<!--copy dependency DLLs to bin folder so we can include them in package -->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Build" />
<Reference Include="Microsoft.Build.Framework" />
<Reference Include="Microsoft.Build.Utilities.v4.0" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Web.Extensions" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="16.10" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup>

View File

@ -45,13 +45,13 @@
**********************************************-->
<ItemGroup>
<!-- game -->
<Reference Include="$(GameExecutableName)" HintPath="$(GamePath)\$(GameExecutableName).exe" Private="$(CopyModReferencesToBuildOutput)" />
<Reference Include="$(GameExecutableName)" HintPath="$(GamePath)\$(GameExecutableName).dll" Private="$(CopyModReferencesToBuildOutput)" />
<Reference Include="StardewValley.GameData" HintPath="$(GamePath)\StardewValley.GameData.dll" Private="$(CopyModReferencesToBuildOutput)" />
<Reference Include="MonoGame.Framework" HintPath="$(GamePath)\MonoGame.Framework.dll" Private="$(CopyModReferencesToBuildOutput)" />
<Reference Include="xTile" HintPath="$(GamePath)\xTile.dll" Private="$(CopyModReferencesToBuildOutput)" />
<!-- SMAPI -->
<Reference Include="StardewModdingAPI" HintPath="$(GamePath)\StardewModdingAPI.exe" Private="$(CopyModReferencesToBuildOutput)" />
<Reference Include="StardewModdingAPI" HintPath="$(GamePath)\StardewModdingAPI.dll" Private="$(CopyModReferencesToBuildOutput)" />
<Reference Include="SMAPI.Toolkit.CoreInterfaces" HintPath="$(GamePath)\smapi-internal\SMAPI.Toolkit.CoreInterfaces.dll" Private="$(CopyModReferencesToBuildOutput)" />
<!-- Harmony -->
@ -68,8 +68,8 @@
<!-- invalid game path -->
<Error Condition="!Exists('$(GamePath)')" Text="The mod build package can't find your game folder. You can specify where to find it; see https://smapi.io/package/custom-game-path." ContinueOnError="false" />
<Error Condition="!Exists('$(GamePath)\$(GameExecutableName).exe')" Text="The mod build package found a game folder at $(GamePath), but it doesn't contain the $(GameExecutableName) file. If this folder is invalid, delete it and the package will autodetect another game install path." ContinueOnError="false" />
<Error Condition="!Exists('$(GamePath)\StardewModdingAPI.exe')" Text="The mod build package found a game folder at $(GamePath), but it doesn't contain SMAPI. You need to install SMAPI before building the mod." ContinueOnError="false" />
<Error Condition="!Exists('$(GamePath)\$(GameExecutableName).dll')" Text="The mod build package found a game folder at $(GamePath), but it doesn't contain the $(GameExecutableName) file. If this folder is invalid, delete it and the package will autodetect another game install path." ContinueOnError="false" />
<Error Condition="!Exists('$(GamePath)\StardewModdingAPI.dll')" Text="The mod build package found a game folder at $(GamePath), but it doesn't contain SMAPI. You need to install SMAPI before building the mod." ContinueOnError="false" />
<!-- invalid target architecture (note: internal value is 'AnyCPU', value shown in Visual Studio is 'Any CPU') -->
<Warning Condition="'$(Platform)' != 'AnyCPU'" Text="The target platform should be set to 'Any CPU' for compatibility with both 32-bit and 64-bit versions of Stardew Valley (currently set to '$(Platform)'). See https://smapi.io/package/wrong-processor-architecture for details." HelpLink="https://smapi.io/package/wrong-processor-architecture" />

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<AssemblyName>ConsoleCommands</AssemblyName>
<RootNamespace>StardewModdingAPI.Mods.ConsoleCommands</RootNamespace>
<TargetFramework>net452</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
@ -13,7 +13,7 @@
</ItemGroup>
<ItemGroup>
<Reference Include="$(GameExecutableName)" HintPath="$(GamePath)\$(GameExecutableName).exe" Private="False" />
<Reference Include="$(GameExecutableName)" HintPath="$(GamePath)\$(GameExecutableName).dll" Private="False" />
<Reference Include="MonoGame.Framework" HintPath="$(GamePath)\MonoGame.Framework.dll" Private="False" />
<Reference Include="StardewValley.GameData" HintPath="$(GamePath)\StardewValley.GameData.dll" Private="False" />
</ItemGroup>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<AssemblyName>ErrorHandler</AssemblyName>
<RootNamespace>StardewModdingAPI.Mods.ErrorHandler</RootNamespace>
<TargetFramework>net452</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
@ -14,7 +14,7 @@
</ItemGroup>
<ItemGroup>
<Reference Include="$(GameExecutableName)" HintPath="$(GamePath)\$(GameExecutableName).exe" Private="False" />
<Reference Include="$(GameExecutableName)" HintPath="$(GamePath)\$(GameExecutableName).dll" Private="False" />
<Reference Include="MonoGame.Framework" HintPath="$(GamePath)\MonoGame.Framework.dll" Private="False" />
<Reference Include="StardewValley.GameData" HintPath="$(GamePath)\StardewValley.GameData.dll" Private="False" />
<Reference Include="xTile" HintPath="$(GamePath)\xTile.dll" Private="False" />

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<AssemblyName>SaveBackup</AssemblyName>
<RootNamespace>StardewModdingAPI.Mods.SaveBackup</RootNamespace>
<TargetFramework>net452</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
@ -13,7 +13,7 @@
</ItemGroup>
<ItemGroup>
<Reference Include="$(GameExecutableName)" HintPath="$(GamePath)\$(GameExecutableName).exe" Private="False" />
<Reference Include="$(GameExecutableName)" HintPath="$(GamePath)\$(GameExecutableName).dll" Private="False" />
</ItemGroup>
<ItemGroup>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<AssemblyName>SMAPI.Tests</AssemblyName>
<RootNamespace>SMAPI.Tests</RootNamespace>
<TargetFramework>net452</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<LangVersion>latest</LangVersion>
</PropertyGroup>
@ -16,6 +16,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NUnit" Version="3.13.2" />
@ -23,7 +24,7 @@
<ItemGroup>
<Reference Include="$(GameExecutableName)">
<HintPath>$(GamePath)\$(GameExecutableName).exe</HintPath>
<HintPath>$(GamePath)\$(GameExecutableName).dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<RootNamespace>StardewModdingAPI</RootNamespace>
<Description>Provides toolkit interfaces which are available to SMAPI mods.</Description>
<TargetFrameworks>net452;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net5.0; netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

View File

@ -0,0 +1,9 @@
namespace StardewModdingAPI.Toolkit.Framework
{
/// <summary>Contains the SMAPI installer's constants and assumptions.</summary>
internal static class Constants
{
/// <summary>The name of the game's main DLL, used to detect game folders.</summary>
public const string GameDllName = "Stardew Valley.dll";
}
}

View File

@ -56,10 +56,7 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning
{
return
dir.Exists
&& (
dir.EnumerateFiles("StardewValley.exe").Any()
|| dir.EnumerateFiles("Stardew Valley.exe").Any()
);
&& dir.EnumerateFiles("Stardew Valley.dll").Any();
}

View File

@ -80,15 +80,6 @@ namespace StardewModdingAPI.Toolkit.Framework
return name;
}
/// <summary>Get the name of the Stardew Valley executable.</summary>
/// <param name="platform">The current platform.</param>
public static string GetExecutableName(string platform)
{
return platform == nameof(Platform.Windows)
? "Stardew Valley.exe"
: "StardewValley.exe";
}
/// <summary>Get whether an executable is 64-bit.</summary>
/// <param name="path">The absolute path to the assembly file.</param>
public static bool Is64BitAssembly(string path)

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<RootNamespace>StardewModdingAPI.Toolkit</RootNamespace>
<Description>A library which encapsulates mod-handling logic for mod managers and tools. Not intended for use by mods.</Description>
<TargetFrameworks>net452;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net5.0; netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
@ -12,8 +12,8 @@
<PackageReference Include="HtmlAgilityPack" Version="1.11.33" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Pathoschild.Http.FluentClient" Version="4.1.0" />
<PackageReference Include="System.Management" Version="4.5.0" Condition="'$(OS)' == 'Windows_NT'" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" Condition="'$(OS)' == 'Windows_NT' AND '$(TargetFramework)' == 'netstandard2.0'" />
<PackageReference Include="System.Management" Version="5.0.0" Condition="'$(OS)' == 'Windows_NT'" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" Condition="'$(OS)' == 'Windows_NT'" />
</ItemGroup>
<ItemGroup>

View File

@ -40,13 +40,6 @@ namespace StardewModdingAPI.Toolkit.Utilities
return LowLevelEnvironmentUtility.GetFriendlyPlatformName(platform.ToString());
}
/// <summary>Get the name of the Stardew Valley executable.</summary>
/// <param name="platform">The current platform.</param>
public static string GetExecutableName(Platform platform)
{
return LowLevelEnvironmentUtility.GetExecutableName(platform.ToString());
}
/// <summary>Get whether an executable is 64-bit.</summary>
/// <param name="path">The absolute path to the assembly file.</param>
public static bool Is64BitAssembly(string path)

View File

@ -88,14 +88,18 @@ namespace StardewModdingAPI.Toolkit.Utilities
/// <summary>Get a directory or file path relative to a given source path. If no relative path is possible (e.g. the paths are on different drives), an absolute path is returned.</summary>
/// <param name="sourceDir">The source folder path.</param>
/// <param name="targetPath">The target folder or file path.</param>
/// <remarks>
///
/// NOTE: this is a heuristic implementation that works in the cases SMAPI needs it for, but it doesn't handle all edge cases (e.g. case-sensitivity on Linux, or traversing between UNC paths on Windows). This should be replaced with the more comprehensive <c>Path.GetRelativePath</c> if the game ever migrates to .NET Core.
///
/// </remarks>
[Pure]
public static string GetRelativePath(string sourceDir, string targetPath)
{
#if NET5_0
return Path.GetRelativePath(sourceDir, targetPath);
#else
// NOTE:
// this is a heuristic implementation that works in the cases SMAPI needs it for, but it
// doesn't handle all edge cases (e.g. case-sensitivity on Linux, or traversing between
// UNC paths on Windows). SMAPI and mods will use the more robust .NET 5 version anyway
// though, this is only for compatibility with the mod build package.
// convert to URIs
Uri from = new Uri(sourceDir.TrimEnd(PathUtilities.PossiblePathSeparators) + "/");
Uri to = new Uri(targetPath.TrimEnd(PathUtilities.PossiblePathSeparators) + "/");
@ -123,6 +127,7 @@ namespace StardewModdingAPI.Toolkit.Utilities
}
return relative;
#endif
}
/// <summary>Get whether a path is relative and doesn't try to climb out of its containing folder (e.g. doesn't contain <c>../</c>).</summary>

View File

@ -290,7 +290,7 @@ namespace StardewModdingAPI.Framework.Logging
/// <param name="customSettings">The custom SMAPI settings.</param>
public void LogIntro(string modsPath, IDictionary<string, object> customSettings)
{
// log platform & patches
// log platform
this.Monitor.Log($"SMAPI {Constants.ApiVersion} with Stardew Valley {Constants.GameVersion} on {EnvironmentUtility.GetFriendlyPlatformName(Constants.Platform)}", LogLevel.Info);
// log basic info

View File

@ -24,7 +24,7 @@ namespace StardewModdingAPI.Framework.Reflection
/// <summary>Construct an instance.</summary>
public InterfaceProxyFactory()
{
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName($"StardewModdingAPI.Proxies, Version={this.GetType().Assembly.GetName().Version}, Culture=neutral"), AssemblyBuilderAccess.Run);
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName($"StardewModdingAPI.Proxies, Version={this.GetType().Assembly.GetName().Version}, Culture=neutral"), AssemblyBuilderAccess.Run);
this.ModuleBuilder = assemblyBuilder.DefineDynamicModule("StardewModdingAPI.Proxies");
}

View File

@ -16,7 +16,6 @@ using Microsoft.Xna.Framework;
#if SMAPI_FOR_WINDOWS
using Microsoft.Win32;
#endif
using Microsoft.Xna.Framework;
using Newtonsoft.Json;
using StardewModdingAPI.Enums;
using StardewModdingAPI.Events;
@ -1298,9 +1297,6 @@ namespace StardewModdingAPI.Framework
{
// create client
string url = this.Settings.WebApiBaseUrl;
#if !SMAPI_FOR_WINDOWS
url = url.Replace("https://", "http://"); // workaround for OpenSSL issues with the game's bundled Mono on Linux/macOS
#endif
WebApiClient client = new WebApiClient(url, Constants.ApiVersion);
this.Monitor.Log("Checking for updates...");
@ -1695,9 +1691,8 @@ namespace StardewModdingAPI.Framework
catch (Exception ex)
{
errorReasonPhrase = "its DLL couldn't be loaded.";
// re-enable in Stardew Valley 1.5.5
//if (ex is BadImageFormatException && !EnvironmentUtility.Is64BitAssembly(assemblyPath))
// errorReasonPhrase = "it needs to be updated for 64-bit mode.";
if (ex is BadImageFormatException && !EnvironmentUtility.Is64BitAssembly(assemblyPath))
errorReasonPhrase = "it needs to be updated for 64-bit mode.";
errorDetails = $"Error: {ex.GetLogSummary()}";
failReason = ModFailReason.LoadFailed;

View File

@ -48,7 +48,7 @@ namespace StardewModdingAPI.Metadata
// rewrite for Stardew Valley 1.5.5
if (platformChanged)
yield return new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchFacade));
//yield return new ArchitectureAssemblyRewriter();
yield return new ArchitectureAssemblyRewriter();
// detect Harmony & rewrite for SMAPI 3.12 (Harmony 1.x => 2.0 update)
yield return new HarmonyRewriter();

View File

@ -3,13 +3,16 @@
<AssemblyName>StardewModdingAPI</AssemblyName>
<RootNamespace>StardewModdingAPI</RootNamespace>
<Description>The modding API for Stardew Valley.</Description>
<TargetFramework>net452</TargetFramework>
<PlatformTarget>x86</PlatformTarget>
<TargetFramework>net5.0</TargetFramework>
<PlatformTarget>x64</PlatformTarget>
<OutputType>Exe</OutputType>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<LargeAddressAware Condition="'$(OS)' == 'Windows_NT'">true</LargeAddressAware>
<ApplicationIcon>icon.ico</ApplicationIcon>
<!--copy dependency DLLs to bin folder so we can include them in installer bundle -->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<Import Project="..\..\build\common.targets" />
@ -19,15 +22,16 @@
<PackageReference Include="Mono.Cecil" Version="0.11.4" />
<PackageReference Include="MonoMod.Common" Version="21.6.21.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Platonymous.TMXTile" Version="1.5.8" />
<PackageReference Include="Platonymous.TMXTile" Version="1.5.9" />
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
<PackageReference Include="System.Runtime.Caching" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="..\..\build\0Harmony.dll" Private="True" />
<Reference Include="$(GameExecutableName)" HintPath="$(GamePath)\$(GameExecutableName).exe" Private="False" />
<Reference Include="$(GameExecutableName)" HintPath="$(GamePath)\$(GameExecutableName).dll" Private="False" />
<Reference Include="StardewValley.GameData" HintPath="$(GamePath)\StardewValley.GameData.dll" Private="False" />
<Reference Include="System.Numerics" Private="True" />
<Reference Include="System.Runtime.Caching" Private="True" />
<Reference Include="GalaxyCSharp" HintPath="$(GamePath)\GalaxyCSharp.dll" Private="False" />
<Reference Include="Lidgren.Network" HintPath="$(GamePath)\Lidgren.Network.dll" Private="False" />
<Reference Include="MonoGame.Framework" HintPath="$(GamePath)\MonoGame.Framework.dll" Private="False" />