From 6efaa651cb2b026b7bace55ffeba9d7c5a3d0567 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 12 Aug 2021 21:26:01 -0400 Subject: drop support for XNA Framework Stardew Valley 1.5.5 migrates to MonoGame on all platforms. --- docs/technical/smapi.md | 1 - 1 file changed, 1 deletion(-) (limited to 'docs/technical') diff --git a/docs/technical/smapi.md b/docs/technical/smapi.md index f454e99c..29fa43a8 100644 --- a/docs/technical/smapi.md +++ b/docs/technical/smapi.md @@ -57,7 +57,6 @@ SMAPI uses a small number of conditional compilation constants, which you can se flag | purpose ---- | ------- `SMAPI_FOR_WINDOWS` | Whether SMAPI is being compiled for Windows; if not set, the code assumes Linux/macOS. Set automatically in `common.targets`. -`SMAPI_FOR_XNA` | Whether SMAPI is being compiled for XNA Framework; if not set, the code assumes MonoGame. Set automatically in `common.targets` with the same value as `SMAPI_FOR_WINDOWS`. ## For SMAPI developers ### Compiling from source -- cgit From 727d75ae728ba6cc8fc070524264c454aac8404f Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 12 Aug 2021 21:26:10 -0400 Subject: update to .NET 5 and official 64-bit --- build/common.targets | 25 ++++-- build/prepare-install-package.targets | 66 +++++--------- docs/release-notes.md | 14 +++ docs/technical/mod-package.md | 1 + docs/technical/web.md | 2 +- src/SMAPI.Installer/Framework/InstallerContext.cs | 45 ---------- src/SMAPI.Installer/Framework/InstallerPaths.cs | 44 +++++----- src/SMAPI.Installer/InteractiveInstaller.cs | 81 ++++++----------- src/SMAPI.Installer/SMAPI.Installer.csproj | 2 +- src/SMAPI.Installer/assets/System.Numerics.dll | Bin 54272 -> 0 bytes .../assets/System.Runtime.Caching.dll | Bin 71168 -> 0 bytes src/SMAPI.Installer/assets/unix-install.sh | 18 +--- src/SMAPI.Installer/assets/unix-launcher.sh | 96 +++++---------------- .../SMAPI.ModBuildConfig.Analyzer.Tests.csproj | 13 +-- .../SMAPI.ModBuildConfig.Analyzer.csproj | 3 +- .../SMAPI.ModBuildConfig.csproj | 16 ++-- src/SMAPI.ModBuildConfig/build/smapi.targets | 8 +- .../SMAPI.Mods.ConsoleCommands.csproj | 4 +- .../SMAPI.Mods.ErrorHandler.csproj | 4 +- .../SMAPI.Mods.SaveBackup.csproj | 4 +- src/SMAPI.Tests/SMAPI.Tests.csproj | 5 +- .../SMAPI.Toolkit.CoreInterfaces.csproj | 2 +- src/SMAPI.Toolkit/Framework/Constants.cs | 9 ++ .../Framework/GameScanning/GameScanner.cs | 5 +- .../Framework/LowLevelEnvironmentUtility.cs | 9 -- src/SMAPI.Toolkit/SMAPI.Toolkit.csproj | 6 +- src/SMAPI.Toolkit/Utilities/EnvironmentUtility.cs | 7 -- src/SMAPI.Toolkit/Utilities/PathUtilities.cs | 15 ++-- src/SMAPI/Framework/Logging/LogManager.cs | 2 +- .../Framework/Reflection/InterfaceProxyFactory.cs | 2 +- src/SMAPI/Framework/SCore.cs | 9 +- src/SMAPI/Metadata/InstructionMetadata.cs | 2 +- src/SMAPI/SMAPI.csproj | 14 +-- 33 files changed, 192 insertions(+), 341 deletions(-) delete mode 100644 src/SMAPI.Installer/assets/System.Numerics.dll delete mode 100644 src/SMAPI.Installer/assets/System.Runtime.Caching.dll create mode 100644 src/SMAPI.Toolkit/Framework/Constants.cs (limited to 'docs/technical') 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);{GAC} - $(DefineConstants);SMAPI_FOR_WINDOWS;SMAPI_FOR_XNA + $(DefineConstants);SMAPI_FOR_WINDOWS @@ -27,20 +27,31 @@ - + + + + + + + + + - - - + + + + + + @@ -54,13 +65,13 @@ - + - + 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 @@ $(SolutionDir)\..\bin $(BuildRootPath)\SMAPI\bin\$(Configuration) - $(BuildRootPath)\SMAPI.Toolkit\bin\$(Configuration)\net452 + $(BuildRootPath)\SMAPI.Toolkit\bin\$(Configuration)\net5.0 $(BuildRootPath)\SMAPI.Mods.ConsoleCommands\bin\$(Configuration) $(BuildRootPath)\SMAPI.Mods.ErrorHandler\bin\$(Configuration) $(BuildRootPath)\SMAPI.Mods.SaveBackup\bin\$(Configuration) @@ -35,12 +35,17 @@ - - - + + + + + + - + + + @@ -61,11 +66,16 @@ - - + + + + + + + @@ -78,63 +88,33 @@ - - - - - - + + + - + - + - - - - - - - - - - - - - - - - + - 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 *********/ - /// The value that represents Windows 7. - private readonly Version Windows7Version = new Version(6, 1); - /// The underlying toolkit game scanner. private readonly GameScanner GameScanner = new GameScanner(); @@ -29,9 +24,6 @@ namespace StardewModdingAPI.Installer.Framework /// The human-readable OS name and version. public string PlatformName { get; } - /// The name of the Stardew Valley executable. - public string ExecutableName { get; } - /// Whether the installer is running on Windows. 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); } /// Get the installer's version number. @@ -57,42 +48,6 @@ namespace StardewModdingAPI.Installer.Framework return new SemanticVersion(raw); } - /// Get whether the current system has .NET Framework 4.5 or later installed. This only applies on Windows. - /// The current platform is not Windows. - 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."); - } - } - - /// Get whether the current system has XNA Framework installed. This only applies on Windows. - /// The current platform is not Windows. - 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."); - } - } - - /// Whether the current OS supports newer versions of .NET Framework. - public bool CanInstallLatestNetFramework() - { - return Environment.OSVersion.Version >= this.Windows7Version; // Windows 7+ - } - /// Get whether a folder seems to contain the game files. /// The folder to check. 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 /// The full path to the user's config overrides file. public string ApiUserConfigPath { get; } - /// The full path to the installed game executable file. - public string ExecutablePath { get; private set; } + /// The full path to the installed game DLL. + public string GameDllPath { get; } - /// The full path to the vanilla game launcher on Linux/macOS. - public string UnixLauncherPath { get; } + /// The full path to the installed SMAPI executable file. + public string UnixSmapiExecutablePath { get; } - /// The full path to the installed SMAPI launcher on Linux/macOS before it's renamed. - public string UnixSmapiLauncherPath { get; } + /// The full path to the vanilla game launch script on Linux/macOS. + public string VanillaLaunchScriptPath { get; } - /// The full path to the vanilla game launcher on Linux/macOS after SMAPI is installed. - public string UnixBackupLauncherPath { get; } + /// The full path to the installed SMAPI launch script on Linux/macOS before it's renamed. + public string NewLaunchScriptPath { get; } + + /// The full path to the backed up game launch script on Linux/macOS after SMAPI is installed. + public string BackupLaunchScriptPath { get; } /********* @@ -63,28 +67,24 @@ namespace StardewModdingAPI.Installer.Framework /// Construct an instance. /// The directory path containing the files to copy into the game folder. /// The directory path for the installed game. - /// The name of the game's executable file for the current platform. - 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"); } - - /// Override the filename for the . - /// the file name. - 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) { @@ -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 *********/ - /// Get whether an executable is 64-bit. - /// The absolute path to the executable file. - private bool Is64Bit(string executablePath) - { - return LowLevelEnvironmentUtility.Is64BitAssembly(executablePath); - } - /// Get the display text for a color scheme. /// The color scheme. 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 @@ StardewModdingAPI.Installer The SMAPI installer for players. - net452 + net5.0 Exe false diff --git a/src/SMAPI.Installer/assets/System.Numerics.dll b/src/SMAPI.Installer/assets/System.Numerics.dll deleted file mode 100644 index fed0f92c..00000000 Binary files a/src/SMAPI.Installer/assets/System.Numerics.dll and /dev/null differ diff --git a/src/SMAPI.Installer/assets/System.Runtime.Caching.dll b/src/SMAPI.Installer/assets/System.Runtime.Caching.dll deleted file mode 100644 index a062391d..00000000 Binary files a/src/SMAPI.Installer/assets/System.Runtime.Caching.dll and /dev/null differ 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 @@  - - netcoreapp2.0 + net5.0 latest - - + + - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + @@ -20,5 +16,4 @@ - 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 @@ - - + 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 @@ StardewModdingAPI.ModBuildConfig - net452 + netstandard2.0 latest true Pathoschild.Stardew.ModBuildConfig Build package for SMAPI mods - 3.3.0 + 3.4.0 Pathoschild - Automates the build configuration for crossplatform Stardew Valley SMAPI mods. For SMAPI 3.0 or later. + Automates the build configuration for crossplatform Stardew Valley SMAPI mods. For SMAPI 3.13.0 or later. MIT images/icon.png https://smapi.io/package/readme false + + + true - - - - - + + 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 @@ **********************************************--> - + - + @@ -68,8 +68,8 @@ - - + + 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 @@ ConsoleCommands StardewModdingAPI.Mods.ConsoleCommands - net452 + net5.0 false @@ -13,7 +13,7 @@ - + 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 @@ ErrorHandler StardewModdingAPI.Mods.ErrorHandler - net452 + net5.0 false @@ -14,7 +14,7 @@ - + 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 @@ SaveBackup StardewModdingAPI.Mods.SaveBackup - net452 + net5.0 false @@ -13,7 +13,7 @@ - + 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 @@ SMAPI.Tests SMAPI.Tests - net452 + net5.0 false latest @@ -16,6 +16,7 @@ + @@ -23,7 +24,7 @@ - $(GamePath)\$(GameExecutableName).exe + $(GamePath)\$(GameExecutableName).dll True 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 @@ StardewModdingAPI Provides toolkit interfaces which are available to SMAPI mods. - net452;netstandard2.0 + net5.0; netstandard2.0 true 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 +{ + /// Contains the SMAPI installer's constants and assumptions. + internal static class Constants + { + /// The name of the game's main DLL, used to detect game folders. + 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; } - /// Get the name of the Stardew Valley executable. - /// The current platform. - public static string GetExecutableName(string platform) - { - return platform == nameof(Platform.Windows) - ? "Stardew Valley.exe" - : "StardewValley.exe"; - } - /// Get whether an executable is 64-bit. /// The absolute path to the assembly file. 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 @@ StardewModdingAPI.Toolkit A library which encapsulates mod-handling logic for mod managers and tools. Not intended for use by mods. - net452;netstandard2.0 + net5.0; netstandard2.0 true @@ -12,8 +12,8 @@ - - + + 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()); } - /// Get the name of the Stardew Valley executable. - /// The current platform. - public static string GetExecutableName(Platform platform) - { - return LowLevelEnvironmentUtility.GetExecutableName(platform.ToString()); - } - /// Get whether an executable is 64-bit. /// The absolute path to the assembly file. 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 /// 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. /// The source folder path. /// The target folder or file path. - /// - /// - /// 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 Path.GetRelativePath if the game ever migrates to .NET Core. - /// - /// [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 } /// Get whether a path is relative and doesn't try to climb out of its containing folder (e.g. doesn't contain ../). 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 /// The custom SMAPI settings. public void LogIntro(string modsPath, IDictionary 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 /// Construct an instance. 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 @@ StardewModdingAPI StardewModdingAPI The modding API for Stardew Valley. - net452 - x86 + net5.0 + x64 Exe true false true icon.ico + + + true @@ -19,15 +22,16 @@ - + + + - + - -- cgit From 217cc7af21a501daabea16dc7331401a19706bf4 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 16 Sep 2021 17:34:31 -0400 Subject: add IgnoreModFilePaths option to package --- docs/technical/mod-package.md | 17 +++++++++++- src/SMAPI.ModBuildConfig/DeployModTask.cs | 32 ++++++++++++++++++++-- .../Framework/ModFileManager.cs | 9 ++++-- src/SMAPI.ModBuildConfig/build/smapi.targets | 1 + 4 files changed, 53 insertions(+), 6 deletions(-) (limited to 'docs/technical') diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md index a3ce8761..0fdd4c4a 100644 --- a/docs/technical/mod-package.md +++ b/docs/technical/mod-package.md @@ -222,6 +222,20 @@ Whether to configure the project so you can launch or debug the game through the Visual Studio (default `true`). There's usually no reason to change this, unless it's a unit test project. + + + +IgnoreModFilePaths + + +A comma-delimited list of literal file paths to ignore, relative to the mod's `bin` folder. Paths +are case-sensitive, but path delimiters are normalized automatically. For example, this ignores a +set of tilesheets: + +```xml +assets/paths.png, assets/springobjects.png +``` + @@ -366,7 +380,8 @@ 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.** +* Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. **Older versions are no longer supported.** +* Added `IgnoreModFilePaths` option to ignore literal paths. * Improved analyzer performance by enabling parallel execution. ## 3.3.0 diff --git a/src/SMAPI.ModBuildConfig/DeployModTask.cs b/src/SMAPI.ModBuildConfig/DeployModTask.cs index 9ee6be12..0c64aed3 100644 --- a/src/SMAPI.ModBuildConfig/DeployModTask.cs +++ b/src/SMAPI.ModBuildConfig/DeployModTask.cs @@ -8,6 +8,7 @@ using System.Text.RegularExpressions; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using StardewModdingAPI.ModBuildConfig.Framework; +using StardewModdingAPI.Toolkit.Utilities; namespace StardewModdingAPI.ModBuildConfig { @@ -45,9 +46,12 @@ namespace StardewModdingAPI.ModBuildConfig [Required] public bool EnableModZip { get; set; } - /// Custom comma-separated regex patterns matching files to ignore when deploying or zipping the mod. + /// A comma-separated list of regex patterns matching files to ignore when deploying or zipping the mod. public string IgnoreModFilePatterns { get; set; } + /// A comma-separated list of relative file paths to ignore when deploying or zipping the mod. + public string IgnoreModFilePaths { get; set; } + /********* ** Public methods @@ -70,10 +74,11 @@ namespace StardewModdingAPI.ModBuildConfig try { // parse ignore patterns + string[] ignoreFilePaths = this.GetCustomIgnoreFilePaths().ToArray(); Regex[] ignoreFilePatterns = this.GetCustomIgnorePatterns().ToArray(); // get mod info - ModFileManager package = new ModFileManager(this.ProjectDir, this.TargetDir, ignoreFilePatterns, validateRequiredModFiles: this.EnableModDeploy || this.EnableModZip); + ModFileManager package = new ModFileManager(this.ProjectDir, this.TargetDir, ignoreFilePaths, ignoreFilePatterns, validateRequiredModFiles: this.EnableModDeploy || this.EnableModZip); // deploy mod files if (this.EnableModDeploy) @@ -157,6 +162,29 @@ namespace StardewModdingAPI.ModBuildConfig } } + /// Get the custom relative file paths provided by the user to ignore. + private IEnumerable GetCustomIgnoreFilePaths() + { + if (string.IsNullOrWhiteSpace(this.IgnoreModFilePaths)) + yield break; + + foreach (string raw in this.IgnoreModFilePaths.Split(',')) + { + string path; + try + { + path = PathUtilities.NormalizePath(raw); + } + catch (Exception ex) + { + this.Log.LogWarning($"[mod build package] Ignored invalid <{nameof(this.IgnoreModFilePaths)}> path {raw}:\n{ex}"); + continue; + } + + yield return path; + } + } + /// Copy the mod files into the game's mod folder. /// The files to include. /// The folder path to create with the mod files. diff --git a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs index 3d9b206b..fbb91193 100644 --- a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs +++ b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs @@ -28,10 +28,11 @@ namespace StardewModdingAPI.ModBuildConfig.Framework /// Construct an instance. /// The folder containing the project files. /// The folder containing the build output. + /// The custom relative file paths provided by the user to ignore. /// Custom regex patterns matching files to ignore when deploying or zipping the mod. /// Whether to validate that required mod files like the manifest are present. /// The mod package isn't valid. - public ModFileManager(string projectDir, string targetDir, Regex[] ignoreFilePatterns, bool validateRequiredModFiles) + public ModFileManager(string projectDir, string targetDir, string[] ignoreFilePaths, Regex[] ignoreFilePatterns, bool validateRequiredModFiles) { this.Files = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -47,7 +48,7 @@ namespace StardewModdingAPI.ModBuildConfig.Framework string relativePath = entry.Item1; FileInfo file = entry.Item2; - if (!this.ShouldIgnore(file, relativePath, ignoreFilePatterns)) + if (!this.ShouldIgnore(file, relativePath, ignoreFilePaths, ignoreFilePatterns)) this.Files[relativePath] = file; } @@ -149,8 +150,9 @@ namespace StardewModdingAPI.ModBuildConfig.Framework /// Get whether a build output file should be ignored. /// The file to check. /// The file's relative path in the package. + /// The custom relative file paths provided by the user to ignore. /// Custom regex patterns matching files to ignore when deploying or zipping the mod. - private bool ShouldIgnore(FileInfo file, string relativePath, Regex[] ignoreFilePatterns) + private bool ShouldIgnore(FileInfo file, string relativePath, string[] ignoreFilePaths, Regex[] ignoreFilePatterns) { bool IsAssemblyFile(string baseName) { @@ -181,6 +183,7 @@ namespace StardewModdingAPI.ModBuildConfig.Framework || this.EqualsInvariant(file.Name, "Thumbs.db") // custom ignore patterns + || ignoreFilePaths.Any(p => p == relativePath) || ignoreFilePatterns.Any(p => p.IsMatch(relativePath)); } diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index 74ac56e6..b254dd7c 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -94,6 +94,7 @@ TargetDir="$(TargetDir)" GameModsDir="$(GameModsPath)" IgnoreModFilePatterns="$(IgnoreModFilePatterns)" + IgnoreModFilePaths="$(IgnoreModFilePaths)" /> -- cgit From 4a26c96fbe600a4a229a1e63abb716a62dc7f450 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 16 Sep 2021 18:48:59 -0400 Subject: remove GameExecutableName build property from package --- build/find-game-folder.targets | 5 ----- docs/technical/mod-package.md | 24 +++++++++++----------- src/SMAPI.ModBuildConfig/build/smapi.targets | 4 ++-- .../SMAPI.Mods.ConsoleCommands.csproj | 2 +- .../SMAPI.Mods.ErrorHandler.csproj | 2 +- .../SMAPI.Mods.SaveBackup.csproj | 2 +- src/SMAPI.Tests/SMAPI.Tests.csproj | 5 +---- src/SMAPI/SMAPI.csproj | 2 +- 8 files changed, 19 insertions(+), 27 deletions(-) (limited to 'docs/technical') diff --git a/build/find-game-folder.targets b/build/find-game-folder.targets index 3341226d..3164b071 100644 --- a/build/find-game-folder.targets +++ b/build/find-game-folder.targets @@ -41,9 +41,4 @@ - - - - Stardew Valley - diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md index 0fdd4c4a..5eff3d2e 100644 --- a/docs/technical/mod-package.md +++ b/docs/technical/mod-package.md @@ -29,7 +29,7 @@ change how these work): * **Detect game path:** The package automatically finds your game folder by scanning the default install paths and Windows registry. It adds two MSBuild properties for use in your `.csproj` file if needed: - `$(GamePath)` and `$(GameExecutableName)`. + `$(GamePath)` and `$(GameModsPath)`. * **Add assembly references:** The package adds assembly references to SMAPI, Stardew Valley, xTile, and the game framework @@ -126,15 +126,6 @@ change it. The absolute path to the folder containing the game's installed mods (defaults to `$(GamePath)/Mods`), used when deploying the mod files. - - - -GameExecutableName - - -The filename for the game's executable (i.e. `StardewValley.exe` on Linux/macOS or -`Stardew Valley.exe` on Windows). This is auto-detected, and you should almost never change this. - @@ -382,13 +373,21 @@ when you compile it. ## Upcoming release * Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. **Older versions are no longer supported.** * Added `IgnoreModFilePaths` option to ignore literal paths. +* Removed the `GameExecutableName` build property (since it now has the same value on all platforms). * Improved analyzer performance by enabling parallel execution. +**Migration guide for mod authors:** +1. See [_migrate to 64-bit_](https://stardewvalleywiki.com/Modding:Migrate_to_64-bit_on_Windows) and + [_migrate to Stardew Valley 1.5.5_](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5). +2. Possible changes in your `.csproj` or `.targets` files: + * If you use `$(GameExecutableName)`, replace it with `Stardew Valley`. + ## 3.3.0 Released 30 March 2021. * Added a build warning when the mod isn't compiled for `Any CPU`. -* Added a `GameFramework` build property set to `MonoGame` or `Xna` based on the platform. This can be overridden to change which framework it references. +* Added a `GameFramework` build property set to `MonoGame` or `Xna` based on the platform. This can + be overridden to change which framework it references. * Added support for building mods against the 64-bit Linux version of the game on Windows. * The package now suppresses the misleading 'processor architecture mismatch' warnings. @@ -396,7 +395,8 @@ Released 30 March 2021. Released 23 September 2020. * Reworked and streamlined how the package is compiled. -* Added [SMAPI-ModTranslationClassBuilder](https://github.com/Pathoschild/SMAPI-ModTranslationClassBuilder) files to the ignore list. +* Added [SMAPI-ModTranslationClassBuilder](https://github.com/Pathoschild/SMAPI-ModTranslationClassBuilder) + files to the ignore list. ### 3.2.1 Released 11 September 2020. diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index b254dd7c..6fc62046 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -48,7 +48,7 @@ **********************************************--> - + @@ -71,7 +71,7 @@ - + diff --git a/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj b/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj index 65d54599..52439c41 100644 --- a/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj +++ b/src/SMAPI.Mods.ConsoleCommands/SMAPI.Mods.ConsoleCommands.csproj @@ -13,8 +13,8 @@ - + diff --git a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj index 2ad19df7..78cdb315 100644 --- a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj +++ b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj @@ -14,8 +14,8 @@ - + diff --git a/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj b/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj index f8908c7d..a8b0dfdb 100644 --- a/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj +++ b/src/SMAPI.Mods.SaveBackup/SMAPI.Mods.SaveBackup.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/SMAPI.Tests/SMAPI.Tests.csproj b/src/SMAPI.Tests/SMAPI.Tests.csproj index e19105ff..8329b2e1 100644 --- a/src/SMAPI.Tests/SMAPI.Tests.csproj +++ b/src/SMAPI.Tests/SMAPI.Tests.csproj @@ -23,10 +23,7 @@ - - $(GamePath)\$(GameExecutableName).dll - True - + diff --git a/src/SMAPI/SMAPI.csproj b/src/SMAPI/SMAPI.csproj index 16ddb92a..4f9aa9b1 100644 --- a/src/SMAPI/SMAPI.csproj +++ b/src/SMAPI/SMAPI.csproj @@ -29,7 +29,7 @@ - + -- cgit From bf10aeef0afae20e1d79f0772ba41a38fcb572ae Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 16 Sep 2021 18:59:25 -0400 Subject: remove GameFramework build property from package --- docs/technical/mod-package.md | 20 +++++++------------- src/SMAPI.ModBuildConfig/build/smapi.targets | 3 --- src/SMAPI/Constants.cs | 3 +-- src/SMAPI/Framework/ModLoading/AssemblyLoader.cs | 5 ++--- src/SMAPI/Framework/SCore.cs | 2 +- 5 files changed, 11 insertions(+), 22 deletions(-) (limited to 'docs/technical') diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md index 5eff3d2e..2e26275b 100644 --- a/docs/technical/mod-package.md +++ b/docs/technical/mod-package.md @@ -32,10 +32,10 @@ change how these work): `$(GamePath)` and `$(GameModsPath)`. * **Add assembly references:** - The package adds assembly references to SMAPI, Stardew Valley, xTile, and the game framework - (MonoGame on Linux/macOS, XNA Framework on Windows). It automatically adjusts depending on which OS - you're compiling it on. If you use [Harmony](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Harmony), - it can optionally add a reference to that too. + The package adds assembly references to MonoGame, SMAPI, Stardew Valley, and xTile. It + automatically adjusts depending on which OS you're compiling it on. If you use + [Harmony](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Harmony), it can optionally add + a reference to that too. * **Copy files into the `Mods` folder:** The package automatically copies your mod's DLL and PDB files, `manifest.json`, [`i18n` @@ -129,14 +129,6 @@ The absolute path to the folder containing the game's installed mods (defaults t -GameFramework - - -The game framework for which the mod is being compiled (one of `Xna` or `MonoGame`). This is -auto-detected based on the platform, and you should almost never change this. - - - @@ -373,7 +365,8 @@ when you compile it. ## Upcoming release * Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. **Older versions are no longer supported.** * Added `IgnoreModFilePaths` option to ignore literal paths. -* Removed the `GameExecutableName` build property (since it now has the same value on all platforms). +* Removed the `GameExecutableName` and `GameFramework` build properties (since they now have the + same value on all platforms). * Improved analyzer performance by enabling parallel execution. **Migration guide for mod authors:** @@ -381,6 +374,7 @@ when you compile it. [_migrate to Stardew Valley 1.5.5_](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5). 2. Possible changes in your `.csproj` or `.targets` files: * If you use `$(GameExecutableName)`, replace it with `Stardew Valley`. + * If you use `$(GameFramework)`, replace it with `MonoGame` and remove any XNA-specific logic. ## 3.3.0 Released 30 March 2021. diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index 6fc62046..8ad298d0 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -30,9 +30,6 @@ false true false - - Xna - MonoGame diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 2c16052b..3ae8661a 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -241,8 +241,7 @@ namespace StardewModdingAPI /// Get metadata for mapping assemblies to the current platform. /// The target game platform. - /// The game framework running the game. - internal static PlatformAssemblyMap GetAssemblyMap(Platform targetPlatform, GameFramework framework) + internal static PlatformAssemblyMap GetAssemblyMap(Platform targetPlatform) { var removeAssemblyReferences = new List(); var targetAssemblies = new List(); diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index 57a76a35..cb5fa2ae 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -53,16 +53,15 @@ namespace StardewModdingAPI.Framework.ModLoading *********/ /// Construct an instance. /// The current game platform. - /// The game framework running the game. /// Encapsulates monitoring and logging. /// Whether to detect paranoid mode issues. /// Whether to rewrite mods for compatibility. - public AssemblyLoader(Platform targetPlatform, GameFramework framework, IMonitor monitor, bool paranoidMode, bool rewriteMods) + public AssemblyLoader(Platform targetPlatform, IMonitor monitor, bool paranoidMode, bool rewriteMods) { this.Monitor = monitor; this.ParanoidMode = paranoidMode; this.RewriteMods = rewriteMods; - this.AssemblyMap = this.TrackForDisposal(Constants.GetAssemblyMap(targetPlatform, framework)); + this.AssemblyMap = this.TrackForDisposal(Constants.GetAssemblyMap(targetPlatform)); // init resolver this.AssemblyDefinitionResolver = this.TrackForDisposal(new AssemblyDefinitionResolver()); diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index a0467daa..55a7f083 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -1473,7 +1473,7 @@ namespace StardewModdingAPI.Framework // load mods IList skippedMods = new List(); - using (AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.Platform, Constants.GameFramework, this.Monitor, this.Settings.ParanoidWarnings, this.Settings.RewriteMods)) + using (AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.Platform, this.Monitor, this.Settings.ParanoidWarnings, this.Settings.RewriteMods)) { // init HashSet suppressUpdateChecks = new HashSet(this.Settings.SuppressUpdateChecks, StringComparer.OrdinalIgnoreCase); -- cgit From f5807e22be157d908e3b8c65f19acaa16c3588e7 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 16 Sep 2021 22:47:05 -0400 Subject: add BundleExtraAssemblies package option for new .NET 5 reference model --- docs/technical/mod-package.md | 100 +++++++++++++---- src/SMAPI.ModBuildConfig/DeployModTask.cs | 34 +++++- .../Framework/ExtraAssemblyType.cs | 21 ++++ .../Framework/ModFileManager.cs | 124 ++++++++++++++++----- src/SMAPI.ModBuildConfig/build/smapi.targets | 22 ++-- 5 files changed, 244 insertions(+), 57 deletions(-) create mode 100644 src/SMAPI.ModBuildConfig/Framework/ExtraAssemblyType.cs (limited to 'docs/technical') diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md index 2e26275b..93e0009d 100644 --- a/docs/technical/mod-package.md +++ b/docs/technical/mod-package.md @@ -39,10 +39,9 @@ change how these work): * **Copy files into the `Mods` folder:** The package automatically copies your mod's DLL and PDB files, `manifest.json`, [`i18n` - files](https://stardewvalleywiki.com/Modding:Translations) (if any), the `assets` folder (if - any), and [build output](https://stackoverflow.com/a/10828462/262123) into your game's `Mods` - folder when you rebuild the code, with a subfolder matching the mod's project name. That lets you - try the mod in-game right after building it. + files](https://stardewvalleywiki.com/Modding:Translations) (if any), and the `assets` folder (if + any) into the `Mods` folder when you rebuild the code, with a subfolder matching the mod's project + name. That lets you try the mod in-game right after building it. * **Create release zip:** The package adds a zip file in your project's `bin` folder when you rebuild the code, in the @@ -189,11 +188,63 @@ The folder path where the release zip is created (defaults to the project's `bin effect -CopyModReferencesToBuildOutput +BundleExtraAssemblies -Whether to copy game and framework DLLs into the mod folder (default `false`). This is useful for -unit test projects, but not needed for mods that'll be run through SMAPI. +**Most mods should not change this option.** + +By default (when this is _not_ enabled), only the mod files [normally considered part of the +mod](#Features) will be added to the release `.zip` and copied into the `Mods` folder (i.e. +"deployed"). That includes the assembly files (`*.dll`, `*.pdb`, and `*.xml`) for your mod project, +but any other DLLs won't be deployed. + +Enabling this option will add _all_ dependencies to the build output, then deploy _some_ of them +depending on the comma-separated value(s) you set: + + + + + + + + + + + + + + + + + + + + + + +
optionresult
ThirdParty + +Assembly files which don't match any other category. + +
System + +Assembly files whose names start with `Microsoft.*` or `System.*`. + +
Game + +Assembly files which are part of MonoGame, SMAPI, or Stardew Valley. + +
All + +Equivalent to `System, Game, ThirdParty`. + +
+ +Most mods should omit the option. Some mods may need `ThirdParty` if they bundle third-party DLLs +with their mod. The other options are mainly useful for unit tests. + +When enabling this option, you should **manually review which files get deployed** and use the +`IgnoreModFilePaths` or `IgnoreModFilePatterns` options to exclude files as needed. @@ -327,16 +378,15 @@ The configuration will check your custom path first, then fall back to the defau still compile on a different computer). ### How do I change which files are included in the mod deploy/zip? -For custom files, you can [add/remove them in the build output](https://stackoverflow.com/a/10828462/262123). -(If your project references another mod, make sure the reference is [_not_ marked 'copy -local'](https://msdn.microsoft.com/en-us/library/t1zz5y8c(v=vs.100).aspx).) - -To exclude a file the package copies by default, see `IgnoreModFilePatterns` under -[_configure_](#configure). +* For normal files, you can [add/remove them in the build output](https://stackoverflow.com/a/10828462/262123). +* For assembly files (`*.dll`, `*.exe`, `*.pdb`, or `*.xml`), see the + [`BundleExtraAssemblies` option](#configure). +* To exclude a file which the package copies by default, see the [`IgnoreModFilePaths` or + `IgnoreModFilePatterns` options](#configure). ### Can I use the package for non-mod projects? -You can use the package in non-mod projects too (e.g. unit tests or framework DLLs). Just disable -the mod-related package features (see [_configure_](#configure)): +Yep, this works in unit tests and framework projects too. Just disable the mod-related package +features (see [_configure_](#configure)): ```xml false @@ -344,9 +394,9 @@ the mod-related package features (see [_configure_](#configure)): false ``` -If you need to copy the referenced DLLs into your build output, add this too: +To copy referenced DLLs into your build output for unit tests, add this too: ```xml -true +All ``` ## For SMAPI developers @@ -363,18 +413,24 @@ when you compile it. ## Release notes ## Upcoming release -* Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. **Older versions are no longer supported.** +* Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. (Older versions are no longer supported.) * Added `IgnoreModFilePaths` option to ignore literal paths. -* Removed the `GameExecutableName` and `GameFramework` build properties (since they now have the - same value on all platforms). +* Added `BundleExtraAssemblies` option to copy bundled DLLs into the mod zip/folder. +* Removed the `GameExecutableName` and `GameFramework` options (since they now have the same value + on all platforms). +* Removed the `CopyModReferencesToBuildOutput` option (superseded by `BundleExtraAssemblies`). * Improved analyzer performance by enabling parallel execution. **Migration guide for mod authors:** 1. See [_migrate to 64-bit_](https://stardewvalleywiki.com/Modding:Migrate_to_64-bit_on_Windows) and [_migrate to Stardew Valley 1.5.5_](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5). 2. Possible changes in your `.csproj` or `.targets` files: - * If you use `$(GameExecutableName)`, replace it with `Stardew Valley`. - * If you use `$(GameFramework)`, replace it with `MonoGame` and remove any XNA-specific logic. + * Replace `$(GameExecutableName)` with `Stardew Valley`. + * Replace `$(GameFramework)` with `MonoGame` and remove any XNA Framework-specific logic. + * Replace `true` with + `Game`. + * If you need to bundle extra DLLs besides your mod DLL, see the [`BundleExtraAssemblies` + documentation](#configure). ## 3.3.0 Released 30 March 2021. diff --git a/src/SMAPI.ModBuildConfig/DeployModTask.cs b/src/SMAPI.ModBuildConfig/DeployModTask.cs index 0c64aed3..140933bd 100644 --- a/src/SMAPI.ModBuildConfig/DeployModTask.cs +++ b/src/SMAPI.ModBuildConfig/DeployModTask.cs @@ -18,6 +18,10 @@ namespace StardewModdingAPI.ModBuildConfig /********* ** Accessors *********/ + /// The name (without extension or path) of the current mod's DLL. + [Required] + public string ModDllName { get; set; } + /// The name of the mod folder. [Required] public string ModFolderName { get; set; } @@ -52,6 +56,9 @@ namespace StardewModdingAPI.ModBuildConfig /// A comma-separated list of relative file paths to ignore when deploying or zipping the mod. public string IgnoreModFilePaths { get; set; } + /// A comma-separated list of values which indicate which extra DLLs to bundle. + public string BundleExtraAssemblies { get; set; } + /********* ** Public methods @@ -73,12 +80,15 @@ namespace StardewModdingAPI.ModBuildConfig try { + // parse extra DLLs to bundle + ExtraAssemblyTypes bundleAssemblyTypes = this.GetExtraAssembliesToBundleOption(); + // parse ignore patterns string[] ignoreFilePaths = this.GetCustomIgnoreFilePaths().ToArray(); Regex[] ignoreFilePatterns = this.GetCustomIgnorePatterns().ToArray(); // get mod info - ModFileManager package = new ModFileManager(this.ProjectDir, this.TargetDir, ignoreFilePaths, ignoreFilePatterns, validateRequiredModFiles: this.EnableModDeploy || this.EnableModZip); + ModFileManager package = new ModFileManager(this.ProjectDir, this.TargetDir, ignoreFilePaths, ignoreFilePatterns, bundleAssemblyTypes, this.ModDllName, validateRequiredModFiles: this.EnableModDeploy || this.EnableModZip); // deploy mod files if (this.EnableModDeploy) @@ -139,6 +149,28 @@ namespace StardewModdingAPI.ModBuildConfig } } + /// Parse the extra assembly types which should be bundled with the mod. + private ExtraAssemblyTypes GetExtraAssembliesToBundleOption() + { + ExtraAssemblyTypes flags = ExtraAssemblyTypes.None; + + if (!string.IsNullOrWhiteSpace(this.BundleExtraAssemblies)) + { + foreach (string raw in this.BundleExtraAssemblies.Split(',')) + { + if (!Enum.TryParse(raw, out ExtraAssemblyTypes type)) + { + this.Log.LogWarning($"[mod build package] Ignored invalid <{nameof(this.BundleExtraAssemblies)}> value '{raw}', expected one of '{string.Join("', '", Enum.GetNames(typeof(ExtraAssemblyTypes)))}'."); + continue; + } + + flags |= type; + } + } + + return flags; + } + /// Get the custom ignore patterns provided by the user. private IEnumerable GetCustomIgnorePatterns() { diff --git a/src/SMAPI.ModBuildConfig/Framework/ExtraAssemblyType.cs b/src/SMAPI.ModBuildConfig/Framework/ExtraAssemblyType.cs new file mode 100644 index 00000000..571bf7c7 --- /dev/null +++ b/src/SMAPI.ModBuildConfig/Framework/ExtraAssemblyType.cs @@ -0,0 +1,21 @@ +using System; + +namespace StardewModdingAPI.ModBuildConfig.Framework +{ + /// An extra assembly type for the field. + [Flags] + internal enum ExtraAssemblyTypes + { + /// Don't include extra assemblies. + None = 0, + + /// Assembly files which are part of MonoGame, SMAPI, or Stardew Valley. + Game = 1, + + /// Assembly files whose names start with Microsoft.* or System.*. + System = 2, + + /// Assembly files which don't match any other category. + ThirdParty = 4 + } +} diff --git a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs index fbb91193..ad4ffdf9 100644 --- a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs +++ b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs @@ -21,6 +21,45 @@ namespace StardewModdingAPI.ModBuildConfig.Framework /// The files that are part of the package. private readonly IDictionary Files; + /// The file extensions used by assembly files. + private readonly ISet AssemblyFileExtensions = new HashSet(StringComparer.OrdinalIgnoreCase) + { + ".dll", + ".exe", + ".pdb", + ".xml" + }; + + /// The DLLs which match the type. + private readonly ISet GameDllNames = new HashSet + { + // SMAPI + "0Harmony", + "Mono.Cecil", + "Mono.Cecil.Mdb", + "Mono.Cecil.Pdb", + "MonoMod.Common", + "Newtonsoft.Json", + "StardewModdingAPI", + "SMAPI.Toolkit", + "SMAPI.Toolkit.CoreInterfaces", + "TMXTile", + + // game + framework + "BmFont", + "FAudio-CS", + "GalaxyCSharp", + "GalaxyCSharpGlue", + "Lidgren.Network", + "MonoGame.Framework", + "SkiaSharp", + "Stardew Valley", + "StardewValley.GameData", + "Steamworks.NET", + "TextCopy", + "xTile" + }; + /********* ** Public methods @@ -30,9 +69,11 @@ namespace StardewModdingAPI.ModBuildConfig.Framework /// The folder containing the build output. /// The custom relative file paths provided by the user to ignore. /// Custom regex patterns matching files to ignore when deploying or zipping the mod. + /// The extra assembly types which should be bundled with the mod. + /// The name (without extension or path) for the current mod's DLL. /// Whether to validate that required mod files like the manifest are present. /// The mod package isn't valid. - public ModFileManager(string projectDir, string targetDir, string[] ignoreFilePaths, Regex[] ignoreFilePatterns, bool validateRequiredModFiles) + public ModFileManager(string projectDir, string targetDir, string[] ignoreFilePaths, Regex[] ignoreFilePatterns, ExtraAssemblyTypes bundleAssemblyTypes, string modDllName, bool validateRequiredModFiles) { this.Files = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -48,7 +89,7 @@ namespace StardewModdingAPI.ModBuildConfig.Framework string relativePath = entry.Item1; FileInfo file = entry.Item2; - if (!this.ShouldIgnore(file, relativePath, ignoreFilePaths, ignoreFilePatterns)) + if (!this.ShouldIgnore(file, relativePath, ignoreFilePaths, ignoreFilePatterns, bundleAssemblyTypes, modDllName)) this.Files[relativePath] = file; } @@ -152,39 +193,70 @@ namespace StardewModdingAPI.ModBuildConfig.Framework /// The file's relative path in the package. /// The custom relative file paths provided by the user to ignore. /// Custom regex patterns matching files to ignore when deploying or zipping the mod. - private bool ShouldIgnore(FileInfo file, string relativePath, string[] ignoreFilePaths, Regex[] ignoreFilePatterns) + /// The extra assembly types which should be bundled with the mod. + /// The name (without extension or path) for the current mod's DLL. + private bool ShouldIgnore(FileInfo file, string relativePath, string[] ignoreFilePaths, Regex[] ignoreFilePatterns, ExtraAssemblyTypes bundleAssemblyTypes, string modDllName) { - bool IsAssemblyFile(string baseName) + // apply custom patterns + if (ignoreFilePaths.Any(p => p == relativePath) || ignoreFilePatterns.Any(p => p.IsMatch(relativePath))) + return true; + + // ignore unneeded files + { + bool shouldIgnore = + // release zips + this.EqualsInvariant(file.Extension, ".zip") + + // *.deps.json (only SMAPI's top-level one is used) + || file.Name.EndsWith(".deps.json") + + // code analysis files + || file.Name.EndsWith(".CodeAnalysisLog.xml", StringComparison.OrdinalIgnoreCase) + || file.Name.EndsWith(".lastcodeanalysissucceeded", StringComparison.OrdinalIgnoreCase) + + // translation class builder (not used at runtime) + || ( + file.Name.StartsWith("Pathoschild.Stardew.ModTranslationClassBuilder") + && this.AssemblyFileExtensions.Contains(file.Extension) + ) + + // OS metadata files + || this.EqualsInvariant(file.Name, ".DS_Store") + || this.EqualsInvariant(file.Name, "Thumbs.db"); + if (shouldIgnore) + return true; + } + + // check for bundled assembly types + // When bundleAssemblyTypes is set, *all* dependencies are copied into the build output but only those which match the given assembly types should be bundled. + if (bundleAssemblyTypes != ExtraAssemblyTypes.None) { - return - this.EqualsInvariant(file.Name, $"{baseName}.dll") - || this.EqualsInvariant(file.Name, $"{baseName}.pdb") - || this.EqualsInvariant(file.Name, $"{baseName}.xnb"); + var type = this.GetExtraAssemblyType(file, modDllName); + if (type != ExtraAssemblyTypes.None && !bundleAssemblyTypes.HasFlag(type)) + return true; } - return - // release zips - this.EqualsInvariant(file.Extension, ".zip") + return false; + } - // unneeded *.deps.json (only SMAPI's top-level one is used) - || file.Name.EndsWith(".deps.json") + /// Get the extra assembly type for a file, assuming that the user specified one or more extra types to bundle. + /// The file to check. + /// The name (without extension or path) for the current mod's DLL. + private ExtraAssemblyTypes GetExtraAssemblyType(FileInfo file, string modDllName) + { + string baseName = Path.GetFileNameWithoutExtension(file.Name); + string extension = file.Extension; - // dependencies bundled with SMAPI - || IsAssemblyFile("0Harmony") - || IsAssemblyFile("Newtonsoft.Json") - || IsAssemblyFile("Pathoschild.Stardew.ModTranslationClassBuilder") // not used at runtime + if (baseName == modDllName || !this.AssemblyFileExtensions.Contains(extension)) + return ExtraAssemblyTypes.None; - // code analysis files - || file.Name.EndsWith(".CodeAnalysisLog.xml", StringComparison.OrdinalIgnoreCase) - || file.Name.EndsWith(".lastcodeanalysissucceeded", StringComparison.OrdinalIgnoreCase) + if (this.GameDllNames.Contains(baseName)) + return ExtraAssemblyTypes.Game; - // OS metadata files - || this.EqualsInvariant(file.Name, ".DS_Store") - || this.EqualsInvariant(file.Name, "Thumbs.db") + if (baseName.StartsWith("System.", StringComparison.OrdinalIgnoreCase) || baseName.StartsWith("Microsoft.", StringComparison.OrdinalIgnoreCase)) + return ExtraAssemblyTypes.System; - // custom ignore patterns - || ignoreFilePaths.Any(p => p == relativePath) - || ignoreFilePatterns.Any(p => p.IsMatch(relativePath)); + return ExtraAssemblyTypes.ThirdParty; } /// Get whether a string is equal to another case-insensitively. diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index 8ad298d0..de00cbe8 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -29,7 +29,10 @@ true false true - false + + + + true
@@ -45,17 +48,17 @@ **********************************************--> - - - - + + + + - - + + - + @@ -81,6 +84,7 @@ **********************************************--> -- cgit