diff options
33 files changed, 192 insertions, 341 deletions
diff --git a/build/common.targets b/build/common.targets index 02142351..a74002a6 100644 --- a/build/common.targets +++ b/build/common.targets @@ -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" /> diff --git a/build/prepare-install-package.targets b/build/prepare-install-package.targets index 601f6496..bc1716a3 100644 --- a/build/prepare-install-package.targets +++ b/build/prepare-install-package.targets @@ -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 "$(PackagePath)\install on Linux.sh"" /> - <Exec Condition="$(PlatformName) == 'unix'" Command="chmod 755 "$(PackagePath)\install on macOS.command"" /> + <Exec Condition="$(PlatformName) == 'unix'" Command="chmod 755 "$(PackagePath)/install on Linux.sh"" /> + <Exec Condition="$(PlatformName) == 'unix'" Command="chmod 755 "$(PackagePath)/install on macOS.command"" /> + <Exec Condition="$(PlatformName) == 'unix'" Command="chmod 755 "$(PackagePath)/bundle/unix-launcher.sh"" /> <!-- 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=""DeveloperMode": true" Replace=""DeveloperMode": 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" /> diff --git a/docs/release-notes.md b/docs/release-notes.md index efda7267..43370409 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -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. diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md index 7eefc7a4..a3ce8761 100644 --- a/docs/technical/mod-package.md +++ b/docs/technical/mod-package.md @@ -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 diff --git a/docs/technical/web.md b/docs/technical/web.md index 50237bfe..f0d43fb1 100644 --- a/docs/technical/web.md +++ b/docs/technical/web.md @@ -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 diff --git a/src/SMAPI.Installer/Framework/InstallerContext.cs b/src/SMAPI.Installer/Framework/InstallerContext.cs index 88e57760..95df32ca 100644 --- a/src/SMAPI.Installer/Framework/InstallerContext.cs +++ b/src/SMAPI.Installer/Framework/InstallerContext.cs @@ -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) diff --git a/src/SMAPI.Installer/Framework/InstallerPaths.cs b/src/SMAPI.Installer/Framework/InstallerPaths.cs index 6ba5fa5f..0976eceb 100644 --- a/src/SMAPI.Installer/Framework/InstallerPaths.cs +++ b/src/SMAPI.Installer/Framework/InstallerPaths.cs @@ -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); - this.BundleApiUserConfigPath = Path.Combine(bundleDir.FullName, "smapi-internal", "config.user.json"); + // 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"); - 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"); + // internal files + this.BundleApiUserConfigPath = Path.Combine(bundleDir.FullName, "smapi-internal", "config.user.json"); 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); - } } } diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index 79c3b891..34285cf7 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -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) { @@ -150,30 +149,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 ****/ // get action from CLI @@ -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)) { diff --git a/src/SMAPI.Installer/SMAPI.Installer.csproj b/src/SMAPI.Installer/SMAPI.Installer.csproj index c47f3e6e..e3e01467 100644 --- a/src/SMAPI.Installer/SMAPI.Installer.csproj +++ b/src/SMAPI.Installer/SMAPI.Installer.csproj @@ -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> diff --git a/src/SMAPI.Installer/assets/System.Numerics.dll b/src/SMAPI.Installer/assets/System.Numerics.dll Binary files differdeleted file mode 100644 index fed0f92c..00000000 --- a/src/SMAPI.Installer/assets/System.Numerics.dll +++ /dev/null diff --git a/src/SMAPI.Installer/assets/System.Runtime.Caching.dll b/src/SMAPI.Installer/assets/System.Runtime.Caching.dll Binary files differdeleted file mode 100644 index a062391d..00000000 --- a/src/SMAPI.Installer/assets/System.Runtime.Caching.dll +++ /dev/null diff --git a/src/SMAPI.Installer/assets/unix-install.sh b/src/SMAPI.Installer/assets/unix-install.sh index 311c5469..a830a22d 100644 --- a/src/SMAPI.Installer/assets/unix-install.sh +++ b/src/SMAPI.Installer/assets/unix-install.sh @@ -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 diff --git a/src/SMAPI.Installer/assets/unix-launcher.sh b/src/SMAPI.Installer/assets/unix-launcher.sh index d309f750..21bed803 100644 --- a/src/SMAPI.Installer/assets/unix-launcher.sh +++ b/src/SMAPI.Installer/assets/unix-launcher.sh @@ -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 - - # 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 + open -a Terminal ./StardewModdingAPI "$@" - # 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 diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj b/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj index dc3d8320..264932e4 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj @@ -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> diff --git a/src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj b/src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj index 0d109b83..3fadc37a 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj +++ b/src/SMAPI.ModBuildConfig.Analyzer/SMAPI.ModBuildConfig.Analyzer.csproj @@ -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> diff --git a/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj b/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj index 93769650..33356413 100644 --- a/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj +++ b/src/SMAPI.ModBuildConfig/SMAPI.ModBuildConfig.csproj @@ -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> diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index be10481b..a3cd6c45 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -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" /> diff --git a/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj b/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj index fa192073..65d54599 100644 --- a/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj +++ b/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj @@ -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> diff --git a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj index 7ba6025b..2ad19df7 100644 --- a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj +++ b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj @@ -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" /> diff --git a/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj b/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj index 079beb08..f8908c7d 100644 --- a/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj +++ b/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj @@ -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> diff --git a/src/SMAPI.Tests/SMAPI.Tests.csproj b/src/SMAPI.Tests/SMAPI.Tests.csproj index 8f7bfab4..e19105ff 100644 --- a/src/SMAPI.Tests/SMAPI.Tests.csproj +++ b/src/SMAPI.Tests/SMAPI.Tests.csproj @@ -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> diff --git a/src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj b/src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj index 0e1e40b2..4c92b4db 100644 --- a/src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj +++ b/src/SMAPI.Toolkit.CoreInterfaces/SMAPI.Toolkit.CoreInterfaces.csproj @@ -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> diff --git a/src/SMAPI.Toolkit/Framework/Constants.cs b/src/SMAPI.Toolkit/Framework/Constants.cs new file mode 100644 index 00000000..55f26582 --- /dev/null +++ b/src/SMAPI.Toolkit/Framework/Constants.cs @@ -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"; + } +} diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs index c90fc1d3..7553c07f 100644 --- a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs +++ b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs @@ -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(); } diff --git a/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs b/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs index 2636aae0..8b6eb5fb 100644 --- a/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs +++ b/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs @@ -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) diff --git a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj index 3d87c169..ec27bf79 100644 --- a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj +++ b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj @@ -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> diff --git a/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs b/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs index 6de79a85..7536337a 100644 --- a/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs +++ b/src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs @@ -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) diff --git a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs index 020ebc6d..c17bb354 100644 --- a/src/SMAPI.Toolkit/Utilities/PathUtilities.cs +++ b/src/SMAPI.Toolkit/Utilities/PathUtilities.cs @@ -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> diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index 2e25a94a..abcb2f64 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -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 diff --git a/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs b/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs index 8d1b6034..5acba569 100644 --- a/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs +++ b/src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs @@ -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"); } diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index b049e868..95a7ace6 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -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; diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index 368306a1..232e54ce 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -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(); diff --git a/src/SMAPI/SMAPI.csproj b/src/SMAPI/SMAPI.csproj index e5cc8da6..a04dd1b6 100644 --- a/src/SMAPI/SMAPI.csproj +++ b/src/SMAPI/SMAPI.csproj @@ -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" /> |