add crossplatform installer (#155)

This commit is contained in:
Jesse Plamondon-Willard 2016-11-03 21:03:03 -04:00
parent 59c900a9ac
commit 0b5a05ba91
13 changed files with 544 additions and 48 deletions

View File

@ -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
```

View File

@ -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))

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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;
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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")]

View File

@ -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>

View File

@ -0,0 +1 @@
See instructions at http://canimod.com/guides/using-mods#installing-smapi.

View File

@ -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

View File

@ -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">

View File

@ -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>