diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-08-19 18:28:16 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-08-19 18:28:16 -0400 |
commit | 826dd53ab550e5b92796c510569118beee6bd044 (patch) | |
tree | d6d8ec7f380112e8ed047a932ae02548dc9b8a2b | |
parent | 417c04076634ea87d7b3030a1acf46825da6e3e6 (diff) | |
download | SMAPI-826dd53ab550e5b92796c510569118beee6bd044.tar.gz SMAPI-826dd53ab550e5b92796c510569118beee6bd044.tar.bz2 SMAPI-826dd53ab550e5b92796c510569118beee6bd044.zip |
move most SMAPI files into subfolder (#582)
-rw-r--r-- | build/common.targets | 22 | ||||
-rw-r--r-- | build/prepare-install-package.targets | 57 | ||||
-rw-r--r-- | docs/release-notes.md | 3 | ||||
-rw-r--r-- | docs/technical-docs.md | 36 | ||||
-rw-r--r-- | src/SMAPI.Installer/InteractiveInstaller.cs | 115 | ||||
-rw-r--r-- | src/SMAPI.ModBuildConfig/build/smapi.targets | 2 | ||||
-rw-r--r-- | src/SMAPI.ModBuildConfig/package.nuspec | 5 | ||||
-rw-r--r-- | src/SMAPI/Constants.cs | 7 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModLoading/AssemblyLoader.cs | 1 | ||||
-rw-r--r-- | src/SMAPI/Program.cs | 85 |
10 files changed, 197 insertions, 136 deletions
diff --git a/build/common.targets b/build/common.targets index 5b6511f8..90c477b6 100644 --- a/build/common.targets +++ b/build/common.targets @@ -99,14 +99,14 @@ </Target> <Target Name="CopySMAPI" Condition="'$(MSBuildProjectName)' == 'StardewModdingAPI'"> <Copy SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFolder="$(GamePath)" /> - <Copy SourceFiles="$(TargetDir)\$(TargetName).config.json" DestinationFolder="$(GamePath)" /> - <Copy SourceFiles="$(TargetDir)\$(TargetName).metadata.json" DestinationFolder="$(GamePath)" /> <Copy SourceFiles="$(TargetDir)\$(TargetName).pdb" DestinationFolder="$(GamePath)" /> <Copy SourceFiles="$(TargetDir)\$(TargetName).xml" DestinationFolder="$(GamePath)" /> - <Copy SourceFiles="$(TargetDir)\0Harmony.dll" DestinationFolder="$(GamePath)" /> - <Copy SourceFiles="$(TargetDir)\0Harmony.pdb" DestinationFolder="$(GamePath)" /> - <Copy SourceFiles="$(TargetDir)\Newtonsoft.Json.dll" DestinationFolder="$(GamePath)" /> - <Copy SourceFiles="$(TargetDir)\Mono.Cecil.dll" DestinationFolder="$(GamePath)" /> + <Copy SourceFiles="$(TargetDir)\$(TargetName).config.json" DestinationFolder="$(GamePath)\smapi-internal" /> + <Copy SourceFiles="$(TargetDir)\$(TargetName).metadata.json" DestinationFolder="$(GamePath)\smapi-internal" /> + <Copy SourceFiles="$(TargetDir)\0Harmony.dll" DestinationFolder="$(GamePath)\smapi-internal" /> + <Copy SourceFiles="$(TargetDir)\0Harmony.pdb" DestinationFolder="$(GamePath)\smapi-internal" /> + <Copy SourceFiles="$(TargetDir)\Newtonsoft.Json.dll" DestinationFolder="$(GamePath)\smapi-internal" /> + <Copy SourceFiles="$(TargetDir)\Mono.Cecil.dll" DestinationFolder="$(GamePath)\smapi-internal" /> </Target> <Target Name="CopyDefaultMods" Condition="'$(MSBuildProjectName)' == 'StardewModdingAPI.Mods.ConsoleCommands' OR '$(MSBuildProjectName)' == 'StardewModdingAPI.Mods.SaveBackup'"> <Copy SourceFiles="$(TargetDir)\$(TargetName).dll" DestinationFolder="$(GamePath)\Mods\$(AssemblyName)" /> @@ -114,12 +114,14 @@ <Copy SourceFiles="$(TargetDir)\manifest.json" DestinationFolder="$(GamePath)\Mods\$(AssemblyName)" /> </Target> <Target Name="CopyToolkit" Condition="'$(MSBuildProjectName)' == 'StardewModdingAPI.Toolkit' AND '$(Configuration)' == 'Debug' AND $(TargetFramework) == 'net4.5'" AfterTargets="PostBuildEvent"> - <Copy SourceFiles="$(TargetDir)\$(TargetName).dll" DestinationFolder="$(GamePath)" /> - <Copy SourceFiles="$(TargetDir)\$(TargetName).pdb" DestinationFolder="$(GamePath)" /> + <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)' == 'StardewModdingAPI.Toolkit.CoreInterfaces' AND '$(Configuration)' == 'Debug' AND $(TargetFramework) == 'net4.5'" AfterTargets="PostBuildEvent"> - <Copy SourceFiles="$(TargetDir)\$(TargetName).dll" DestinationFolder="$(GamePath)" /> - <Copy SourceFiles="$(TargetDir)\$(TargetName).pdb" DestinationFolder="$(GamePath)" /> + <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> <!-- launch SMAPI on debug --> diff --git a/build/prepare-install-package.targets b/build/prepare-install-package.targets index 79185896..35ff78a5 100644 --- a/build/prepare-install-package.targets +++ b/build/prepare-install-package.targets @@ -23,47 +23,50 @@ <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFiles="$(PackagePath)\install on Windows.exe" /> <Copy SourceFiles="$(TargetDir)\readme.txt" DestinationFiles="$(PackagePath)\README.txt" /> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(TargetDir)\unix-launcher.sh" DestinationFiles="$(PackageInternalPath)\Mono\StardewModdingAPI" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(TargetDir)\unix-install.sh" DestinationFiles="$(PackagePath)\install.sh" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(TargetDir)\unix-install.sh" DestinationFiles="$(PackagePath)\install on Linux.sh" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(TargetDir)\unix-install.sh" DestinationFiles="$(PackagePath)\install on Mac.command" /> <!-- copy SMAPI files for Mono --> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFiles="$(PackageInternalPath)\Mono\install.exe" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\0Harmony.dll" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\0Harmony.pdb" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\Mono.Cecil.dll" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\Newtonsoft.Json.dll" DestinationFolder="$(PackageInternalPath)\Mono" /> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.exe" DestinationFolder="$(PackageInternalPath)\Mono" /> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.pdb" DestinationFolder="$(PackageInternalPath)\Mono" /> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.xml" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.config.json" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.metadata.json" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Numerics.dll" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Runtime.Caching.dll" DestinationFolder="$(PackageInternalPath)\Mono" /> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\steam_appid.txt" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.dll" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.pdb" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.xml" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.dll" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.pdb" DestinationFolder="$(PackageInternalPath)\Mono" /> - <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.xml" DestinationFolder="$(PackageInternalPath)\Mono" /> <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="@(CompiledMods)" DestinationFolder="$(PackageInternalPath)\Mono\Mods\%(RecursiveDir)" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\0Harmony.dll" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\0Harmony.pdb" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\Mono.Cecil.dll" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\Newtonsoft.Json.dll" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.config.json" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.metadata.json" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Numerics.dll" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Runtime.Caching.dll" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.dll" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.pdb" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.xml" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.dll" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.pdb" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.xml" DestinationFolder="$(PackageInternalPath)\Mono\smapi-internal" /> + <!-- copy SMAPI files for Windows --> - <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\Mono.Cecil.dll" DestinationFolder="$(PackageInternalPath)\Windows" /> - <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\0Harmony.dll" DestinationFolder="$(PackageInternalPath)\Windows" /> - <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\0Harmony.pdb" DestinationFolder="$(PackageInternalPath)\Windows" /> - <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\Newtonsoft.Json.dll" DestinationFolder="$(PackageInternalPath)\Windows" /> <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.exe" DestinationFolder="$(PackageInternalPath)\Windows" /> <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.pdb" DestinationFolder="$(PackageInternalPath)\Windows" /> <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.xml" DestinationFolder="$(PackageInternalPath)\Windows" /> - <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.config.json" DestinationFolder="$(PackageInternalPath)\Windows" /> - <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.metadata.json" DestinationFolder="$(PackageInternalPath)\Windows" /> <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\steam_appid.txt" DestinationFolder="$(PackageInternalPath)\Windows" /> - <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.dll" DestinationFolder="$(PackageInternalPath)\Windows" /> - <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.pdb" DestinationFolder="$(PackageInternalPath)\Windows" /> - <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.xml" DestinationFolder="$(PackageInternalPath)\Windows" /> - <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.dll" DestinationFolder="$(PackageInternalPath)\Windows" /> - <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.pdb" DestinationFolder="$(PackageInternalPath)\Windows" /> - <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.xml" DestinationFolder="$(PackageInternalPath)\Windows" /> <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="@(CompiledMods)" DestinationFolder="$(PackageInternalPath)\Windows\Mods\%(RecursiveDir)" /> + + <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\Mono.Cecil.dll" DestinationFolder="$(PackageInternalPath)\Windows\smapi-internal" /> + <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\0Harmony.dll" DestinationFolder="$(PackageInternalPath)\Windows\smapi-internal" /> + <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\0Harmony.pdb" DestinationFolder="$(PackageInternalPath)\Windows\smapi-internal" /> + <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\Newtonsoft.Json.dll" DestinationFolder="$(PackageInternalPath)\Windows\smapi-internal" /> + <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.config.json" DestinationFolder="$(PackageInternalPath)\Windows\smapi-internal" /> + <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.metadata.json" DestinationFolder="$(PackageInternalPath)\Windows\smapi-internal" /> + <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.dll" DestinationFolder="$(PackageInternalPath)\Windows\smapi-internal" /> + <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.pdb" DestinationFolder="$(PackageInternalPath)\Windows\smapi-internal" /> + <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.xml" DestinationFolder="$(PackageInternalPath)\Windows\smapi-internal" /> + <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.dll" DestinationFolder="$(PackageInternalPath)\Windows\smapi-internal" /> + <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.pdb" DestinationFolder="$(PackageInternalPath)\Windows\smapi-internal" /> + <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.xml" DestinationFolder="$(PackageInternalPath)\Windows\smapi-internal" /> </Target> </Project> diff --git a/docs/release-notes.md b/docs/release-notes.md index c7097f97..0ec842ef 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,12 +1,15 @@ # Release notes ## 2.8 (upcoming) * For players: + * Moved most SMAPI files into a `smapi-internal` subfolder. * Updated compatibility list. * For modders: * Added [data API](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Data). * Added `IContentPack.WriteJsonFile` method. + * Added IntelliSense documentation when not using the 'for developers' version of SMAPI. * Fixed `IContentPack.ReadJsonFile` allowing non-relative paths. + * **Breaking change:** most SMAPI files have been moved into a `smapi-internal` subfolder. This won't affect compiled mods, but you'll need to update the mod build config NuGet package when compiling mods. ## 2.7 * For players: diff --git a/docs/technical-docs.md b/docs/technical-docs.md index ed45871a..be809c3f 100644 --- a/docs/technical-docs.md +++ b/docs/technical-docs.md @@ -50,15 +50,15 @@ on the wiki for the first-time setup. 1. Update the version number in `GlobalAssemblyInfo.cs` and `Constants::Version`. Make sure you use a [semantic version](http://semver.org). Recommended format: - build type | format | example - :--------- | :-------------------------------- | :------ - dev build | `<version>-alpha.<timestamp>` | `2.0-alpha.20171230` - prerelease | `<version>-prerelease.<ID>` | `2.0-prerelease.2` - release | `<version>` | `2.0` + build type | format | example + :--------- | :----------------------- | :------ + dev build | `<version>-alpha.<date>` | `3.0-alpha.20171230` + prerelease | `<version>-beta.<count>` | `3.0-beta.2` + release | `<version>` | `3.0` 2. In Windows: 1. Rebuild the solution in _Release_ mode. - 2. Rename `bin/Packaged` to `SMAPI <version>` (e.g. `SMAPI 2.0`). + 2. Rename `bin/Packaged` to `SMAPI <version>` (e.g. `SMAPI 3.0`). 2. Transfer the `SMAPI <version>` folder to Linux or Mac. _This adds the installer executable and Windows files. We'll do the rest in Linux or Mac, since we need to set Unix file permissions that Windows won't save._ @@ -69,36 +69,26 @@ on the wiki for the first-time setup. 3. If you did everything right so far, you should have a folder like this: ``` - SMAPI-2.x/ - install.exe - readme.txt + SMAPI 3.0 installer/ + install on Linux.sh + install on Mac.command + install on Windows.exe + README.txt internal/ Mono/ Mods/* - Mono.Cecil.dll - Newtonsoft.Json.dll + smapi-internal/* StardewModdingAPI - StardewModdingAPI.config.json - StardewModdingAPI.Internal.dll - StardewModdingAPI.metadata.json StardewModdingAPI.exe StardewModdingAPI.pdb StardewModdingAPI.xml steam_appid.txt - System.Numerics.dll - System.Runtime.Caching.dll - System.ValueTuple.dll Windows/ Mods/* - Mono.Cecil.dll - Newtonsoft.Json.dll - StardewModdingAPI.config.json - StardewModdingAPI.Internal.dll - StardewModdingAPI.metadata.json + smapi-internal/* StardewModdingAPI.exe StardewModdingAPI.pdb StardewModdingAPI.xml - System.ValueTuple.dll steam_appid.txt ``` 4. Open a terminal in the `SMAPI <version>` folder and run `chmod 755 internal/Mono/StardewModdingAPI`. diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index 0aac1da2..f9e1ff94 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -93,40 +93,39 @@ namespace StardewModdingApi.Installer { string GetInstallPath(string path) => Path.Combine(installDir.FullName, path); - // common - yield return GetInstallPath("0Harmony.dll"); - yield return GetInstallPath("0Harmony.pdb"); - yield return GetInstallPath("Mono.Cecil.dll"); - yield return GetInstallPath("Newtonsoft.Json.dll"); + // current files + yield return GetInstallPath("libgdiplus.dylib"); // Linux/Mac only + yield return GetInstallPath("StardewModdingAPI"); // Linux/Mac only yield return GetInstallPath("StardewModdingAPI.exe"); - yield return GetInstallPath("StardewModdingAPI.config.json"); - yield return GetInstallPath("StardewModdingAPI.metadata.json"); - yield return GetInstallPath("StardewModdingAPI.Toolkit.dll"); - yield return GetInstallPath("StardewModdingAPI.Toolkit.pdb"); - yield return GetInstallPath("StardewModdingAPI.Toolkit.xml"); - yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.dll"); - yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.pdb"); - yield return GetInstallPath("StardewModdingAPI.Toolkit.CoreInterfaces.xml"); + yield return GetInstallPath("StardewModdingAPI.exe.mdb"); // Linux/Mac only + yield return GetInstallPath("StardewModdingAPI.pdb"); // Windows only yield return GetInstallPath("StardewModdingAPI.xml"); - yield return GetInstallPath("System.ValueTuple.dll"); - yield return GetInstallPath("steam_appid.txt"); - - // Linux/Mac only - yield return GetInstallPath("libgdiplus.dylib"); - yield return GetInstallPath("StardewModdingAPI"); - yield return GetInstallPath("StardewModdingAPI.exe.mdb"); - yield return GetInstallPath("System.Numerics.dll"); - yield return GetInstallPath("System.Runtime.Caching.dll"); - - // Windows only - yield return GetInstallPath("StardewModdingAPI.pdb"); + yield return GetInstallPath("smapi-internal"); // obsolete - yield return GetInstallPath(Path.Combine("Mods", ".cache")); // 1.3-1.4 + yield return GetInstallPath(Path.Combine("Mods", ".cache")); // 1.3-1.4 yield return GetInstallPath(Path.Combine("Mods", "TrainerMod")); // *–2.0 (renamed to ConsoleCommands) - yield return GetInstallPath("Mono.Cecil.Rocks.dll"); // 1.3–1.8 - yield return GetInstallPath("StardewModdingAPI-settings.json"); // 1.0-1.4 + yield return GetInstallPath("Mono.Cecil.Rocks.dll"); // 1.3–1.8 + yield return GetInstallPath("StardewModdingAPI-settings.json"); // 1.0-1.4 yield return GetInstallPath("StardewModdingAPI.AssemblyRewriters.dll"); // 1.3-2.5.5 + yield return GetInstallPath("0Harmony.dll"); // moved in 2.8 + yield return GetInstallPath("0Harmony.pdb"); // moved in 2.8 + yield return GetInstallPath("Mono.Cecil.dll"); // moved in 2.8 + yield return GetInstallPath("Newtonsoft.Json.dll"); // moved in 2.8 + yield return GetInstallPath("StardewModdingAPI.config.json"); // moved in 2.8 + yield return GetInstallPath("StardewModdingAPI.metadata.json"); // moved in 2.8 + yield return GetInstallPath("StardewModdingAPI.Toolkit.dll"); // moved in 2.8 + yield return GetInstallPath("StardewModdingAPI.Toolkit.pdb"); // moved in 2.8 + yield return GetInstallPath("StardewModdingAPI.Toolkit.xml"); // moved in 2.8 + 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("StardewModdingAPI.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("steam_appid.txt"); // moved in 2.8 + if (modsDir.Exists) { foreach (DirectoryInfo modDir in modsDir.EnumerateDirectories()) @@ -438,14 +437,13 @@ namespace StardewModdingApi.Installer { // copy SMAPI files to game dir this.PrintDebug("Adding SMAPI files..."); - foreach (FileInfo sourceFile in paths.PackageDir.EnumerateFiles().Where(this.ShouldCopyFile)) + foreach (FileSystemInfo sourceEntry in paths.PackageDir.EnumerateFileSystemInfos().Where(this.ShouldCopy)) { - if (sourceFile.Name == this.InstallerFileName) + if (sourceEntry.Name == this.InstallerFileName) continue; - string targetPath = Path.Combine(paths.GameDir.FullName, sourceFile.Name); - this.InteractivelyDelete(targetPath); - sourceFile.CopyTo(targetPath); + this.InteractivelyDelete(Path.Combine(paths.GameDir.FullName, sourceEntry.Name)); + this.RecursiveCopy(sourceEntry, paths.GameDir); } // replace mod launcher (if possible) @@ -508,7 +506,7 @@ namespace StardewModdingApi.Installer targetDir.Create(); // copy files - foreach (FileInfo sourceFile in sourceDir.EnumerateFiles().Where(this.ShouldCopyFile)) + foreach (FileInfo sourceFile in sourceDir.EnumerateFiles().Where(this.ShouldCopy)) sourceFile.CopyTo(Path.Combine(targetDir.FullName, sourceFile.Name)); } @@ -690,6 +688,31 @@ namespace StardewModdingApi.Installer } } + /// <summary>Recursively copy a directory or file.</summary> + /// <param name="source">The file or folder to copy.</param> + /// <param name="targetFolder">The folder to copy into.</param> + private void RecursiveCopy(FileSystemInfo source, DirectoryInfo targetFolder) + { + if (!targetFolder.Exists) + targetFolder.Create(); + + switch (source) + { + case FileInfo sourceFile: + sourceFile.CopyTo(Path.Combine(targetFolder.FullName, sourceFile.Name)); + break; + + case DirectoryInfo sourceDir: + DirectoryInfo targetSubfolder = new DirectoryInfo(Path.Combine(targetFolder.FullName, sourceDir.Name)); + foreach (var entry in sourceDir.EnumerateFileSystemInfos()) + this.RecursiveCopy(entry, targetSubfolder); + break; + + default: + throw new NotSupportedException($"Unknown filesystem info type '{source.GetType().FullName}'."); + } + } + /// <summary>Delete a file or folder regardless of file permissions, and block until deletion completes.</summary> /// <param name="entry">The file or folder to reset.</param> /// <remarks>This method is mirred from <c>FileUtilities.ForceDelete</c> in the toolkit.</remarks> @@ -871,7 +894,7 @@ namespace StardewModdingApi.Installer this.PrintDebug(" Support for mods here was dropped in SMAPI 1.0 (it was never officially supported)."); // move mods if no conflicts (else warn) - foreach (FileSystemInfo entry in modDir.EnumerateFileSystemInfos().Where(this.ShouldCopyFile)) + foreach (FileSystemInfo entry in modDir.EnumerateFileSystemInfos().Where(this.ShouldCopy)) { // get type bool isDir = entry is DirectoryInfo; @@ -928,22 +951,26 @@ namespace StardewModdingApi.Installer Directory.CreateDirectory(newPath); DirectoryInfo directory = (DirectoryInfo)entry; - foreach (FileSystemInfo child in directory.EnumerateFileSystemInfos().Where(this.ShouldCopyFile)) + foreach (FileSystemInfo child in directory.EnumerateFileSystemInfos().Where(this.ShouldCopy)) this.Move(child, Path.Combine(newPath, child.Name)); directory.Delete(recursive: true); } } - /// <summary>Get whether a file should be copied when moving a folder.</summary> - /// <param name="file">The file info.</param> - private bool ShouldCopyFile(FileSystemInfo file) + /// <summary>Get whether a file or folder should be copied from the installer files.</summary> + /// <param name="entry">The file or folder info.</param> + private bool ShouldCopy(FileSystemInfo entry) { - // ignore Mac symlink - if (file is FileInfo && file.Name == "mcs") - return false; - - return true; + switch (entry.Name) + { + case "mcs": + return false; // ignore Mac symlink + case "Mods": + return false; // Mods folder handled separately + default: + return true; + } } } } diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets index d1c8a4eb..db9fe8bd 100644 --- a/src/SMAPI.ModBuildConfig/build/smapi.targets +++ b/src/SMAPI.ModBuildConfig/build/smapi.targets @@ -136,7 +136,7 @@ <Private Condition="$(CopyModReferencesToBuildOutput)">true</Private> </Reference> <Reference Include="StardewModdingAPI.Toolkit.CoreInterfaces"> - <HintPath>$(GamePath)\StardewModdingAPI.Toolkit.CoreInterfaces.dll</HintPath> + <HintPath>$(GamePath)\smapi-internal\StardewModdingAPI.Toolkit.CoreInterfaces.dll</HintPath> <Private>false</Private> <Private Condition="$(CopyModReferencesToBuildOutput)">true</Private> </Reference> diff --git a/src/SMAPI.ModBuildConfig/package.nuspec b/src/SMAPI.ModBuildConfig/package.nuspec index 3d6f2598..04880101 100644 --- a/src/SMAPI.ModBuildConfig/package.nuspec +++ b/src/SMAPI.ModBuildConfig/package.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"> <metadata> <id>Pathoschild.Stardew.ModBuildConfig</id> - <version>2.1.0</version> + <version>2.1.1</version> <title>Build package for SMAPI mods</title> <authors>Pathoschild</authors> <owners>Pathoschild</owners> @@ -19,6 +19,9 @@ - Added option to ignore files by regex pattern. - Added reference to new SMAPI DLL. - Fixed some game paths not detected by NuGet package. + + 2.1.1: + - Update for SMAPI 2.8. </releaseNotes> </metadata> </package> diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index bd512fb1..0e0ae239 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -64,11 +64,14 @@ namespace StardewModdingAPI /// <summary>The URL of the SMAPI home page.</summary> internal const string HomePageUrl = "https://smapi.io"; + /// <summary>The absolute path to the folder containing SMAPI's internal files.</summary> + internal static readonly string InternalFilesPath = Program.DllSearchPath; + /// <summary>The file path for the SMAPI configuration file.</summary> - internal static string ApiConfigPath => Path.Combine(Constants.ExecutionPath, $"{typeof(Program).Assembly.GetName().Name}.config.json"); + internal static string ApiConfigPath => Path.Combine(Constants.InternalFilesPath, "StardewModdingAPI.config.json"); /// <summary>The file path for the SMAPI metadata file.</summary> - internal static string ApiMetadataPath => Path.Combine(Constants.ExecutionPath, $"{typeof(Program).Assembly.GetName().Name}.metadata.json"); + internal static string ApiMetadataPath => Path.Combine(Constants.InternalFilesPath, "StardewModdingAPI.metadata.json"); /// <summary>The filename prefix used for all SMAPI logs.</summary> internal static string LogNamePrefix { get; } = "SMAPI-"; diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index 37b1a378..e750c659 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -45,6 +45,7 @@ namespace StardewModdingAPI.Framework.ModLoading this.AssemblyMap = this.TrackForDisposal(Constants.GetAssemblyMap(targetPlatform)); this.AssemblyDefinitionResolver = this.TrackForDisposal(new AssemblyDefinitionResolver()); this.AssemblyDefinitionResolver.AddSearchDirectory(Constants.ExecutionPath); + this.AssemblyDefinitionResolver.AddSearchDirectory(Constants.InternalFilesPath); // generate type => assembly lookup for types which should be rewritten this.TypeAssemblies = new Dictionary<string, Assembly>(); diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index c40d2ff6..64eeb45a 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -45,6 +45,11 @@ namespace StardewModdingAPI /********* ** Properties *********/ + /// <summary>The absolute path to search for SMAPI's internal DLLs.</summary> + /// <remarks>We can't use <see cref="Constants.ExecutionPath"/> directly, since <see cref="Constants"/> depends on DLLs loaded from this folder.</remarks> + [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute", Justification = "The assembly location is never null in this context.")] + internal static readonly string DllSearchPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "smapi-internal"); + /// <summary>The log file to which to write messages.</summary> private readonly LogFileManager LogFile; @@ -111,6 +116,8 @@ namespace StardewModdingAPI /// <param name="args">The command-line arguments.</param> public static void Main(string[] args) { + // initial setup + AppDomain.CurrentDomain.AssemblyResolve += Program.CurrentDomain_AssemblyResolve; Program.AssertMinimumCompatibility(); // get flags from arguments @@ -135,10 +142,48 @@ namespace StardewModdingAPI program.RunInteractively(); } + /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary> + public void Dispose() + { + // skip if already disposed + if (this.IsDisposed) + return; + this.IsDisposed = true; + this.Monitor.Log("Disposing...", LogLevel.Trace); + + // dispose mod data + foreach (IModMetadata mod in this.ModRegistry.GetAll()) + { + try + { + (mod.Mod as IDisposable)?.Dispose(); + } + catch (Exception ex) + { + mod.LogAsMod($"Mod failed during disposal: {ex.GetLogSummary()}.", LogLevel.Warn); + } + } + + // dispose core components + this.IsGameRunning = false; + this.ConsoleManager?.Dispose(); + this.ContentCore?.Dispose(); + this.CancellationTokenSource?.Dispose(); + this.GameInstance?.Dispose(); + this.LogFile?.Dispose(); + + // end game (moved from Game1.OnExiting to let us clean up first) + Process.GetCurrentProcess().Kill(); + } + + + /********* + ** Private methods + *********/ /// <summary>Construct an instance.</summary> /// <param name="modsPath">The path to search for mods.</param> /// <param name="writeToConsole">Whether to output log messages to the console.</param> - public Program(string modsPath, bool writeToConsole) + private Program(string modsPath, bool writeToConsole) { // init paths this.VerifyPath(modsPath); @@ -189,7 +234,7 @@ namespace StardewModdingAPI /// <summary>Launch SMAPI.</summary> [HandleProcessCorruptedStateExceptions, SecurityCritical] // let try..catch handle corrupted state exceptions - public void RunInteractively() + private void RunInteractively() { // initialise SMAPI try @@ -320,44 +365,28 @@ namespace StardewModdingAPI } } - /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary> - public void Dispose() + /// <summary>Method called when assembly resolution fails, which may return a manually resolved assembly.</summary> + /// <param name="sender">The event sender.</param> + /// <param name="e">The event arguments.</param> + private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs e) { - // skip if already disposed - if (this.IsDisposed) - return; - this.IsDisposed = true; - this.Monitor.Log("Disposing...", LogLevel.Trace); - - // dispose mod data - foreach (IModMetadata mod in this.ModRegistry.GetAll()) + AssemblyName name = new AssemblyName(e.Name); + foreach (FileInfo dll in new DirectoryInfo(Program.DllSearchPath).EnumerateFiles("*.dll")) { try { - (mod.Mod as IDisposable)?.Dispose(); + if (name.Name.Equals(AssemblyName.GetAssemblyName(dll.FullName).Name, StringComparison.InvariantCultureIgnoreCase)) + return Assembly.LoadFrom(dll.FullName); } catch (Exception ex) { - mod.LogAsMod($"Mod failed during disposal: {ex.GetLogSummary()}.", LogLevel.Warn); + throw new InvalidOperationException($"Could not load dependency 'smapi-lib/{dll.Name}'. Consider deleting the smapi-lib folder and reinstalling SMAPI.", ex); } } - // dispose core components - this.IsGameRunning = false; - this.ConsoleManager?.Dispose(); - this.ContentCore?.Dispose(); - this.CancellationTokenSource?.Dispose(); - this.GameInstance?.Dispose(); - this.LogFile?.Dispose(); - - // end game (moved from Game1.OnExiting to let us clean up first) - Process.GetCurrentProcess().Kill(); + return null; } - - /********* - ** Private methods - *********/ /// <summary>Assert that the minimum conditions are present to initialise SMAPI without type load exceptions.</summary> private static void AssertMinimumCompatibility() { |