summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2018-08-19 18:28:16 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2018-08-19 18:28:16 -0400
commit826dd53ab550e5b92796c510569118beee6bd044 (patch)
treed6d8ec7f380112e8ed047a932ae02548dc9b8a2b
parent417c04076634ea87d7b3030a1acf46825da6e3e6 (diff)
downloadSMAPI-826dd53ab550e5b92796c510569118beee6bd044.tar.gz
SMAPI-826dd53ab550e5b92796c510569118beee6bd044.tar.bz2
SMAPI-826dd53ab550e5b92796c510569118beee6bd044.zip
move most SMAPI files into subfolder (#582)
-rw-r--r--build/common.targets22
-rw-r--r--build/prepare-install-package.targets57
-rw-r--r--docs/release-notes.md3
-rw-r--r--docs/technical-docs.md36
-rw-r--r--src/SMAPI.Installer/InteractiveInstaller.cs115
-rw-r--r--src/SMAPI.ModBuildConfig/build/smapi.targets2
-rw-r--r--src/SMAPI.ModBuildConfig/package.nuspec5
-rw-r--r--src/SMAPI/Constants.cs7
-rw-r--r--src/SMAPI/Framework/ModLoading/AssemblyLoader.cs1
-rw-r--r--src/SMAPI/Program.cs85
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()
{