summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2016-11-03 21:03:03 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2016-11-03 21:03:03 -0400
commit0b5a05ba9120f7acee961ed75e62eff4fd68a821 (patch)
treedee1e302b6ecdd992efcdd92bcc6bbed8e07223b
parent59c900a9ac936491386e70d9c841e572f2a49ecd (diff)
downloadSMAPI-0b5a05ba9120f7acee961ed75e62eff4fd68a821.tar.gz
SMAPI-0b5a05ba9120f7acee961ed75e62eff4fd68a821.tar.bz2
SMAPI-0b5a05ba9120f7acee961ed75e62eff4fd68a821.zip
add crossplatform installer (#155)
-rw-r--r--README.md85
-rw-r--r--release-notes.md4
-rw-r--r--src/StardewModdingAPI.Installer/Enums/Platform.cs12
-rw-r--r--src/StardewModdingAPI.Installer/Enums/ScriptAction.cs12
-rw-r--r--src/StardewModdingAPI.Installer/InteractiveInstaller.cs325
-rw-r--r--src/StardewModdingAPI.Installer/Program.cs17
-rw-r--r--src/StardewModdingAPI.Installer/Properties/AssemblyInfo.cs9
-rw-r--r--src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj80
-rw-r--r--src/StardewModdingAPI.Installer/readme.txt1
-rw-r--r--src/StardewModdingAPI.sln18
-rw-r--r--src/StardewModdingAPI/StardewModdingAPI.csproj20
-rw-r--r--src/StardewModdingAPI/unix-launcher.sh (renamed from src/StardewModdingAPI/StardewModdingAPI)0
-rw-r--r--src/TrainerMod/TrainerMod.csproj9
13 files changed, 544 insertions, 48 deletions
diff --git a/README.md b/README.md
index dcb9e04b..1300da96 100644
--- a/README.md
+++ b/README.md
@@ -18,46 +18,65 @@ your game files.
* [SMAPI/Farmhand Discord](https://discordapp.com/invite/0t3fh2xhHVc6Vdyx) (chat with SMAPI developers)
## For SMAPI developers
+_This section is about compiling SMAPI itself from source. If you don't know what that means, this
+section isn't relevant to you; see the previous sections to use or create mods._
### Compiling from source
-Using one of the SMAPI releases is recommended for most users.
+Using an official SMAPI release is recommended for most users.
-If you'd like to compile SMAPI from source, you can do that on any platform. SMAPI uses build
-configuration derived from the [crosswiki mod config](https://github.com/Pathoschild/Stardew.ModBuildConfig#readme)
-to detect your current OS automatically and load the correct references.
+If you'd like to compile SMAPI from source, you can do that on any platform using
+[Visual Studio](https://www.visualstudio.com/vs/community/) or [MonoDevelop](http://www.monodevelop.com/).
+SMAPI uses build configuration derived from the [crosswiki mod config](https://github.com/Pathoschild/Stardew.ModBuildConfig#readme)
+to detect your current OS automatically and load the correct references. Compile output will be
+placed in a `bin` directory at the root of the git repository.
### Preparing a release
+To prepare a crossplatform SMAPI release, you'll need to compile it on two platforms. See
+_[crossplatforming a SMAPI mod](http://canimod.com/guides/crossplatforming-a-smapi-mod#preparing-a-mod-release)_
+for the first-time setup.
-1. Open the project in [Visual Studio](https://www.visualstudio.com/vs/community/) or [MonoDevelop](http://www.monodevelop.com/).
-2. Switch to _Release_ build mode.
-3. Update the version number in `AssemblyInfo.cs`.
-4. Update the version number in `Constants::Version`. Add the minimum game version and target
- platform at the end of the version number (like `0.41.0 1.1 for Windows`).
-5. Build the solution.
-6. Copy the files for the target platform into the archive structure below.
-7. Repeat for each platform.
+For simplicity, all paths are relative to the root of the repository (the directory containing `src`).
-The release should consist of three files like this:
+1. Update the version number in `AssemblyInfo.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>` | `1.0.0-alpha-201611300500`
+ beta | `<version>-beta<incrementing ID>` | `1.0.0-beta2`
+ release | `<version>` | `1.0.0`
+
+2. In Windows:
+ 1. Rebuild the solution in _Release_ mode.
+ 2. Transfer the `bin/Release/~Package` directory 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._
+
+2. In Linux or Mac:
+ 1. Rebuild the solution in _Release_ mode.
+ 2. Copy `bin/Release/~Package/Mono` into the package directory you transferred from Windows.
+ 3. Open a terminal in your package directory and run `chmod 755 Mono/StardewModdingAPI`.
+ 4. Rename your package directory to `SMAPI-<version>-installer`.
+ 5. Compress it into a `SMAPI-<version>.zip` file.
+
+If you did everything right, you should have a release file like this:
```
-SMAPI-1.0-Linux.tar.gz
- Mods/*
- Newtonsoft.Json.dll
- StardewModdingAPI
- StardewModdingAPI.exe
- StardewModdingAPI.mdb
- System.Numerics.dll
-
-SMAPI-1.0-Mac.tar.gz
- Mods/*
- Newtonsoft.Json.dll
- StardewModdingAPI
- StardewModdingAPI.exe
- StardewModdingAPI.mdb
- System.Numerics.dll
-
-SMAPI-1.0-Windows.zip
- Mods/*
- StardewModdingAPI.exe
- StardewModdingAPI.pdb
+SMAPI-1.0.zip
+ SMAPI-1.0-installer/
+ Mono/
+ Mods/*
+ Newtonsoft.Json.dll
+ StardewModdingAPI
+ StardewModdingAPI.exe
+ StardewModdingAPI.exe.mdb
+ System.Numerics.dll
+ steam_appid.txt
+ Windows/
+ Mods/*
+ StardewModdingAPI.exe
+ StardewModdingAPI.pdb
+ steam_appid.txt
+ install.exe
+ readme.txt
```
diff --git a/release-notes.md b/release-notes.md
index 8b5a87d3..8299300e 100644
--- a/release-notes.md
+++ b/release-notes.md
@@ -3,10 +3,12 @@
## 1.x
* 1.0 (upcoming, [log](https://github.com/CLxS/SMAPI/compare/0.40.1.1-3...master))
* Added support for Linux and Mac.
+ * Added installer.
* Added background update check on launch.
* Added OS version to log.
* Added zoom-adjusted mouse position to mouse-changed event arguments.
* Switched to [semantic versioning](http://semver.org).
+ * Fixed missing `steam_appid.txt` file.
* Fixed mod versions not being displayed correctly on log.
* Fixed misspelled field in `manifest.json` schema.
* Fixed several events not correctly propagating state.
@@ -15,8 +17,8 @@
* Internal cleanup:
* Simplified compiling from source.
* Added code documentation.
- * Internal cleanup & refactoring.
* Removed obsolete and unfinished code.
+ * Internal cleanup & refactoring.
## 0.x
* 0.40.1.1 (2016-09-30, [log](https://github.com/CLxS/SMAPI/compare/0.40.0...0.40.1.1-3))
diff --git a/src/StardewModdingAPI.Installer/Enums/Platform.cs b/src/StardewModdingAPI.Installer/Enums/Platform.cs
new file mode 100644
index 00000000..9bcaa3c3
--- /dev/null
+++ b/src/StardewModdingAPI.Installer/Enums/Platform.cs
@@ -0,0 +1,12 @@
+namespace StardewModdingApi.Installer.Enums
+{
+ /// <summary>The game's platform version.</summary>
+ internal enum Platform
+ {
+ /// <summary>The Linux/Mac version of the game.</summary>
+ Mono,
+
+ /// <summary>The Windows version of the game.</summary>
+ Windows
+ }
+} \ No newline at end of file
diff --git a/src/StardewModdingAPI.Installer/Enums/ScriptAction.cs b/src/StardewModdingAPI.Installer/Enums/ScriptAction.cs
new file mode 100644
index 00000000..e62b2a7c
--- /dev/null
+++ b/src/StardewModdingAPI.Installer/Enums/ScriptAction.cs
@@ -0,0 +1,12 @@
+namespace StardewModdingApi.Installer.Enums
+{
+ /// <summary>The action to perform.</summary>
+ internal enum ScriptAction
+ {
+ /// <summary>Install SMAPI to the game directory.</summary>
+ Install,
+
+ /// <summary>Remove SMAPI from the game directory.</summary>
+ Uninstall
+ }
+} \ No newline at end of file
diff --git a/src/StardewModdingAPI.Installer/InteractiveInstaller.cs b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs
new file mode 100644
index 00000000..022ac4e6
--- /dev/null
+++ b/src/StardewModdingAPI.Installer/InteractiveInstaller.cs
@@ -0,0 +1,325 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using StardewModdingApi.Installer.Enums;
+
+namespace StardewModdingApi.Installer
+{
+ /// <summary>Interactively performs the install and uninstall logic.</summary>
+ internal class InteractiveInstaller
+ {
+ /*********
+ ** Properties
+ *********/
+ /// <summary>The default file paths where Stardew Valley can be installed.</summary>
+ /// <remarks>Derived from the crossplatform mod config: https://github.com/Pathoschild/Stardew.ModBuildConfig. </remarks>
+ private readonly string[] DefaultInstallPaths = {
+ // Linux
+ $"{Environment.GetEnvironmentVariable("HOME")}/GOG Games/Stardew Valley/game",
+ $"{Environment.GetEnvironmentVariable("HOME")}/.local/share/Steam/steamapps/common/Stardew Valley",
+
+ // Mac
+ $"{Environment.GetEnvironmentVariable("HOME")}/Library/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS",
+
+ // Windows
+ @"C:\Program Files (x86)\GalaxyClient\Games\Stardew Valley",
+ @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley"
+ };
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Run the install or uninstall script.</summary>
+ /// <param name="args">The command line arguments.</param>
+ /// <remarks>
+ /// Initialisation flow:
+ /// 1. Collect information (mainly OS and install path) and validate it.
+ /// 2. Ask the user whether to install or uninstall.
+ ///
+ /// Install flow:
+ /// 1. Copy the SMAPI files from package/Windows or package/Mono into the game directory.
+ /// 2. On Linux/Mac: back up the game launcher and replace it with the SMAPI launcher. (This isn't possible on Windows, so the user needs to configure it manually.)
+ /// 3. Create the 'Mods' directory.
+ /// 4. Copy the bundled mods into the 'Mods' directory (deleting any existing versions).
+ ///
+ /// Uninstall logic:
+ /// 1. On Linux/Mac: if a backup of the launcher exists, delete the launcher and restore the backup.
+ /// 2. Delete all files in the game directory matching a file under package/Windows or package/Mono.
+ /// </remarks>
+ public void Run(string[] args)
+ {
+ /****
+ ** collect details
+ ****/
+ this.PrintDebug("Collecting information...");
+ Platform platform = this.DetectPlatform();
+ DirectoryInfo packageDir = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), platform.ToString()));
+ DirectoryInfo installDir = this.InteractivelyGetInstallPath();
+ string executablePath = Path.Combine(installDir.FullName, platform == Platform.Mono ? "StardewValley.exe" : "Stardew Valley.exe");
+ string unixGameLauncherPath = Path.Combine(installDir.FullName, "StardewValley");
+ string unixGameLauncherBackupPath = Path.Combine(installDir.FullName, "StardewValley-original");
+ string unixSmapiLauncherPath = Path.Combine(installDir.FullName, "StardewModdingAPI");
+
+ this.PrintDebug($"Detected {(platform == Platform.Windows ? "Windows" : "Linux or Mac")}.");
+ this.PrintDebug($"Detected game in {installDir}.");
+
+ /****
+ ** validate assumptions
+ ****/
+ this.PrintDebug("Verifying...");
+ if (!packageDir.Exists)
+ {
+ this.ExitError($"The '{platform}' package directory is missing (should be at {packageDir}).");
+ return;
+ }
+ if (!File.Exists(executablePath))
+ {
+ this.ExitError("The detected game install path doesn't contain a Stardew Valley executable.");
+ return;
+ }
+ Console.WriteLine();
+
+ /****
+ ** ask user what to do
+ ****/
+ Console.WriteLine("You can....");
+ Console.ForegroundColor = ConsoleColor.DarkGreen;
+ if (platform == Platform.Mono)
+ Console.WriteLine("[1] Install SMAPI. This will safely update the files so you can launch the game the same way as before.");
+ else
+ Console.WriteLine("[1] Install SMAPI. You'll need to launch StardewModdingAPI.exe instead afterwards; see the readme.txt for details.");
+ Console.ForegroundColor = ConsoleColor.DarkRed;
+ Console.WriteLine("[2] Uninstall SMAPI.");
+ Console.ResetColor();
+
+ ScriptAction action;
+ {
+ string choice = this.InteractivelyChoose("What do you want to do?", "1", "2");
+ switch (choice)
+ {
+ case "1":
+ action = ScriptAction.Install;
+ break;
+ case "2":
+ action = ScriptAction.Uninstall;
+ break;
+ default:
+ throw new InvalidOperationException($"Unexpected action key '{choice}'.");
+ }
+ }
+ Console.WriteLine();
+
+ /****
+ ** Perform action
+ ****/
+ switch (action)
+ {
+ case ScriptAction.Uninstall:
+ {
+ // restore game launcher
+ if (platform == Platform.Mono && File.Exists(unixGameLauncherBackupPath))
+ {
+ this.PrintDebug("Restoring game launcher...");
+ if (File.Exists(unixGameLauncherPath))
+ File.Delete(unixGameLauncherPath);
+ File.Move(unixGameLauncherBackupPath, unixGameLauncherPath);
+ }
+
+ // remove SMAPI files
+ this.PrintDebug("Removing SMAPI files...");
+ foreach (FileInfo sourceFile in packageDir.EnumerateFiles())
+ {
+ string targetPath = Path.Combine(installDir.FullName, sourceFile.Name);
+ if (File.Exists(targetPath))
+ File.Delete(targetPath);
+ }
+ }
+ break;
+
+ case ScriptAction.Install:
+ {
+ // copy SMAPI files to game dir
+ this.PrintDebug("Copying SMAPI files to game directory...");
+ foreach (FileInfo sourceFile in packageDir.EnumerateFiles())
+ {
+ string targetPath = Path.Combine(installDir.FullName, sourceFile.Name);
+ if (File.Exists(targetPath))
+ File.Delete(targetPath);
+ sourceFile.CopyTo(targetPath);
+ }
+
+ // replace mod launcher (if possible)
+ if (platform == Platform.Mono)
+ {
+ this.PrintDebug("Safely replacing game launcher...");
+ if (!File.Exists(unixGameLauncherBackupPath))
+ File.Move(unixGameLauncherPath, unixGameLauncherBackupPath);
+ else if (File.Exists(unixGameLauncherPath))
+ File.Delete(unixGameLauncherPath);
+
+ File.Move(unixSmapiLauncherPath, unixGameLauncherPath);
+ }
+
+ // create mods directory (if needed)
+ DirectoryInfo modsDir = new DirectoryInfo(Path.Combine(installDir.FullName, "Mods"));
+ if (!modsDir.Exists)
+ {
+ this.PrintDebug("Creating mods directory...");
+ modsDir.Create();
+ }
+
+ // add or replace bundled mods
+ Directory.CreateDirectory(Path.Combine(installDir.FullName, "Mods"));
+ DirectoryInfo packagedModsDir = new DirectoryInfo(Path.Combine(packageDir.FullName, "Mods"));
+ if (packagedModsDir.Exists && packagedModsDir.EnumerateDirectories().Any())
+ {
+ this.PrintDebug("Adding bundled mods...");
+ foreach (DirectoryInfo sourceDir in packagedModsDir.EnumerateDirectories())
+ {
+ this.PrintDebug($" adding {sourceDir.Name}...");
+
+ // initialise target dir
+ DirectoryInfo targetDir = new DirectoryInfo(Path.Combine(modsDir.FullName, sourceDir.Name));
+ if (targetDir.Exists)
+ targetDir.Delete(recursive: true);
+ targetDir.Create();
+
+ // copy files
+ foreach (FileInfo sourceFile in sourceDir.EnumerateFiles())
+ sourceFile.CopyTo(Path.Combine(targetDir.FullName, sourceFile.Name));
+ }
+ }
+ }
+ break;
+ }
+ Console.WriteLine();
+
+ /****
+ ** exit
+ ****/
+ Console.WriteLine("Done!");
+ if (platform == Platform.Windows)
+ {
+ if(action == ScriptAction.Install)
+ Console.WriteLine("Don't forget to launch StardewModdingAPI.exe instead of the normal game executable. See the readme.txt for details.");
+ else
+ Console.WriteLine("If you manually changed shortcuts or Steam to launch SMAPI, don't forget to change those back.");
+ }
+ Console.ReadKey();
+ }
+
+
+ /*********
+ ** Private methods
+ *********/
+ /// <summary>Detect the game's platform.</summary>
+ /// <exception cref="NotSupportedException">The platform is not supported.</exception>
+ private Platform DetectPlatform()
+ {
+ switch (Environment.OSVersion.Platform)
+ {
+ case PlatformID.MacOSX:
+ case PlatformID.Unix:
+ return Platform.Mono;
+
+ default:
+ return Platform.Windows;
+ }
+ }
+
+ /// <summary>Print a debug message.</summary>
+ /// <param name="text">The text to print.</param>
+ private void PrintDebug(string text)
+ {
+ Console.ForegroundColor = ConsoleColor.DarkGray;
+ Console.WriteLine(text);
+ Console.ResetColor();
+ }
+
+ /// <summary>Print a warning message.</summary>
+ /// <param name="text">The text to print.</param>
+ private void PrintWarning(string text)
+ {
+ Console.ForegroundColor = ConsoleColor.DarkYellow;
+ Console.WriteLine(text);
+ Console.ResetColor();
+ }
+
+ /// <summary>Print an error and pause the console if needed.</summary>
+ /// <param name="error">The error text.</param>
+ private void ExitError(string error)
+ {
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine(error);
+ Console.ResetColor();
+ Console.ReadLine();
+ }
+
+ /// <summary>Interactively ask the user to choose a value.</summary>
+ /// <param name="message">The message to print.</param>
+ /// <param name="options">The allowed options (not case sensitive).</param>
+ private string InteractivelyChoose(string message, params string[] options)
+ {
+ while (true)
+ {
+ Console.WriteLine(message);
+ string input = Console.ReadLine()?.Trim().ToLowerInvariant();
+ if (!options.Contains(input))
+ {
+ Console.WriteLine("That's not a valid option.");
+ continue;
+ }
+ return input;
+ }
+ }
+
+ /// <summary>Interactively locate the game's install path.</summary>
+ private DirectoryInfo InteractivelyGetInstallPath()
+ {
+ // try default paths
+ foreach (string defaultPath in this.DefaultInstallPaths)
+ {
+ if (Directory.Exists(defaultPath))
+ return new DirectoryInfo(defaultPath);
+ }
+
+ // ask user
+ Console.WriteLine("Oops, couldn't find your Stardew Valley install path automatically. You'll need to specify where the game is installed (or install SMAPI manually).");
+ while (true)
+ {
+ // get path from user
+ Console.WriteLine(" Enter the game's full directory path (the one containing 'StardewValley.exe' or 'Stardew Valley.exe').");
+ Console.Write(" > ");
+ string path = Console.ReadLine();
+ if (string.IsNullOrWhiteSpace(path))
+ {
+ Console.WriteLine(" You must specify a directory path to continue.");
+ continue;
+ }
+
+ // get directory
+ if (File.Exists(path))
+ path = Path.GetDirectoryName(path);
+ DirectoryInfo directory = new DirectoryInfo(path);
+
+ // validate path
+ if (!directory.Exists)
+ {
+ Console.WriteLine(" That directory doesn't seem to exist.");
+ continue;
+ }
+ if (!directory.EnumerateFiles("*.exe").Any(p => p.Name == "StardewValley.exe" || p.Name == "Stardew Valley.exe"))
+ {
+ Console.WriteLine(" That directory doesn't contain a Stardew Valley executable.");
+ continue;
+ }
+
+ // looks OK
+ Console.WriteLine(" OK!");
+ return directory;
+ }
+ }
+ }
+}
diff --git a/src/StardewModdingAPI.Installer/Program.cs b/src/StardewModdingAPI.Installer/Program.cs
new file mode 100644
index 00000000..8f328ecf
--- /dev/null
+++ b/src/StardewModdingAPI.Installer/Program.cs
@@ -0,0 +1,17 @@
+namespace StardewModdingApi.Installer
+{
+ /// <summary>The entry point for SMAPI's install and uninstall console app.</summary>
+ internal class Program
+ {
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Run the install or uninstall script.</summary>
+ /// <param name="args">The command line arguments.</param>
+ public static void Main(string[] args)
+ {
+ var installer = new InteractiveInstaller();
+ installer.Run(args);
+ }
+ }
+}
diff --git a/src/StardewModdingAPI.Installer/Properties/AssemblyInfo.cs b/src/StardewModdingAPI.Installer/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..5d2b0dcc
--- /dev/null
+++ b/src/StardewModdingAPI.Installer/Properties/AssemblyInfo.cs
@@ -0,0 +1,9 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("StardewModdingAPI.Installer")]
+[assembly: AssemblyProduct("StardewModdingAPI.Installer")]
+[assembly: ComVisible(false)]
+[assembly: Guid("443ddf81-6aaf-420a-a610-3459f37e5575")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj b/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj
new file mode 100644
index 00000000..e5271e96
--- /dev/null
+++ b/src/StardewModdingAPI.Installer/StardewModdingAPI.Installer.csproj
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{443DDF81-6AAF-420A-A610-3459F37E5575}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>StardewModdingAPI.Installer</RootNamespace>
+ <AssemblyName>StardewModdingAPI.Installer</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>$(SolutionDir)\..\bin\Debug\Installer</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>$(SolutionDir)\..\bin\Release\Installer</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Enums\ScriptAction.cs" />
+ <Compile Include="Enums\Platform.cs" />
+ <Compile Include="InteractiveInstaller.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="readme.txt">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- package files -->
+ <Target Name="AfterBuild">
+ <PropertyGroup>
+ <CompiledInstallerPath>$(SolutionDir)\..\bin\$(Configuration)\~Package</CompiledInstallerPath>
+ <CompiledSmapiPath>$(SolutionDir)\..\bin\$(Configuration)\SMAPI</CompiledSmapiPath>
+ </PropertyGroup>
+ <ItemGroup>
+ <CompiledMods Include="$(SolutionDir)\..\bin\$(Configuration)\Mods\**\*.*" />
+ </ItemGroup>
+ <!-- reset package directory -->
+ <RemoveDir Directories="$(CompiledInstallerPath)" />
+ <!-- copy installer files -->
+ <Copy SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFiles="$(CompiledInstallerPath)\install.exe" />
+ <Copy SourceFiles="$(TargetDir)\readme.txt" DestinationFiles="$(CompiledInstallerPath)\readme.txt" />
+ <!-- copy SMAPI files for Mono -->
+ <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\Newtonsoft.Json.dll" DestinationFolder="$(CompiledInstallerPath)\Mono" />
+ <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.exe" DestinationFolder="$(CompiledInstallerPath)\Mono" />
+ <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.exe.mdb" DestinationFolder="$(CompiledInstallerPath)\Mono" />
+ <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Numerics.dll" DestinationFolder="$(CompiledInstallerPath)\Mono" />
+ <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\unix-launcher.sh" DestinationFiles="$(CompiledInstallerPath)\Mono\StardewModdingAPI" />
+ <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\steam_appid.txt" DestinationFolder="$(CompiledInstallerPath)\Mono" />
+ <Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="@(CompiledMods)" DestinationFolder="$(CompiledInstallerPath)\Mono\Mods\%(RecursiveDir)" />
+ <!-- copy SMAPI files for Windows -->
+ <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.exe" DestinationFolder="$(CompiledInstallerPath)\Windows" />
+ <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.pdb" DestinationFolder="$(CompiledInstallerPath)\Windows" />
+ <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.xml" DestinationFolder="$(CompiledInstallerPath)\Windows" />
+ <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\steam_appid.txt" DestinationFolder="$(CompiledInstallerPath)\Windows" />
+ <Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="@(CompiledMods)" DestinationFolder="$(CompiledInstallerPath)\Windows\Mods\%(RecursiveDir)" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/src/StardewModdingAPI.Installer/readme.txt b/src/StardewModdingAPI.Installer/readme.txt
new file mode 100644
index 00000000..3865c768
--- /dev/null
+++ b/src/StardewModdingAPI.Installer/readme.txt
@@ -0,0 +1 @@
+See instructions at http://canimod.com/guides/using-mods#installing-smapi. \ No newline at end of file
diff --git a/src/StardewModdingAPI.sln b/src/StardewModdingAPI.sln
index 4d11c88d..9c999731 100644
--- a/src/StardewModdingAPI.sln
+++ b/src/StardewModdingAPI.sln
@@ -15,6 +15,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "metadata", "metadata", "{86
..\release-notes.md = ..\release-notes.md
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StardewModdingAPI.Installer", "StardewModdingAPI.Installer\StardewModdingAPI.Installer.csproj", "{443DDF81-6AAF-420A-A610-3459F37E5575}"
+ ProjectSection(ProjectDependencies) = postProject
+ {28480467-1A48-46A7-99F8-236D95225359} = {28480467-1A48-46A7-99F8-236D95225359}
+ {F1A573B0-F436-472C-AE29-0B91EA6B9F8F} = {F1A573B0-F436-472C-AE29-0B91EA6B9F8F}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -47,6 +53,18 @@ Global
{F1A573B0-F436-472C-AE29-0B91EA6B9F8F}.Release|Mixed Platforms.Build.0 = Release|x86
{F1A573B0-F436-472C-AE29-0B91EA6B9F8F}.Release|x86.ActiveCfg = Release|x86
{F1A573B0-F436-472C-AE29-0B91EA6B9F8F}.Release|x86.Build.0 = Release|x86
+ {443DDF81-6AAF-420A-A610-3459F37E5575}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {443DDF81-6AAF-420A-A610-3459F37E5575}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {443DDF81-6AAF-420A-A610-3459F37E5575}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {443DDF81-6AAF-420A-A610-3459F37E5575}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {443DDF81-6AAF-420A-A610-3459F37E5575}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {443DDF81-6AAF-420A-A610-3459F37E5575}.Debug|x86.Build.0 = Debug|Any CPU
+ {443DDF81-6AAF-420A-A610-3459F37E5575}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {443DDF81-6AAF-420A-A610-3459F37E5575}.Release|Any CPU.Build.0 = Release|Any CPU
+ {443DDF81-6AAF-420A-A610-3459F37E5575}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {443DDF81-6AAF-420A-A610-3459F37E5575}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {443DDF81-6AAF-420A-A610-3459F37E5575}.Release|x86.ActiveCfg = Release|Any CPU
+ {443DDF81-6AAF-420A-A610-3459F37E5575}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/StardewModdingAPI/StardewModdingAPI.csproj b/src/StardewModdingAPI/StardewModdingAPI.csproj
index e79cabf4..b182bf4a 100644
--- a/src/StardewModdingAPI/StardewModdingAPI.csproj
+++ b/src/StardewModdingAPI/StardewModdingAPI.csproj
@@ -33,7 +33,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>true</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
+ <OutputPath>$(SolutionDir)\..\bin\Debug\SMAPI</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
@@ -44,7 +44,7 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
+ <OutputPath>$(SolutionDir)\..\bin\Release\SMAPI</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
@@ -58,7 +58,8 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<UseVSHostingProcess>true</UseVSHostingProcess>
<Optimize>false</Optimize>
- <DocumentationFile>bin\Debug\StardewModdingAPI.XML</DocumentationFile>
+ <OutputPath>$(SolutionDir)\..\bin\Debug\SMAPI</OutputPath>
+ <DocumentationFile>bin\Debug\StardewModdingAPI.xml</DocumentationFile>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<LangVersion>6</LangVersion>
</PropertyGroup>
@@ -66,7 +67,8 @@
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\Release\</OutputPath>
<Prefer32Bit>false</Prefer32Bit>
- <DocumentationFile>bin\Release\StardewModdingAPI.XML</DocumentationFile>
+ <OutputPath>$(SolutionDir)\..\bin\Release\SMAPI</OutputPath>
+ <DocumentationFile>bin\Release\StardewModdingAPI.xml</DocumentationFile>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
@@ -148,7 +150,7 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
- <Reference Include="System.Numerics" Condition="$(OS) != 'Windows_NT'">
+ <Reference Include="System.Numerics">
<Private>True</Private>
</Reference>
<Reference Include="System.Windows.Forms" Condition="$(OS) == 'Windows_NT'" />
@@ -213,14 +215,16 @@
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
- <Content Include="StardewModdingAPI" Condition="$(OS) != 'Windows_NT'">
+ <None Include="unix-launcher.sh">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
- </Content>
+ </None>
</ItemGroup>
<ItemGroup>
<Content Include="FodyWeavers.xml" />
<Content Include="icon.ico" />
- <Content Include="steam_appid.txt" />
+ <Content Include="steam_appid.txt">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.5">
diff --git a/src/StardewModdingAPI/StardewModdingAPI b/src/StardewModdingAPI/unix-launcher.sh
index 0bfe0d5c..0bfe0d5c 100644
--- a/src/StardewModdingAPI/StardewModdingAPI
+++ b/src/StardewModdingAPI/unix-launcher.sh
diff --git a/src/TrainerMod/TrainerMod.csproj b/src/TrainerMod/TrainerMod.csproj
index e5002ba4..2bb92768 100644
--- a/src/TrainerMod/TrainerMod.csproj
+++ b/src/TrainerMod/TrainerMod.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
@@ -11,15 +11,12 @@
<AssemblyName>TrainerMod</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
- <TargetFrameworkProfile />
- <NuGetPackageImportStamp>
- </NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>true</Optimize>
- <OutputPath>..\StardewModdingAPI\bin\Debug\Mods\TrainerMod\</OutputPath>
+ <OutputPath>$(SolutionDir)\..\bin\Debug\Mods\TrainerMod\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
@@ -31,7 +28,7 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
- <OutputPath>..\StardewModdingAPI\bin\Release\Mods\TrainerMod\</OutputPath>
+ <OutputPath>$(SolutionDir)\..\bin\Release\Mods\TrainerMod\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>