Compare commits
2 Commits
develop
...
experiment
Author | SHA1 | Date |
---|---|---|
Jesse Plamondon-Willard | e16584527c | |
Jesse Plamondon-Willard | 90ca3d6ba1 |
|
@ -12,19 +12,12 @@ insert_final_newline = true
|
|||
trim_trailing_whitespace = true
|
||||
charset = utf-8
|
||||
|
||||
[*.{csproj,nuspec,targets}]
|
||||
[*.{csproj,json,nuspec,targets}]
|
||||
indent_size = 2
|
||||
|
||||
[*.csproj]
|
||||
charset = utf-8-bom
|
||||
insert_final_newline = false
|
||||
|
||||
[README.txt]
|
||||
end_of_line=crlf
|
||||
|
||||
[*.{command,sh}]
|
||||
end_of_line=lf
|
||||
|
||||
##########
|
||||
## C# formatting
|
||||
## documentation: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference
|
||||
|
@ -71,11 +64,4 @@ csharp_style_expression_bodied_accessors = true:suggestion
|
|||
csharp_style_inlined_variable_declaration = true:warning
|
||||
|
||||
# avoid superfluous braces
|
||||
csharp_prefer_braces = false:hint
|
||||
|
||||
##########
|
||||
## Column guidelines
|
||||
## documentation: https://marketplace.visualstudio.com/items?itemName=PaulHarrington.EditorGuidelines
|
||||
##########
|
||||
[*.md]
|
||||
guidelines = 100
|
||||
csharp_prefer_braces = false:suggestion
|
||||
|
|
|
@ -1,6 +1,2 @@
|
|||
# normalize line endings
|
||||
# normalise line endings
|
||||
* text=auto
|
||||
README.txt text eol=crlf
|
||||
|
||||
*.command text eol=lf
|
||||
*.sh text eol=lf
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
Do you want to...
|
||||
|
||||
* **Ask for help or report a bug?**
|
||||
Please see 'get help' on [the SMAPI website](https://smapi.io) instead, don't create a GitHub
|
||||
issue.
|
||||
* **Ask for help using SMAPI?**
|
||||
Please post a message in the [SMAPI support thread](http://community.playstarbound.com/threads/108375)
|
||||
or [ask on Discord](https://stardewvalleywiki.com/Modding:Community#Discord), don't create a
|
||||
GitHub issue.
|
||||
|
||||
* **Report a bug?**
|
||||
Please post a message in the [SMAPI support thread](http://community.playstarbound.com/threads/108375)
|
||||
or [ask on Discord](https://stardewvalleywiki.com/Modding:Community#Discord) instead, unless
|
||||
you're sure it's a bug in SMAPI itself.
|
||||
|
||||
* **Submit a pull request?**
|
||||
Pull requests are welcome! If you're submitting a new feature, it's best to discuss first to make
|
||||
sure it'll be accepted. Feel free to come chat [on Discord](https://smapi.io/community).
|
||||
sure it'll be accepted. Feel free to come chat in [#modding on Discord](https://stardewvalleywiki.com/Modding:Community#Discord)
|
||||
or post in the [SMAPI support thread](http://community.playstarbound.com/threads/108375).
|
||||
|
||||
Documenting your code and using the same formatting conventions is appreciated, but don't worry too
|
||||
much about it. We'll fix up the code after we accept the pull request if needed.
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
patreon: pathoschild
|
||||
ko_fi: pathoschild
|
||||
custom: https://www.paypal.me/pathoschild
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Report a problem with SMAPI.
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
|
||||
Only report a bug here if you're sure it's a SMAPI bug! To request support instead, see:
|
||||
- #modding on Discord: https://stardewvalleywiki.com/Modding:Community#Discord
|
||||
- support forum thread: https://community.playstarbound.com/threads/108375
|
||||
- Nexus mod page: https://www.nexusmods.com/stardewvalley/mods/2400
|
||||
|
||||
Replace the instructions below with the bug details.
|
||||
|
||||
-->
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is. Provide any other details you think might be relevant here.
|
||||
|
||||
**To Reproduce**
|
||||
Exact steps which reproduce the bug, if possible. For example:
|
||||
1. Load save '...'.
|
||||
2. Walk to '....'.
|
||||
3. Click '....'.
|
||||
4. Error occurs.
|
||||
|
||||
**Log file**
|
||||
Upload your SMAPI log to https://log.smapi.io and post a link here.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
|
@ -1,8 +0,0 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Troubleshooting guide for players
|
||||
url: https://smapi.io/troubleshoot
|
||||
about: See if your question is already answered first!
|
||||
- name: Get help or discuss
|
||||
url: https://smapi.io/help
|
||||
about: Ask for help from the community, or join the Stardew Valley Discord to ask questions, report issues, or discuss with the SMAPI developer, players, and mod authors. The SMAPI developer is @Pathoschild#0001 on Discord.
|
|
@ -1,37 +0,0 @@
|
|||
---
|
||||
name: Create a development task
|
||||
about: DON'T DO THIS BEFORE READING. This is for specific changes to the code or technical bug reports. See below if something isn't working, you have questions or ideas, or you want to discuss something.
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
|
||||
|
||||
|
||||
|
||||
STOP!
|
||||
|
||||
Is this a specific development task? Don't create an issue if not!
|
||||
See https://smapi.io/community if something isn't working, you have questions or ideas, or you want
|
||||
to discuss something.
|
||||
|
||||
If you're absolutely sure it's a specific development task (e.g. a specific bug, not just
|
||||
'something went wrong on my computer'), edit the template below.
|
||||
|
||||
-->
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is. Provide any other details you think might be relevant here.
|
||||
|
||||
**To Reproduce**
|
||||
Exact steps which reproduce the bug, if possible. For example:
|
||||
1. Load save '...'.
|
||||
2. Walk to '....'.
|
||||
3. Click '....'.
|
||||
4. Error occurs.
|
||||
|
||||
**Log file**
|
||||
Upload your SMAPI log to https://smapi.io/log and post a link here.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for SMAPI.
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
|
||||
GitHub issues are only used for development tasks. Please don't submit feature requests here! Instead, see...
|
||||
|
||||
- #modding on Discord: https://stardewvalleywiki.com/Modding:Community#Discord
|
||||
- support forum thread: https://community.playstarbound.com/threads/108375
|
||||
- Nexus page: https://www.nexusmods.com/stardewvalley/mods/2400
|
||||
|
||||
-->
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
name: General
|
||||
about: Create a ticket about something else.
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
|
||||
GitHub issues are only used for development tasks. For support and questions, see...
|
||||
|
||||
- #modding on Discord: https://stardewvalleywiki.com/Modding:Community#Discord
|
||||
- support forum thread: https://community.playstarbound.com/threads/108375
|
||||
- Nexus page: https://www.nexusmods.com/stardewvalley/mods/2400
|
||||
|
||||
-->
|
|
@ -1,3 +1,5 @@
|
|||
GitHub issues are only used for SMAPI development tasks.
|
||||
|
||||
To get help with SMAPI problems, see 'get help' on [the SMAPI website](https://smapi.io/) instead.
|
||||
To get help with SMAPI problems, you can...
|
||||
* [ask on Discord](https://stardewvalleywiki.com/Modding:Community#Discord);
|
||||
* or post in the [SMAPI support thread](https://community.playstarbound.com/threads/108375).
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
[Oo]bj/
|
||||
|
||||
# Visual Studio cache/options
|
||||
.config/
|
||||
.vs/
|
||||
|
||||
# ReSharper
|
||||
|
@ -19,9 +18,6 @@ _ReSharper*/
|
|||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# Rider
|
||||
.idea/
|
||||
|
||||
# NuGet packages
|
||||
*.nupkg
|
||||
**/packages/*
|
||||
|
@ -30,18 +26,3 @@ _ReSharper*/
|
|||
|
||||
# sensitive files
|
||||
appsettings.Development.json
|
||||
|
||||
# Azure generated files
|
||||
src/SMAPI.Web/Properties/PublishProfiles/*.pubxml
|
||||
src/SMAPI.Web/Properties/ServiceDependencies/* - Web Deploy/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# Loader Game Asserts
|
||||
src/Loader/Assets/Content/
|
||||
src/Loader/libs/
|
||||
|
||||
# VSHistory
|
||||
**/.vshistory/
|
||||
/build/StardewValleyAndroidStuff/
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyProduct("SMAPI")]
|
||||
[assembly: AssemblyVersion("2.8.2")]
|
||||
[assembly: AssemblyFileVersion("2.8.2")]
|
|
@ -1,78 +1,139 @@
|
|||
<!--
|
||||
|
||||
This MSBuild file sets the common configuration and build scripts used by all the projects in this
|
||||
repo. It imports the other MSBuild files as needed.
|
||||
|
||||
-->
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- load dev settings -->
|
||||
<Import Condition="$(OS) != 'Windows_NT' AND Exists('$(HOME)\stardewvalley.targets')" Project="$(HOME)\stardewvalley.targets" />
|
||||
<Import Condition="$(OS) == 'Windows_NT' AND Exists('$(USERPROFILE)\stardewvalley.targets')" Project="$(USERPROFILE)\stardewvalley.targets" />
|
||||
|
||||
<!-- find game path -->
|
||||
<PropertyGroup>
|
||||
<!--set general build properties -->
|
||||
<Version>3.18.4</Version>
|
||||
<Product>SMAPI</Product>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
|
||||
<DefineConstants Condition="$(OS) == 'Windows_NT' AND '$(BUILD_FOR_MOBILE)' == ''">$(DefineConstants);SMAPI_DEPRECATED;SMAPI_FOR_WINDOWS</DefineConstants>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<!-- Linux paths -->
|
||||
<GamePath Condition="!Exists('$(GamePath)')">$(HOME)/GOG Games/Stardew Valley/game</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">$(HOME)/.local/share/Steam/steamapps/common/Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">$(HOME)/.steam/steam/steamapps/common/Stardew Valley</GamePath>
|
||||
|
||||
<!--embed symbols for error stack trace line numbers on Linux/macOS: https://github.com/dotnet/runtime/issues/39987-->
|
||||
<DebugType>embedded</DebugType>
|
||||
<!-- Mac paths -->
|
||||
<GamePath Condition="!Exists('$(GamePath)')">/Applications/Stardew Valley.app/Contents/MacOS</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">$(HOME)/Library/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS</GamePath>
|
||||
|
||||
<!--enable nullable annotations, except in .NET Standard 2.0 where they aren't supported-->
|
||||
<Nullable Condition="'$(TargetFramework)' != 'netstandard2.0'">enable</Nullable>
|
||||
<NoWarn Condition="'$(TargetFramework)' == 'netstandard2.0'">$(NoWarn);CS8632</NoWarn>
|
||||
<!-- Windows paths -->
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files\GalaxyClient\Games\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files\GOG Galaxy\Games\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files\Steam\steamapps\common\Stardew Valley</GamePath>
|
||||
|
||||
<!--set platform-->
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files (x86)\GalaxyClient\Games\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files (x86)\GOG Galaxy\Games\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley</GamePath>
|
||||
|
||||
<GamePath Condition="!Exists('$(GamePath)') AND '$(OS)' == 'Windows_NT'">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\GOG.com\Games\1453375253', 'PATH', null, RegistryView.Registry32))</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)') AND '$(OS)' == 'Windows_NT'">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 413150', 'InstallLocation', null, RegistryView.Registry64, RegistryView.Registry32))</GamePath>
|
||||
|
||||
<!--compile constants -->
|
||||
<DefineConstants Condition="$(OS) == 'Windows_NT'">$(DefineConstants);SMAPI_FOR_WINDOWS</DefineConstants>
|
||||
<CopyToGameFolder>false</CopyToGameFolder>
|
||||
|
||||
<!-- allow mods to be compiled as AnyCPU for compatibility with older platforms -->
|
||||
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
|
||||
|
||||
<!--
|
||||
suppress warnings that don't apply, so it's easier to spot actual issues.
|
||||
|
||||
warning | builds | summary | rationale
|
||||
┄┄┄┄┄┄┄ | ┄┄┄┄┄┄┄┄┄┄ | ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ | ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
|
||||
CS0436 | all | local type conflicts with imported type | SMAPI needs to use certain low-level code during very early compatibility checks, before it's safe to load any other DLLs.
|
||||
CS0612 | deprecated | member is obsolete | internal references to deprecated code when deprecated code is enabled.
|
||||
CS0618 | deprecated | member is obsolete (with message) | internal references to deprecated code when deprecated code is enabled.
|
||||
CA1416 | all | platform code available on all platforms | Compiler doesn't recognize the #if constants used by SMAPI.
|
||||
CS0809 | all | obsolete overload for non-obsolete member | This is deliberate to signal to mods that certain APIs are only implemented for the game and shouldn't be called by mods.
|
||||
NU1701 | all | NuGet package targets older .NET version | All such packages are carefully tested to make sure they do work.
|
||||
-->
|
||||
<NoWarn Condition="$(DefineConstants.Contains(SMAPI_DEPRECATED))">$(NoWarn);CS0612;CS0618</NoWarn>
|
||||
<NoWarn>$(NoWarn);CS0436;CA1416;CS0809;NU1701</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="$(COMPILE_WITH_PLUGIN) == 'True'">
|
||||
<PackageReference Include="Microsoft.Net.Compilers" Version="3.3.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<!-- add common references -->
|
||||
<ItemGroup>
|
||||
<Reference Condition="'$(OS)' == 'Windows_NT' AND '$(MSBuildProjectName)' != 'StardewModdingAPI.Toolkit' AND '$(MSBuildProjectName)' != 'StardewModdingAPI.Toolkit.CoreInterfaces'" Include="System.Management" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--find game folder-->
|
||||
<Import Project="find-game-folder.targets" />
|
||||
<!-- <Target Name="ValidateInstallPath" AfterTargets="BeforeBuild">-->
|
||||
<!-- <!– if game path is invalid, show one user-friendly error instead of a slew of reference errors –>-->
|
||||
<!-- <Error Condition="!Exists('$(GamePath)')" Text="Failed to find the game install path automatically. You can specify where to find it; see https://smapi.io/package/custom-game-path." />-->
|
||||
<!-- </Target>-->
|
||||
<!-- add game references-->
|
||||
<Choose>
|
||||
<When Condition="'$(MSBuildProjectName)' == 'StardewModdingAPI' OR '$(MSBuildProjectName)' == 'StardewModdingAPI.Mods.ConsoleCommands' OR '$(MSBuildProjectName)' == 'StardewModdingAPI.Mods.SaveBackup' OR '$(MSBuildProjectName)' == 'StardewModdingAPI.Tests'">
|
||||
<!-- Windows -->
|
||||
<ItemGroup Condition="$(OS) == 'Windows_NT'">
|
||||
<Reference Include="Stardew Valley">
|
||||
<HintPath>$(GamePath)\Stardew Valley.exe</HintPath>
|
||||
<Private Condition="'$(MSBuildProjectName)' != 'StardewModdingAPI.Tests'">False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Netcode">
|
||||
<HintPath>$(GamePath)\Netcode.dll</HintPath>
|
||||
<Private Condition="'$(MSBuildProjectName)' != 'StardewModdingAPI.Tests'">False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Xna.Framework.Xact, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- common build settings -->
|
||||
<PropertyGroup>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<!--deploy local files-->
|
||||
<Import Project="deploy-local-smapi.targets" Condition="'$(CopyToGameFolder)' == 'true'" />
|
||||
<!-- Linux/Mac -->
|
||||
<ItemGroup Condition="$(OS) != 'Windows_NT'">
|
||||
<Reference Include="StardewValley">
|
||||
<HintPath>$(GamePath)\StardewValley.exe</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="MonoGame.Framework">
|
||||
<HintPath>$(GamePath)\MonoGame.Framework.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- launch SMAPI through Visual Studio -->
|
||||
<PropertyGroup Condition="'$(MSBuildProjectName)' == 'SMAPI'">
|
||||
<!-- common -->
|
||||
<ItemGroup>
|
||||
<Reference Include="GalaxyCSharp">
|
||||
<HintPath>$(GamePath)\GalaxyCSharp.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Lidgren.Network">
|
||||
<HintPath>$(GamePath)\Lidgren.Network.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="xTile">
|
||||
<HintPath>$(GamePath)\xTile.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
|
||||
<!-- if game path is invalid, show one user-friendly error instead of a slew of reference errors -->
|
||||
<Target Name="BeforeBuild">
|
||||
<Error Condition="!Exists('$(GamePath)')" Text="Failed to find the game install path automatically; edit the *.csproj file and manually add a <GamePath> setting with the full directory path containing the Stardew Valley executable." />
|
||||
</Target>
|
||||
|
||||
<!-- copy files into game directory and enable debugging (only in debug mode) -->
|
||||
<Target Name="AfterBuild">
|
||||
<CallTarget Targets="CopySMAPI;CopyDefaultMods" />
|
||||
</Target>
|
||||
<Target Name="CopySMAPI" Condition="'$(MSBuildProjectName)' == 'StardewModdingAPI'">
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFolder="$(GamePath)" />
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).pdb" DestinationFolder="$(GamePath)" />
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).xml" 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)\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)" />
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).pdb" DestinationFolder="$(GamePath)\Mods\$(AssemblyName)" Condition="Exists('$(TargetDir)\$(TargetName).pdb')" />
|
||||
<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)\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)\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 -->
|
||||
<PropertyGroup Condition="$(Configuration) == 'Debug'">
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>$(GamePath)\StardewModdingAPI.exe</StartProgram>
|
||||
<StartWorkingDirectory>$(GamePath)</StartWorkingDirectory>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Somehow this makes Visual Studio for macOS recognise the previous section. Nobody knows why. -->
|
||||
<!-- Somehow this makes Visual Studio for Mac recognise the previous section. Nobody knows why. -->
|
||||
<PropertyGroup Condition="'$(RunConfiguration)' == 'Default'" />
|
||||
</Project>
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!--set properties -->
|
||||
<PropertyGroup>
|
||||
<!-- <BUILD_FOR_MOBILE></BUILD_FOR_MOBILE>-->
|
||||
<BUILD_FOR_MOBILE>GOOGLE</BUILD_FOR_MOBILE>
|
||||
<!-- <BUILD_FOR_MOBILE>GOOGLE_145</BUILD_FOR_MOBILE>-->
|
||||
<!-- <BUILD_FOR_MOBILE>AMAZON</BUILD_FOR_MOBILE>-->
|
||||
<!-- <BUILD_FOR_MOBILE>SAMSUNG</BUILD_FOR_MOBILE>-->
|
||||
<!-- <BUILD_FOR_MOBILE>GOOGLE_LEGACY</BUILD_FOR_MOBILE>-->
|
||||
<COMPILE_WITH_PLUGIN>False</COMPILE_WITH_PLUGIN>
|
||||
<DefineConstants Condition="'$(BUILD_FOR_MOBILE)' == 'GOOGLE'">SMAPI_DEPRECATED;SMAPI_FOR_MOBILE;ANDROID_TARGET_GOOGLE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1,77 +0,0 @@
|
|||
<!--
|
||||
|
||||
This MSBuild file copies SMAPI and the bundled mods into the local Stardew Valley folder on build
|
||||
to simplify testing. This just avoids needing to run the SMAPI installer each time.
|
||||
|
||||
This assumes `find-game-folder.targets` has already been imported and validated.
|
||||
|
||||
-->
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Target Name="CopySmapiFiles" AfterTargets="AfterBuild">
|
||||
<CallTarget Targets="CopySMAPI;CopyDefaultMods" />
|
||||
</Target>
|
||||
<Target Name="CopySMAPI" Condition="'$(MSBuildProjectName)' == 'SMAPI'">
|
||||
<!-- SMAPI -->
|
||||
<ItemGroup>
|
||||
<TranslationFiles Include="$(TargetDir)\i18n\*.json" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).dll" DestinationFolder="$(GamePath)" />
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFolder="$(GamePath)" Condition="$(OS) == 'Windows_NT'" />
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName)" DestinationFolder="$(GamePath)" Condition="$(OS) != 'Windows_NT'" />
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).xml" DestinationFolder="$(GamePath)" />
|
||||
<Copy SourceFiles="$(TargetDir)\SMAPI.config.json" DestinationFiles="$(GamePath)\smapi-internal\config.json" />
|
||||
<Copy SourceFiles="$(TargetDir)\SMAPI.metadata.json" DestinationFiles="$(GamePath)\smapi-internal\metadata.json" />
|
||||
<Copy SourceFiles="$(TargetDir)\Newtonsoft.Json.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="$(TargetDir)\TMXTile.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="$(TargetDir)\Pintail.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="@(TranslationFiles)" DestinationFolder="$(GamePath)\smapi-internal\i18n" />
|
||||
|
||||
<!-- Harmony + dependencies -->
|
||||
<Copy SourceFiles="$(TargetDir)\0Harmony.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="$(TargetDir)\0Harmony.xml" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="$(TargetDir)\Mono.Cecil.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="$(TargetDir)\Mono.Cecil.Mdb.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="$(TargetDir)\Mono.Cecil.Pdb.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="$(TargetDir)\MonoMod.Common.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
|
||||
<!-- FluentHttpClient + dependencies -->
|
||||
<Copy SourceFiles="$(TargetDir)\Pathoschild.Http.Client.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="$(TargetDir)\System.Net.Http.Formatting.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
|
||||
<!-- .NET dependencies -->
|
||||
<Copy SourceFiles="$(TargetDir)\System.Management.dll" DestinationFolder="$(GamePath)\smapi-internal" Condition="$(OS) == 'Windows_NT'" />
|
||||
|
||||
<!-- Legacy .NET dependencies (remove in SMAPI 4.0.0) -->
|
||||
<Copy SourceFiles="$(TargetDir)\System.Configuration.ConfigurationManager.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="$(TargetDir)\System.Runtime.Caching.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="$(TargetDir)\System.Security.Permissions.dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
</Target>
|
||||
|
||||
<!-- .NET metadata files -->
|
||||
<Target Name="CopyNetMetadata" Condition="'$(MSBuildProjectName)' == 'SMAPI.Installer'" AfterTargets="PostBuildEvent">
|
||||
<Copy SourceFiles="$(TargetDir)\assets\runtimeconfig.json" DestinationFiles="$(GamePath)\StardewModdingAPI.runtimeconfig.json" />
|
||||
<Copy SourceFiles="$(TargetDir)\assets\windows-exe-config.xml" DestinationFiles="$(GamePath)\StardewModdingAPI.exe.config" Condition="$(OS) == 'Windows_NT'" />
|
||||
<Copy SourceFiles="$(GamePath)\Stardew Valley.deps.json" DestinationFiles="$(GamePath)\StardewModdingAPI.deps.json" Condition="!Exists('$(GamePath)\StardewModdingAPI.deps.json')" />
|
||||
</Target>
|
||||
|
||||
<!-- bundled mods -->
|
||||
<Target Name="CopyDefaultMods" Condition="'$(MSBuildProjectName)' == 'SMAPI.Mods.ConsoleCommands' OR '$(MSBuildProjectName)' == 'SMAPI.Mods.ErrorHandler' OR '$(MSBuildProjectName)' == 'SMAPI.Mods.SaveBackup'">
|
||||
<ItemGroup>
|
||||
<TranslationFiles Include="$(TargetDir)\i18n\*.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).dll" DestinationFolder="$(GamePath)\Mods\$(AssemblyName)" />
|
||||
<Copy SourceFiles="$(TargetDir)\manifest.json" DestinationFolder="$(GamePath)\Mods\$(AssemblyName)" />
|
||||
<Copy SourceFiles="@(TranslationFiles)" DestinationFolder="$(GamePath)\Mods\$(AssemblyName)\i18n" />
|
||||
</Target>
|
||||
|
||||
<!-- toolkit -->
|
||||
<Target Name="CopyToolkit" Condition="'$(MSBuildProjectName)' == 'SMAPI.Toolkit'" AfterTargets="PostBuildEvent">
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).xml" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
</Target>
|
||||
<Target Name="CopyToolkitCoreInterfaces" Condition="'$(MSBuildProjectName)' == 'SMAPI.Toolkit.CoreInterfaces'" AfterTargets="PostBuildEvent">
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).dll" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).xml" DestinationFolder="$(GamePath)\smapi-internal" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,66 +0,0 @@
|
|||
<!--
|
||||
|
||||
This MSBuild file detects the Stardew Valley install path if possible, and sets the 'GamePath'
|
||||
property.
|
||||
|
||||
-->
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- import developer's custom path (if any) -->
|
||||
<Import Condition="$(OS) != 'Windows_NT' AND Exists('$(HOME)\stardewvalley.targets')" Project="$(HOME)\stardewvalley.targets" />
|
||||
<Import Condition="$(OS) == 'Windows_NT' AND Exists('$(USERPROFILE)\stardewvalley.targets')" Project="$(USERPROFILE)\stardewvalley.targets" />
|
||||
|
||||
<!-- find game path -->
|
||||
<Choose>
|
||||
<When Condition="$(OS) == 'Unix' OR $(OS) == 'OSX'">
|
||||
<PropertyGroup>
|
||||
<!-- Linux -->
|
||||
<GamePath Condition="!Exists('$(GamePath)')">$(HOME)/GOG Games/Stardew Valley/game</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">$(HOME)/.steam/steam/steamapps/common/Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">$(HOME)/.local/share/Steam/steamapps/common/Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">$(HOME)/.var/app/com.valvesoftware.Steam/data/Steam/steamapps/common/Stardew Valley</GamePath>
|
||||
|
||||
<!-- macOS (may be 'Unix' or 'OSX') -->
|
||||
<GamePath Condition="!Exists('$(GamePath)')">/Applications/Stardew Valley.app/Contents/MacOS</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">$(HOME)/Library/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS</GamePath>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
<When Condition="$(OS) == 'Windows_NT'">
|
||||
<PropertyGroup>
|
||||
<!-- registry paths -->
|
||||
<GamePath Condition="!Exists('$(GamePath)')">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\GOG.com\Games\1453375253', 'PATH', null, RegistryView.Registry32))</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 413150', 'InstallLocation', null, RegistryView.Registry64, RegistryView.Registry32))</GamePath>
|
||||
|
||||
<!-- derive from Steam library path -->
|
||||
<_SteamLibraryPath>$([MSBuild]::GetRegistryValueFromView('HKEY_CURRENT_USER\SOFTWARE\Valve\Steam', 'SteamPath', null, RegistryView.Registry32))</_SteamLibraryPath>
|
||||
<GamePath Condition="!Exists('$(GamePath)') AND '$(_SteamLibraryPath)' != ''">$(_SteamLibraryPath)\steamapps\common\Stardew Valley</GamePath>
|
||||
|
||||
<!-- GOG paths -->
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files\GalaxyClient\Games\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files\GOG Galaxy\Games\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files\GOG Games\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files (x86)\GalaxyClient\Games\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files (x86)\GOG Galaxy\Games\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files (x86)\GOG Games\Stardew Valley</GamePath>
|
||||
|
||||
<!-- Xbox app paths -->
|
||||
<!--
|
||||
The Xbox app saves the install path to the registry, but we can't use it here since it
|
||||
saves the internal readonly path (like C:\Program Files\WindowsApps\Mutable\<package ID>)
|
||||
instead of the mods-enabled path (like C:\Program Files\ModifiableWindowsApps\Stardew Valley).
|
||||
Fortunately we can cheat a bit: players can customize the install drive, but they can't
|
||||
change the install path on the drive.
|
||||
-->
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files\ModifiableWindowsApps\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">D:\Program Files\ModifiableWindowsApps\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">E:\Program Files\ModifiableWindowsApps\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">F:\Program Files\ModifiableWindowsApps\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">G:\Program Files\ModifiableWindowsApps\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">H:\Program Files\ModifiableWindowsApps\Stardew Valley</GamePath>
|
||||
|
||||
<!-- Steam paths -->
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files\Steam\steamapps\common\Stardew Valley</GamePath>
|
||||
<GamePath Condition="!Exists('$(GamePath)')">C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley</GamePath>
|
||||
</PropertyGroup>
|
||||
</When>
|
||||
</Choose>
|
||||
</Project>
|
|
@ -0,0 +1,127 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!--
|
||||
|
||||
This build task is run from the installer project after all projects have been compiled, and
|
||||
creates the build package in the bin\Packages folder.
|
||||
|
||||
-->
|
||||
<Target Name="AfterBuild">
|
||||
<PropertyGroup>
|
||||
<RootPath>$(SolutionDir)\..</RootPath>
|
||||
<CompiledRootPath>$(RootPath)\bin\$(Configuration)</CompiledRootPath>
|
||||
<CompiledSmapiPath>$(CompiledRootPath)\SMAPI</CompiledSmapiPath>
|
||||
<CompiledToolkitPath>$(CompiledRootPath)\SMAPI.Toolkit\net4.5</CompiledToolkitPath>
|
||||
<PackagePath>$(SolutionDir)\..\bin\SMAPI installer</PackagePath>
|
||||
<PackageDevPath>$(SolutionDir)\..\bin\SMAPI installer for developers</PackageDevPath>
|
||||
<PlatformName>windows</PlatformName>
|
||||
<PlatformName Condition="$(OS) != 'Windows_NT'">unix</PlatformName>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<CompiledMods Include="$(SolutionDir)\..\bin\$(Configuration)\Mods\**\*.*" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- reset package directory -->
|
||||
<RemoveDir Directories="$(PackagePath)" />
|
||||
<RemoveDir Directories="$(PackageDevPath)" />
|
||||
|
||||
<!-- copy installer files -->
|
||||
<Copy SourceFiles="$(TargetDir)\unix-install.sh" DestinationFiles="$(PackagePath)\install on Linux.sh" />
|
||||
<Copy SourceFiles="$(TargetDir)\unix-install.sh" DestinationFiles="$(PackagePath)\install on Mac.command" />
|
||||
<Copy SourceFiles="$(TargetDir)\windows-install.bat" DestinationFiles="$(PackagePath)\install on Windows.bat" />
|
||||
<Copy SourceFiles="$(TargetDir)\README.txt" DestinationFiles="$(PackagePath)\README.txt" />
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).exe" DestinationFiles="$(PackagePath)\internal\$(PlatformName)-install.exe" />
|
||||
<Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(TargetDir)\windows-exe-config.xml" DestinationFiles="$(PackagePath)\internal\$(PlatformName)-install.exe.config" />
|
||||
|
||||
<!--copy bundle files-->
|
||||
<Copy SourceFiles="$(TargetDir)\unix-launcher.sh" DestinationFiles="$(PackagePath)\bundle\StardewModdingAPI" />
|
||||
<Copy SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.exe" DestinationFolder="$(PackagePath)\bundle" />
|
||||
<Copy SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.pdb" DestinationFolder="$(PackagePath)\bundle" />
|
||||
<Copy SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.xml" DestinationFolder="$(PackagePath)\bundle" />
|
||||
<Copy SourceFiles="$(CompiledSmapiPath)\steam_appid.txt" DestinationFolder="$(PackagePath)\bundle" />
|
||||
<Copy SourceFiles="$(CompiledSmapiPath)\0Harmony.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(CompiledSmapiPath)\Mono.Cecil.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(CompiledSmapiPath)\Newtonsoft.Json.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.config.json" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(CompiledSmapiPath)\StardewModdingAPI.metadata.json" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.pdb" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.xml" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.pdb" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(CompiledToolkitPath)\StardewModdingAPI.Toolkit.CoreInterfaces.xml" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="@(CompiledMods)" DestinationFolder="$(PackagePath)\bundle\Mods\%(RecursiveDir)" />
|
||||
<Copy Condition="$(OS) == 'Windows_NT'" SourceFiles="$(TargetDir)\windows-exe-config.xml" DestinationFiles="$(PackagePath)\bundle\StardewModdingAPI.exe.config" />
|
||||
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Numerics.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(CompiledSmapiPath)\System.Runtime.Caching.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
|
||||
<!-- fix errors on Linux/Mac (sample: https://log.smapi.io/mMdFUpgB) -->
|
||||
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(RootPath)\build\lib\System.Numerics.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy Condition="$(OS) != 'Windows_NT'" SourceFiles="$(RootPath)\build\lib\System.Runtime.Caching.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
|
||||
<!-- fix Linux/Mac permissions -->
|
||||
<Exec Condition="$(OS) != 'Windows_NT'" Command="chmod 755 "$(PackagePath)\install on Linux.sh"" />
|
||||
<Exec Condition="$(OS) != 'Windows_NT'" Command="chmod 755 "$(PackagePath)\install on Mac.command"" />
|
||||
|
||||
<!-- finalise 'for developers' installer -->
|
||||
<ItemGroup>
|
||||
<PackageFiles Include="$(PackagePath)\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(PackageFiles)" DestinationFolder="$(PackageDevPath)\%(RecursiveDir)" />
|
||||
<ZipDirectory FromDirPath="$(PackageDevPath)\bundle" ToFilePath="$(PackageDevPath)\internal\$(PlatformName)-install.dat" />
|
||||
<RemoveDir Directories="$(PackageDevPath)\bundle" />
|
||||
|
||||
<!-- finalise normal installer -->
|
||||
<ReplaceFileText FilePath="$(PackagePath)\bundle\smapi-internal\StardewModdingAPI.config.json" Search=""DeveloperMode": true" Replace=""DeveloperMode": false" />
|
||||
<ZipDirectory FromDirPath="$(PackagePath)\bundle" ToFilePath="$(PackagePath)\internal\$(PlatformName)-install.dat" />
|
||||
<RemoveDir Directories="$(PackagePath)\bundle" />
|
||||
</Target>
|
||||
|
||||
<!-- Create a zip file with the contents of a given folder path. Derived from https://stackoverflow.com/a/38127938/262123. -->
|
||||
<UsingTask TaskName="ZipDirectory" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
|
||||
<ParameterGroup>
|
||||
<FromDirPath ParameterType="System.String" Required="true" />
|
||||
<ToFilePath ParameterType="System.String" Required="true" />
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<Reference Include="System.IO.Compression.FileSystem" />
|
||||
<Using Namespace="System.IO.Compression" />
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
try
|
||||
{
|
||||
ZipFile.CreateFromDirectory(FromDirPath, ToFilePath);
|
||||
return true;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Log.LogErrorFromException(ex);
|
||||
return false;
|
||||
}
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
|
||||
<!-- Replace text in a file based on a regex pattern. Derived from https://stackoverflow.com/a/22571621/262123. -->
|
||||
<UsingTask TaskName="ReplaceFileText" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
||||
<ParameterGroup>
|
||||
<FilePath ParameterType="System.String" Required="true" />
|
||||
<Search ParameterType="System.String" Required="true" />
|
||||
<Replace ParameterType="System.String" Required="true" />
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<Reference Include="System.Core" />
|
||||
<Using Namespace="System" />
|
||||
<Using Namespace="System.IO" />
|
||||
<Using Namespace="System.Text.RegularExpressions" />
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
File.WriteAllText(
|
||||
FilePath,
|
||||
Regex.Replace(File.ReadAllText(FilePath), Search, Replace)
|
||||
);
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
</Project>
|
|
@ -0,0 +1,23 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!--
|
||||
|
||||
This build task is run from the ModBuildConfig project after it's been compiled, and copies the
|
||||
package files to the bin\Pathoschild.Stardew.ModBuildConfig folder.
|
||||
|
||||
-->
|
||||
<Target Name="AfterBuild">
|
||||
<PropertyGroup>
|
||||
<PackagePath>$(SolutionDir)\..\bin\Pathoschild.Stardew.ModBuildConfig</PackagePath>
|
||||
</PropertyGroup>
|
||||
<RemoveDir Directories="$(PackagePath)" />
|
||||
<Copy SourceFiles="$(ProjectDir)/package.nuspec" DestinationFolder="$(PackagePath)" />
|
||||
<Copy SourceFiles="$(ProjectDir)/build/smapi.targets" DestinationFiles="$(PackagePath)/build/Pathoschild.Stardew.ModBuildConfig.targets" />
|
||||
<Copy SourceFiles="$(TargetDir)/Newtonsoft.Json.dll" DestinationFolder="$(PackagePath)/build" />
|
||||
<Copy SourceFiles="$(TargetDir)/StardewModdingAPI.ModBuildConfig.dll" DestinationFolder="$(PackagePath)/build" />
|
||||
<Copy SourceFiles="$(TargetDir)/StardewModdingAPI.Toolkit.dll" DestinationFolder="$(PackagePath)/build" />
|
||||
<Copy SourceFiles="$(TargetDir)/StardewModdingAPI.Toolkit.CoreInterfaces.dll" DestinationFolder="$(PackagePath)/build" />
|
||||
<Copy SourceFiles="$(SolutionDir)/SMAPI.ModBuildConfig.Analyzer/bin/netstandard1.3/StardewModdingAPI.ModBuildConfig.Analyzer.dll" DestinationFolder="$(PackagePath)/analyzers/dotnet/cs" />
|
||||
<Copy SourceFiles="$(SolutionDir)/SMAPI.ModBuildConfig.Analyzer/tools/install.ps1" DestinationFolder="$(PackagePath)/tools" />
|
||||
<Copy SourceFiles="$(SolutionDir)/SMAPI.ModBuildConfig.Analyzer/tools/uninstall.ps1" DestinationFolder="$(PackagePath)/tools" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,212 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
#
|
||||
# This is the Bash equivalent of ../windows/prepare-install-package.ps1.
|
||||
# When making changes, both scripts should be updated.
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
##########
|
||||
## Fetch values
|
||||
##########
|
||||
# paths
|
||||
gamePath="/home/pathoschild/Stardew Valley"
|
||||
bundleModNames=("ConsoleCommands" "ErrorHandler" "SaveBackup")
|
||||
|
||||
# build configuration
|
||||
buildConfig="Release"
|
||||
folders=("linux" "macOS" "windows")
|
||||
declare -A runtimes=(["linux"]="linux-x64" ["macOS"]="osx-x64" ["windows"]="win-x64")
|
||||
declare -A msBuildPlatformNames=(["linux"]="Unix" ["macOS"]="OSX" ["windows"]="Windows_NT")
|
||||
|
||||
# version number
|
||||
version="$1"
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "SMAPI release version (like '4.0.0'):"
|
||||
read version
|
||||
fi
|
||||
|
||||
|
||||
##########
|
||||
## Move to SMAPI root
|
||||
##########
|
||||
cd "`dirname "$0"`/../.."
|
||||
|
||||
|
||||
##########
|
||||
## Clear old build files
|
||||
##########
|
||||
echo "Clearing old builds..."
|
||||
echo "-------------------------------------------------"
|
||||
for path in bin */**/bin */**/obj; do
|
||||
echo "$path"
|
||||
rm -rf $path
|
||||
done
|
||||
echo ""
|
||||
|
||||
##########
|
||||
## Compile files
|
||||
##########
|
||||
. ${0%/*}/set-smapi-version.sh "$version"
|
||||
for folder in ${folders[@]}; do
|
||||
runtime=${runtimes[$folder]}
|
||||
msbuildPlatformName=${msBuildPlatformNames[$folder]}
|
||||
|
||||
echo "Compiling SMAPI for $folder..."
|
||||
echo "-------------------------------------------------"
|
||||
dotnet publish src/SMAPI --configuration $buildConfig -v minimal --runtime "$runtime" -p:OS="$msbuildPlatformName" -p:GamePath="$gamePath" -p:CopyToGameFolder="false" --self-contained true
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
echo "Compiling installer for $folder..."
|
||||
echo "-------------------------------------------------"
|
||||
dotnet publish src/SMAPI.Installer --configuration $buildConfig -v minimal --runtime "$runtime" -p:OS="$msbuildPlatformName" -p:GamePath="$gamePath" -p:CopyToGameFolder="false" -p:PublishTrimmed=True -p:TrimMode=Link --self-contained true
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
for modName in ${bundleModNames[@]}; do
|
||||
echo "Compiling $modName for $folder..."
|
||||
echo "-------------------------------------------------"
|
||||
dotnet publish src/SMAPI.Mods.$modName --configuration $buildConfig -v minimal --runtime "$runtime" -p:OS="$msbuildPlatformName" -p:GamePath="$gamePath" -p:CopyToGameFolder="false"
|
||||
echo ""
|
||||
echo ""
|
||||
done
|
||||
done
|
||||
|
||||
|
||||
##########
|
||||
## Prepare install package
|
||||
##########
|
||||
echo "Preparing install package..."
|
||||
echo "-------------------------------------------------"
|
||||
|
||||
# init paths
|
||||
installAssets="src/SMAPI.Installer/assets"
|
||||
packagePath="bin/SMAPI installer"
|
||||
packageDevPath="bin/SMAPI installer for developers"
|
||||
|
||||
# init structure
|
||||
for folder in ${folders[@]}; do
|
||||
mkdir "$packagePath/internal/$folder/bundle/smapi-internal" --parents
|
||||
done
|
||||
|
||||
# copy base installer files
|
||||
for name in "install on Linux.sh" "install on macOS.command" "install on Windows.bat" "README.txt"; do
|
||||
cp "$installAssets/$name" "$packagePath"
|
||||
done
|
||||
|
||||
# copy per-platform files
|
||||
for folder in ${folders[@]}; do
|
||||
runtime=${runtimes[$folder]}
|
||||
|
||||
# get paths
|
||||
smapiBin="src/SMAPI/bin/$buildConfig/$runtime/publish"
|
||||
internalPath="$packagePath/internal/$folder"
|
||||
bundlePath="$internalPath/bundle"
|
||||
|
||||
# installer files
|
||||
cp -r "src/SMAPI.Installer/bin/$buildConfig/$runtime/publish"/* "$internalPath"
|
||||
rm -rf "$internalPath/assets"
|
||||
|
||||
# runtime config for SMAPI
|
||||
# This is identical to the one generated by the build, except that the min runtime version is
|
||||
# set to 5.0.0 (instead of whatever version it was built with) and rollForward is set to latestMinor instead of
|
||||
# minor.
|
||||
cp "$installAssets/runtimeconfig.json" "$bundlePath/StardewModdingAPI.runtimeconfig.json"
|
||||
|
||||
# installer DLL config
|
||||
if [ $folder == "windows" ]; then
|
||||
cp "$installAssets/windows-exe-config.xml" "$packagePath/internal/windows/install.exe.config"
|
||||
fi
|
||||
|
||||
# bundle root files
|
||||
for name in "StardewModdingAPI" "StardewModdingAPI.dll" "StardewModdingAPI.xml" "steam_appid.txt"; do
|
||||
if [ $name == "StardewModdingAPI" ] && [ $folder == "windows" ]; then
|
||||
name="$name.exe"
|
||||
fi
|
||||
|
||||
cp "$smapiBin/$name" "$bundlePath"
|
||||
done
|
||||
|
||||
# bundle i18n
|
||||
cp -r "$smapiBin/i18n" "$bundlePath/smapi-internal"
|
||||
|
||||
# bundle smapi-internal
|
||||
for name in "0Harmony.dll" "0Harmony.xml" "Mono.Cecil.dll" "Mono.Cecil.Mdb.dll" "Mono.Cecil.Pdb.dll" "MonoMod.Common.dll" "Newtonsoft.Json.dll" "Pathoschild.Http.Client.dll" "Pintail.dll" "TMXTile.dll" "SMAPI.Toolkit.dll" "SMAPI.Toolkit.xml" "SMAPI.Toolkit.CoreInterfaces.dll" "SMAPI.Toolkit.CoreInterfaces.xml" "System.Net.Http.Formatting.dll"; do
|
||||
cp "$smapiBin/$name" "$bundlePath/smapi-internal"
|
||||
done
|
||||
|
||||
cp "$smapiBin/SMAPI.config.json" "$bundlePath/smapi-internal/config.json"
|
||||
cp "$smapiBin/SMAPI.metadata.json" "$bundlePath/smapi-internal/metadata.json"
|
||||
if [ $folder == "linux" ] || [ $folder == "macOS" ]; then
|
||||
cp "$installAssets/unix-launcher.sh" "$bundlePath"
|
||||
else
|
||||
cp "$installAssets/windows-exe-config.xml" "$bundlePath/StardewModdingAPI.exe.config"
|
||||
fi
|
||||
|
||||
# copy .NET dependencies
|
||||
if [ $folder == "windows" ]; then
|
||||
cp "$smapiBin/System.Management.dll" "$bundlePath/smapi-internal"
|
||||
fi
|
||||
|
||||
# copy legacy .NET dependencies (remove in SMAPI 4.0.0)
|
||||
cp "$smapiBin/System.Configuration.ConfigurationManager.dll" "$bundlePath/smapi-internal"
|
||||
cp "$smapiBin/System.Runtime.Caching.dll" "$bundlePath/smapi-internal"
|
||||
cp "$smapiBin/System.Security.Permissions.dll" "$bundlePath/smapi-internal"
|
||||
|
||||
# copy bundled mods
|
||||
for modName in ${bundleModNames[@]}; do
|
||||
fromPath="src/SMAPI.Mods.$modName/bin/$buildConfig/$runtime/publish"
|
||||
targetPath="$bundlePath/Mods/$modName"
|
||||
|
||||
mkdir "$targetPath" --parents
|
||||
|
||||
cp "$fromPath/$modName.dll" "$targetPath"
|
||||
cp "$fromPath/manifest.json" "$targetPath"
|
||||
if [ -d "$fromPath/i18n" ]; then
|
||||
cp -r "$fromPath/i18n" "$targetPath"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# mark scripts executable
|
||||
for path in "install on Linux.sh" "install on macOS.command" "bundle/unix-launcher.sh"; do
|
||||
if [ -f "$packagePath/$path" ]; then
|
||||
chmod 755 "$packagePath/$path"
|
||||
fi
|
||||
done
|
||||
|
||||
# split into main + for-dev folders
|
||||
cp -r "$packagePath" "$packageDevPath"
|
||||
for folder in ${folders[@]}; do
|
||||
# disable developer mode in main package
|
||||
sed --in-place --expression="s/\"DeveloperMode\": true/\"DeveloperMode\": false/" "$packagePath/internal/$folder/bundle/smapi-internal/config.json"
|
||||
|
||||
# convert bundle folder into final 'install.dat' files
|
||||
for path in "$packagePath/internal/$folder" "$packageDevPath/internal/$folder"; do
|
||||
pushd "$path/bundle" > /dev/null
|
||||
zip "install.dat" * --recurse-paths --quiet
|
||||
popd > /dev/null
|
||||
mv "$path/bundle/install.dat" "$path/install.dat"
|
||||
rm -rf "$path/bundle"
|
||||
done
|
||||
done
|
||||
|
||||
|
||||
##########
|
||||
## Create release zips
|
||||
##########
|
||||
# rename folders
|
||||
mv "$packagePath" "bin/SMAPI $version installer"
|
||||
mv "$packageDevPath" "bin/SMAPI $version installer for developers"
|
||||
|
||||
# package files
|
||||
pushd bin > /dev/null
|
||||
zip -9 "SMAPI $version installer.zip" "SMAPI $version installer" --recurse-paths --quiet
|
||||
zip -9 "SMAPI $version installer for developers.zip" "SMAPI $version installer for developers" --recurse-paths --quiet
|
||||
popd > /dev/null
|
||||
|
||||
echo ""
|
||||
echo "Done! Package created in $(pwd)/bin"
|
|
@ -1,26 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
#
|
||||
# This is the Bash equivalent of ../windows/set-smapi-version.ps1.
|
||||
# When making changes, both scripts should be updated.
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
# get version number
|
||||
version="$1"
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "SMAPI release version (like '4.0.0'):"
|
||||
read version
|
||||
fi
|
||||
|
||||
# move to SMAPI root
|
||||
cd "`dirname "$0"`/../.."
|
||||
|
||||
# apply changes
|
||||
sed "s/<Version>.+<\/Version>/<Version>$version<\/Version>/" "build/common.targets" --in-place --regexp-extended
|
||||
sed "s/RawApiVersion = \".+?\";/RawApiVersion = \"$version\";/" "src/SMAPI/Constants.cs" --in-place --regexp-extended
|
||||
for modName in "ConsoleCommands" "ErrorHandler" "SaveBackup"; do
|
||||
sed "s/\"(Version|MinimumApiVersion)\": \".+?\"/\"\1\": \"$version\"/g" "src/SMAPI.Mods.$modName/manifest.json" --in-place --regexp-extended
|
||||
done
|
|
@ -1,67 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
##########
|
||||
## Read config
|
||||
##########
|
||||
# get SMAPI version
|
||||
version="$1"
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "SMAPI release version (like '4.0.0'):"
|
||||
read version
|
||||
fi
|
||||
|
||||
# get Windows bin path
|
||||
windowsBinPath="$2"
|
||||
if [ $# -le 1 ]; then
|
||||
echo "Windows compiled bin path:"
|
||||
read windowsBinPath
|
||||
fi
|
||||
|
||||
# installer internal folders
|
||||
buildFolders=("linux" "macOS" "windows")
|
||||
|
||||
|
||||
##########
|
||||
## Finalize release package
|
||||
##########
|
||||
for folderName in "SMAPI $version installer" "SMAPI $version installer for developers"; do
|
||||
# move files to Linux filesystem
|
||||
echo "Preparing $folderName.zip..."
|
||||
echo "-------------------------------------------------"
|
||||
echo "copying '$windowsBinPath/$folderName' to Linux filesystem..."
|
||||
cp -r "$windowsBinPath/$folderName" .
|
||||
|
||||
# fix permissions
|
||||
echo "fixing permissions..."
|
||||
find "$folderName" -type d -exec chmod 755 {} \;
|
||||
find "$folderName" -type f -exec chmod 644 {} \;
|
||||
find "$folderName" -name "*.sh" -exec chmod 755 {} \;
|
||||
find "$folderName" -name "*.command" -exec chmod 755 {} \;
|
||||
find "$folderName" -name "SMAPI.Installer" -exec chmod 755 {} \;
|
||||
find "$folderName" -name "StardewModdingAPI" -exec chmod 755 {} \;
|
||||
|
||||
# convert bundle folder into final 'install.dat' files
|
||||
for build in ${buildFolders[@]}; do
|
||||
echo "packaging $folderName/internal/$build/install.dat..."
|
||||
pushd "$folderName/internal/$build/bundle" > /dev/null
|
||||
zip "install.dat" * --recurse-paths --quiet
|
||||
mv install.dat ../
|
||||
popd > /dev/null
|
||||
|
||||
rm -rf "$folderName/internal/$build/bundle"
|
||||
done
|
||||
|
||||
# zip installer
|
||||
echo "packaging installer..."
|
||||
zip -9 "$folderName.zip" "$folderName" --recurse-paths --quiet
|
||||
|
||||
# move zip back to Windows bin path
|
||||
echo "moving release zip to $windowsBinPath/$folderName.zip..."
|
||||
mv "$folderName.zip" "$windowsBinPath"
|
||||
rm -rf "$folderName"
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "Done!"
|
|
@ -1,11 +0,0 @@
|
|||
function In-Place-Regex {
|
||||
param (
|
||||
[Parameter(Mandatory)][string]$Path,
|
||||
[Parameter(Mandatory)][string]$Search,
|
||||
[Parameter(Mandatory)][string]$Replace
|
||||
)
|
||||
|
||||
$content = (Get-Content "$Path" -Encoding UTF8)
|
||||
$content = ($content -replace "$Search", "$Replace")
|
||||
[System.IO.File]::WriteAllLines((Get-Item "$Path").FullName, $content)
|
||||
}
|
|
@ -1,241 +0,0 @@
|
|||
#
|
||||
#
|
||||
# This is the PowerShell equivalent of ../unix/prepare-install-package.sh, *except* that it doesn't
|
||||
# set Linux permissions, create the install.dat files, or create the final zip (unless you specify
|
||||
# --windows-only). Due to limitations in PowerShell, the final changes are handled by the
|
||||
# windows/finalize-install-package.sh file in WSL.
|
||||
#
|
||||
# When making changes, make sure to update ../unix/prepare-install-package.ps1 too.
|
||||
#
|
||||
#
|
||||
|
||||
. "$PSScriptRoot/lib/in-place-regex.ps1"
|
||||
|
||||
|
||||
##########
|
||||
## Fetch values
|
||||
##########
|
||||
# paths
|
||||
$gamePath = "C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley"
|
||||
$bundleModNames = "ConsoleCommands", "ErrorHandler", "SaveBackup"
|
||||
|
||||
# build configuration
|
||||
$buildConfig = "Release"
|
||||
$folders = "linux", "macOS", "windows"
|
||||
$runtimes = @{ linux = "linux-x64"; macOS = "osx-x64"; windows = "win-x64" }
|
||||
$msBuildPlatformNames = @{ linux = "Unix"; macOS = "OSX"; windows = "Windows_NT" }
|
||||
|
||||
# version number
|
||||
$version = $args[0]
|
||||
if (!$version) {
|
||||
$version = Read-Host "SMAPI release version (like '4.0.0')"
|
||||
}
|
||||
|
||||
# Windows-only build
|
||||
$windowsOnly = $false
|
||||
foreach ($arg in $args) {
|
||||
if ($arg -eq "--windows-only") {
|
||||
$windowsOnly = $true
|
||||
$folders = "windows"
|
||||
$runtimes = @{ windows = "win-x64" }
|
||||
$msBuildPlatformNames = @{ windows = "Windows_NT" }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##########
|
||||
## Move to SMAPI root
|
||||
##########
|
||||
cd "$PSScriptRoot/../.."
|
||||
|
||||
|
||||
##########
|
||||
## Clear old build files
|
||||
##########
|
||||
echo "Clearing old builds..."
|
||||
echo "-------------------------------------------------"
|
||||
|
||||
foreach ($path in (dir -Recurse -Include ('bin', 'obj'))) {
|
||||
echo "$path"
|
||||
rm -Recurse -Force "$path"
|
||||
}
|
||||
echo ""
|
||||
|
||||
|
||||
##########
|
||||
## Compile files
|
||||
##########
|
||||
. "$PSScriptRoot/set-smapi-version.ps1" "$version"
|
||||
foreach ($folder in $folders) {
|
||||
$runtime = $runtimes[$folder]
|
||||
$msbuildPlatformName = $msBuildPlatformNames[$folder]
|
||||
|
||||
echo "Compiling SMAPI for $folder..."
|
||||
echo "-------------------------------------------------"
|
||||
dotnet publish src/SMAPI --configuration $buildConfig -v minimal --runtime "$runtime" -p:OS="$msbuildPlatformName" -p:GamePath="$gamePath" -p:CopyToGameFolder="false" --self-contained true
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
echo "Compiling installer for $folder..."
|
||||
echo "-------------------------------------------------"
|
||||
dotnet publish src/SMAPI.Installer --configuration $buildConfig -v minimal --runtime "$runtime" -p:OS="$msbuildPlatformName" -p:GamePath="$gamePath" -p:CopyToGameFolder="false" -p:PublishTrimmed=True -p:TrimMode=Link --self-contained true
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
foreach ($modName in $bundleModNames) {
|
||||
echo "Compiling $modName for $folder..."
|
||||
echo "-------------------------------------------------"
|
||||
dotnet publish src/SMAPI.Mods.$modName --configuration $buildConfig -v minimal --runtime "$runtime" -p:OS="$msbuildPlatformName" -p:GamePath="$gamePath" -p:CopyToGameFolder="false"
|
||||
echo ""
|
||||
echo ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##########
|
||||
## Prepare install package
|
||||
##########
|
||||
echo "Preparing install package..."
|
||||
echo "----------------------------"
|
||||
|
||||
# init paths
|
||||
$installAssets = "src/SMAPI.Installer/assets"
|
||||
$packagePath = "bin/SMAPI installer"
|
||||
$packageDevPath = "bin/SMAPI installer for developers"
|
||||
|
||||
# init structure
|
||||
foreach ($folder in $folders) {
|
||||
mkdir "$packagePath/internal/$folder/bundle/smapi-internal" > $null
|
||||
}
|
||||
|
||||
# copy base installer files
|
||||
foreach ($name in @("install on Linux.sh", "install on macOS.command", "install on Windows.bat", "README.txt")) {
|
||||
if ($windowsOnly -and ($name -eq "install on Linux.sh" -or $name -eq "install on macOS.command")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cp "$installAssets/$name" "$packagePath"
|
||||
}
|
||||
|
||||
# copy per-platform files
|
||||
foreach ($folder in $folders) {
|
||||
$runtime = $runtimes[$folder]
|
||||
|
||||
# get paths
|
||||
$smapiBin = "src/SMAPI/bin/$buildConfig/$runtime/publish"
|
||||
$internalPath = "$packagePath/internal/$folder"
|
||||
$bundlePath = "$internalPath/bundle"
|
||||
|
||||
# installer files
|
||||
cp "src/SMAPI.Installer/bin/$buildConfig/$runtime/publish/*" "$internalPath" -Recurse
|
||||
rm -Recurse -Force "$internalPath/assets"
|
||||
|
||||
# runtime config for SMAPI
|
||||
# This is identical to the one generated by the build, except that the min runtime version is
|
||||
# set to 5.0.0 (instead of whatever version it was built with) and rollForward is set to latestMinor instead of
|
||||
# minor.
|
||||
cp "$installAssets/runtimeconfig.json" "$bundlePath/StardewModdingAPI.runtimeconfig.json"
|
||||
|
||||
# installer DLL config
|
||||
if ($folder -eq "windows") {
|
||||
cp "$installAssets/windows-exe-config.xml" "$packagePath/internal/windows/install.exe.config"
|
||||
}
|
||||
|
||||
# bundle root files
|
||||
foreach ($name in @("StardewModdingAPI", "StardewModdingAPI.dll", "StardewModdingAPI.xml", "steam_appid.txt")) {
|
||||
if ($name -eq "StardewModdingAPI" -and $folder -eq "windows") {
|
||||
$name = "$name.exe"
|
||||
}
|
||||
|
||||
cp "$smapiBin/$name" "$bundlePath"
|
||||
}
|
||||
|
||||
# bundle i18n
|
||||
cp -Recurse "$smapiBin/i18n" "$bundlePath/smapi-internal"
|
||||
|
||||
# bundle smapi-internal
|
||||
foreach ($name in @("0Harmony.dll", "0Harmony.xml", "Mono.Cecil.dll", "Mono.Cecil.Mdb.dll", "Mono.Cecil.Pdb.dll", "MonoMod.Common.dll", "Newtonsoft.Json.dll", "Pathoschild.Http.Client.dll", "Pintail.dll", "TMXTile.dll", "SMAPI.Toolkit.dll", "SMAPI.Toolkit.xml", "SMAPI.Toolkit.CoreInterfaces.dll", "SMAPI.Toolkit.CoreInterfaces.xml", "System.Net.Http.Formatting.dll")) {
|
||||
cp "$smapiBin/$name" "$bundlePath/smapi-internal"
|
||||
}
|
||||
|
||||
if ($folder -eq "windows") {
|
||||
cp "$smapiBin/VdfConverter.dll" "$bundlePath/smapi-internal"
|
||||
}
|
||||
|
||||
cp "$smapiBin/SMAPI.config.json" "$bundlePath/smapi-internal/config.json"
|
||||
cp "$smapiBin/SMAPI.metadata.json" "$bundlePath/smapi-internal/metadata.json"
|
||||
if ($folder -eq "linux" -or $folder -eq "macOS") {
|
||||
cp "$installAssets/unix-launcher.sh" "$bundlePath"
|
||||
}
|
||||
else {
|
||||
cp "$installAssets/windows-exe-config.xml" "$bundlePath/StardewModdingAPI.exe.config"
|
||||
}
|
||||
|
||||
# copy .NET dependencies
|
||||
if ($folder -eq "windows") {
|
||||
cp "$smapiBin/System.Management.dll" "$bundlePath/smapi-internal"
|
||||
}
|
||||
|
||||
# copy legacy .NET dependencies (remove in SMAPI 4.0.0)
|
||||
cp "$smapiBin/System.Configuration.ConfigurationManager.dll" "$bundlePath/smapi-internal"
|
||||
cp "$smapiBin/System.Runtime.Caching.dll" "$bundlePath/smapi-internal"
|
||||
cp "$smapiBin/System.Security.Permissions.dll" "$bundlePath/smapi-internal"
|
||||
|
||||
# copy bundled mods
|
||||
foreach ($modName in $bundleModNames) {
|
||||
$fromPath = "src/SMAPI.Mods.$modName/bin/$buildConfig/$runtime/publish"
|
||||
$targetPath = "$bundlePath/Mods/$modName"
|
||||
|
||||
mkdir "$targetPath" > $null
|
||||
|
||||
cp "$fromPath/$modName.dll" "$targetPath"
|
||||
cp "$fromPath/manifest.json" "$targetPath"
|
||||
if (Test-Path "$fromPath/i18n" -PathType Container) {
|
||||
cp -Recurse "$fromPath/i18n" "$targetPath"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# DISABLED: will be handled by Linux script
|
||||
# mark scripts executable
|
||||
#ForEach ($path in @("install on Linux.sh", "install on macOS.command", "bundle/unix-launcher.sh")) {
|
||||
# if (Test-Path "$packagePath/$path" -PathType Leaf) {
|
||||
# chmod 755 "$packagePath/$path"
|
||||
# }
|
||||
#}
|
||||
|
||||
# split into main + for-dev folders
|
||||
cp -Recurse "$packagePath" "$packageDevPath"
|
||||
foreach ($folder in $folders) {
|
||||
# disable developer mode in main package
|
||||
In-Place-Regex -Path "$packagePath/internal/$folder/bundle/smapi-internal/config.json" -Search "`"DeveloperMode`": true" -Replace "`"DeveloperMode`": false"
|
||||
|
||||
# convert bundle folder into final 'install.dat' files
|
||||
if ($windowsOnly)
|
||||
{
|
||||
foreach ($path in @("$packagePath/internal/$folder", "$packageDevPath/internal/$folder"))
|
||||
{
|
||||
Compress-Archive -Path "$path/bundle/*" -CompressionLevel Optimal -DestinationPath "$path/install.zip"
|
||||
mv "$path/install.zip" "$path/install.dat"
|
||||
rm -Recurse -Force "$path/bundle"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
###########
|
||||
### Create release zips
|
||||
###########
|
||||
# rename folders
|
||||
mv "$packagePath" "bin/SMAPI $version installer"
|
||||
mv "$packageDevPath" "bin/SMAPI $version installer for developers"
|
||||
|
||||
# package files
|
||||
if ($windowsOnly)
|
||||
{
|
||||
Compress-Archive -Path "bin/SMAPI $version installer" -DestinationPath "bin/SMAPI $version installer.zip" -CompressionLevel Optimal
|
||||
Compress-Archive -Path "bin/SMAPI $version installer for developers" -DestinationPath "bin/SMAPI $version installer for developers.zip" -CompressionLevel Optimal
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "Done! See docs/technical/smapi.md to create the release zips."
|
|
@ -1,25 +0,0 @@
|
|||
#
|
||||
#
|
||||
# This is the PowerShell equivalent of ../unix/set-smapi-version.sh.
|
||||
# When making changes, both scripts should be updated.
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
. "$PSScriptRoot\lib\in-place-regex.ps1"
|
||||
|
||||
# get version number
|
||||
$version=$args[0]
|
||||
if (!$version) {
|
||||
$version = Read-Host "SMAPI release version (like '4.0.0')"
|
||||
}
|
||||
|
||||
# move to SMAPI root
|
||||
cd "$PSScriptRoot/../.."
|
||||
|
||||
# apply changes
|
||||
In-Place-Regex -Path "build/common.targets" -Search "<Version>.+</Version>" -Replace "<Version>$version</Version>"
|
||||
In-Place-Regex -Path "src/SMAPI/Constants.cs" -Search "RawApiVersion = `".+?`";" -Replace "RawApiVersion = `"$version`";"
|
||||
ForEach ($modName in "ConsoleCommands","ErrorHandler","SaveBackup") {
|
||||
In-Place-Regex -Path "src/SMAPI.Mods.$modName/manifest.json" -Search "`"(Version|MinimumApiVersion)`": `".+?`"" -Replace "`"`$1`": `"$version`""
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
**SMAPI** is an open-source modding framework and API for [Stardew Valley](https://stardewvalley.net/)
|
||||
that lets you play the game with mods. It's safely installed alongside the game's executable, and
|
||||
doesn't change any of your game files. It serves seven main purposes:
|
||||
**SMAPI** is an open-source modding API for [Stardew Valley](https://stardewvalley.net/) that lets
|
||||
you play the game with mods. It's safely installed alongside the game's executable, and doesn't
|
||||
change any of your game files. It serves eight main purposes:
|
||||
|
||||
1. **Load mods into the game.**
|
||||
_SMAPI loads mods when the game is starting up so they can interact with it. (Code mods aren't
|
||||
|
@ -10,19 +10,20 @@ doesn't change any of your game files. It serves seven main purposes:
|
|||
_SMAPI provides APIs and events which let mods interact with the game in ways they otherwise
|
||||
couldn't._
|
||||
|
||||
3. **Rewrite mods for compatibility.**
|
||||
_SMAPI rewrites mods' compiled code before loading them so they work on Linux/macOS/Windows
|
||||
without the mods needing to handle differences between the Linux/macOS and Windows versions of
|
||||
the game. In some cases it also rewrites code broken by a game update so the mod doesn't break._
|
||||
3. **Rewrite mods for crossplatform compatibility.**
|
||||
_SMAPI rewrites mods' compiled code before loading them so they work on Linux/Mac/Windows
|
||||
without the mods needing to handle differences between the Linux/Mac and Windows versions of the
|
||||
game._
|
||||
|
||||
5. **Intercept errors and automatically fix saves.**
|
||||
_SMAPI intercepts errors, shows the error info in the SMAPI console, and in most cases
|
||||
automatically recovers the game. That prevents mods from crashing the game, and makes it
|
||||
possible to troubleshoot errors in the game itself that would otherwise show a generic 'program
|
||||
has stopped working' type of message._
|
||||
4. **Rewrite mods to update them.**
|
||||
_SMAPI detects when a mod accesses part of the game that changed in a game update which affects
|
||||
many mods, and rewrites the mod so it's compatible._
|
||||
|
||||
_SMAPI also automatically fixes save data in some cases when a load would crash, e.g. due to a
|
||||
custom location or NPC mod that was removed._
|
||||
5. **Intercept errors.**
|
||||
_SMAPI intercepts errors that happen in the game, displays the error details in the console
|
||||
window, and in most cases automatically recovers the game. This prevents mods from accidentally
|
||||
crashing the game, and makes it possible to troubleshoot errors in the game itself that would
|
||||
otherwise show a generic 'program has stopped working' type of message._
|
||||
|
||||
6. **Provide update checks.**
|
||||
_SMAPI automatically checks for new versions of your installed mods, and notifies you when any
|
||||
|
@ -33,47 +34,20 @@ doesn't change any of your game files. It serves seven main purposes:
|
|||
they cause problems._
|
||||
|
||||
8. **Back up your save files.**
|
||||
_SMAPI automatically creates a daily backup of your saves and keeps ten backups (via the bundled
|
||||
Save Backup mod), in case something goes wrong._
|
||||
_SMAPI automatically creates a daily backup of your saves and keeps ten backups, in case
|
||||
something goes wrong. (Via the bundled SaveBackup mod.)_
|
||||
|
||||
## Documentation
|
||||
Have questions? Come [ask the community](https://smapi.io/community) to get help from SMAPI
|
||||
developers and other modders!
|
||||
Have questions? Come [chat on Discord](https://discord.gg/KCJHWhX) with SMAPI developers and other
|
||||
modders!
|
||||
|
||||
### For players
|
||||
* [Player guide](https://stardewvalleywiki.com/Modding:Player_Guide)
|
||||
|
||||
### For modders
|
||||
* [Modding documentation](https://smapi.io/docs)
|
||||
* [Mod build configuration](technical/mod-package.md)
|
||||
* [Modding documentation](https://stardewvalleywiki.com/Modding:Index)
|
||||
* [Mod build configuration](mod-build-config.md)
|
||||
* [Release notes](release-notes.md)
|
||||
|
||||
### For SMAPI developers
|
||||
* [Technical docs](technical/smapi.md)
|
||||
|
||||
## Translating SMAPI
|
||||
SMAPI rarely shows text in-game, so it only has a few translations. Contributions are welcome! See
|
||||
[Modding:Translations](https://stardewvalleywiki.com/Modding:Translations) on the wiki for help
|
||||
contributing translations.
|
||||
|
||||
locale | status
|
||||
----------- | :----------------
|
||||
default | ✓ [fully translated](../src/SMAPI/i18n/default.json)
|
||||
Chinese | ✓ [fully translated](../src/SMAPI/i18n/zh.json)
|
||||
French | ✓ [fully translated](../src/SMAPI/i18n/fr.json)
|
||||
German | ✓ [fully translated](../src/SMAPI/i18n/de.json)
|
||||
Hungarian | ✓ [fully translated](../src/SMAPI/i18n/hu.json)
|
||||
Italian | ✓ [fully translated](../src/SMAPI/i18n/it.json)
|
||||
Japanese | ✓ [fully translated](../src/SMAPI/i18n/ja.json)
|
||||
Korean | ✓ [fully translated](../src/SMAPI/i18n/ko.json)
|
||||
[Polish] | ✓ [fully translated](../src/SMAPI/i18n/pl.json)
|
||||
Portuguese | ✓ [fully translated](../src/SMAPI/i18n/pt.json)
|
||||
Russian | ✓ [fully translated](../src/SMAPI/i18n/ru.json)
|
||||
Spanish | ✓ [fully translated](../src/SMAPI/i18n/es.json)
|
||||
[Thai] | ✓ [fully translated](../src/SMAPI/i18n/th.json)
|
||||
Turkish | ✓ [fully translated](../src/SMAPI/i18n/tr.json)
|
||||
[Ukrainian] | ✓ [fully translated](../src/SMAPI/i18n/uk.json)
|
||||
|
||||
[Polish]: https://www.nexusmods.com/stardewvalley/mods/3616
|
||||
[Thai]: https://www.nexusmods.com/stardewvalley/mods/7052
|
||||
[Ukrainian]: https://www.nexusmods.com/stardewvalley/mods/8427
|
||||
* [Technical docs](technical-docs.md)
|
||||
|
|
|
@ -1 +1,277 @@
|
|||
[Documentation moved](technical/mod-package.md).
|
||||
The **mod build package** is an open-source NuGet package which automates the MSBuild configuration
|
||||
for SMAPI mods.
|
||||
|
||||
The package...
|
||||
|
||||
* detects your game install path;
|
||||
* adds the assembly references you need (with automatic support for Linux/Mac/Windows);
|
||||
* packages the mod into your `Mods` folder when you rebuild the code (configurable);
|
||||
* configures Visual Studio to enable debugging into the code when the game is running (_Windows only_);
|
||||
* adds C# analyzers to warn for Stardew Valley-specific issues.
|
||||
|
||||
## Contents
|
||||
* [Install](#install)
|
||||
* [Configure](#configure)
|
||||
* [Code analysis warnings](#code-analysis-warnings)
|
||||
* [Troubleshoot](#troubleshoot)
|
||||
* [Release notes](#release-notes)
|
||||
|
||||
## Install
|
||||
**When creating a new mod:**
|
||||
|
||||
1. Create an empty library project.
|
||||
2. Reference the [`Pathoschild.Stardew.ModBuildConfig` NuGet package](https://www.nuget.org/packages/Pathoschild.Stardew.ModBuildConfig).
|
||||
3. [Write your code](https://stardewvalleywiki.com/Modding:Creating_a_SMAPI_mod).
|
||||
4. Compile on any platform.
|
||||
|
||||
**When migrating an existing mod:**
|
||||
|
||||
1. Remove any project references to `Microsoft.Xna.*`, `MonoGame`, Stardew Valley,
|
||||
`StardewModdingAPI`, and `xTile`.
|
||||
2. Reference the [`Pathoschild.Stardew.ModBuildConfig` NuGet package](https://www.nuget.org/packages/Pathoschild.Stardew.ModBuildConfig).
|
||||
3. Compile on any platform.
|
||||
|
||||
## Configure
|
||||
### Deploy files into the `Mods` folder
|
||||
By default, your mod will be copied into the game's `Mods` folder (with a subfolder matching your
|
||||
project name) when you rebuild the code. The package will automatically include your
|
||||
`manifest.json`, any `i18n` files, and the build output.
|
||||
|
||||
To add custom files to the mod folder, just [add them to the build output](https://stackoverflow.com/a/10828462/262123).
|
||||
(If your project references another mod, make sure the reference is [_not_ marked 'copy local'](https://msdn.microsoft.com/en-us/library/t1zz5y8c(v=vs.100).aspx).)
|
||||
|
||||
You can change the mod's folder name by adding this above the first `</PropertyGroup>` in your
|
||||
`.csproj`:
|
||||
```xml
|
||||
<ModFolderName>YourModName</ModFolderName>
|
||||
```
|
||||
|
||||
If you don't want to deploy the mod automatically, you can add this:
|
||||
```xml
|
||||
<EnableModDeploy>False</EnableModDeploy>
|
||||
```
|
||||
|
||||
### Create release zip
|
||||
By default, a zip file will be created in the build output when you rebuild the code. This zip file
|
||||
contains all the files needed to share your mod in the recommended format for uploading to Nexus
|
||||
Mods or other sites.
|
||||
|
||||
You can change the zipped folder name (and zip name) by adding this above the first
|
||||
`</PropertyGroup>` in your `.csproj`:
|
||||
```xml
|
||||
<ModFolderName>YourModName</ModFolderName>
|
||||
```
|
||||
|
||||
You can change the folder path where the zip is created like this:
|
||||
```xml
|
||||
<ModZipPath>$(SolutionDir)\_releases</ModZipPath>
|
||||
```
|
||||
|
||||
Finally, you can disable the zip creation with this:
|
||||
```xml
|
||||
<EnableModZip>False</EnableModZip>
|
||||
```
|
||||
|
||||
Or only create it in release builds with this:
|
||||
```xml
|
||||
<EnableModZip Condition="$(Configuration) != 'Release'">False</EnableModZip>
|
||||
```
|
||||
|
||||
### Game path
|
||||
The package usually detects where your game is installed automatically. If it can't find your game
|
||||
or you have multiple installs, you can specify the path yourself. There's two ways to do that:
|
||||
|
||||
* **Option 1: global game path (recommended).**
|
||||
_This will apply to every project that uses the package._
|
||||
|
||||
1. Get the full folder path containing the Stardew Valley executable.
|
||||
2. Create this file:
|
||||
|
||||
platform | path
|
||||
--------- | ----
|
||||
Linux/Mac | `~/stardewvalley.targets`
|
||||
Windows | `%USERPROFILE%\stardewvalley.targets`
|
||||
|
||||
3. Save the file with this content:
|
||||
|
||||
```xml
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<GamePath>PATH_HERE</GamePath>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
```
|
||||
|
||||
4. Replace `PATH_HERE` with your game path.
|
||||
|
||||
* **Option 2: path in the project file.**
|
||||
_You'll need to do this for each project that uses the package._
|
||||
|
||||
1. Get the folder path containing the Stardew Valley `.exe` file.
|
||||
2. Add this to your `.csproj` file under the `<Project` line:
|
||||
|
||||
```xml
|
||||
<PropertyGroup>
|
||||
<GamePath>PATH_HERE</GamePath>
|
||||
</PropertyGroup>
|
||||
```
|
||||
|
||||
3. Replace `PATH_HERE` with your custom game install path.
|
||||
|
||||
The configuration will check your custom path first, then fall back to the default paths (so it'll
|
||||
still compile on a different computer).
|
||||
|
||||
### Ignore files
|
||||
If you don't want to include a file in the mod folder or release zip:
|
||||
* Make sure it's not copied to the build output. For a DLL, make sure the reference is [not marked 'copy local'](https://msdn.microsoft.com/en-us/library/t1zz5y8c(v=vs.100).aspx).
|
||||
* Or add this to your `.csproj` file under the `<Project` line:
|
||||
```xml
|
||||
<IgnoreModFilePatterns>\.txt$, \.pdf$</IgnoreModFilePatterns>
|
||||
```
|
||||
This is a comma-delimited list of regular expression patterns. If any pattern matches a file's
|
||||
relative path in your mod folder, that file won't be included.
|
||||
|
||||
### Non-mod projects
|
||||
**(upcoming in 2.1)**
|
||||
|
||||
You can use the package in non-mod projects too (e.g. unit tests or framework DLLs). You'll need to
|
||||
disable deploying the mod and creating a release zip:
|
||||
|
||||
```xml
|
||||
<EnableModDeploy>False</EnableModDeploy>
|
||||
<EnableModZip>False</EnableModZip>
|
||||
```
|
||||
|
||||
If this is for unit tests, you may need to copy the referenced DLLs into your build output too:
|
||||
```xml
|
||||
<CopyModReferencesToBuildOutput>True</CopyModReferencesToBuildOutput>
|
||||
```
|
||||
|
||||
## Code warnings
|
||||
### Overview
|
||||
The NuGet package adds code warnings in Visual Studio specific to Stardew Valley. For example:
|
||||
![](screenshots/code-analyzer-example.png)
|
||||
|
||||
You can hide the warnings using the warning ID (shown under 'code' in the Error List). See...
|
||||
* [for specific code](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-pragma-warning);
|
||||
* for a method using this attribute:
|
||||
```cs
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("SMAPI.CommonErrors", "AvoidNetField")]
|
||||
```
|
||||
* for an entire project:
|
||||
1. Expand the _References_ node for the project in Visual Studio.
|
||||
2. Right-click on _Analyzers_ and choose _Open Active Rule Set_.
|
||||
4. Expand _StardewModdingAPI.ModBuildConfig.Analyzer_ and uncheck the warnings you want to hide.
|
||||
|
||||
See below for help with each specific warning.
|
||||
|
||||
### Avoid implicit net field cast
|
||||
Warning text:
|
||||
> This implicitly converts '{{expression}}' from {{net type}} to {{other type}}, but
|
||||
> {{net type}} has unintuitive implicit conversion rules. Consider comparing against the actual
|
||||
> value instead to avoid bugs.
|
||||
|
||||
Stardew Valley uses net types (like `NetBool` and `NetInt`) to handle multiplayer sync. These types
|
||||
can implicitly convert to their equivalent normal values (like `bool x = new NetBool()`), but their
|
||||
conversion rules are unintuitive and error-prone. For example,
|
||||
`item?.category == null && item?.category != null` can both be true at once, and
|
||||
`building.indoors != null` can be true for a null value.
|
||||
|
||||
Suggested fix:
|
||||
* Some net fields have an equivalent non-net property like `monster.Health` (`int`) instead of
|
||||
`monster.health` (`NetInt`). The package will add a separate [AvoidNetField](#avoid-net-field) warning for
|
||||
these. Use the suggested property instead.
|
||||
* For a reference type (i.e. one that can contain `null`), you can use the `.Value` property:
|
||||
```c#
|
||||
if (building.indoors.Value == null)
|
||||
```
|
||||
Or convert the value before comparison:
|
||||
```c#
|
||||
GameLocation indoors = building.indoors;
|
||||
if(indoors == null)
|
||||
// ...
|
||||
```
|
||||
* For a value type (i.e. one that can't contain `null`), check if the object is null (if applicable)
|
||||
and compare with `.Value`:
|
||||
```cs
|
||||
if (item != null && item.category.Value == 0)
|
||||
```
|
||||
|
||||
### Avoid net field
|
||||
Warning text:
|
||||
> '{{expression}}' is a {{net type}} field; consider using the {{property name}} property instead.
|
||||
|
||||
Your code accesses a net field, which has some unusual behavior (see [AvoidImplicitNetFieldCast](#avoid-implicit-net-field-cast)).
|
||||
This field has an equivalent non-net property that avoids those issues.
|
||||
|
||||
Suggested fix: access the suggested property name instead.
|
||||
|
||||
### Avoid obsolete field
|
||||
Warning text:
|
||||
> The '{{old field}}' field is obsolete and should be replaced with '{{new field}}'.
|
||||
|
||||
Your code accesses a field which is obsolete or no longer works. Use the suggested field instead.
|
||||
|
||||
## Troubleshoot
|
||||
### "Failed to find the game install path"
|
||||
That error means the package couldn't find your game. You can specify the game path yourself; see
|
||||
_[Game path](#game-path)_ above.
|
||||
|
||||
## Release notes
|
||||
### 2.1 alpha
|
||||
* Added support for Stardew Valley 1.3.
|
||||
* Added support for unit test projects.
|
||||
* Added C# analyzers to warn about implicit conversions of Netcode fields in Stardew Valley 1.3.
|
||||
|
||||
### 2.0.2
|
||||
* Fixed compatibility issue on Linux.
|
||||
|
||||
### 2.0.1
|
||||
* Fixed mod deploy failing to create subfolders if they don't already exist.
|
||||
|
||||
### 2.0
|
||||
* Added: mods are now copied into the `Mods` folder automatically (configurable).
|
||||
* Added: release zips are now created automatically in your build output folder (configurable).
|
||||
* Added: mod deploy and release zips now exclude Json.NET automatically, since it's provided by SMAPI.
|
||||
* Added mod's version to release zip filename.
|
||||
* Improved errors to simplify troubleshooting.
|
||||
* Fixed release zip not having a mod folder.
|
||||
* Fixed release zip failing if mod name contains characters that aren't valid in a filename.
|
||||
|
||||
### 1.7.1
|
||||
* Fixed issue where i18n folders were flattened.
|
||||
* The manifest/i18n files in the project now take precedence over those in the build output if both
|
||||
are present.
|
||||
|
||||
### 1.7
|
||||
* Added option to create release zips on build.
|
||||
* Added reference to XNA's XACT library for audio-related mods.
|
||||
|
||||
### 1.6
|
||||
* Added support for deploying mod files into `Mods` automatically.
|
||||
* Added a build error if a game folder is found, but doesn't contain Stardew Valley or SMAPI.
|
||||
|
||||
### 1.5
|
||||
* Added support for setting a custom game path globally.
|
||||
* Added default GOG path on Mac.
|
||||
|
||||
### 1.4
|
||||
* Fixed detection of non-default game paths on 32-bit Windows.
|
||||
* Removed support for SilVerPLuM (discontinued).
|
||||
* Removed support for overriding the target platform (no longer needed since SMAPI crossplatforms
|
||||
mods automatically).
|
||||
|
||||
### 1.3
|
||||
* Added support for non-default game paths on Windows.
|
||||
|
||||
### 1.2
|
||||
* Exclude game binaries from mod build output.
|
||||
|
||||
### 1.1
|
||||
* Added support for overriding the target platform.
|
||||
|
||||
### 1.0
|
||||
* Initial release.
|
||||
* Added support for detecting the game path automatically.
|
||||
* Added support for injecting XNA/MonoGame references automatically based on the OS.
|
||||
* Added support for mod builders like SilVerPLuM.
|
||||
|
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
@ -0,0 +1,232 @@
|
|||
← [README](README.md)
|
||||
|
||||
This file provides more technical documentation about SMAPI. If you only want to use or create
|
||||
mods, this section isn't relevant to you; see the main README to use or create mods.
|
||||
|
||||
# Contents
|
||||
* [SMAPI](#smapi)
|
||||
* [Development](#development)
|
||||
* [Compiling from source](#compiling-from-source)
|
||||
* [Debugging a local build](#debugging-a-local-build)
|
||||
* [Preparing a release](#preparing-a-release)
|
||||
* [Customisation](#customisation)
|
||||
* [Configuration file](#configuration-file)
|
||||
* [Command-line arguments](#command-line-arguments)
|
||||
* [Compile flags](#compile-flags)
|
||||
* [SMAPI web services](#smapi-web-services)
|
||||
* [Overview](#overview)
|
||||
* [Log parser](#log-parser)
|
||||
* [Web API](#web-api)
|
||||
* [Development](#development-2)
|
||||
* [Local development](#local-development)
|
||||
* [Deploying to Amazon Beanstalk](#deploying-to-amazon-beanstalk)
|
||||
* [Mod build config package](#mod-build-config-package)
|
||||
|
||||
# SMAPI
|
||||
## Development
|
||||
### Compiling from source
|
||||
Using an official SMAPI release is recommended for most users.
|
||||
|
||||
SMAPI uses some C# 7 code, so you'll need at least
|
||||
[Visual Studio 2017](https://www.visualstudio.com/vs/community/) on Windows,
|
||||
[MonoDevelop 7.0](https://www.monodevelop.com/) on Linux,
|
||||
[Visual Studio 2017 for Mac](https://www.visualstudio.com/vs/visual-studio-mac/), or an equivalent
|
||||
IDE to compile it. It uses build configuration derived from the
|
||||
[crossplatform 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` folder at the root of the git repository.
|
||||
|
||||
### Debugging a local build
|
||||
Rebuilding the solution in debug mode will copy the SMAPI files into your game folder. Starting
|
||||
the `StardewModdingAPI` project with debugging from Visual Studio (on Mac or Windows) will launch
|
||||
SMAPI with the debugger attached, so you can intercept errors and step through the code being
|
||||
executed. This doesn't work in MonoDevelop on Linux, unfortunately.
|
||||
|
||||
### Preparing a release
|
||||
To prepare a crossplatform SMAPI release, you'll need to compile it on two platforms. See
|
||||
[crossplatforming info](https://stardewvalleywiki.com/Modding:Modder_Guide/Test_and_Troubleshoot#Testing_on_all_platforms)
|
||||
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](https://semver.org). Recommended format:
|
||||
|
||||
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. Copy `windows-install.*` from `bin/SMAPI installer` and `bin/SMAPI installer for developers` to
|
||||
Linux/Mac.
|
||||
|
||||
3. In Linux/Mac:
|
||||
1. Rebuild the solution in Release mode.
|
||||
2. Add the `windows-install.*` files to the `bin/SMAPI installer` and
|
||||
`bin/SMAPI installer for developers` folders.
|
||||
3. Rename the folders to `SMAPI <version> installer` and `SMAPI <version> installer for developers`.
|
||||
4. Zip the two folders.
|
||||
|
||||
## Customisation
|
||||
### Configuration file
|
||||
You can customise the SMAPI behaviour by editing the `StardewModdingAPI.config.json` file in your
|
||||
game folder.
|
||||
|
||||
Basic fields:
|
||||
|
||||
field | purpose
|
||||
----------------- | -------
|
||||
`DeveloperMode` | Default `false` (except in _SMAPI for developers_ releases). Whether to enable features intended for mod developers (mainly more detailed console logging).
|
||||
`CheckForUpdates` | Default `true`. Whether SMAPI should check for a newer version when you load the game. If a new version is available, a small message will appear in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.
|
||||
`VerboseLogging` | Default `false`. Whether SMAPI should log more information about the game context.
|
||||
`ModData` | Internal metadata about SMAPI mods. Changing this isn't recommended and may destabilise your game. See documentation in the file.
|
||||
|
||||
### Command-line arguments
|
||||
The SMAPI installer recognises three command-line arguments:
|
||||
|
||||
argument | purpose
|
||||
-------- | -------
|
||||
`--install` | Preselects the install action, skipping the prompt asking what the user wants to do.
|
||||
`--uninstall` | Preselects the uninstall action, skipping the prompt asking what the user wants to do.
|
||||
`--game-path "path"` | Specifies the full path to the folder containing the Stardew Valley executable, skipping automatic detection and any prompt to choose a path. If the path is not valid, the installer displays an error.
|
||||
|
||||
SMAPI itself recognises two arguments, but these are intended for internal use or testing and may
|
||||
change without warning.
|
||||
|
||||
argument | purpose
|
||||
-------- | -------
|
||||
`--no-terminal` | SMAPI won't write anything to the console window. (Messages will still be written to the log file.)
|
||||
`--mods-path` | The path to search for mods, if not the standard `Mods` folder. This can be a path relative to the game folder (like `--mods-path "Mods (test)"`) or an absolute path.
|
||||
|
||||
### Compile flags
|
||||
SMAPI uses a small number of conditional compilation constants, which you can set by editing the
|
||||
`<DefineConstants>` element in `StardewModdingAPI.csproj`. Supported constants:
|
||||
|
||||
flag | purpose
|
||||
---- | -------
|
||||
`SMAPI_FOR_WINDOWS` | Whether SMAPI is being compiled on Windows for players on Windows. Set automatically in `crossplatform.targets`.
|
||||
`SMAPI_3_0_STRICT` | Whether to exclude all deprecated APIs from compilation. This is useful for testing mods for SMAPI 3.0 compatibility.
|
||||
|
||||
# SMAPI web services
|
||||
## Overview
|
||||
The `StardewModdingAPI.Web` project provides an API and web UI hosted at `*.smapi.io`.
|
||||
|
||||
### Log parser
|
||||
The log parser provides a web UI for uploading, parsing, and sharing SMAPI logs. The logs are
|
||||
persisted in a compressed form to Pastebin.
|
||||
|
||||
The log parser lives at https://log.smapi.io.
|
||||
|
||||
### Web API
|
||||
SMAPI provides a web API at `api.smapi.io` for use by SMAPI and external tools. The URL includes a
|
||||
`{version}` token, which is the SMAPI version for backwards compatibility. This API is publicly
|
||||
accessible but not officially released; it may change at any time.
|
||||
|
||||
The API has one `/mods` endpoint. This provides mod info, including official versions and URLs
|
||||
(from Chucklefish, GitHub, or Nexus), unofficial versions from the wiki, and optional mod metadata
|
||||
from the wiki and SMAPI's internal data. This is used by SMAPI to perform update checks, and by
|
||||
external tools to fetch mod data.
|
||||
|
||||
The API accepts a `POST` request with the mods to match, each of which **must** specify an ID and
|
||||
may _optionally_ specify [update keys](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest#Update_checks).
|
||||
The API will automatically try to fetch known update keys from the wiki and internal data based on
|
||||
the given ID.
|
||||
|
||||
```
|
||||
POST https://api.smapi.io/v2.0/mods
|
||||
{
|
||||
"mods": [
|
||||
{
|
||||
"id": "Pathoschild.LookupAnything",
|
||||
"updateKeys": [ "nexus:541", "chucklefish:4250" ]
|
||||
}
|
||||
],
|
||||
"includeExtendedMetadata": true
|
||||
}
|
||||
```
|
||||
|
||||
The API will automatically aggregate versions and errors. Each mod will include...
|
||||
* an `id` (matching what you passed in);
|
||||
* up to three versions: `main` (e.g. 'latest version' field on Nexus), `optional` if newer (e.g.
|
||||
optional files on Nexus), and `unofficial` if newer (from the wiki);
|
||||
* `metadata` with mod info crossreferenced from the wiki and internal data (only if you specified
|
||||
`includeExtendedMetadata: true`);
|
||||
* and `errors` containing any error messages that occurred while fetching data.
|
||||
|
||||
For example:
|
||||
```
|
||||
[
|
||||
{
|
||||
"id": "Pathoschild.LookupAnything",
|
||||
"main": {
|
||||
"version": "1.19",
|
||||
"url": "https://www.nexusmods.com/stardewvalley/mods/541"
|
||||
},
|
||||
"metadata": {
|
||||
"id": [
|
||||
"Pathoschild.LookupAnything",
|
||||
"LookupAnything"
|
||||
],
|
||||
"name": "Lookup Anything",
|
||||
"nexusID": 541,
|
||||
"gitHubRepo": "Pathoschild/StardewMods",
|
||||
"compatibilityStatus": "Ok",
|
||||
"compatibilitySummary": "✓ use latest version."
|
||||
},
|
||||
"errors": []
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Development
|
||||
### Local development
|
||||
`StardewModdingAPI.Web` is a regular ASP.NET MVC Core app, so you can just launch it from within
|
||||
Visual Studio to run a local version.
|
||||
|
||||
There are two differences when it's run locally: all endpoints use HTTP instead of HTTPS, and the
|
||||
subdomain portion becomes a route (e.g. `log.smapi.io` → `localhost:59482/log`).
|
||||
|
||||
Before running it locally, you need to enter your credentials in the `appsettings.Development.json`
|
||||
file. See the next section for a description of each setting. This file is listed in `.gitignore`
|
||||
to prevent accidentally committing credentials.
|
||||
|
||||
### Deploying to Amazon Beanstalk
|
||||
The app can be deployed to a standard Amazon Beanstalk IIS environment. When creating the
|
||||
environment, make sure to specify the following environment properties:
|
||||
|
||||
property name | description
|
||||
------------------------------- | -----------------
|
||||
`LogParser:PastebinDevKey` | The [Pastebin developer key](https://pastebin.com/api#1) used to authenticate with the Pastebin API.
|
||||
`LogParser:PastebinUserKey` | The [Pastebin user key](https://pastebin.com/api#8) used to authenticate with the Pastebin API. Can be left blank to post anonymously.
|
||||
`LogParser:SectionUrl` | The root URL of the log page, like `https://log.smapi.io/`.
|
||||
`ModUpdateCheck:GitHubPassword` | The password with which to authenticate to GitHub when fetching release info.
|
||||
`ModUpdateCheck:GitHubUsername` | The username with which to authenticate to GitHub when fetching release info.
|
||||
|
||||
## Mod build config package
|
||||
### Overview
|
||||
The mod build config package is a NuGet package that mods reference to automatically set up
|
||||
references, configure the build, and add analyzers specific to Stardew Valley mods.
|
||||
|
||||
This involves three projects:
|
||||
|
||||
project | purpose
|
||||
------------------------------------------------- | ----------------
|
||||
`StardewModdingAPI.ModBuildConfig` | Configures the build (references, deploying the mod files, setting up debugging, etc).
|
||||
`StardewModdingAPI.ModBuildConfig.Analyzer` | Adds C# analyzers which show code warnings in Visual Studio.
|
||||
`StardewModdingAPI.ModBuildConfig.Analyzer.Tests` | Unit tests for the C# analyzers.
|
||||
|
||||
When the projects are built, the relevant files are copied into `bin/Pathoschild.Stardew.ModBuildConfig`.
|
||||
|
||||
### Preparing a build
|
||||
To prepare a build of the NuGet package:
|
||||
1. Install the [NuGet CLI](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools#nugetexe-cli).
|
||||
1. Change the version and release notes in `package.nuspec`.
|
||||
2. Rebuild the solution in _Release_ mode.
|
||||
3. Open a terminal in the `bin/Pathoschild.Stardew.ModBuildConfig` package and run this command:
|
||||
```bash
|
||||
nuget.exe pack
|
||||
```
|
||||
|
||||
That will create a `Pathoschild.Stardew.ModBuildConfig-<version>.nupkg` file in the same directory
|
||||
which can be uploaded to NuGet or referenced directly.
|
|
@ -1,618 +0,0 @@
|
|||
← [SMAPI](../README.md)
|
||||
|
||||
The **mod build package** is an open-source NuGet package which automates the MSBuild configuration
|
||||
for SMAPI mods and related tools. The package is fully compatible with Linux, macOS, and Windows.
|
||||
|
||||
## Contents
|
||||
* [Use](#use)
|
||||
* [Features](#features)
|
||||
* [Configure](#configure)
|
||||
* [Code warnings](#code-warnings)
|
||||
* [FAQs](#faqs)
|
||||
* [How do I set the game path?](#custom-game-path)
|
||||
* [How do I change which files are included in the mod deploy/zip?](#how-do-i-change-which-files-are-included-in-the-mod-deployzip)
|
||||
* [Can I use the package for non-mod projects?](#can-i-use-the-package-for-non-mod-projects)
|
||||
* [For SMAPI developers](#for-smapi-developers)
|
||||
* [Release notes](#release-notes)
|
||||
|
||||
## Use
|
||||
1. Create an empty library project.
|
||||
2. Reference the [`Pathoschild.Stardew.ModBuildConfig` NuGet package](https://www.nuget.org/packages/Pathoschild.Stardew.ModBuildConfig).
|
||||
3. [Write your code](https://stardewvalleywiki.com/Modding:Creating_a_SMAPI_mod).
|
||||
4. Compile on any platform.
|
||||
5. Run the game to play with your mod.
|
||||
|
||||
## Features
|
||||
The package includes several features to simplify mod development (see [_configure_](#configure) to
|
||||
change how these work):
|
||||
|
||||
* **Detect game path:**
|
||||
The package automatically finds your game folder by scanning the default install paths and
|
||||
Windows registry. It adds two MSBuild properties for use in your `.csproj` file if needed:
|
||||
`$(GamePath)` and `$(GameModsPath)`.
|
||||
|
||||
* **Add assembly references:**
|
||||
The package adds assembly references to MonoGame, SMAPI, Stardew Valley, and xTile. It
|
||||
automatically adjusts depending on which OS you're compiling it on. If you use
|
||||
[Harmony](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Harmony), it can optionally add
|
||||
a reference to that too.
|
||||
|
||||
* **Copy files into the `Mods` folder:**
|
||||
The package automatically copies your mod's DLL and PDB files, `manifest.json`, [`i18n`
|
||||
files](https://stardewvalleywiki.com/Modding:Translations) (if any), and the `assets` folder (if
|
||||
any) into the `Mods` folder when you rebuild the code, with a subfolder matching the mod's project
|
||||
name. That lets you try the mod in-game right after building it.
|
||||
|
||||
* **Create release zip:**
|
||||
The package adds a zip file in your project's `bin` folder when you rebuild the code, in the
|
||||
format recommended for uploading to mod sites like Nexus Mods. This includes the same files as
|
||||
the previous feature.
|
||||
|
||||
* **Launch or debug mod:**
|
||||
On Windows only, the package configures Visual Studio so you can launch the game and attach a
|
||||
debugger using _Debug > Start Debugging_ or _Debug > Start Without Debugging_. This lets you [set
|
||||
breakpoints](https://docs.microsoft.com/en-us/visualstudio/debugger/using-breakpoints?view=vs-2019)
|
||||
in your code while the game is running, or [make simple changes to the mod code without needing to
|
||||
restart the game](https://docs.microsoft.com/en-us/visualstudio/debugger/edit-and-continue?view=vs-2019).
|
||||
This is disabled on Linux/macOS due to limitations with the Mono wrapper.
|
||||
|
||||
* **Preconfigure common settings:**
|
||||
The package automatically enables `.pdb` files (so error logs show line numbers to simplify
|
||||
debugging), and enables support for the simplified SDK-style `.csproj` format.
|
||||
|
||||
* **Add code warnings:**
|
||||
The package runs code analysis on your mod and raises warnings for some common errors or
|
||||
pitfalls. See [_code warnings_](#code-warnings) for more info.
|
||||
|
||||
## Configure
|
||||
### How to set options
|
||||
You can configure the package by setting build properties, which are essentially tags like this:
|
||||
```xml
|
||||
<PropertyGroup>
|
||||
<ModFolderName>CustomModName</ModFolderName>
|
||||
<EnableModDeploy>false</EnableModDeploy>
|
||||
</PropertyGroup>
|
||||
```
|
||||
|
||||
There are two places you can put them:
|
||||
|
||||
* **Global properties** apply to every mod project you open on your computer. That's recommended
|
||||
for properties you want to set for all mods (e.g. a custom game path). Here's where to put them:
|
||||
|
||||
1. Open the home folder on your computer (see instructions for
|
||||
[Linux](https://superuser.com/questions/409218/where-is-my-users-home-folder-in-ubuntu),
|
||||
[macOS](https://www.cnet.com/how-to/how-to-find-your-macs-home-folder-and-add-it-to-finder/),
|
||||
or [Windows](https://www.computerhope.com/issues/ch000109.htm)).
|
||||
2. Create a `stardewvalley.targets` file with this content:
|
||||
```xml
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
```
|
||||
3. Add the properties between the `<PropertyGroup>` and `</PropertyGroup>`.
|
||||
|
||||
* **Project properties** apply to a specific project. This is mainly useful for mod-specific
|
||||
options like the mod name. Here's where to put them:
|
||||
|
||||
1. Open the folder containing your mod's source code.
|
||||
2. Open the `.csproj` file in a text editor (Notepad is fine).
|
||||
3. Add the properties between the first `<PropertyGroup>` and `</PropertyGroup>` tags you find.
|
||||
|
||||
**Note:** you can't use a property before it's defined. That mainly means that when setting
|
||||
`GameModsPath`, you'll need to either specify `GamePath` manually or put the full path in
|
||||
`GameModsPath`.
|
||||
|
||||
### Available properties
|
||||
These are the options you can set:
|
||||
|
||||
<ul>
|
||||
<li>Game properties:
|
||||
<table>
|
||||
<tr>
|
||||
<th>property</th>
|
||||
<th>effect</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>GamePath</code></td>
|
||||
<td>
|
||||
|
||||
The absolute path to the Stardew Valley folder. This is auto-detected, so you usually don't need to
|
||||
change it.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>GameModsPath</code></td>
|
||||
<td>
|
||||
|
||||
The absolute path to the folder containing the game's installed mods (defaults to
|
||||
`$(GamePath)/Mods`), used when deploying the mod files.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
</table>
|
||||
</li>
|
||||
|
||||
<li>Mod build properties:
|
||||
<table>
|
||||
<tr>
|
||||
<th>property</th>
|
||||
<th>effect</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>EnableHarmony</code></td>
|
||||
<td>
|
||||
|
||||
Whether to add a reference to [Harmony](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Harmony)
|
||||
(default `false`). This is only needed if you use Harmony.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>EnableModDeploy</code></td>
|
||||
<td>
|
||||
|
||||
Whether to copy the mod files into your game's `Mods` folder (default `true`).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>EnableModZip</code></td>
|
||||
<td>
|
||||
|
||||
Whether to create a release-ready `.zip` file in the mod project's `bin` folder (default `true`).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>ModFolderName</code></td>
|
||||
<td>
|
||||
|
||||
The mod name for its folder under `Mods` and its release zip (defaults to the project name).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>ModZipPath</code></td>
|
||||
<td>
|
||||
|
||||
The folder path where the release zip is created (defaults to the project's `bin` folder).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</li>
|
||||
|
||||
<li>Specialized properties:
|
||||
<table>
|
||||
<tr>
|
||||
<th>property</th>
|
||||
<th>effect</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>BundleExtraAssemblies</code></td>
|
||||
<td>
|
||||
|
||||
**Most mods should not change this option.**
|
||||
|
||||
By default (when this is _not_ enabled), only the mod files [normally considered part of the
|
||||
mod](#Features) will be added to the release `.zip` and copied into the `Mods` folder (i.e.
|
||||
"deployed"). That includes the assembly files (`*.dll`, `*.pdb`, and `*.xml`) for your mod project,
|
||||
but any other DLLs won't be deployed.
|
||||
|
||||
Enabling this option will add _all_ dependencies to the build output, then deploy _some_ of them
|
||||
depending on the comma-separated value(s) you set:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>option</th>
|
||||
<th>result</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>ThirdParty</code></td>
|
||||
<td>
|
||||
|
||||
Assembly files which don't match any other category.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>System</code></td>
|
||||
<td>
|
||||
|
||||
Assembly files whose names start with `Microsoft.*` or `System.*`.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Game</code></td>
|
||||
<td>
|
||||
|
||||
Assembly files which are part of MonoGame, SMAPI, or Stardew Valley.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>All</code></td>
|
||||
<td>
|
||||
|
||||
Equivalent to `System, Game, ThirdParty`.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Most mods should omit the option. Some mods may need `ThirdParty` if they bundle third-party DLLs
|
||||
with their mod. The other options are mainly useful for unit tests.
|
||||
|
||||
When enabling this option, you should **manually review which files get deployed** and use the
|
||||
`IgnoreModFilePaths` or `IgnoreModFilePatterns` options to exclude files as needed.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>EnableGameDebugging</code></td>
|
||||
<td>
|
||||
|
||||
Whether to configure the project so you can launch or debug the game through the _Debug_ menu in
|
||||
Visual Studio (default `true`). There's usually no reason to change this, unless it's a unit test
|
||||
project.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>IgnoreModFilePaths</code></td>
|
||||
<td>
|
||||
|
||||
A comma-delimited list of literal file paths to ignore, relative to the mod's `bin` folder. Paths
|
||||
are case-sensitive, but path delimiters are normalized automatically. For example, this ignores a
|
||||
set of tilesheets:
|
||||
|
||||
```xml
|
||||
<IgnoreModFilePaths>assets/paths.png, assets/springobjects.png</IgnoreModFilePaths>
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>IgnoreModFilePatterns</code></td>
|
||||
<td>
|
||||
|
||||
A comma-delimited list of regex patterns matching files to ignore when deploying or zipping the mod
|
||||
files (default empty). For crossplatform compatibility, you should replace path delimiters with `[/\\]`.
|
||||
|
||||
For example, this excludes all `.txt` and `.pdf` files, as well as the `assets/paths.png` file:
|
||||
|
||||
```xml
|
||||
<IgnoreModFilePatterns>\.txt$, \.pdf$, assets[/\\]paths.png</IgnoreModFilePatterns>
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
## Code warnings
|
||||
### Overview
|
||||
The NuGet package adds code warnings in Visual Studio specific to Stardew Valley. For example:
|
||||
![](screenshots/code-analyzer-example.png)
|
||||
|
||||
You can [hide the warnings](https://visualstudiomagazine.com/articles/2017/09/01/hide-compiler-warnings.aspx)
|
||||
if needed using the warning ID (shown under 'code' in the Error List).
|
||||
|
||||
See below for help with specific warnings.
|
||||
|
||||
### Avoid implicit net field cast
|
||||
Warning text:
|
||||
> This implicitly converts '{{expression}}' from {{net type}} to {{other type}}, but
|
||||
> {{net type}} has unintuitive implicit conversion rules. Consider comparing against the actual
|
||||
> value instead to avoid bugs.
|
||||
|
||||
Stardew Valley uses net types (like `NetBool` and `NetInt`) to handle multiplayer sync. These types
|
||||
can implicitly convert to their equivalent normal values (like `bool x = new NetBool()`), but their
|
||||
conversion rules are unintuitive and error-prone. For example,
|
||||
`item?.category == null && item?.category != null` can both be true at once, and
|
||||
`building.indoors != null` can be true for a null value.
|
||||
|
||||
Suggested fix:
|
||||
* Some net fields have an equivalent non-net property like `monster.Health` (`int`) instead of
|
||||
`monster.health` (`NetInt`). The package will add a separate [AvoidNetField](#avoid-net-field) warning for
|
||||
these. Use the suggested property instead.
|
||||
* For a reference type (i.e. one that can contain `null`), you can use the `.Value` property:
|
||||
```c#
|
||||
if (building.indoors.Value == null)
|
||||
```
|
||||
Or convert the value before comparison:
|
||||
```c#
|
||||
GameLocation indoors = building.indoors;
|
||||
if(indoors == null)
|
||||
// ...
|
||||
```
|
||||
* For a value type (i.e. one that can't contain `null`), check if the object is null (if applicable)
|
||||
and compare with `.Value`:
|
||||
```cs
|
||||
if (item != null && item.category.Value == 0)
|
||||
```
|
||||
|
||||
### Avoid net field
|
||||
Warning text:
|
||||
> '{{expression}}' is a {{net type}} field; consider using the {{property name}} property instead.
|
||||
|
||||
Your code accesses a net field, which has some unusual behavior (see [AvoidImplicitNetFieldCast](#avoid-implicit-net-field-cast)).
|
||||
This field has an equivalent non-net property that avoids those issues.
|
||||
|
||||
Suggested fix: access the suggested property name instead.
|
||||
|
||||
### Avoid obsolete field
|
||||
Warning text:
|
||||
> The '{{old field}}' field is obsolete and should be replaced with '{{new field}}'.
|
||||
|
||||
Your code accesses a field which is obsolete or no longer works. Use the suggested field instead.
|
||||
|
||||
### Wrong processor architecture
|
||||
Warning text:
|
||||
> The target platform should be set to 'Any CPU' for compatibility with both 32-bit and 64-bit
|
||||
> versions of Stardew Valley (currently set to '{{current platform}}').
|
||||
|
||||
Mods can be used in either 32-bit or 64-bit mode. Your project's target platform isn't set to the
|
||||
default 'Any CPU', so it won't work in both. You can fix it by [setting the target platform to
|
||||
'Any CPU'](https://docs.microsoft.com/en-ca/visualstudio/ide/how-to-configure-projects-to-target-platforms).
|
||||
|
||||
## FAQs
|
||||
### How do I set the game path?<span id="custom-game-path"></span>
|
||||
The package detects where your game is installed automatically, so you usually don't need to set it
|
||||
manually. If it can't find your game or you have multiple installs, you can specify the path
|
||||
yourself.
|
||||
|
||||
To do that:
|
||||
|
||||
1. Get the full folder path containing the Stardew Valley executable.
|
||||
2. See [_configure_](#configure) to add this property:
|
||||
```xml
|
||||
<PropertyGroup>
|
||||
<GamePath>PATH_HERE</GamePath>
|
||||
</PropertyGroup>
|
||||
```
|
||||
3. Replace `PATH_HERE` with your game's folder path (don't add quotes).
|
||||
|
||||
The configuration will check your custom path first, then fall back to the default paths (so it'll
|
||||
still compile on a different computer).
|
||||
|
||||
### How do I change which files are included in the mod deploy/zip?
|
||||
* For normal files, you can [add/remove them in the build output](https://stackoverflow.com/a/10828462/262123).
|
||||
* For assembly files (`*.dll`, `*.exe`, `*.pdb`, or `*.xml`), see the
|
||||
[`BundleExtraAssemblies` option](#configure).
|
||||
* To exclude a file which the package copies by default, see the [`IgnoreModFilePaths` or
|
||||
`IgnoreModFilePatterns` options](#configure).
|
||||
|
||||
### Can I use the package for non-mod projects?
|
||||
Yep, this works in unit tests and framework projects too. Just disable the mod-related package
|
||||
features (see [_configure_](#configure)):
|
||||
|
||||
```xml
|
||||
<EnableGameDebugging>false</EnableGameDebugging>
|
||||
<EnableModDeploy>false</EnableModDeploy>
|
||||
<EnableModZip>false</EnableModZip>
|
||||
```
|
||||
|
||||
To copy referenced DLLs into your build output for unit tests, add this too:
|
||||
```xml
|
||||
<BundleExtraAssemblies>All</BundleExtraAssemblies>
|
||||
```
|
||||
|
||||
## For SMAPI developers
|
||||
The mod build package consists of three projects:
|
||||
|
||||
project | purpose
|
||||
------------------------------------------------- | ----------------
|
||||
`StardewModdingAPI.ModBuildConfig` | Configures the build (references, deploying the mod files, setting up debugging, etc).
|
||||
`StardewModdingAPI.ModBuildConfig.Analyzer` | Adds C# analyzers which show code warnings in Visual Studio.
|
||||
`StardewModdingAPI.ModBuildConfig.Analyzer.Tests` | Unit tests for the C# analyzers.
|
||||
|
||||
The NuGet package is generated automatically in `StardewModdingAPI.ModBuildConfig`'s `bin` folder
|
||||
when you compile it.
|
||||
|
||||
## Release notes
|
||||
## 4.1.1
|
||||
Released 24 June 2023 for SMAPI 3.13.0 or later.
|
||||
|
||||
* Replaced `.pdb` files with embedded symbols by default. This fixes logged errors not having line numbers on Linux/macOS.
|
||||
|
||||
### 4.1.0
|
||||
Released 08 January 2023 for SMAPI 3.13.0 or later.
|
||||
|
||||
* Added `manifest.json` format validation on build (thanks to tylergibbs2!).
|
||||
* Fixed game DLLs not excluded from the release zip when they're referenced explicitly but `BundleExtraAssemblies` isn't set.
|
||||
|
||||
### 4.0.2
|
||||
Released 09 October 2022 for SMAPI 3.13.0 or later.
|
||||
|
||||
* Switched to the newer crossplatform `portable` debug symbols (thanks to lanturnalis!).
|
||||
* Fixed `BundleExtraAssemblies` option being partly case-sensitive.
|
||||
* Fixed `BundleExtraAssemblies` not applying `All` value to game assemblies.
|
||||
|
||||
### 4.0.1
|
||||
Released 14 April 2022 for SMAPI 3.13.0 or later.
|
||||
|
||||
* Added detection for Xbox app game folders.
|
||||
* Fixed "_conflicts between different versions of Microsoft.Win32.Registry_" warnings in recent SMAPI versions.
|
||||
* Internal refactoring.
|
||||
|
||||
### 4.0.0
|
||||
Released 30 November 2021 for SMAPI 3.13.0 or later.
|
||||
|
||||
* Updated for Stardew Valley 1.5.5 and SMAPI 3.13.0. (Older versions are no longer supported.)
|
||||
* Added `IgnoreModFilePaths` option to ignore literal paths.
|
||||
* Added `BundleExtraAssemblies` option to copy bundled DLLs into the mod zip/folder.
|
||||
* Removed the `GameExecutableName` and `GameFramework` options (since they now have the same value
|
||||
on all platforms).
|
||||
* Removed the `CopyModReferencesToBuildOutput` option (superseded by `BundleExtraAssemblies`).
|
||||
* Improved analyzer performance by enabling parallel execution.
|
||||
|
||||
**Migration guide for mod authors:**
|
||||
1. See [_migrate to 64-bit_](https://stardewvalleywiki.com/Modding:Migrate_to_64-bit_on_Windows) and
|
||||
[_migrate to Stardew Valley 1.5.5_](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.5.5).
|
||||
2. Possible changes in your `.csproj` or `.targets` files:
|
||||
* Replace `$(GameExecutableName)` with `Stardew Valley`.
|
||||
* Replace `$(GameFramework)` with `MonoGame` and remove any XNA Framework-specific logic.
|
||||
* Replace `<CopyModReferencesToBuildOutput>true</CopyModReferencesToBuildOutput>` with
|
||||
`<BundleExtraAssemblies>Game</BundleExtraAssemblies>`.
|
||||
* If you need to bundle extra DLLs besides your mod DLL, see the [`BundleExtraAssemblies`
|
||||
documentation](#configure).
|
||||
|
||||
### 3.3.0
|
||||
Released 30 March 2021 for SMAPI 3.0.0 or later.
|
||||
|
||||
* Added a build warning when the mod isn't compiled for `Any CPU`.
|
||||
* Added a `GameFramework` build property set to `MonoGame` or `Xna` based on the platform. This can
|
||||
be overridden to change which framework it references.
|
||||
* Added support for building mods against the 64-bit Linux version of the game on Windows.
|
||||
* The package now suppresses the misleading 'processor architecture mismatch' warnings.
|
||||
|
||||
### 3.2.2
|
||||
Released 23 September 2020 for SMAPI 3.0.0 or later.
|
||||
|
||||
* Reworked and streamlined how the package is compiled.
|
||||
* Added [SMAPI-ModTranslationClassBuilder](https://github.com/Pathoschild/SMAPI-ModTranslationClassBuilder)
|
||||
files to the ignore list.
|
||||
|
||||
### 3.2.1
|
||||
Released 11 September 2020 for SMAPI 3.0.0 or later.
|
||||
|
||||
* Added more detailed logging.
|
||||
* Fixed _path's format is not supported_ error when using default `Mods` path in 3.2.
|
||||
|
||||
### 3.2.0
|
||||
Released 07 September 2020 for SMAPI 3.0.0 or later.
|
||||
|
||||
* Added option to change `Mods` folder path.
|
||||
* Rewrote documentation to make it easier to read.
|
||||
|
||||
### 3.1.0
|
||||
Released 01 February 2020 for SMAPI 3.0.0 or later.
|
||||
|
||||
* Added support for semantic versioning 2.0.
|
||||
* `0Harmony.dll` is now ignored if the mod references Harmony directly (it's bundled with SMAPI).
|
||||
|
||||
### 3.0.0
|
||||
Released 26 November 2019 for SMAPI 3.0.0 or later.
|
||||
|
||||
* Updated for SMAPI 3.0 and Stardew Valley 1.4.
|
||||
* Added automatic support for `assets` folders.
|
||||
* Added `$(GameExecutableName)` MSBuild variable.
|
||||
* Added support for projects using the simplified `.csproj` format.
|
||||
* Added option to disable game debugging config.
|
||||
* Added `.pdb` files to builds by default (to enable line numbers in error stack traces).
|
||||
* Added optional Harmony reference.
|
||||
* Fixed `Newtonsoft.Json.pdb` included in release zips when Json.NET is referenced directly.
|
||||
* Fixed `<IgnoreModFilePatterns>` not working for `i18n` files.
|
||||
* Dropped support for older versions of SMAPI and Visual Studio.
|
||||
* Migrated package icon to NuGet's new format.
|
||||
|
||||
### 2.2.0
|
||||
Released 28 October 2018.
|
||||
|
||||
* Added support for SMAPI 2.8+ (still compatible with earlier versions).
|
||||
* Added default game paths for 32-bit Windows.
|
||||
* Fixed valid manifests marked invalid in some cases.
|
||||
|
||||
### 2.1.0
|
||||
Released 27 July 2018.
|
||||
|
||||
* Added support for Stardew Valley 1.3.
|
||||
* Added support for non-mod projects.
|
||||
* Added C# analyzers to warn about implicit conversions of Netcode fields in Stardew Valley 1.3.
|
||||
* Added option to ignore files by regex pattern.
|
||||
* Added reference to new SMAPI DLL.
|
||||
* Fixed some game paths not detected by NuGet package.
|
||||
|
||||
### 2.0.2
|
||||
Released 01 November 2017.
|
||||
|
||||
* Fixed compatibility issue on Linux.
|
||||
|
||||
### 2.0.1
|
||||
Released 11 October 2017.
|
||||
|
||||
* Fixed mod deploy failing to create subfolders if they don't already exist.
|
||||
|
||||
### 2.0.0
|
||||
Released 11 October 2017.
|
||||
|
||||
* Added: mods are now copied into the `Mods` folder automatically (configurable).
|
||||
* Added: release zips are now created automatically in your build output folder (configurable).
|
||||
* Added: mod deploy and release zips now exclude Json.NET automatically, since it's provided by SMAPI.
|
||||
* Added mod's version to release zip filename.
|
||||
* Improved errors to simplify troubleshooting.
|
||||
* Fixed release zip not having a mod folder.
|
||||
* Fixed release zip failing if mod name contains characters that aren't valid in a filename.
|
||||
|
||||
### 1.7.1
|
||||
Released 28 July 2017.
|
||||
|
||||
* Fixed issue where i18n folders were flattened.
|
||||
* The manifest/i18n files in the project now take precedence over those in the build output if both
|
||||
are present.
|
||||
|
||||
### 1.7.0
|
||||
Released 28 July 2017.
|
||||
|
||||
* Added option to create release zips on build.
|
||||
* Added reference to XNA's XACT library for audio-related mods.
|
||||
|
||||
### 1.6.2
|
||||
Released 10 July 2017.
|
||||
|
||||
* Further improved crossplatform game path detection.
|
||||
* Removed undocumented `GamePlatform` build property.
|
||||
|
||||
### 1.6.1
|
||||
Released 09 July 2017.
|
||||
|
||||
* Improved crossplatform game path detection.
|
||||
|
||||
### 1.6.0
|
||||
Released 05 June 2017.
|
||||
|
||||
* Added support for deploying mod files into `Mods` automatically.
|
||||
* Added a build error if a game folder is found, but doesn't contain Stardew Valley or SMAPI.
|
||||
|
||||
### 1.5.0
|
||||
Released 23 January 2017.
|
||||
|
||||
* Added support for setting a custom game path globally.
|
||||
* Added default GOG path on macOS.
|
||||
|
||||
### 1.4.0
|
||||
Released 11 January 2017.
|
||||
|
||||
* Fixed detection of non-default game paths on 32-bit Windows.
|
||||
* Removed support for SilVerPLuM (discontinued).
|
||||
* Removed support for overriding the target platform (no longer needed since SMAPI crossplatforms
|
||||
mods automatically).
|
||||
|
||||
### 1.3.0
|
||||
Released 31 December 2016.
|
||||
|
||||
* Added support for non-default game paths on Windows.
|
||||
|
||||
### 1.2.0
|
||||
Released 24 October 2016.
|
||||
|
||||
* Exclude game binaries from mod build output.
|
||||
|
||||
### 1.1.0
|
||||
Released 21 October 2016.
|
||||
|
||||
* Added support for overriding the target platform.
|
||||
|
||||
### 1.0.0
|
||||
Released 21 October 2016.
|
||||
|
||||
* Initial release.
|
||||
* Added support for detecting the game path automatically.
|
||||
* Added support for injecting XNA/MonoGame references automatically based on the OS.
|
||||
* Added support for mod builders like SilVerPLuM.
|
|
@ -1,176 +0,0 @@
|
|||
← [README](../README.md)
|
||||
|
||||
This file provides more technical documentation about SMAPI. If you only want to use or create
|
||||
mods, this section isn't relevant to you; see the main README to use or create mods.
|
||||
|
||||
This document is about SMAPI itself; see also [mod build package](mod-package.md) and
|
||||
[web services](web.md).
|
||||
|
||||
# Contents
|
||||
* [Customisation](#customisation)
|
||||
* [Configuration file](#configuration-file)
|
||||
* [Command-line arguments](#command-line-arguments)
|
||||
* [Compile flags](#compile-flags)
|
||||
* [Compile from source code](#compile-from-source-code)
|
||||
* [Main project](#main-project)
|
||||
* [Custom Harmony build](#custom-harmony-build)
|
||||
* [Prepare a release](#prepare-a-release)
|
||||
* [On any platform](#on-any-platform)
|
||||
* [On Windows](#on-windows)
|
||||
* [Release notes](#release-notes)
|
||||
|
||||
## Customisation
|
||||
### Configuration file
|
||||
You can customise some SMAPI behaviour by editing the `smapi-internal/config.json` file in your
|
||||
game folder. See documentation in the file for more info.
|
||||
|
||||
### Command-line arguments
|
||||
The SMAPI installer recognises three command-line arguments:
|
||||
|
||||
argument | purpose
|
||||
-------- | -------
|
||||
`--install` | Preselects the install action, skipping the prompt asking what the user wants to do.
|
||||
`--uninstall` | Preselects the uninstall action, skipping the prompt asking what the user wants to do.
|
||||
`--game-path "path"` | Specifies the full path to the folder containing the Stardew Valley executable, skipping automatic detection and any prompt to choose a path. If the path is not valid, the installer displays an error.
|
||||
`--no-prompt` | Don't let the installer wait for user input (e.g. for cases where it's being run by a script). If the installer is unable to continue without user input, it'll fail instead.
|
||||
|
||||
SMAPI itself recognises five arguments, but these are meant for internal use or testing, and might
|
||||
change without warning. **On Linux/macOS**, command-line arguments won't work; see _environment
|
||||
variables_ below instead.
|
||||
|
||||
argument | purpose
|
||||
-------- | -------
|
||||
`--developer-mode`<br />`--developer-mode-off` | Enable or disable features intended for mod developers. Currently this only makes `TRACE`-level messages appear in the console.
|
||||
`--no-terminal` | SMAPI won't log anything to the console. On Linux/macOS only, this will also prevent the launch script from trying to open a terminal window. (Messages will still be written to the log file.)
|
||||
`--use-current-shell` | On Linux/macOS only, the launch script won't try to open a terminal window. All console output will be sent to the shell running the launch script.
|
||||
`--mods-path` | The path to search for mods, if not the standard `Mods` folder. This can be a path relative to the game folder (like `--mods-path "Mods (test)"`) or an absolute path.
|
||||
|
||||
### Environment variables
|
||||
The above SMAPI arguments may not work on Linux/macOS due to the way the game launcher works. You
|
||||
can set temporary environment variables instead. For example:
|
||||
> SMAPI_MODS_PATH="Mods (multiplayer)" /path/to/StardewValley
|
||||
|
||||
environment variable | purpose
|
||||
-------------------- | -------
|
||||
`SMAPI_DEVELOPER_MODE` | Equivalent to `--developer-mode` and `--developer-mode-off` above. The value must be `true` or `false`.
|
||||
`SMAPI_MODS_PATH` | Equivalent to `--mods-path` above.
|
||||
`SMAPI_NO_TERMINAL` | Equivalent to `--no-terminal` above.
|
||||
`SMAPI_USE_CURRENT_SHELL` | Equivalent to `--use-current-shell` above.
|
||||
|
||||
### Compile flags
|
||||
SMAPI uses a small number of conditional compilation constants, which you can set by editing the
|
||||
`<DefineConstants>` element in `SMAPI.csproj`. Supported constants:
|
||||
|
||||
flag | purpose
|
||||
---- | -------
|
||||
`SMAPI_FOR_WINDOWS` | Whether SMAPI is being compiled for Windows; if not set, the code assumes Linux/macOS. Set automatically in `common.targets`.
|
||||
`SMAPI_DEPRECATED` | Whether to include deprecated code in the build.
|
||||
|
||||
## Compile from source code
|
||||
### Main project
|
||||
Using an official SMAPI release is recommended for most users, but you can compile from source
|
||||
directly if needed. Just open the project in an IDE like [Visual
|
||||
Studio](https://visualstudio.microsoft.com/vs/community/) or [Rider](https://www.jetbrains.com/rider/),
|
||||
and build the `SMAPI` project. The project will automatically adjust the build settings for your
|
||||
current OS and Stardew Valley install path.
|
||||
|
||||
Rebuilding the solution in debug mode will copy the SMAPI files into your game folder. Starting
|
||||
the `SMAPI` project with debugging from Visual Studio or Rider should launch SMAPI with the
|
||||
debugger attached, so you can intercept errors and step through the code being executed.
|
||||
|
||||
### Custom Harmony build
|
||||
SMAPI uses [a custom build of Harmony 2.2.2](https://github.com/Pathoschild/Harmony#readme), which
|
||||
is included in the `build` folder. To use a different build, just replace `0Harmony.dll` in that
|
||||
folder before compiling.
|
||||
|
||||
## Prepare a release
|
||||
### On any platform
|
||||
**⚠ Ideally we'd have one set of instructions for all platforms. The instructions in this section
|
||||
will produce a fully functional release for all supported platforms, _except_ that the application
|
||||
icon for SMAPI on Windows will disappear due to [.NET runtime bug
|
||||
3828](https://github.com/dotnet/runtime/issues/3828). Until that's fixed, see the _[on
|
||||
Windows](#on-windows)_ section below to create a build that retains the icon.**
|
||||
|
||||
#### First-time setup
|
||||
1. On Windows only:
|
||||
1. [Install Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install).
|
||||
2. Run `sudo apt update` in WSL to update the package list.
|
||||
3. The rest of the instructions below should be run in WSL.
|
||||
2. Install the required software:
|
||||
1. Install the [.NET 5 SDK](https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu).
|
||||
_For Ubuntu-based systems, you can run `lsb_release -a` to get the Ubuntu version number._
|
||||
2. [Install Steam](https://linuxconfig.org/how-to-install-steam-on-ubuntu-20-04-focal-fossa-linux).
|
||||
3. Launch `steam` and install the game like usual.
|
||||
4. Download and install your preferred IDE. For the [latest standalone Rider
|
||||
version](https://www.jetbrains.com/help/rider/Installation_guide.html#prerequisites):
|
||||
```sh
|
||||
wget "<download url here>" -O rider-install.tar.gz
|
||||
sudo tar -xzvf rider-install.tar.gz -C /opt
|
||||
ln -s "/opt/JetBrains Rider-<version>/bin/rider.sh"
|
||||
./rider.sh
|
||||
```
|
||||
3. Clone the SMAPI repo:
|
||||
```sh
|
||||
git clone https://github.com/Pathoschild/SMAPI.git
|
||||
```
|
||||
|
||||
### Launch the game
|
||||
1. Run these commands to start Steam:
|
||||
```sh
|
||||
export TERM=xterm
|
||||
steam
|
||||
```
|
||||
2. Launch the game through the Steam UI.
|
||||
|
||||
### Prepare the release
|
||||
1. Run `build/unix/prepare-install-package.sh VERSION_HERE` to create the release package in the
|
||||
root `bin` folder.
|
||||
|
||||
Make sure you use a [semantic version](https://semver.org). Recommended format:
|
||||
|
||||
build type | format | example
|
||||
:--------- | :----------------------- | :------
|
||||
dev build | `<version>-alpha.<date>` | `4.0.0-alpha.20251230`
|
||||
prerelease | `<version>-beta.<date>` | `4.0.0-beta.20251230`
|
||||
release | `<version>` | `4.0.0`
|
||||
|
||||
### On Windows
|
||||
#### First-time setup
|
||||
1. Set up Windows Subsystem for Linux (WSL):
|
||||
1. [Install WSL](https://docs.microsoft.com/en-us/windows/wsl/install).
|
||||
2. Run `sudo apt update` in WSL to update the package list.
|
||||
3. The rest of the instructions below should be run in WSL.
|
||||
2. Install the required software:
|
||||
1. Install the [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0).
|
||||
2. Install [Stardew Valley](https://www.stardewvalley.net/).
|
||||
3. Clone the SMAPI repo:
|
||||
```sh
|
||||
git clone https://github.com/Pathoschild/SMAPI.git
|
||||
```
|
||||
|
||||
### Prepare the release
|
||||
1. Run `build/windows/prepare-install-package.ps1 VERSION_HERE` in PowerShell to create the release
|
||||
package folders in the root `bin` folder.
|
||||
|
||||
Make sure you use a [semantic version](https://semver.org). Recommended format:
|
||||
|
||||
build type | format | example
|
||||
:--------- | :----------------------- | :------
|
||||
dev build | `<version>-alpha.<date>` | `4.0.0-alpha.20251230`
|
||||
prerelease | `<version>-beta.<date>` | `4.0.0-beta.20251230`
|
||||
release | `<version>` | `4.0.0`
|
||||
|
||||
2. Launch WSL and run this script:
|
||||
```bash
|
||||
# edit to match the build created in steps 1
|
||||
# In WSL, `/mnt/c/example` accesses `C:\example` on the Windows filesystem.
|
||||
version="4.0.0"
|
||||
binFolder="/mnt/e/source/_Stardew/SMAPI/bin"
|
||||
build/windows/finalize-install-package.sh "$version" "$binFolder"
|
||||
```
|
||||
|
||||
Note: to prepare a test Windows-only build, you can pass `--windows-only` in the first step and
|
||||
skip the second one.
|
||||
|
||||
## Release notes
|
||||
See [release notes](../release-notes.md).
|
|
@ -1,388 +0,0 @@
|
|||
← [README](../README.md)
|
||||
|
||||
**SMAPI.Web** contains the code for the `smapi.io` website, including the mod compatibility list
|
||||
and update check API.
|
||||
|
||||
## Contents
|
||||
* [Log parser](#log-parser)
|
||||
* [JSON validator](#json-validator)
|
||||
* [Web API](#web-api)
|
||||
* [Short URLs](#short-urls)
|
||||
* [For SMAPI developers](#for-smapi-developers)
|
||||
* [Local development](#local-development)
|
||||
* [Production environment](#production-environment)
|
||||
|
||||
## Log parser
|
||||
The log parser at https://smapi.io/log provides a web UI for uploading, parsing, and sharing SMAPI
|
||||
logs.
|
||||
|
||||
The logs are saved in a compressed form to Amazon Blob storage for 30 days.
|
||||
|
||||
## JSON validator
|
||||
### Overview
|
||||
The JSON validator at https://smapi.io/json provides a web UI for uploading and sharing JSON files,
|
||||
and validating them as plain JSON or against a predefined format like `manifest.json` or Content
|
||||
Patcher's `content.json`.
|
||||
|
||||
The logs are saved in a compressed form to Amazon Blob storage for 30 days.
|
||||
|
||||
### Schema file format
|
||||
Schema files are defined in `wwwroot/schemas` using the [JSON Schema](https://json-schema.org/)
|
||||
format. The JSON validator UI recognises a superset of the standard fields to change output:
|
||||
|
||||
<dl>
|
||||
<dt>Documentation URL</dt>
|
||||
<dd>
|
||||
|
||||
The root schema may have a `@documentationURL` field, which is a web URL for the user
|
||||
documentation:
|
||||
```js
|
||||
"@documentationUrl": "https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest"
|
||||
```
|
||||
|
||||
If present, this is shown in the JSON validator UI.
|
||||
|
||||
</dd>
|
||||
<dt>Error messages</dt>
|
||||
<dd>
|
||||
|
||||
Any part of the schema can define an `@errorMessages` field, which overrides matching schema
|
||||
errors. You can override by error code (recommended), or by error type and a regex pattern matched
|
||||
against the error message (more fragile):
|
||||
|
||||
```js
|
||||
// by error type
|
||||
"pattern": "^[a-zA-Z0-9_.-]+\\.dll$",
|
||||
"@errorMessages": {
|
||||
"pattern": "Invalid value; must be a filename ending with .dll."
|
||||
}
|
||||
```
|
||||
```js
|
||||
// by error type + message pattern
|
||||
"@errorMessages": {
|
||||
"oneOf:valid against no schemas": "Missing required field: EntryDll or ContentPackFor.",
|
||||
"oneOf:valid against more than one schema": "Can't specify both EntryDll or ContentPackFor, they're mutually exclusive."
|
||||
}
|
||||
```
|
||||
|
||||
Error messages may contain special tokens:
|
||||
|
||||
* The `@value` token is replaced with the error's value field. This is usually (but not always) the
|
||||
original field value.
|
||||
* When an error has child errors, by default they're flattened into one message:
|
||||
```
|
||||
line | field | error
|
||||
---- | ---------- | -------------------------------------------------------------------------
|
||||
4 | Changes[0] | JSON does not match schema from 'then'.
|
||||
| | ==> Changes[0].ToArea.Y: Invalid type. Expected Integer but got String.
|
||||
| | ==> Changes[0].ToArea: Missing required fields: Height.
|
||||
```
|
||||
|
||||
If you set the message for an error to `$transparent`, the parent error is omitted entirely and
|
||||
the child errors are shown instead:
|
||||
```
|
||||
line | field | error
|
||||
---- | ------------------- | ----------------------------------------------
|
||||
8 | Changes[0].ToArea.Y | Invalid type. Expected Integer but got String.
|
||||
8 | Changes[0].ToArea | Missing required fields: Height.
|
||||
```
|
||||
|
||||
The child errors themselves may be marked `$transparent`, etc. If an error has no child errors,
|
||||
this override is ignored.
|
||||
|
||||
Validation errors for `then` blocks are transparent by default, unless overridden.
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
### Using a schema file directly
|
||||
You can reference the validator schemas in your JSON file directly using the `$schema` field, for
|
||||
text editors that support schema validation. For example:
|
||||
```js
|
||||
{
|
||||
"$schema": "https://smapi.io/schemas/manifest.json",
|
||||
"Name": "Some mod",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Available schemas:
|
||||
|
||||
format | schema URL
|
||||
------ | ----------
|
||||
[SMAPI: `manifest.json`](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest) | https://smapi.io/schemas/manifest.json
|
||||
[SMAPI: translations (`i18n` folder)](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Translation) | https://smapi.io/schemas/i18n.json
|
||||
[Content Patcher: `content.json`](https://github.com/Pathoschild/StardewMods/tree/develop/ContentPatcher#readme) | https://smapi.io/schemas/content-patcher.json
|
||||
|
||||
## Web API
|
||||
### Overview
|
||||
SMAPI provides a web API at `smapi.io/api` for use by SMAPI and external tools. The URL includes a
|
||||
`{version}` token, which is the SMAPI version for backwards compatibility. This API is publicly
|
||||
accessible but not officially released; it may change at any time.
|
||||
|
||||
### `/mods` endpoint
|
||||
The API has one `/mods` endpoint. This crossreferences the mod against a variety of sources (e.g.
|
||||
the wiki, Chucklefish, CurseForge, ModDrop, and Nexus) to provide metadata mainly intended for
|
||||
update checks.
|
||||
|
||||
The API accepts a `POST` request with these fields:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>field</th>
|
||||
<th>summary</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>mods</code></td>
|
||||
<td>
|
||||
|
||||
The mods for which to fetch metadata. Included fields:
|
||||
|
||||
|
||||
field | summary
|
||||
----- | -------
|
||||
`id` | The unique ID in the mod's `manifest.json`. This is used to crossreference with the wiki, and to index mods in the response. If it's unknown (e.g. you just have an update key), you can use a unique fake ID like `FAKE.Nexus.2400`.
|
||||
`updateKeys` | _(optional)_ [Update keys](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest#Update_checks) which specify the mod pages to check, in addition to any mod pages linked to the `ID`.
|
||||
`installedVersion` | _(optional)_ The installed version of the mod. If not specified, the API won't recommend an update.
|
||||
`isBroken` | _(optional)_ Whether SMAPI failed to load the installed version of the mod, e.g. due to incompatibility. If true, the web API will be more permissive when recommending updates (e.g. allowing a stable → prerelease update).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>apiVersion</code></td>
|
||||
<td>
|
||||
|
||||
_(optional)_ The installed version of SMAPI. If not specified, the API won't recommend an update.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>gameVersion</code></td>
|
||||
<td>
|
||||
|
||||
_(optional)_ The installed version of Stardew Valley. This may be used to select updates.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>platform</code></td>
|
||||
<td>
|
||||
|
||||
_(optional)_ The player's OS (`Android`, `Linux`, `Mac`, or `Windows`). This may be used to select updates.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>includeExtendedMetadata</code></td>
|
||||
<td>
|
||||
|
||||
_(optional)_ Whether to include extra metadata that's not needed for SMAPI update checks, but which
|
||||
may be useful to external tools.
|
||||
|
||||
</td>
|
||||
</table>
|
||||
|
||||
Example request:
|
||||
```js
|
||||
POST https://smapi.io/api/v3.0/mods
|
||||
{
|
||||
"mods": [
|
||||
{
|
||||
"id": "Pathoschild.ContentPatcher",
|
||||
"updateKeys": [ "nexus:1915" ],
|
||||
"installedVersion": "1.9.2",
|
||||
"isBroken": false
|
||||
}
|
||||
],
|
||||
"apiVersion": "3.0.0",
|
||||
"gameVersion": "1.4.0",
|
||||
"platform": "Windows",
|
||||
"includeExtendedMetadata": true
|
||||
}
|
||||
```
|
||||
|
||||
Response fields:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>field</th>
|
||||
<th>summary</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>id</code></td>
|
||||
<td>
|
||||
|
||||
The mod ID you specified in the request.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>suggestedUpdate</code></td>
|
||||
<td>
|
||||
|
||||
The update version recommended by the web API, if any. This is based on some internal rules (e.g.
|
||||
it won't recommend a prerelease update if the player has a working stable version) and context
|
||||
(e.g. whether the player is in the game beta channel). Choosing an update version yourself isn't
|
||||
recommended, but you can set `includeExtendedMetadata: true` and check the `metadata` field if you
|
||||
really want to do that.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>errors</code></td>
|
||||
<td>
|
||||
|
||||
Human-readable errors that occurred fetching the version info (e.g. if a mod page has an invalid
|
||||
version).
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>metadata</code></td>
|
||||
<td>
|
||||
|
||||
Extra metadata that's not needed for SMAPI update checks but which may be useful to external tools,
|
||||
if you set `includeExtendedMetadata: true` in the request. Included fields:
|
||||
|
||||
field | summary
|
||||
----- | -------
|
||||
`id` | The known `manifest.json` unique IDs for this mod defined on the wiki, if any. That includes historical versions of the mod.
|
||||
`name` | The normalised name for this mod based on the crossreferenced sites.
|
||||
`nexusID` | The mod ID on [Nexus Mods](https://www.nexusmods.com/stardewvalley/), if any.
|
||||
`chucklefishID` | The mod ID in the [Chucklefish mod repo](https://community.playstarbound.com/resources/categories/stardew-valley.22/), if any.
|
||||
`curseForgeID` | The mod project ID on [CurseForge](https://www.curseforge.com/stardewvalley), if any.
|
||||
`curseForgeKey` | The mod key on [CurseForge](https://www.curseforge.com/stardewvalley), if any. This is used in the mod page URL.
|
||||
`modDropID` | The mod ID on [ModDrop](https://www.moddrop.com/stardew-valley), if any.
|
||||
`gitHubRepo` | The GitHub repository containing the mod code, if any. Specified in the `Owner/Repo` form.
|
||||
`customSourceUrl` | The custom URL to the mod code, if any. This is used for mods which aren't stored in a GitHub repo.
|
||||
`customUrl` | The custom URL to the mod page, if any. This is used for mods which aren't stored on one of the standard mod sites covered by the ID fields.
|
||||
`main` | The primary mod version, if any. This depends on the mod site, but it's typically either the version of the mod itself or of its latest non-optional download.
|
||||
`optional` | The latest optional download version, if any.
|
||||
`unofficial` | The version of the unofficial update defined on the wiki for this mod, if any.
|
||||
`unofficialForBeta` | Equivalent to `unofficial`, but for beta versions of SMAPI or Stardew Valley.
|
||||
`hasBetaInfo` | Whether there's an ongoing Stardew Valley or SMAPI beta which may affect update checks.
|
||||
`compatibilityStatus` | The compatibility status for the mod for the stable version of the game, as defined on the wiki, if any. See [possible values](https://github.com/Pathoschild/SMAPI/blob/develop/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs).
|
||||
`compatibilitySummary` | The human-readable summary of the mod's compatibility in HTML format, if any.
|
||||
`brokeIn` | The SMAPI or Stardew Valley version that broke this mod, if any.
|
||||
`betaCompatibilityStatus`<br />`betaCompatibilitySummary`<br />`betaBrokeIn` | Equivalent to the preceding fields, but for beta versions of SMAPI or Stardew Valley.
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Example response with `includeExtendedMetadata: false`:
|
||||
```js
|
||||
[
|
||||
{
|
||||
"id": "Pathoschild.ContentPatcher",
|
||||
"suggestedUpdate": {
|
||||
"version": "1.10.0",
|
||||
"url": "https://www.nexusmods.com/stardewvalley/mods/1915"
|
||||
},
|
||||
"errors": []
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Example response with `includeExtendedMetadata: true`:
|
||||
```js
|
||||
[
|
||||
{
|
||||
"id": "Pathoschild.ContentPatcher",
|
||||
"suggestedUpdate": {
|
||||
"version": "1.10.0",
|
||||
"url": "https://www.nexusmods.com/stardewvalley/mods/1915"
|
||||
},
|
||||
"metadata": {
|
||||
"id": [ "Pathoschild.ContentPatcher" ],
|
||||
"name": "Content Patcher",
|
||||
"nexusID": 1915,
|
||||
"curseForgeID": 309243,
|
||||
"curseForgeKey": "content-patcher",
|
||||
"modDropID": 470174,
|
||||
"gitHubRepo": "Pathoschild/StardewMods",
|
||||
"main": {
|
||||
"version": "1.10",
|
||||
"url": "https://www.nexusmods.com/stardewvalley/mods/1915"
|
||||
},
|
||||
"hasBetaInfo": true,
|
||||
"compatibilityStatus": "Ok",
|
||||
"compatibilitySummary": "✓ use latest version."
|
||||
},
|
||||
"errors": []
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Short URLs
|
||||
The SMAPI web services provides a few short URLs for convenience:
|
||||
|
||||
short url | → | target page
|
||||
:-------- | - | :----------
|
||||
[smapi.io/3.0](https://smapi.io/3.0) | → | [stardewvalleywiki.com/Modding:Migrate_to_SMAPI_3.0](https://stardewvalleywiki.com/Modding:Migrate_to_SMAPI_3.0)
|
||||
[smapi.io/community](https://smapi.io/community) | → | [stardewvalleywiki.com/Modding:Community](https://stardewvalleywiki.com/Modding:Community)
|
||||
[smapi.io/docs](https://smapi.io/docs) | → | [stardewvalleywiki.com/Modding:Index](https://stardewvalleywiki.com/Modding:Index)
|
||||
[smapi.io/package](https://smapi.io/package) | → | [github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md](https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md)
|
||||
[smapi.io/troubleshoot](https://smapi.io/troubleshoot) | → | [stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting](https://stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting)
|
||||
[smapi.io/xnb](https://smapi.io/xnb) | → | [stardewvalleywiki.com/Modding:Using_XNB_mods](https://stardewvalleywiki.com/Modding:Using_XNB_mods)
|
||||
|
||||
## For SMAPI developers
|
||||
### Local environment
|
||||
A local environment lets you run a complete copy of the web project (including cache database) on
|
||||
your machine, with no external dependencies aside from the actual mod sites.
|
||||
|
||||
1. Edit `appsettings.Development.json` and set these options:
|
||||
|
||||
property name | description
|
||||
------------- | -----------
|
||||
`NexusApiKey` | [Your Nexus API key](https://www.nexusmods.com/users/myaccount?tab=api#personal_key).
|
||||
|
||||
Optional settings:
|
||||
|
||||
property name | description
|
||||
--------------------------- | -----------
|
||||
`AzureBlobConnectionString` | The connection string for the Azure Blob storage account. Defaults to using the system's temporary file folder if not specified.
|
||||
`GitHubUsername`<br />`GitHubPassword` | The GitHub credentials with which to query GitHub release info. Defaults to anonymous requests if not specified.
|
||||
|
||||
2. Launch `SMAPI.Web` from Visual Studio to run a local version of the site.
|
||||
|
||||
### Production environment
|
||||
A production environment includes the web servers and cache database hosted online for public
|
||||
access.
|
||||
|
||||
This section assumes you're creating a new environment on Azure, but the app isn't tied to any
|
||||
Azure services. If you want to host it on a different site, you'll need to adjust the instructions
|
||||
accordingly.
|
||||
|
||||
Initial setup:
|
||||
|
||||
1. Create an Azure Blob storage account for uploaded files.
|
||||
2. Create an Azure App Services environment running the latest .NET on Linux or Windows.
|
||||
3. Add these application settings in the new App Services environment:
|
||||
|
||||
property name | description
|
||||
------------------------------- | -----------------
|
||||
`ApiClients.AzureBlobConnectionString` | The connection string for the Azure Blob storage account created in step 2.
|
||||
`ApiClients.GitHubUsername`<br />`ApiClients.GitHubPassword` | The login credentials for the GitHub account with which to fetch release info. If these are omitted, GitHub will impose much stricter rate limits.
|
||||
`ApiClients:NexusApiKey` | The [Nexus API authentication key](https://github.com/Pathoschild/FluentNexus#init-a-client).
|
||||
|
||||
Optional settings:
|
||||
|
||||
property name | description
|
||||
------------------------------- | -----------------
|
||||
`BackgroundServices:Enabled` | Set to `true` to enable background processes like fetching data from the wiki, or false to disable them.
|
||||
`Site:BetaEnabled` | Set to `true` to show a separate download button if there's a beta version of SMAPI in its GitHub releases.
|
||||
`Site:BetaBlurb` | If `Site:BetaEnabled` is true and there's a beta version of SMAPI in its GitHub releases, this is shown on the beta download button as explanatory subtext.
|
||||
`Site:SupporterList` | A list of Patreon supports to credit on the download page.
|
||||
|
||||
To deploy updates, just [redeploy the web project from Visual Studio](https://docs.microsoft.com/en-us/visualstudio/deployment/quickstart-deploy-to-azure).
|
|
@ -1,19 +0,0 @@
|
|||
Any raw assets you want to be deployed with your application can be placed in
|
||||
this directory (and child directories) and given a Build Action of "AndroidAsset".
|
||||
|
||||
These files will be deployed with your package and will be accessible using Android's
|
||||
AssetManager, like this:
|
||||
|
||||
public class ReadAsset : Activity
|
||||
{
|
||||
protected override void OnCreate (Bundle bundle)
|
||||
{
|
||||
base.OnCreate (bundle);
|
||||
|
||||
InputStream input = Assets.Open ("my_asset.txt");
|
||||
}
|
||||
}
|
||||
|
||||
Additionally, some Android functions will automatically load asset files:
|
||||
|
||||
Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
|
|
@ -1,110 +0,0 @@
|
|||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{45D7D2FB-6B70-45D1-A595-6E289D6A3468}</ProjectGuid>
|
||||
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<TemplateGuid>{122416d6-6b49-4ee2-a1e8-b825f31c79fe}</TemplateGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Loader</RootNamespace>
|
||||
<AssemblyName>Loader</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidApplication>True</AndroidApplication>
|
||||
<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
|
||||
<AndroidResgenClass>Resource</AndroidResgenClass>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v12.0</TargetFrameworkVersion>
|
||||
<TargetFramework>net5.0-android</TargetFramework>
|
||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
|
||||
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
|
||||
<MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
|
||||
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
<DebugType>portable</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidUseSharedRuntime>true</AndroidUseSharedRuntime>
|
||||
<AndroidLinkMode>None</AndroidLinkMode>
|
||||
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>
|
||||
<AndroidManagedSymbols>false</AndroidManagedSymbols>
|
||||
<AndroidUseAapt2>true</AndroidUseAapt2>
|
||||
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a;x86_64</AndroidSupportedAbis>
|
||||
<AndroidDexTool>d8</AndroidDexTool>
|
||||
<!-- <AndroidLinkSkip>Mono.Android;MonoGame.Framework;mscorlib;System.Core;System;System.Drawing.Common;System.Numerics;System.Runtime.Serialization;System.Xml;System.Xml.Linq</AndroidLinkSkip>-->
|
||||
<AndroidEnableMultiDex>true</AndroidEnableMultiDex>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugSymbols>False</DebugSymbols>
|
||||
<DebugType>portable</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AndroidManagedSymbols>false</AndroidManagedSymbols>
|
||||
<AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
|
||||
<AndroidLinkMode>None</AndroidLinkMode>
|
||||
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>
|
||||
<AndroidUseAapt2>true</AndroidUseAapt2>
|
||||
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a;x86_64</AndroidSupportedAbis>
|
||||
<AndroidDexTool>d8</AndroidDexTool>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Resources\Resource.designer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Resources\AboutResources.txt" />
|
||||
<None Include="Properties\AndroidManifest.xml" />
|
||||
<None Include="Assets\AboutAssets.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\icon.png" />
|
||||
<AndroidResource Include="Resources\drawable\splash.png" />
|
||||
<AndroidResource Include="Resources\drawable\splash_logos_crop.png" />
|
||||
<AndroidResource Include="Resources\drawable\splash_screen.xml" />
|
||||
<AndroidResource Include="Resources\values\colors.xml" />
|
||||
<AndroidResource Include="Resources\values\ic_launcher_background.xml" />
|
||||
<AndroidResource Include="Resources\values\strings.xml" />
|
||||
<AndroidResource Include="Resources\values\styles.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Android" />
|
||||
<Reference Include="Mono.Security" />
|
||||
<ProjectReference Include="..\SMAPI\SMAPI.csproj" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\mipmap\ic_launcher.png" />
|
||||
<AndroidResource Include="Resources\mipmap\ic_launcher_background.png" />
|
||||
<AndroidResource Include="Resources\mipmap\ic_launcher_foreground.png" />
|
||||
<AndroidResource Include="Resources\mipmap\ic_launcher_round.png" />
|
||||
<AndroidResource Include="Resources\xml\provider_paths.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidAsset Include="Assets\Content\**" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="156" android:versionName="1.5.6.31" android:installLocation="auto" package="com.zane.stardewvalley2" platformBuildVersionCode="31" platformBuildVersionName="9">
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<application
|
||||
android:label="SMAPI Stardew Valley"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:name="android.app.Application"
|
||||
android:allowBackup="true"
|
||||
android:resizeableActivity="false"
|
||||
android:debuggable="true"
|
||||
android:requestLegacyExternalStorage="true">
|
||||
</application>
|
||||
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
|
||||
</manifest>
|
|
@ -1,28 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Loader")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Loader")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,44 +0,0 @@
|
|||
Images, layout descriptions, binary blobs and string dictionaries can be included
|
||||
in your application as resource files. Various Android APIs are designed to
|
||||
operate on the resource IDs instead of dealing with images, strings or binary blobs
|
||||
directly.
|
||||
|
||||
For example, a sample Android app that contains a user interface layout (main.xml),
|
||||
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
|
||||
would keep its resources in the "Resources" directory of the application:
|
||||
|
||||
Resources/
|
||||
drawable/
|
||||
icon.png
|
||||
|
||||
layout/
|
||||
main.xml
|
||||
|
||||
values/
|
||||
strings.xml
|
||||
|
||||
In order to get the build system to recognize Android resources, set the build action to
|
||||
"AndroidResource". The native Android APIs do not operate directly with filenames, but
|
||||
instead operate on resource IDs. When you compile an Android application that uses resources,
|
||||
the build system will package the resources for distribution and generate a class called "R"
|
||||
(this is an Android convention) that contains the tokens for each one of the resources
|
||||
included. For example, for the above Resources layout, this is what the R class would expose:
|
||||
|
||||
public class R {
|
||||
public class drawable {
|
||||
public const int icon = 0x123;
|
||||
}
|
||||
|
||||
public class layout {
|
||||
public const int main = 0x456;
|
||||
}
|
||||
|
||||
public class strings {
|
||||
public const int first_string = 0xabc;
|
||||
public const int second_string = 0xbcd;
|
||||
}
|
||||
}
|
||||
|
||||
You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main
|
||||
to reference the layout/main.xml file, or R.strings.first_string to reference the first
|
||||
string in the dictionary file values/strings.xml.
|
|
@ -1,175 +0,0 @@
|
|||
#pragma warning disable 1591
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
[assembly: global::Android.Runtime.ResourceDesignerAttribute("Loader.Resource", IsApplication=true)]
|
||||
|
||||
namespace Loader
|
||||
{
|
||||
|
||||
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.2.0.99")]
|
||||
public partial class Resource
|
||||
{
|
||||
|
||||
static Resource()
|
||||
{
|
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||
}
|
||||
|
||||
public static void UpdateIdValues()
|
||||
{
|
||||
global::StardewModdingAPI.Resource.String.app_name = global::Loader.Resource.String.app_name;
|
||||
global::StardewModdingAPI.Resource.String.hello = global::Loader.Resource.String.hello;
|
||||
}
|
||||
|
||||
public partial class Attribute
|
||||
{
|
||||
|
||||
static Attribute()
|
||||
{
|
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||
}
|
||||
|
||||
private Attribute()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Color
|
||||
{
|
||||
|
||||
// aapt resource value: 0x7F010000
|
||||
public const int colorAccent = 2130771968;
|
||||
|
||||
// aapt resource value: 0x7F010001
|
||||
public const int colorPrimary = 2130771969;
|
||||
|
||||
// aapt resource value: 0x7F010002
|
||||
public const int colorPrimaryDark = 2130771970;
|
||||
|
||||
// aapt resource value: 0x7F010003
|
||||
public const int ic_launcher_background = 2130771971;
|
||||
|
||||
static Color()
|
||||
{
|
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||
}
|
||||
|
||||
private Color()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Drawable
|
||||
{
|
||||
|
||||
// aapt resource value: 0x7F020000
|
||||
public const int icon = 2130837504;
|
||||
|
||||
// aapt resource value: 0x7F020001
|
||||
public const int splash = 2130837505;
|
||||
|
||||
// aapt resource value: 0x7F020002
|
||||
public const int splash_logos_crop = 2130837506;
|
||||
|
||||
// aapt resource value: 0x7F020003
|
||||
public const int splash_screen = 2130837507;
|
||||
|
||||
static Drawable()
|
||||
{
|
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||
}
|
||||
|
||||
private Drawable()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Mipmap
|
||||
{
|
||||
|
||||
// aapt resource value: 0x7F030000
|
||||
public const int ic_launcher = 2130903040;
|
||||
|
||||
// aapt resource value: 0x7F030001
|
||||
public const int ic_launcher_background = 2130903041;
|
||||
|
||||
// aapt resource value: 0x7F030002
|
||||
public const int ic_launcher_foreground = 2130903042;
|
||||
|
||||
// aapt resource value: 0x7F030003
|
||||
public const int ic_launcher_round = 2130903043;
|
||||
|
||||
static Mipmap()
|
||||
{
|
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||
}
|
||||
|
||||
private Mipmap()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public partial class String
|
||||
{
|
||||
|
||||
// aapt resource value: 0x7F040000
|
||||
public const int action_settings = 2130968576;
|
||||
|
||||
// aapt resource value: 0x7F040001
|
||||
public const int app_name = 2130968577;
|
||||
|
||||
// aapt resource value: 0x7F040002
|
||||
public const int hello = 2130968578;
|
||||
|
||||
static String()
|
||||
{
|
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||
}
|
||||
|
||||
private String()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Style
|
||||
{
|
||||
|
||||
// aapt resource value: 0x7F050000
|
||||
public const int Theme_Splash = 2131034112;
|
||||
|
||||
static Style()
|
||||
{
|
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||
}
|
||||
|
||||
private Style()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Xml
|
||||
{
|
||||
|
||||
// aapt resource value: 0x7F060000
|
||||
public const int provider_paths = 2131099648;
|
||||
|
||||
static Xml()
|
||||
{
|
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||
}
|
||||
|
||||
private Xml()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 14 KiB |
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<color android:color="#ffffff" />
|
||||
</item>
|
||||
<item>
|
||||
<bitmap android:tileMode="disabled" android:gravity="center" android:src="@drawable/splash_logos_crop"/>
|
||||
</item>
|
||||
</layer-list>
|
Before Width: | Height: | Size: 314 B |
Before Width: | Height: | Size: 965 B |
Before Width: | Height: | Size: 373 B |
Before Width: | Height: | Size: 6.1 KiB |
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#2c3e50</color>
|
||||
<color name="colorPrimaryDark">#1B3147</color>
|
||||
<color name="colorAccent">#3498db</color>
|
||||
</resources>
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#2C3E50</color>
|
||||
</resources>
|
|
@ -1,4 +0,0 @@
|
|||
<resources>
|
||||
<string name="app_name">Loader</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
</resources>
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="Theme.Splash" parent="android:Theme">
|
||||
<item name="android:windowBackground">@drawable/splash_screen</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowFullscreen">true</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<external-path name="external_files" path="." />
|
||||
<files-path name="files" path="." />
|
||||
<internal-path name="internal_files" path="." />
|
||||
</paths>
|
|
@ -1,3 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
</packages>
|
|
@ -1,42 +0,0 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
#nullable enable
|
||||
namespace System.Linq
|
||||
{
|
||||
public static class EnumerableExtension
|
||||
{
|
||||
/// <summary>Produces a sequence of tuples with elements from the two specified sequences.</summary>
|
||||
/// <param name="first">The first sequence to merge.</param>
|
||||
/// <param name="second">The second sequence to merge.</param>
|
||||
/// <typeparam name="TFirst">The type of the elements of the first input sequence.</typeparam>
|
||||
/// <typeparam name="TSecond">The type of the elements of the second input sequence.</typeparam>
|
||||
/// <returns>A sequence of tuples with elements taken from the first and second sequences, in that order.</returns>
|
||||
public static IEnumerable<(TFirst First, TSecond Second)> Zip<TFirst, TSecond>(
|
||||
this IEnumerable<TFirst> first,
|
||||
IEnumerable<TSecond> second)
|
||||
{
|
||||
if (first == null)
|
||||
throw new ArgumentNullException("first");
|
||||
if (second == null)
|
||||
throw new ArgumentNullException("second");
|
||||
return ZipIterator<TFirst, TSecond>(first, second);
|
||||
}
|
||||
#nullable disable
|
||||
private static IEnumerable<(TFirst First, TSecond Second)> ZipIterator<TFirst, TSecond>(
|
||||
IEnumerable<TFirst> first,
|
||||
IEnumerable<TSecond> second)
|
||||
{
|
||||
using (IEnumerator<TFirst> e1 = first.GetEnumerator())
|
||||
{
|
||||
using (IEnumerator<TSecond> e2 = second.GetEnumerator())
|
||||
{
|
||||
while (e1.MoveNext() && e2.MoveNext())
|
||||
yield return (e1.Current, e2.Current);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
namespace System;
|
||||
using Internal.Runtime.CompilerServices;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
public static class MobileMemoryExtension
|
||||
{
|
||||
|
||||
/// <summary>Indicates whether a specified value is found in a read-only span. Values are compared using IEquatable{T}.Equals(T).</summary>
|
||||
/// <param name="span">The span to search.</param>
|
||||
/// <param name="value">The value to search for.</param>
|
||||
/// <typeparam name="T">The type of the span.</typeparam>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if found, <see langword="false" /> otherwise.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool Contains<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
|
||||
{
|
||||
return span.IndexOf(value) >= 0;
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
namespace System;
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
public static class MobileTypeExtension
|
||||
{
|
||||
|
||||
/// <summary>Determines whether the current type can be assigned to a variable of the specified <paramref name="targetType" />.</summary>
|
||||
/// <param name="targetType">The type to compare with the current type.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if any of the following conditions is true:
|
||||
///
|
||||
/// - The current instance and <paramref name="targetType" /> represent the same type.
|
||||
///
|
||||
/// - The current type is derived either directly or indirectly from <paramref name="targetType" />. The current type is derived directly from <paramref name="targetType" /> if it inherits from <paramref name="targetType" />; the current type is derived indirectly from <paramref name="targetType" /> if it inherits from a succession of one or more classes that inherit from <paramref name="targetType" />.
|
||||
///
|
||||
/// - <paramref name="targetType" /> is an interface that the current type implements.
|
||||
///
|
||||
/// - The current type is a generic type parameter, and <paramref name="targetType" /> represents one of the constraints of the current type.
|
||||
///
|
||||
/// - The current type represents a value type, and <paramref name="targetType" /> represents <c>Nullable<c></c> (<c>Nullable(Of c)</c> in Visual Basic).
|
||||
///
|
||||
/// <see langword="false" /> if none of these conditions are true, or if <paramref name="targetType" /> or <see langword="this" /> is <see langword="null" />.</returns>
|
||||
public static bool IsAssignableTo(this Type type, [NotNullWhen(true)] Type? targetType) => (object) targetType != null && targetType.IsAssignableFrom(type);
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
|
||||
#nullable enable
|
||||
namespace System.Collections.Generic
|
||||
{
|
||||
/// <summary>An <see cref="T:System.Collections.Generic.IEqualityComparer`1" /> that uses reference equality (<see cref="M:System.Object.ReferenceEquals(System.Object,System.Object)" />) instead of value equality (<see cref="M:System.Object.Equals(System.Object)" />) when comparing two object instances.</summary>
|
||||
public sealed class ReferenceEqualityComparer : IEqualityComparer<object?>, IEqualityComparer
|
||||
{
|
||||
private ReferenceEqualityComparer()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Gets the singleton <see cref="T:System.Collections.Generic.ReferenceEqualityComparer" /> instance.</summary>
|
||||
public static ReferenceEqualityComparer Instance { get; } = new ReferenceEqualityComparer();
|
||||
|
||||
/// <summary>Determines whether two object references refer to the same object instance.</summary>
|
||||
/// <param name="x">The first object to compare.</param>
|
||||
/// <param name="y">The second object to compare.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true" /> if both <paramref name="x" /> and <paramref name="y" /> refer to the same object instance or if both are <see langword="null" />; otherwise, <see langword="false" />.</returns>
|
||||
public bool Equals(object? x, object? y) => x == y;
|
||||
|
||||
/// <summary>Returns a hash code for the specified object. The returned hash code is based on the object identity, not on the contents of the object.</summary>
|
||||
/// <param name="obj">The object for which to retrieve the hash code.</param>
|
||||
/// <returns>A hash code for the identity of <paramref name="obj" />.</returns>
|
||||
public int GetHashCode(object? obj) => RuntimeHelpers.GetHashCode(obj);
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{E5FE4C97-1A7C-4A97-9904-7351CA020C7F}</ProjectGuid>
|
||||
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MobilePatch</RootNamespace>
|
||||
<AssemblyName>MobilePatch</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
|
||||
<TargetFrameworkVersion>v12.0</TargetFrameworkVersion>
|
||||
<TargetFramework>net5.0-android</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Android" />
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Mobile\EnumerableExtension.cs" />
|
||||
<Compile Include="Mobile\MobileMemoryExtension.cs" />
|
||||
<Compile Include="Mobile\MobileTypeExtension.cs" />
|
||||
<Compile Include="Mobile\ReferenceEqualityComparer.cs" />
|
||||
<Compile Include="Resources\Resource.Designer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\AboutResources.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\values\strings.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\drawable\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,30 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Android.App;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("MobilePatch")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("MobilePatch")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2023")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,44 +0,0 @@
|
|||
Images, layout descriptions, binary blobs and string dictionaries can be included
|
||||
in your application as resource files. Various Android APIs are designed to
|
||||
operate on the resource IDs instead of dealing with images, strings or binary blobs
|
||||
directly.
|
||||
|
||||
For example, a sample Android app that contains a user interface layout (main.axml),
|
||||
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
|
||||
would keep its resources in the "Resources" directory of the application:
|
||||
|
||||
Resources/
|
||||
drawable/
|
||||
icon.png
|
||||
|
||||
layout/
|
||||
main.axml
|
||||
|
||||
values/
|
||||
strings.xml
|
||||
|
||||
In order to get the build system to recognize Android resources, set the build action to
|
||||
"AndroidResource". The native Android APIs do not operate directly with filenames, but
|
||||
instead operate on resource IDs. When you compile an Android application that uses resources,
|
||||
the build system will package the resources for distribution and generate a class called "R"
|
||||
(this is an Android convention) that contains the tokens for each one of the resources
|
||||
included. For example, for the above Resources layout, this is what the R class would expose:
|
||||
|
||||
public class R {
|
||||
public class drawable {
|
||||
public const int icon = 0x123;
|
||||
}
|
||||
|
||||
public class layout {
|
||||
public const int main = 0x456;
|
||||
}
|
||||
|
||||
public class strings {
|
||||
public const int first_string = 0xabc;
|
||||
public const int second_string = 0xbcd;
|
||||
}
|
||||
}
|
||||
|
||||
You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main
|
||||
to reference the layout/main.axml file, or R.strings.first_string to reference the first
|
||||
string in the dictionary file values/strings.xml.
|
|
@ -1,59 +0,0 @@
|
|||
#pragma warning disable 1591
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
[assembly: global::Android.Runtime.ResourceDesignerAttribute("MobilePatch.Resource", IsApplication=false)]
|
||||
|
||||
namespace MobilePatch
|
||||
{
|
||||
|
||||
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.2.0.99")]
|
||||
public partial class Resource
|
||||
{
|
||||
|
||||
static Resource()
|
||||
{
|
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||
}
|
||||
|
||||
public partial class Attribute
|
||||
{
|
||||
|
||||
static Attribute()
|
||||
{
|
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||
}
|
||||
|
||||
private Attribute()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public partial class String
|
||||
{
|
||||
|
||||
// aapt resource value: 0x7F010000
|
||||
public static int app_name = 2130771968;
|
||||
|
||||
// aapt resource value: 0x7F010001
|
||||
public static int hello = 2130771969;
|
||||
|
||||
static String()
|
||||
{
|
||||
global::Android.Runtime.ResourceIdManager.UpdateIdValues();
|
||||
}
|
||||
|
||||
private String()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
|
@ -1,4 +0,0 @@
|
|||
<resources>
|
||||
<string name="hello">Hello World, Click Me!</string>
|
||||
<string name="app_name">MobilePatch</string>
|
||||
</resources>
|
|
@ -9,4 +9,4 @@
|
|||
/// <summary>Remove SMAPI from the game directory.</summary>
|
||||
Uninstall
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
using System.IO;
|
||||
using StardewModdingAPI.Toolkit;
|
||||
using StardewModdingAPI.Toolkit.Framework.GameScanning;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
|
||||
namespace StardewModdingAPI.Installer.Framework
|
||||
{
|
||||
/// <summary>The installer context.</summary>
|
||||
internal class InstallerContext
|
||||
{
|
||||
/*********
|
||||
** Fields
|
||||
*********/
|
||||
/// <summary>The underlying toolkit game scanner.</summary>
|
||||
private readonly GameScanner GameScanner = new();
|
||||
|
||||
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>The current OS.</summary>
|
||||
public Platform Platform { get; }
|
||||
|
||||
/// <summary>The human-readable OS name and version.</summary>
|
||||
public string PlatformName { get; }
|
||||
|
||||
/// <summary>Whether the installer is running on Windows.</summary>
|
||||
public bool IsWindows => this.Platform == Platform.Windows;
|
||||
|
||||
/// <summary>Whether the installer is running on a Unix OS (including Linux or macOS).</summary>
|
||||
public bool IsUnix => !this.IsWindows;
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
public InstallerContext()
|
||||
{
|
||||
this.Platform = EnvironmentUtility.DetectPlatform();
|
||||
this.PlatformName = EnvironmentUtility.GetFriendlyPlatformName(this.Platform);
|
||||
}
|
||||
|
||||
/// <summary>Get the installer's version number.</summary>
|
||||
public ISemanticVersion GetInstallerVersion()
|
||||
{
|
||||
var raw = this.GetType().Assembly.GetName().Version!;
|
||||
return new SemanticVersion(raw);
|
||||
}
|
||||
|
||||
/// <summary>Get whether a folder seems to contain the game files.</summary>
|
||||
/// <param name="dir">The folder to check.</param>
|
||||
public bool LooksLikeGameFolder(DirectoryInfo dir)
|
||||
{
|
||||
return this.GameScanner.LooksLikeGameFolder(dir);
|
||||
}
|
||||
|
||||
/// <summary>Get whether a folder seems to contain the game, and which version it contains if so.</summary>
|
||||
/// <param name="dir">The folder to check.</param>
|
||||
public GameFolderType GetGameFolderType(DirectoryInfo dir)
|
||||
{
|
||||
return this.GameScanner.GetGameFolderType(dir);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using System.IO;
|
||||
using StardewModdingAPI.Toolkit.Framework;
|
||||
|
||||
namespace StardewModdingAPI.Installer.Framework
|
||||
{
|
||||
|
@ -9,9 +8,6 @@ namespace StardewModdingAPI.Installer.Framework
|
|||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/****
|
||||
** Main folders
|
||||
****/
|
||||
/// <summary>The directory path containing the files to copy into the game folder.</summary>
|
||||
public DirectoryInfo BundleDir { get; }
|
||||
|
||||
|
@ -21,18 +17,9 @@ namespace StardewModdingAPI.Installer.Framework
|
|||
/// <summary>The directory into which to install mods.</summary>
|
||||
public DirectoryInfo ModsDir { get; }
|
||||
|
||||
/****
|
||||
** Installer paths
|
||||
****/
|
||||
/// <summary>The full path to directory path containing the files to copy into the game folder.</summary>
|
||||
public string BundlePath => this.BundleDir.FullName;
|
||||
|
||||
/// <summary>The full path to the backup API user settings folder, if applicable.</summary>
|
||||
public string BundleApiUserConfigPath { get; }
|
||||
|
||||
/****
|
||||
** Game paths
|
||||
****/
|
||||
/// <summary>The full path to the directory containing the installed game.</summary>
|
||||
public string GamePath => this.GameDir.FullName;
|
||||
|
||||
|
@ -42,23 +29,17 @@ namespace StardewModdingAPI.Installer.Framework
|
|||
/// <summary>The full path to SMAPI's internal configuration file.</summary>
|
||||
public string ApiConfigPath { get; }
|
||||
|
||||
/// <summary>The full path to the user's config overrides file.</summary>
|
||||
public string ApiUserConfigPath { get; }
|
||||
|
||||
/// <summary>The full path to the installed game DLL.</summary>
|
||||
public string GameDllPath { get; }
|
||||
|
||||
/// <summary>The full path to the installed SMAPI executable file.</summary>
|
||||
public string UnixSmapiExecutablePath { get; }
|
||||
public string ExecutablePath { get; }
|
||||
|
||||
/// <summary>The full path to the vanilla game launch script on Linux/macOS.</summary>
|
||||
public string VanillaLaunchScriptPath { get; }
|
||||
/// <summary>The full path to the vanilla game launcher on Linux/Mac.</summary>
|
||||
public string UnixLauncherPath { get; }
|
||||
|
||||
/// <summary>The full path to the installed SMAPI launch script on Linux/macOS before it's renamed.</summary>
|
||||
public string NewLaunchScriptPath { get; }
|
||||
/// <summary>The full path to the installed SMAPI launcher on Linux/Mac before it's renamed.</summary>
|
||||
public string UnixSmapiLauncherPath { get; }
|
||||
|
||||
/// <summary>The full path to the backed up game launch script on Linux/macOS after SMAPI is installed.</summary>
|
||||
public string BackupLaunchScriptPath { get; }
|
||||
/// <summary>The full path to the vanilla game launcher on Linux/Mac after SMAPI is installed.</summary>
|
||||
public string UnixBackupLauncherPath { get; }
|
||||
|
||||
|
||||
/*********
|
||||
|
@ -67,24 +48,18 @@ namespace StardewModdingAPI.Installer.Framework
|
|||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="bundleDir">The directory path containing the files to copy into the game folder.</param>
|
||||
/// <param name="gameDir">The directory path for the installed game.</param>
|
||||
public InstallerPaths(DirectoryInfo bundleDir, DirectoryInfo gameDir)
|
||||
/// <param name="gameExecutableName">The name of the game's executable file for the current platform.</param>
|
||||
public InstallerPaths(DirectoryInfo bundleDir, DirectoryInfo gameDir, string gameExecutableName)
|
||||
{
|
||||
// base paths
|
||||
this.BundleDir = bundleDir;
|
||||
this.GameDir = gameDir;
|
||||
this.ModsDir = new DirectoryInfo(Path.Combine(gameDir.FullName, "Mods"));
|
||||
this.GameDllPath = Path.Combine(gameDir.FullName, Constants.GameDllName);
|
||||
|
||||
// launch scripts
|
||||
this.VanillaLaunchScriptPath = Path.Combine(gameDir.FullName, "StardewValley");
|
||||
this.NewLaunchScriptPath = Path.Combine(gameDir.FullName, "unix-launcher.sh");
|
||||
this.BackupLaunchScriptPath = Path.Combine(gameDir.FullName, "StardewValley-original");
|
||||
this.UnixSmapiExecutablePath = Path.Combine(gameDir.FullName, "StardewModdingAPI");
|
||||
|
||||
// internal files
|
||||
this.BundleApiUserConfigPath = Path.Combine(bundleDir.FullName, "smapi-internal", "config.user.json");
|
||||
this.ApiConfigPath = Path.Combine(gameDir.FullName, "smapi-internal", "config.json");
|
||||
this.ApiUserConfigPath = Path.Combine(gameDir.FullName, "smapi-internal", "config.user.json");
|
||||
this.ExecutablePath = Path.Combine(gameDir.FullName, gameExecutableName);
|
||||
this.UnixLauncherPath = Path.Combine(gameDir.FullName, "StardewValley");
|
||||
this.UnixSmapiLauncherPath = Path.Combine(gameDir.FullName, "StardewModdingAPI");
|
||||
this.UnixBackupLauncherPath = Path.Combine(gameDir.FullName, "StardewValley-original");
|
||||
this.ApiConfigPath = Path.Combine(gameDir.FullName, "smapi-internal", "StardewModdingAPI.config.json");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using StardewModdingAPI.Internal;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
|
||||
namespace StardewModdingApi.Installer
|
||||
{
|
||||
|
@ -11,11 +12,11 @@ namespace StardewModdingApi.Installer
|
|||
internal class Program
|
||||
{
|
||||
/*********
|
||||
** Fields
|
||||
** Properties
|
||||
*********/
|
||||
/// <summary>The absolute path of the installer folder.</summary>
|
||||
[SuppressMessage("ReSharper", "AssignNullToNotNullAttribute", Justification = "The assembly location is never null in this context.")]
|
||||
private static readonly string InstallerPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!;
|
||||
private static readonly string InstallerPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
|
||||
/// <summary>The absolute path of the folder containing the unzipped installer files.</summary>
|
||||
private static readonly string ExtractedBundlePath = Path.Combine(Path.GetTempPath(), $"SMAPI-installer-{Guid.NewGuid():N}");
|
||||
|
@ -31,16 +32,17 @@ namespace StardewModdingApi.Installer
|
|||
public static void Main(string[] args)
|
||||
{
|
||||
// find install bundle
|
||||
FileInfo zipFile = new(Path.Combine(Program.InstallerPath, "install.dat"));
|
||||
PlatformID platform = Environment.OSVersion.Platform;
|
||||
FileInfo zipFile = new FileInfo(Path.Combine(Program.InstallerPath, $"{(platform == PlatformID.Win32NT ? "windows" : "unix")}-install.dat"));
|
||||
if (!zipFile.Exists)
|
||||
{
|
||||
Console.WriteLine($"Oops! Some of the installer files are missing; try re-downloading the installer. (Missing file: {zipFile.FullName})");
|
||||
Console.WriteLine($"Oops! Some of the installer files are missing; try redownloading the installer. (Missing file: {zipFile.FullName})");
|
||||
Console.ReadLine();
|
||||
return;
|
||||
}
|
||||
|
||||
// unzip bundle into temp folder
|
||||
DirectoryInfo bundleDir = new(Program.ExtractedBundlePath);
|
||||
DirectoryInfo bundleDir = new DirectoryInfo(Program.ExtractedBundlePath);
|
||||
Console.WriteLine("Extracting install files...");
|
||||
ZipFile.ExtractToDirectory(zipFile.FullName, bundleDir.FullName);
|
||||
|
||||
|
@ -49,15 +51,7 @@ namespace StardewModdingApi.Installer
|
|||
|
||||
// launch installer
|
||||
var installer = new InteractiveInstaller(bundleDir.FullName);
|
||||
|
||||
try
|
||||
{
|
||||
installer.Run(args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.PrintErrorAndExit($"The installer failed with an unexpected exception.\nIf you need help fixing this error, see https://smapi.io/help\n\n{ex}");
|
||||
}
|
||||
installer.Run(args);
|
||||
}
|
||||
|
||||
/*********
|
||||
|
@ -66,14 +60,14 @@ namespace StardewModdingApi.Installer
|
|||
/// <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)
|
||||
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
AssemblyName name = new(e.Name);
|
||||
AssemblyName name = new AssemblyName(e.Name);
|
||||
foreach (FileInfo dll in new DirectoryInfo(Program.InternalFilesPath).EnumerateFiles("*.dll"))
|
||||
{
|
||||
if (name.Name != null && name.Name.Equals(AssemblyName.GetAssemblyName(dll.FullName).Name, StringComparison.OrdinalIgnoreCase))
|
||||
if (name.Name.Equals(AssemblyName.GetAssemblyName(dll.FullName).Name, StringComparison.InvariantCultureIgnoreCase))
|
||||
return Assembly.LoadFrom(dll.FullName);
|
||||
}
|
||||
return null;
|
||||
|
@ -84,19 +78,5 @@ namespace StardewModdingApi.Installer
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Write an error directly to the console and exit.</summary>
|
||||
/// <param name="message">The error message to display.</param>
|
||||
private static void PrintErrorAndExit(string message)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(message);
|
||||
Console.ResetColor();
|
||||
|
||||
Console.WriteLine("Game has ended. Press any key to exit.");
|
||||
Thread.Sleep(100);
|
||||
Console.ReadKey();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyTitle("SMAPI.Installer")]
|
||||
[assembly: AssemblyDescription("The SMAPI installer for players.")]
|
|
@ -14,34 +14,31 @@
|
|||
SMAPI lets you run Stardew Valley with mods. Don't forget to download mods separately.
|
||||
|
||||
|
||||
Automated install
|
||||
Player's guide
|
||||
--------------------------------
|
||||
See https://stardewvalleywiki.com/Modding:Player_Guide for help installing SMAPI, adding mods, etc.
|
||||
|
||||
|
||||
Manual install
|
||||
--------------------------------
|
||||
THIS IS NOT RECOMMENDED FOR MOST PLAYERS. See the instructions above instead.
|
||||
THIS IS NOT RECOMMENDED FOR MOST PLAYERS. See instructions above instead.
|
||||
If you really want to install SMAPI manually, here's how.
|
||||
|
||||
1. Unzip "internal/windows/install.dat" (on Windows) or "internal/unix/install.dat" (on Linux or
|
||||
macOS). You can change '.dat' to '.zip', it's just a normal zip file renamed to prevent
|
||||
confusion.
|
||||
|
||||
1. Unzip "internal/windows-install.dat" (on Windows) or "internal/unix-install.dat" (on Linux/Mac).
|
||||
You can change '.dat' to '.zip', it's just a normal zip file renamed to prevent confusion.
|
||||
2. Copy the files from the folder you just unzipped into your game folder. The
|
||||
`StardewModdingAPI.exe` file should be right next to the game's executable.
|
||||
|
||||
3. Copy `Stardew Valley.deps.json` in the game folder, and rename the copy to
|
||||
`StardewModdingAPI.deps.json`.
|
||||
|
||||
4.
|
||||
3.
|
||||
- Windows only: if you use Steam, see the install guide above to enable achievements and
|
||||
overlay. Otherwise, just run StardewModdingAPI.exe in your game folder to play with mods.
|
||||
|
||||
- Linux/macOS only: rename the "StardewValley" file (no extension) to "StardewValley-original", and
|
||||
- Linux/Mac only: rename the "StardewValley" file (no extension) to "StardewValley-original", and
|
||||
"StardewModdingAPI" (no extension) to "StardewValley". Now just launch the game as usual to
|
||||
play with mods.
|
||||
|
||||
When installing on Linux or macOS:
|
||||
- To configure the color scheme, edit the `smapi-internal/config.json` file and see instructions
|
||||
there for the 'ColorScheme' setting.
|
||||
When installing on Linux or Mac:
|
||||
- Make sure Mono is installed (normally the installer checks for you). While it's not required,
|
||||
many mods won't work correctly without it. (Specifically, mods which load PNG images may crash or
|
||||
freeze the game.)
|
||||
- To configure the color scheme, edit the `smapi-internal/StardewModdingAPI.config.json` file and
|
||||
see instructions there for the 'ColorScheme' setting.
|
|
@ -1,20 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<RootNamespace>StardewModdingAPI.Installer</RootNamespace>
|
||||
<Description>The SMAPI installer for players.</Description>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SMAPI.Toolkit\SMAPI.Toolkit.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="assets\*" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="..\SMAPI.Internal\SMAPI.Internal.projitems" Label="Shared" />
|
||||
<Import Project="..\..\build\common.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,79 @@
|
|||
<?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)' == '' ">x86</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|x86' ">
|
||||
<PlatformTarget>x86</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|x86' ">
|
||||
<PlatformTarget>x86</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" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.IO.Compression.FileSystem" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\build\GlobalAssemblyInfo.cs">
|
||||
<Link>Properties\GlobalAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Enums\ScriptAction.cs" />
|
||||
<Compile Include="Framework\InstallerPaths.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>
|
||||
<ItemGroup>
|
||||
<Content Include="windows-exe-config.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="windows-install.bat">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="unix-install.sh">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="unix-launcher.sh">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\StardewModdingAPI.Toolkit\StardewModdingAPI.Toolkit.csproj">
|
||||
<Project>{ea5cfd2e-9453-4d29-b80f-8e0ea23f4ac6}</Project>
|
||||
<Name>StardewModdingAPI.Toolkit</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="..\SMAPI.Internal\SMAPI.Internal.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\..\build\common.targets" />
|
||||
<Import Project="..\..\build\prepare-install-package.targets" />
|
||||
</Project>
|
|
@ -1,4 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
cd "`dirname "$0"`"
|
||||
internal/linux/SMAPI.Installer
|
|
@ -1,43 +0,0 @@
|
|||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
SET installerDir="%~dp0"
|
||||
|
||||
REM make sure we're not running within a zip folder
|
||||
REM The error level is usually 0 (install dir contains temp path), 1 (it doesn't), or 9009 (findstr doesn't exist due to a Windows issue).
|
||||
REM If the command doesn't exist, just skip this check.
|
||||
echo %installerDir% | findstr /C:"%TEMP%" 1>nul 2>null
|
||||
if %ERRORLEVEL% EQU 0 (
|
||||
echo Oops! It looks like you're running the installer from inside a zip file. Make sure you unzip the download first.
|
||||
echo.
|
||||
pause
|
||||
exit
|
||||
)
|
||||
|
||||
REM make sure an antivirus hasn't deleted the installer DLL
|
||||
if not exist %installerDir%"internal\windows\SMAPI.Installer.dll" (
|
||||
echo Oops! SMAPI is missing one of its files. Your antivirus might have deleted it.
|
||||
echo Missing file: %installerDir%internal\windows\SMAPI.Installer.dll
|
||||
echo.
|
||||
pause
|
||||
exit
|
||||
)
|
||||
if not exist %installerDir%"internal\windows\SMAPI.Installer.exe" (
|
||||
echo Oops! SMAPI is missing one of its files. Your antivirus might have deleted it.
|
||||
echo Missing file: %installerDir%internal\windows\SMAPI.Installer.exe
|
||||
echo.
|
||||
pause
|
||||
exit
|
||||
)
|
||||
|
||||
REM start installer
|
||||
internal\windows\SMAPI.Installer.exe
|
||||
|
||||
REM keep window open if it failed
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
echo.
|
||||
echo Oops! The SMAPI installer seems to have failed. The error details may be shown above.
|
||||
echo.
|
||||
pause
|
||||
exit
|
||||
)
|
|
@ -1,6 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
cd "`dirname "$0"`"
|
||||
|
||||
xattr -r -d com.apple.quarantine internal
|
||||
internal/macOS/SMAPI.Installer
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net5.0",
|
||||
"includedFrameworks": [
|
||||
{
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "5.0.0",
|
||||
"rollForward": "latestMinor"
|
||||
}
|
||||
],
|
||||
"configProperties": {
|
||||
// disable tiered runtime JIT: https://github.com/dotnet/runtime/blob/main/docs/design/features/tiered-compilation.md
|
||||
// This is disabled by the base game, and causes issues with Harmony patches.
|
||||
"System.Runtime.TieredCompilation": false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,169 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
##########
|
||||
## Initial setup
|
||||
##########
|
||||
# move to script's directory
|
||||
cd "$(dirname "$0")" || exit $?
|
||||
|
||||
# Whether to avoid opening a separate terminal window, and avoid logging anything to the console.
|
||||
# This isn't recommended since you won't see errors, warnings, and update alerts.
|
||||
SKIP_TERMINAL=false
|
||||
|
||||
# Whether to avoid opening a separate terminal, but still send the usual log output to the console.
|
||||
USE_CURRENT_SHELL=false
|
||||
|
||||
|
||||
##########
|
||||
## Read environment variables
|
||||
##########
|
||||
if [ "$SMAPI_NO_TERMINAL" == "true" ]; then
|
||||
SKIP_TERMINAL=true
|
||||
fi
|
||||
if [ "$SMAPI_USE_CURRENT_SHELL" == "true" ]; then
|
||||
USE_CURRENT_SHELL=true
|
||||
fi
|
||||
|
||||
|
||||
##########
|
||||
## Read command-line arguments
|
||||
##########
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
--skip-terminal ) SKIP_TERMINAL=true; shift ;;
|
||||
--use-current-shell ) USE_CURRENT_SHELL=true; shift ;;
|
||||
-- ) shift; break ;;
|
||||
* ) shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$SKIP_TERMINAL" == "true" ]; then
|
||||
USE_CURRENT_SHELL=true
|
||||
fi
|
||||
|
||||
|
||||
##########
|
||||
## Open terminal if needed
|
||||
##########
|
||||
# on macOS, make sure we're running in a Terminal
|
||||
# Besides letting the player see errors/warnings/alerts in the console, this is also needed because
|
||||
# Steam messes with the PATH.
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
if [ ! -t 1 ]; then # not open in Terminal (https://stackoverflow.com/q/911168/262123)
|
||||
# reopen in Terminal if needed
|
||||
# https://stackoverflow.com/a/29511052/262123
|
||||
if [ "$USE_CURRENT_SHELL" == "false" ]; then
|
||||
echo "Reopening in the Terminal app..."
|
||||
echo '#!/bin/sh' > /tmp/open-smapi-terminal.command
|
||||
echo "\"$0\" $@ --use-current-shell" >> /tmp/open-smapi-terminal.command
|
||||
chmod +x /tmp/open-smapi-terminal.command
|
||||
cat /tmp/open-smapi-terminal.command
|
||||
open -W /tmp/open-smapi-terminal.command
|
||||
rm /tmp/open-smapi-terminal.command
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
##########
|
||||
## Validate assumptions
|
||||
##########
|
||||
# script must be run from the game folder
|
||||
if [ ! -f "Stardew Valley.dll" ]; then
|
||||
printf "Oops! SMAPI must be placed in the Stardew Valley game folder.\nSee instructions: https://stardewvalleywiki.com/Modding:Player_Guide";
|
||||
read -r
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
##########
|
||||
## Launch SMAPI
|
||||
##########
|
||||
# macOS
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
./StardewModdingAPI "$@"
|
||||
|
||||
# Linux
|
||||
else
|
||||
# choose binary file to launch
|
||||
LAUNCH_FILE="./StardewModdingAPI"
|
||||
export LAUNCH_FILE
|
||||
|
||||
# run in terminal
|
||||
if [ "$USE_CURRENT_SHELL" == "false" ]; then
|
||||
# select terminal (prefer xterm for best compatibility, then known supported terminals)
|
||||
for terminal in xterm gnome-terminal kitty terminator xfce4-terminal konsole terminal termite alacritty mate-terminal x-terminal-emulator wezterm; do
|
||||
if command -v "$terminal" 2>/dev/null; then
|
||||
export TERMINAL_NAME=$terminal
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
# find the true shell behind x-terminal-emulator
|
||||
if [ "$TERMINAL_NAME" = "x-terminal-emulator" ]; then
|
||||
TERMINAL_NAME="$(basename "$(readlink -f "$(command -v x-terminal-emulator)")")"
|
||||
export TERMINAL_NAME
|
||||
fi
|
||||
|
||||
# run in selected terminal and account for quirks
|
||||
TERMINAL_PATH="$(command -v "$TERMINAL_NAME")"
|
||||
export TERMINAL_PATH
|
||||
if [ -x "$TERMINAL_PATH" ]; then
|
||||
case $TERMINAL_NAME in
|
||||
terminal|termite)
|
||||
# consumes only one argument after -e
|
||||
# options containing space characters are unsupported
|
||||
exec "$TERMINAL_NAME" -e "env TERM=xterm $LAUNCH_FILE $@"
|
||||
;;
|
||||
|
||||
xterm|konsole|alacritty)
|
||||
# consumes all arguments after -e
|
||||
exec "$TERMINAL_NAME" -e env TERM=xterm $LAUNCH_FILE "$@"
|
||||
;;
|
||||
|
||||
terminator|xfce4-terminal|mate-terminal)
|
||||
# consumes all arguments after -x
|
||||
exec "$TERMINAL_NAME" -x env TERM=xterm $LAUNCH_FILE "$@"
|
||||
;;
|
||||
|
||||
gnome-terminal)
|
||||
# consumes all arguments after --
|
||||
exec "$TERMINAL_NAME" -- env TERM=xterm $LAUNCH_FILE "$@"
|
||||
;;
|
||||
|
||||
wezterm)
|
||||
# consumes all arguments after start --. does not copy working directory automatically, needs --cwd for that.
|
||||
exec "$TERMINAL_NAME" start --cwd "$(pwd)" -- env TERM=xterm $LAUNCH_FILE "$@"
|
||||
;;
|
||||
|
||||
kitty)
|
||||
# consumes all trailing arguments
|
||||
exec "$TERMINAL_NAME" env TERM=xterm $LAUNCH_FILE "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
# If we don't know the terminal, just try to run it in the current shell.
|
||||
# If THAT fails, launch with no output.
|
||||
env TERM=xterm $LAUNCH_FILE "$@"
|
||||
if [ $? -eq 127 ]; then
|
||||
exec $LAUNCH_FILE --no-terminal "$@"
|
||||
fi
|
||||
esac
|
||||
|
||||
## terminal isn't executable; fallback to current shell or no terminal
|
||||
else
|
||||
echo "The '$TERMINAL_NAME' terminal isn't executable. SMAPI might be running in a sandbox or the system might be misconfigured? Falling back to current shell."
|
||||
env TERM=xterm $LAUNCH_FILE "$@"
|
||||
if [ $? -eq 127 ]; then
|
||||
exec $LAUNCH_FILE --no-terminal "$@"
|
||||
fi
|
||||
fi
|
||||
|
||||
# explicitly run without terminal
|
||||
elif [ "$SKIP_TERMINAL" == "true" ]; then
|
||||
exec $LAUNCH_FILE --no-terminal "$@"
|
||||
else
|
||||
exec $LAUNCH_FILE "$@"
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
# Run the SMAPI installer through Mono on Linux or Mac.
|
||||
|
||||
# Move to script's directory
|
||||
cd "`dirname "$0"`"
|
||||
|
||||
# get cross-distro version of POSIX command
|
||||
COMMAND=""
|
||||
if command -v command >/dev/null 2>&1; then
|
||||
COMMAND="command -v"
|
||||
elif type type >/dev/null 2>&1; then
|
||||
COMMAND="type"
|
||||
fi
|
||||
|
||||
# validate Mono & run installer
|
||||
if $COMMAND mono >/dev/null 2>&1; then
|
||||
mono internal/unix-install.exe
|
||||
else
|
||||
echo "Oops! Looks like Mono isn't installed. Please install Mono from https://mono-project.com, reboot, and run this installer again."
|
||||
read
|
||||
fi
|
|
@ -0,0 +1,95 @@
|
|||
#!/bin/bash
|
||||
# MonoKickstart Shell Script
|
||||
# Written by Ethan "flibitijibibo" Lee
|
||||
# Modified for StardewModdingAPI by Viz and Pathoschild
|
||||
|
||||
# Move to script's directory
|
||||
cd "`dirname "$0"`"
|
||||
|
||||
# Get the system architecture
|
||||
UNAME=`uname`
|
||||
ARCH=`uname -m`
|
||||
|
||||
# MonoKickstart picks the right libfolder, so just execute the right binary.
|
||||
if [ "$UNAME" == "Darwin" ]; then
|
||||
# ... Except on OSX.
|
||||
export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:./osx/
|
||||
|
||||
# El Capitan is a total idiot and wipes this variable out, making the
|
||||
# Steam overlay disappear. This sidesteps "System Integrity Protection"
|
||||
# and resets the variable with Valve's own variable (they provided this
|
||||
# fix by the way, thanks Valve!). Note that you will need to update your
|
||||
# launch configuration to the script location, NOT just the app location
|
||||
# (i.e. Kick.app/Contents/MacOS/Kick, not just Kick.app).
|
||||
# -flibit
|
||||
if [ "$STEAM_DYLD_INSERT_LIBRARIES" != "" ] && [ "$DYLD_INSERT_LIBRARIES" == "" ]; then
|
||||
export DYLD_INSERT_LIBRARIES="$STEAM_DYLD_INSERT_LIBRARIES"
|
||||
fi
|
||||
|
||||
# this was here before
|
||||
ln -sf mcs.bin.osx mcs
|
||||
|
||||
# fix "DllNotFoundException: libgdiplus.dylib" errors when loading images in SMAPI
|
||||
if [ -f libgdiplus.dylib ]; then
|
||||
rm libgdiplus.dylib
|
||||
fi
|
||||
if [ -f /Library/Frameworks/Mono.framework/Versions/Current/lib/libgdiplus.dylib ]; then
|
||||
ln -s /Library/Frameworks/Mono.framework/Versions/Current/lib/libgdiplus.dylib libgdiplus.dylib
|
||||
fi
|
||||
|
||||
# launch SMAPI
|
||||
cp StardewValley.bin.osx StardewModdingAPI.bin.osx
|
||||
open -a Terminal ./StardewModdingAPI.bin.osx $@
|
||||
else
|
||||
# choose launcher
|
||||
LAUNCHER=""
|
||||
if [ "$ARCH" == "x86_64" ]; then
|
||||
ln -sf mcs.bin.x86_64 mcs
|
||||
cp StardewValley.bin.x86_64 StardewModdingAPI.bin.x86_64
|
||||
LAUNCHER="./StardewModdingAPI.bin.x86_64 $@"
|
||||
else
|
||||
ln -sf mcs.bin.x86 mcs
|
||||
cp StardewValley.bin.x86 StardewModdingAPI.bin.x86
|
||||
LAUNCHER="./StardewModdingAPI.bin.x86 $@"
|
||||
fi
|
||||
|
||||
# get cross-distro version of POSIX command
|
||||
COMMAND=""
|
||||
if command -v command 2>/dev/null; then
|
||||
COMMAND="command -v"
|
||||
elif type type 2>/dev/null; then
|
||||
COMMAND="type"
|
||||
fi
|
||||
|
||||
# open SMAPI in terminal
|
||||
if $COMMAND xterm 2>/dev/null; then
|
||||
xterm -e "$LAUNCHER"
|
||||
elif $COMMAND x-terminal-emulator 2>/dev/null; then
|
||||
# Terminator converts -e to -x when used through x-terminal-emulator for some reason (per
|
||||
# `man terminator`), which causes an "unable to find shell" error. If x-terminal-emulator
|
||||
# is mapped to Terminator, invoke it directly instead.
|
||||
if [[ "$(readlink -e $(which x-terminal-emulator))" == *"/terminator" ]]; then
|
||||
terminator -e "sh -c 'TERM=xterm $LAUNCHER'"
|
||||
else
|
||||
x-terminal-emulator -e "sh -c 'TERM=xterm $LAUNCHER'"
|
||||
fi
|
||||
elif $COMMAND xfce4-terminal 2>/dev/null; then
|
||||
xfce4-terminal -e "sh -c 'TERM=xterm $LAUNCHER'"
|
||||
elif $COMMAND gnome-terminal 2>/dev/null; then
|
||||
gnome-terminal -e "sh -c 'TERM=xterm $LAUNCHER'"
|
||||
elif $COMMAND konsole 2>/dev/null; then
|
||||
konsole -p Environment=TERM=xterm -e "$LAUNCHER"
|
||||
elif $COMMAND terminal 2>/dev/null; then
|
||||
terminal -e "sh -c 'TERM=xterm $LAUNCHER'"
|
||||
else
|
||||
sh -c 'TERM=xterm $LAUNCHER'
|
||||
fi
|
||||
|
||||
# some Linux users get error 127 (command not found) from the above block, even though
|
||||
# `command -v` indicates the command is valid. As a fallback, launch SMAPI without a terminal when
|
||||
# that happens and pass in an argument indicating SMAPI shouldn't try writing to the terminal
|
||||
# (which can be slow if there is none).
|
||||
if [ $? -eq 127 ]; then
|
||||
$LAUNCHER --no-terminal
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,8 @@
|
|||
@echo off
|
||||
echo %~dp0 | findstr /C:"%TEMP%" 1>nul
|
||||
if not errorlevel 1 (
|
||||
echo Oops! It looks like you're running the installer from inside a zip file. Make sure you unzip the download first.
|
||||
pause
|
||||
) else (
|
||||
start /WAIT /B internal/windows-install.exe
|
||||
)
|
|
@ -1,54 +0,0 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace StardewModdingAPI.Internal.Patching
|
||||
{
|
||||
/// <summary>Provides base implementation logic for <see cref="IPatcher"/> instances.</summary>
|
||||
internal abstract class BasePatcher : IPatcher
|
||||
{
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <inheritdoc />
|
||||
public abstract void Apply(Harmony harmony, IMonitor monitor);
|
||||
|
||||
|
||||
/*********
|
||||
** Protected methods
|
||||
*********/
|
||||
/// <summary>Get a method and assert that it was found.</summary>
|
||||
/// <typeparam name="TTarget">The type containing the method.</typeparam>
|
||||
/// <param name="parameters">The method parameter types, or <c>null</c> if it's not overloaded.</param>
|
||||
protected ConstructorInfo RequireConstructor<TTarget>(params Type[] parameters)
|
||||
{
|
||||
return PatchHelper.RequireConstructor<TTarget>(parameters);
|
||||
}
|
||||
|
||||
/// <summary>Get a method and assert that it was found.</summary>
|
||||
/// <typeparam name="TTarget">The type containing the method.</typeparam>
|
||||
/// <param name="name">The method name.</param>
|
||||
/// <param name="parameters">The method parameter types, or <c>null</c> if it's not overloaded.</param>
|
||||
/// <param name="generics">The method generic types, or <c>null</c> if it's not generic.</param>
|
||||
protected MethodInfo RequireMethod<TTarget>(string name, Type[]? parameters = null, Type[]? generics = null)
|
||||
{
|
||||
return PatchHelper.RequireMethod<TTarget>(name, parameters, generics);
|
||||
}
|
||||
|
||||
/// <summary>Get a Harmony patch method on the current patcher instance.</summary>
|
||||
/// <param name="name">The method name.</param>
|
||||
/// <param name="priority">The patch priority to apply, usually specified using Harmony's <see cref="Priority"/> enum, or <c>null</c> to keep the default value.</param>
|
||||
protected HarmonyMethod GetHarmonyMethod(string name, int? priority = null)
|
||||
{
|
||||
HarmonyMethod method = new(
|
||||
AccessTools.Method(this.GetType(), name)
|
||||
?? throw new InvalidOperationException($"Can't find patcher method {PatchHelper.GetMethodString(this.GetType(), name)}.")
|
||||
);
|
||||
|
||||
if (priority.HasValue)
|
||||
method.priority = priority.Value;
|
||||
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
using System;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace StardewModdingAPI.Internal.Patching
|
||||
{
|
||||
/// <summary>Simplifies applying <see cref="IPatcher"/> instances to the game.</summary>
|
||||
internal static class HarmonyPatcher
|
||||
{
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Apply the given Harmony patchers.</summary>
|
||||
/// <param name="id">The mod ID applying the patchers.</param>
|
||||
/// <param name="monitor">The monitor with which to log any errors.</param>
|
||||
/// <param name="patchers">The patchers to apply.</param>
|
||||
public static Harmony Apply(string id, IMonitor monitor, params IPatcher[] patchers)
|
||||
{
|
||||
Harmony harmony = new(id);
|
||||
|
||||
foreach (IPatcher patcher in patchers)
|
||||
{
|
||||
try
|
||||
{
|
||||
patcher.Apply(harmony, monitor);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
monitor.Log($"Couldn't apply runtime patch '{patcher.GetType().Name}' to the game. Some SMAPI features may not work correctly. See log file for details.", LogLevel.Error);
|
||||
monitor.Log($"Technical details:\n{ex.GetLogSummary()}");
|
||||
}
|
||||
}
|
||||
|
||||
return harmony;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
using HarmonyLib;
|
||||
|
||||
namespace StardewModdingAPI.Internal.Patching
|
||||
{
|
||||
/// <summary>A set of Harmony patches to apply.</summary>
|
||||
internal interface IPatcher
|
||||
{
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Apply the Harmony patches for this instance.</summary>
|
||||
/// <param name="harmony">The Harmony instance.</param>
|
||||
/// <param name="monitor">The monitor with which to log any errors.</param>
|
||||
public void Apply(Harmony harmony, IMonitor monitor);
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace StardewModdingAPI.Internal.Patching
|
||||
{
|
||||
/// <summary>Provides utility methods for patching game code with Harmony.</summary>
|
||||
internal static class PatchHelper
|
||||
{
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Get a constructor and assert that it was found.</summary>
|
||||
/// <typeparam name="TTarget">The type containing the method.</typeparam>
|
||||
/// <param name="parameters">The method parameter types, or <c>null</c> if it's not overloaded.</param>
|
||||
/// <exception cref="InvalidOperationException">The type has no matching constructor.</exception>
|
||||
public static ConstructorInfo RequireConstructor<TTarget>(Type[]? parameters = null)
|
||||
{
|
||||
return
|
||||
AccessTools.Constructor(typeof(TTarget), parameters)
|
||||
?? throw new InvalidOperationException($"Can't find constructor {PatchHelper.GetMethodString(typeof(TTarget), null, parameters)} to patch.");
|
||||
}
|
||||
|
||||
/// <summary>Get a method and assert that it was found.</summary>
|
||||
/// <typeparam name="TTarget">The type containing the method.</typeparam>
|
||||
/// <param name="name">The method name.</param>
|
||||
/// <param name="parameters">The method parameter types, or <c>null</c> if it's not overloaded.</param>
|
||||
/// <param name="generics">The method generic types, or <c>null</c> if it's not generic.</param>
|
||||
/// <exception cref="InvalidOperationException">The type has no matching method.</exception>
|
||||
public static MethodInfo RequireMethod<TTarget>(string name, Type[]? parameters = null, Type[]? generics = null)
|
||||
{
|
||||
return
|
||||
AccessTools.Method(typeof(TTarget), name, parameters, generics)
|
||||
?? throw new InvalidOperationException($"Can't find method {PatchHelper.GetMethodString(typeof(TTarget), name, parameters, generics)} to patch.");
|
||||
}
|
||||
|
||||
/// <summary>Get a human-readable representation of a method target.</summary>
|
||||
/// <param name="type">The type containing the method.</param>
|
||||
/// <param name="name">The method name, or <c>null</c> for a constructor.</param>
|
||||
/// <param name="parameters">The method parameter types, or <c>null</c> if it's not overloaded.</param>
|
||||
/// <param name="generics">The method generic types, or <c>null</c> if it's not generic.</param>
|
||||
public static string GetMethodString(Type type, string? name, Type[]? parameters = null, Type[]? generics = null)
|
||||
{
|
||||
StringBuilder str = new();
|
||||
|
||||
// type
|
||||
str.Append(type.FullName);
|
||||
|
||||
// method name (if not constructor)
|
||||
if (name != null)
|
||||
{
|
||||
str.Append('.');
|
||||
str.Append(name);
|
||||
}
|
||||
|
||||
// generics
|
||||
if (generics?.Any() == true)
|
||||
{
|
||||
str.Append('<');
|
||||
str.Append(string.Join(", ", generics.Select(p => p.FullName)));
|
||||
str.Append('>');
|
||||
}
|
||||
|
||||
// parameters
|
||||
if (parameters?.Any() == true)
|
||||
{
|
||||
str.Append('(');
|
||||
str.Append(string.Join(", ", parameters.Select(p => p.FullName)));
|
||||
str.Append(')');
|
||||
}
|
||||
|
||||
return str.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' < '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
<HasSharedItems>true</HasSharedItems>
|
||||
<SharedGUID>6c16e948-3e5c-47a7-bf4b-07a7469a87a5</SharedGUID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<Import_RootNamespace>SMAPI.Internal.Patching</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)BasePatcher.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HarmonyPatcher.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)IPatcher.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)PatchHelper.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>6c16e948-3e5c-47a7-bf4b-07a7469a87a5</ProjectGuid>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||
<PropertyGroup />
|
||||
<Import Project="SMAPI.Internal.Patching.projitems" Label="Shared" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||
</Project>
|
|
@ -1,31 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace StardewModdingAPI.Internal.ConsoleWriting
|
||||
{
|
||||
/// <summary>The console color scheme options.</summary>
|
||||
internal class ColorSchemeConfig
|
||||
{
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>The default color scheme ID to use, or <see cref="MonitorColorScheme.AutoDetect"/> to select one automatically.</summary>
|
||||
public MonitorColorScheme UseScheme { get; }
|
||||
|
||||
/// <summary>The available console color schemes.</summary>
|
||||
public IDictionary<MonitorColorScheme, IDictionary<ConsoleLogLevel, ConsoleColor>> Schemes { get; }
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="useScheme">The default color scheme ID to use, or <see cref="MonitorColorScheme.AutoDetect"/> to select one automatically.</param>
|
||||
/// <param name="schemes">The available console color schemes.</param>
|
||||
public ColorSchemeConfig(MonitorColorScheme useScheme, IDictionary<MonitorColorScheme, IDictionary<ConsoleLogLevel, ConsoleColor>> schemes)
|
||||
{
|
||||
this.UseScheme = useScheme;
|
||||
this.Schemes = schemes;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
|
||||
namespace StardewModdingAPI.Internal.ConsoleWriting
|
||||
{
|
||||
/// <summary>Writes color-coded text to the console.</summary>
|
||||
internal class ColorfulConsoleWriter : IConsoleWriter
|
||||
/// <summary>Provides a wrapper for writing color-coded text to the console.</summary>
|
||||
internal class ColorfulConsoleWriter
|
||||
{
|
||||
/*********
|
||||
** Fields
|
||||
** Properties
|
||||
*********/
|
||||
/// <summary>The console text color for each log level.</summary>
|
||||
private readonly IDictionary<ConsoleLogLevel, ConsoleColor>? Colors;
|
||||
private readonly IDictionary<ConsoleLogLevel, ConsoleColor> Colors;
|
||||
|
||||
/// <summary>Whether the current console supports color formatting.</summary>
|
||||
#if !SMAPI_FOR_MOBILE
|
||||
[MemberNotNullWhen(true, nameof(ColorfulConsoleWriter.Colors))]
|
||||
#endif
|
||||
private bool SupportsColor { get; }
|
||||
private readonly bool SupportsColor;
|
||||
|
||||
|
||||
/*********
|
||||
|
@ -26,24 +21,11 @@ namespace StardewModdingAPI.Internal.ConsoleWriting
|
|||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="platform">The target platform.</param>
|
||||
public ColorfulConsoleWriter(Platform platform)
|
||||
: this(platform, ColorfulConsoleWriter.GetDefaultColorSchemeConfig(MonitorColorScheme.AutoDetect)) { }
|
||||
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="platform">The target platform.</param>
|
||||
/// <param name="colorConfig">The colors to use for text written to the SMAPI console.</param>
|
||||
public ColorfulConsoleWriter(Platform platform, ColorSchemeConfig colorConfig)
|
||||
/// <param name="colorScheme">The console color scheme to use.</param>
|
||||
public ColorfulConsoleWriter(Platform platform, MonitorColorScheme colorScheme)
|
||||
{
|
||||
if (colorConfig.UseScheme == MonitorColorScheme.None)
|
||||
{
|
||||
this.SupportsColor = false;
|
||||
this.Colors = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.SupportsColor = this.TestColorSupport();
|
||||
this.Colors = this.GetConsoleColorScheme(platform, colorConfig);
|
||||
}
|
||||
this.SupportsColor = this.TestColorSupport();
|
||||
this.Colors = this.GetConsoleColorScheme(platform, colorScheme);
|
||||
}
|
||||
|
||||
/// <summary>Write a message line to the log.</summary>
|
||||
|
@ -71,39 +53,6 @@ namespace StardewModdingAPI.Internal.ConsoleWriting
|
|||
Console.WriteLine(message);
|
||||
}
|
||||
|
||||
/// <summary>Get the default color scheme config for cases where it's not configurable (e.g. the installer).</summary>
|
||||
/// <param name="useScheme">The default color scheme ID to use, or <see cref="MonitorColorScheme.AutoDetect"/> to select one automatically.</param>
|
||||
/// <remarks>The colors here should be kept in sync with the SMAPI config file.</remarks>
|
||||
public static ColorSchemeConfig GetDefaultColorSchemeConfig(MonitorColorScheme useScheme)
|
||||
{
|
||||
return new ColorSchemeConfig(
|
||||
useScheme: useScheme,
|
||||
schemes: new Dictionary<MonitorColorScheme, IDictionary<ConsoleLogLevel, ConsoleColor>>
|
||||
{
|
||||
[MonitorColorScheme.DarkBackground] = new Dictionary<ConsoleLogLevel, ConsoleColor>
|
||||
{
|
||||
[ConsoleLogLevel.Trace] = ConsoleColor.DarkGray,
|
||||
[ConsoleLogLevel.Debug] = ConsoleColor.DarkGray,
|
||||
[ConsoleLogLevel.Info] = ConsoleColor.White,
|
||||
[ConsoleLogLevel.Warn] = ConsoleColor.Yellow,
|
||||
[ConsoleLogLevel.Error] = ConsoleColor.Red,
|
||||
[ConsoleLogLevel.Alert] = ConsoleColor.Magenta,
|
||||
[ConsoleLogLevel.Success] = ConsoleColor.DarkGreen
|
||||
},
|
||||
[MonitorColorScheme.LightBackground] = new Dictionary<ConsoleLogLevel, ConsoleColor>
|
||||
{
|
||||
[ConsoleLogLevel.Trace] = ConsoleColor.DarkGray,
|
||||
[ConsoleLogLevel.Debug] = ConsoleColor.DarkGray,
|
||||
[ConsoleLogLevel.Info] = ConsoleColor.Black,
|
||||
[ConsoleLogLevel.Warn] = ConsoleColor.DarkYellow,
|
||||
[ConsoleLogLevel.Error] = ConsoleColor.Red,
|
||||
[ConsoleLogLevel.Alert] = ConsoleColor.DarkMagenta,
|
||||
[ConsoleLogLevel.Success] = ConsoleColor.DarkGreen
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*********
|
||||
** Private methods
|
||||
|
@ -124,22 +73,47 @@ namespace StardewModdingAPI.Internal.ConsoleWriting
|
|||
|
||||
/// <summary>Get the color scheme to use for the current console.</summary>
|
||||
/// <param name="platform">The target platform.</param>
|
||||
/// <param name="colorConfig">The colors to use for text written to the SMAPI console.</param>
|
||||
private IDictionary<ConsoleLogLevel, ConsoleColor> GetConsoleColorScheme(Platform platform, ColorSchemeConfig colorConfig)
|
||||
/// <param name="colorScheme">The console color scheme to use.</param>
|
||||
private IDictionary<ConsoleLogLevel, ConsoleColor> GetConsoleColorScheme(Platform platform, MonitorColorScheme colorScheme)
|
||||
{
|
||||
// get color scheme ID
|
||||
MonitorColorScheme schemeID = colorConfig.UseScheme;
|
||||
if (schemeID == MonitorColorScheme.AutoDetect)
|
||||
// auto detect color scheme
|
||||
if (colorScheme == MonitorColorScheme.AutoDetect)
|
||||
{
|
||||
schemeID = platform == Platform.Mac
|
||||
? MonitorColorScheme.LightBackground // macOS doesn't provide console background color info, but it's usually white.
|
||||
colorScheme = platform == Platform.Mac
|
||||
? MonitorColorScheme.LightBackground // MacOS doesn't provide console background color info, but it's usually white.
|
||||
: ColorfulConsoleWriter.IsDark(Console.BackgroundColor) ? MonitorColorScheme.DarkBackground : MonitorColorScheme.LightBackground;
|
||||
}
|
||||
|
||||
// get colors for scheme
|
||||
return colorConfig.Schemes.TryGetValue(schemeID, out IDictionary<ConsoleLogLevel, ConsoleColor>? scheme)
|
||||
? scheme
|
||||
: throw new NotSupportedException($"Unknown color scheme '{schemeID}'.");
|
||||
switch (colorScheme)
|
||||
{
|
||||
case MonitorColorScheme.DarkBackground:
|
||||
return new Dictionary<ConsoleLogLevel, ConsoleColor>
|
||||
{
|
||||
[ConsoleLogLevel.Trace] = ConsoleColor.DarkGray,
|
||||
[ConsoleLogLevel.Debug] = ConsoleColor.DarkGray,
|
||||
[ConsoleLogLevel.Info] = ConsoleColor.White,
|
||||
[ConsoleLogLevel.Warn] = ConsoleColor.Yellow,
|
||||
[ConsoleLogLevel.Error] = ConsoleColor.Red,
|
||||
[ConsoleLogLevel.Alert] = ConsoleColor.Magenta,
|
||||
[ConsoleLogLevel.Success] = ConsoleColor.DarkGreen
|
||||
};
|
||||
|
||||
case MonitorColorScheme.LightBackground:
|
||||
return new Dictionary<ConsoleLogLevel, ConsoleColor>
|
||||
{
|
||||
[ConsoleLogLevel.Trace] = ConsoleColor.DarkGray,
|
||||
[ConsoleLogLevel.Debug] = ConsoleColor.DarkGray,
|
||||
[ConsoleLogLevel.Info] = ConsoleColor.Black,
|
||||
[ConsoleLogLevel.Warn] = ConsoleColor.DarkYellow,
|
||||
[ConsoleLogLevel.Error] = ConsoleColor.Red,
|
||||
[ConsoleLogLevel.Alert] = ConsoleColor.DarkMagenta,
|
||||
[ConsoleLogLevel.Success] = ConsoleColor.DarkGreen
|
||||
};
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"Unknown color scheme '{colorScheme}'.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Get whether a console color should be considered dark, which is subjectively defined as 'white looks better than black on this text'.</summary>
|
||||
|
@ -151,7 +125,7 @@ namespace StardewModdingAPI.Internal.ConsoleWriting
|
|||
case ConsoleColor.Black:
|
||||
case ConsoleColor.Blue:
|
||||
case ConsoleColor.DarkBlue:
|
||||
case ConsoleColor.DarkMagenta: // PowerShell
|
||||
case ConsoleColor.DarkMagenta: // Powershell
|
||||
case ConsoleColor.DarkRed:
|
||||
case ConsoleColor.Red:
|
||||
return true;
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
namespace StardewModdingAPI.Internal.ConsoleWriting
|
||||
{
|
||||
/// <summary>Writes text to the console.</summary>
|
||||
internal interface IConsoleWriter
|
||||
{
|
||||
/// <summary>Write a message line to the log.</summary>
|
||||
/// <param name="message">The message to log.</param>
|
||||
/// <param name="level">The log level.</param>
|
||||
void WriteLine(string message, ConsoleLogLevel level);
|
||||
}
|
||||
}
|