Merge branch 'develop' into stable
This commit is contained in:
commit
8a2618d812
|
@ -22,6 +22,9 @@ 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
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# normalize line endings
|
||||
* text=auto
|
||||
README.txt text=crlf
|
||||
README.txt text eol=crlf
|
||||
|
||||
*.command text eol=lf
|
||||
*.sh text eol=lf
|
||||
|
|
|
@ -1,13 +1,29 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<!--set general build properties -->
|
||||
<Version>3.13.1</Version>
|
||||
<Version>3.13.2</Version>
|
||||
<Product>SMAPI</Product>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
|
||||
|
||||
<!--set platform-->
|
||||
<DefineConstants Condition="$(OS) == 'Windows_NT'">$(DefineConstants);SMAPI_FOR_WINDOWS</DefineConstants>
|
||||
<CopyToGameFolder>true</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.
|
||||
CA1416 | all | platform code available on all platforms | Compiler doesn't recognize the #if constants used by SMAPI.
|
||||
CS0809 | all | obsolete overload for non-onsolete 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>$(NoWarn);CS0436;CA1416;CS0809;NU1701</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--find game folder-->
|
||||
|
@ -19,7 +35,7 @@
|
|||
</Target>
|
||||
|
||||
<!-- copy files into game directory and enable debugging -->
|
||||
<Target Name="CopySmapiFiles" AfterTargets="AfterBuild">
|
||||
<Target Name="CopySmapiFiles" AfterTargets="AfterBuild" Condition="'$(CopyToGameFolder)' == 'true'">
|
||||
<CallTarget Targets="CopySMAPI;CopyDefaultMods" />
|
||||
</Target>
|
||||
<Target Name="CopySMAPI" Condition="'$(MSBuildProjectName)' == 'SMAPI'">
|
||||
|
|
|
@ -1,130 +0,0 @@
|
|||
<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="PrepareInstaller" AfterTargets="AfterBuild">
|
||||
<PropertyGroup>
|
||||
<PlatformName>windows</PlatformName>
|
||||
<PlatformName Condition="$(OS) != 'Windows_NT'">unix</PlatformName>
|
||||
|
||||
<BuildRootPath>$(SolutionDir)</BuildRootPath>
|
||||
<OutRootPath>$(SolutionDir)\..\bin</OutRootPath>
|
||||
|
||||
<SmapiBin>$(BuildRootPath)\SMAPI\bin\$(Configuration)</SmapiBin>
|
||||
<ToolkitBin>$(BuildRootPath)\SMAPI.Toolkit\bin\$(Configuration)\net5.0</ToolkitBin>
|
||||
<ConsoleCommandsBin>$(BuildRootPath)\SMAPI.Mods.ConsoleCommands\bin\$(Configuration)</ConsoleCommandsBin>
|
||||
<ErrorHandlerBin>$(BuildRootPath)\SMAPI.Mods.ErrorHandler\bin\$(Configuration)</ErrorHandlerBin>
|
||||
<SaveBackupBin>$(BuildRootPath)\SMAPI.Mods.SaveBackup\bin\$(Configuration)</SaveBackupBin>
|
||||
|
||||
<PackagePath>$(OutRootPath)\SMAPI installer</PackagePath>
|
||||
<PackageDevPath>$(OutRootPath)\SMAPI installer for developers</PackageDevPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<TranslationFiles Include="$(SmapiBin)\i18n\*.json" />
|
||||
<ErrorHandlerTranslationFiles Include="$(ErrorHandlerBin)\i18n\*.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- reset package directory -->
|
||||
<RemoveDir Directories="$(PackagePath)" />
|
||||
<RemoveDir Directories="$(PackageDevPath)" />
|
||||
|
||||
<!-- copy installer files -->
|
||||
<Copy SourceFiles="$(TargetDir)\assets\unix-install.sh" DestinationFiles="$(PackagePath)\install on Linux.sh" />
|
||||
<Copy SourceFiles="$(TargetDir)\assets\unix-install.sh" DestinationFiles="$(PackagePath)\install on macOS.command" />
|
||||
<Copy SourceFiles="$(TargetDir)\assets\windows-install.bat" DestinationFiles="$(PackagePath)\install on Windows.bat" />
|
||||
<Copy SourceFiles="$(TargetDir)\assets\README.txt" DestinationFolder="$(PackagePath)" />
|
||||
<Copy SourceFiles="$(TargetDir)\assets\windows-exe-config.xml" DestinationFiles="$(PackagePath)\internal\$(PlatformName)\install.exe.config" Condition="$(PlatformName) == 'windows'" />
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).dll" DestinationFolder="$(PackagePath)\internal\$(PlatformName)" />
|
||||
<Copy SourceFiles="$(TargetDir)\$(TargetName).runtimeconfig.json" DestinationFolder="$(PackagePath)\internal\$(PlatformName)" />
|
||||
|
||||
<!--copy bundle files-->
|
||||
<Copy SourceFiles="$(TargetDir)\assets\runtimeconfig.$(PlatformName).json" DestinationFiles="$(PackagePath)\bundle\StardewModdingAPI.runtimeconfig.json" />
|
||||
<Copy SourceFiles="$(SmapiBin)\StardewModdingAPI.dll" DestinationFolder="$(PackagePath)\bundle" />
|
||||
<Copy SourceFiles="$(SmapiBin)\StardewModdingAPI.exe" DestinationFolder="$(PackagePath)\bundle" Condition="$(PlatformName) == 'windows'" />
|
||||
<Copy SourceFiles="$(SmapiBin)\StardewModdingAPI" DestinationFolder="$(PackagePath)\bundle" Condition="$(PlatformName) != 'windows'" />
|
||||
<Copy SourceFiles="$(SmapiBin)\StardewModdingAPI.pdb" DestinationFolder="$(PackagePath)\bundle" />
|
||||
<Copy SourceFiles="$(SmapiBin)\StardewModdingAPI.xml" DestinationFolder="$(PackagePath)\bundle" />
|
||||
<Copy SourceFiles="$(SmapiBin)\steam_appid.txt" DestinationFolder="$(PackagePath)\bundle" />
|
||||
<Copy SourceFiles="$(SmapiBin)\0Harmony.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(SmapiBin)\0Harmony.xml" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(SmapiBin)\Mono.Cecil.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(SmapiBin)\Mono.Cecil.Mdb.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(SmapiBin)\Mono.Cecil.Pdb.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(SmapiBin)\MonoMod.Common.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(SmapiBin)\Newtonsoft.Json.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(SmapiBin)\TMXTile.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(SmapiBin)\SMAPI.config.json" DestinationFiles="$(PackagePath)\bundle\smapi-internal\config.json" />
|
||||
<Copy SourceFiles="$(SmapiBin)\SMAPI.metadata.json" DestinationFiles="$(PackagePath)\bundle\smapi-internal\metadata.json" />
|
||||
<Copy SourceFiles="$(ToolkitBin)\SMAPI.Toolkit.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(ToolkitBin)\SMAPI.Toolkit.pdb" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(ToolkitBin)\SMAPI.Toolkit.xml" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(ToolkitBin)\SMAPI.Toolkit.CoreInterfaces.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(ToolkitBin)\SMAPI.Toolkit.CoreInterfaces.pdb" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(ToolkitBin)\SMAPI.Toolkit.CoreInterfaces.xml" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="@(TranslationFiles)" DestinationFolder="$(PackagePath)\bundle\smapi-internal\i18n" />
|
||||
<Copy Condition="$(PlatformName) == 'unix'" SourceFiles="$(TargetDir)\assets\unix-launcher.sh" DestinationFolder="$(PackagePath)\bundle" />
|
||||
<Copy Condition="$(PlatformName) == 'unix'" SourceFiles="$(SmapiBin)\System.Runtime.Caching.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy Condition="$(PlatformName) == 'windows'" SourceFiles="$(TargetDir)\assets\windows-exe-config.xml" DestinationFiles="$(PackagePath)\bundle\StardewModdingAPI.exe.config" />
|
||||
|
||||
<!-- copy .NET dependencies -->
|
||||
<Copy SourceFiles="$(SmapiBin)\System.Configuration.ConfigurationManager.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(SmapiBin)\System.Management.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" Condition="$(PlatformName) == 'windows'" />
|
||||
<Copy SourceFiles="$(SmapiBin)\System.Runtime.Caching.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
<Copy SourceFiles="$(SmapiBin)\System.Security.Permissions.dll" DestinationFolder="$(PackagePath)\bundle\smapi-internal" />
|
||||
|
||||
<!--copy bundled mods-->
|
||||
<Copy SourceFiles="$(ConsoleCommandsBin)\ConsoleCommands.dll" DestinationFolder="$(PackagePath)\bundle\Mods\ConsoleCommands" />
|
||||
<Copy SourceFiles="$(ConsoleCommandsBin)\ConsoleCommands.pdb" DestinationFolder="$(PackagePath)\bundle\Mods\ConsoleCommands" />
|
||||
<Copy SourceFiles="$(ConsoleCommandsBin)\manifest.json" DestinationFolder="$(PackagePath)\bundle\Mods\ConsoleCommands" />
|
||||
<Copy SourceFiles="$(ErrorHandlerBin)\ErrorHandler.dll" DestinationFolder="$(PackagePath)\bundle\Mods\ErrorHandler" />
|
||||
<Copy SourceFiles="$(ErrorHandlerBin)\ErrorHandler.pdb" DestinationFolder="$(PackagePath)\bundle\Mods\ErrorHandler" />
|
||||
<Copy SourceFiles="$(ErrorHandlerBin)\manifest.json" DestinationFolder="$(PackagePath)\bundle\Mods\ErrorHandler" />
|
||||
<Copy SourceFiles="@(ErrorHandlerTranslationFiles)" DestinationFolder="$(PackagePath)\bundle\Mods\ErrorHandler\i18n" />
|
||||
<Copy SourceFiles="$(SaveBackupBin)\SaveBackup.dll" DestinationFolder="$(PackagePath)\bundle\Mods\SaveBackup" />
|
||||
<Copy SourceFiles="$(SaveBackupBin)\SaveBackup.pdb" DestinationFolder="$(PackagePath)\bundle\Mods\SaveBackup" />
|
||||
<Copy SourceFiles="$(SaveBackupBin)\manifest.json" DestinationFolder="$(PackagePath)\bundle\Mods\SaveBackup" />
|
||||
|
||||
<!-- fix Linux/macOS permissions -->
|
||||
<Exec Condition="$(PlatformName) == 'unix'" Command="chmod 755 "$(PackagePath)/install on Linux.sh"" />
|
||||
<Exec Condition="$(PlatformName) == 'unix'" Command="chmod 755 "$(PackagePath)/install on macOS.command"" />
|
||||
<Exec Condition="$(PlatformName) == 'unix'" Command="chmod 755 "$(PackagePath)/bundle/unix-launcher.sh"" />
|
||||
|
||||
<!-- finalise 'for developers' installer -->
|
||||
<ItemGroup>
|
||||
<PackageFiles Include="$(PackagePath)\**\*.*" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(PackageFiles)" DestinationFolder="$(PackageDevPath)\%(RecursiveDir)" />
|
||||
<ZipDirectory SourceDirectory="$(PackageDevPath)\bundle" DestinationFile="$(PackageDevPath)\internal\$(PlatformName)\install.dat" />
|
||||
<RemoveDir Directories="$(PackageDevPath)\bundle" />
|
||||
|
||||
<!-- finalise normal installer -->
|
||||
<ReplaceFileText FilePath="$(PackagePath)\bundle\smapi-internal\config.json" Search=""DeveloperMode": true" Replace=""DeveloperMode": false" />
|
||||
<ZipDirectory SourceDirectory="$(PackagePath)\bundle" DestinationFile="$(PackagePath)\internal\$(PlatformName)\install.dat" />
|
||||
<RemoveDir Directories="$(PackagePath)\bundle" />
|
||||
</Target>
|
||||
|
||||
<!-- Replace text in a file based on a regex pattern. Derived from https://stackoverflow.com/a/22571621/262123. -->
|
||||
<UsingTask TaskName="ReplaceFileText" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
|
||||
<ParameterGroup>
|
||||
<FilePath ParameterType="System.String" Required="true" />
|
||||
<Search ParameterType="System.String" Required="true" />
|
||||
<Replace ParameterType="System.String" Required="true" />
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<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,211 @@
|
|||
#!/bin/bash
|
||||
|
||||
#
|
||||
#
|
||||
# This is the Bash equivalent of ../windows/prepare-install-package.ps1.
|
||||
# When making changes, both scripts should be updated.
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
##########
|
||||
## Constants
|
||||
##########
|
||||
# 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")
|
||||
|
||||
|
||||
##########
|
||||
## 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
|
||||
##########
|
||||
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.pdb" "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" "TMXTile.dll" "SMAPI.Toolkit.dll" "SMAPI.Toolkit.pdb" "SMAPI.Toolkit.xml" "SMAPI.Toolkit.CoreInterfaces.dll" "SMAPI.Toolkit.CoreInterfaces.pdb" "SMAPI.Toolkit.CoreInterfaces.xml"; 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"
|
||||
cp "$smapiBin/System.Runtime.Caching.dll" "$bundlePath/smapi-internal"
|
||||
else
|
||||
cp "$installAssets/windows-exe-config.xml" "$bundlePath/StardewModdingAPI.exe.config"
|
||||
fi
|
||||
|
||||
# copy .NET dependencies
|
||||
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"
|
||||
if [ $folder == "windows" ]; then
|
||||
cp "$smapiBin/System.Management.dll" "$bundlePath/smapi-internal"
|
||||
fi
|
||||
|
||||
# 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/$modName.pdb" "$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
|
||||
##########
|
||||
# get version number
|
||||
version="$1"
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "SMAPI release version (like '4.0.0'):"
|
||||
read version
|
||||
fi
|
||||
|
||||
# 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"
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/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
|
|
@ -0,0 +1,67 @@
|
|||
#!/bin/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!"
|
|
@ -0,0 +1,11 @@
|
|||
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)
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
#
|
||||
#
|
||||
# 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. 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"
|
||||
|
||||
##########
|
||||
## Constants
|
||||
##########
|
||||
# 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" }
|
||||
|
||||
|
||||
##########
|
||||
## 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
|
||||
##########
|
||||
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")) {
|
||||
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.pdb", "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", "TMXTile.dll", "SMAPI.Toolkit.dll", "SMAPI.Toolkit.pdb", "SMAPI.Toolkit.xml", "SMAPI.Toolkit.CoreInterfaces.dll", "SMAPI.Toolkit.CoreInterfaces.pdb", "SMAPI.Toolkit.CoreInterfaces.xml")) {
|
||||
cp "$smapiBin/$name" "$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"
|
||||
cp "$smapiBin/System.Runtime.Caching.dll" "$bundlePath/smapi-internal"
|
||||
}
|
||||
else {
|
||||
cp "$installAssets/windows-exe-config.xml" "$bundlePath/StardewModdingAPI.exe.config"
|
||||
}
|
||||
|
||||
# copy .NET dependencies
|
||||
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"
|
||||
if ($folder -eq "windows") {
|
||||
cp "$smapiBin/System.Management.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/$modName.pdb" "$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"
|
||||
|
||||
# DISABLED: will be handled by Linux script
|
||||
# convert bundle folder into final 'install.dat' files
|
||||
#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
|
||||
###########
|
||||
# get version number
|
||||
$version = $args[0]
|
||||
if (!$version) {
|
||||
$version = Read-Host "SMAPI release version (like '4.0.0')"
|
||||
}
|
||||
|
||||
# rename folders
|
||||
mv "$packagePath" "bin/SMAPI $version installer"
|
||||
mv "$packageDevPath" "bin/SMAPI $version installer for developers"
|
||||
|
||||
# DISABLED: will be handled by Linux script
|
||||
## package files
|
||||
#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."
|
|
@ -0,0 +1,25 @@
|
|||
#
|
||||
#
|
||||
# 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,11 +1,27 @@
|
|||
← [README](README.md)
|
||||
|
||||
# Release notes
|
||||
## 3.13.2
|
||||
Released 05 December 2021 for Stardew Valley 1.5.5 or later.
|
||||
|
||||
* For players:
|
||||
* You no longer need .NET 5 to install or use SMAPI.
|
||||
* The installer now detects when the game folder contains an incompatible legacy game version.
|
||||
* Updated for the latest Stardew Valley 1.5.5 hotfix.
|
||||
* Updated compatibility list.
|
||||
|
||||
* For the web UI:
|
||||
* Fixed the JSON validator marking `.fnt` files invalid in Content Patcher files.
|
||||
|
||||
* For SMAPI maintainers:
|
||||
* Added [release package scripts](technical/smapi.md) to streamline preparing SMAPI releases.
|
||||
|
||||
## 3.13.1
|
||||
Released 30 November 2021 for Stardew Valley 1.5.5 or later.
|
||||
|
||||
* Improved .NET 5 validation in Windows installer to better explain how to get the right version.
|
||||
* Fixed installer failing on Windows when run from the game folder.
|
||||
* For players:
|
||||
* Improved .NET 5 validation in Windows installer to better explain how to get the right version.
|
||||
* Fixed installer failing on Windows when run from the game folder.
|
||||
|
||||
## 3.13.0
|
||||
Released 30 November 2021 for Stardew Valley 1.5.5 or later.
|
||||
|
|
|
@ -412,7 +412,9 @@ The NuGet package is generated automatically in `StardewModdingAPI.ModBuildConfi
|
|||
when you compile it.
|
||||
|
||||
## Release notes
|
||||
## Upcoming release
|
||||
## 4.0.0
|
||||
Released 30 November 2021.
|
||||
|
||||
* 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.
|
||||
|
|
|
@ -11,11 +11,12 @@ This document is about SMAPI itself; see also [mod build package](mod-package.md
|
|||
* [Configuration file](#configuration-file)
|
||||
* [Command-line arguments](#command-line-arguments)
|
||||
* [Compile flags](#compile-flags)
|
||||
* [For SMAPI developers](#for-smapi-developers)
|
||||
* [Compiling from source](#compiling-from-source)
|
||||
* [Debugging a local build](#debugging-a-local-build)
|
||||
* [Preparing a release](#preparing-a-release)
|
||||
* [Using a custom Harmony build](#using-a-custom-harmony-build)
|
||||
* [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
|
||||
|
@ -58,39 +59,42 @@ 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`.
|
||||
|
||||
## For SMAPI developers
|
||||
### Compiling from source
|
||||
## 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. There are no special steps (just open the project and compile), but SMAPI often
|
||||
uses the latest C# syntax. You may need the latest version of your IDE to compile it.
|
||||
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.
|
||||
|
||||
SMAPI uses build configuration derived from the [crossplatform mod config](https://smapi.io/package/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 `SMAPI` project with debugging from Visual Studio (on macOS or Windows) will launch SMAPI with
|
||||
the debugger attached, so you can intercept errors and step through the code being executed. That
|
||||
doesn't work in MonoDevelop on Linux, unfortunately.
|
||||
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.
|
||||
|
||||
### Preparing a release
|
||||
To prepare a crossplatform SMAPI release, you'll need to compile it on two platforms: Windows and
|
||||
Linux. The instructions below assume you have Windows 11, but you can adapt them for
|
||||
a different setup if needed.
|
||||
### Custom Harmony build
|
||||
SMAPI uses [a custom build of Harmony](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.
|
||||
|
||||
#### Initial setup
|
||||
First-time setup on Windows:
|
||||
1. [Install Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install).
|
||||
2. Install the needed software in WSL:
|
||||
1. Run `sudo apt update` to update the package list.
|
||||
2. Install [the .NET 5 SDK](https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu)
|
||||
(for Stardew Valley 1.5.5+) or [`mono-complete`](https://www.mono-project.com/download/stable/)
|
||||
(for earlier versions).
|
||||
_You can run `lsb_release -a` to get the Ubuntu version number._
|
||||
3. [Install Steam](https://linuxconfig.org/how-to-install-steam-on-ubuntu-20-04-focal-fossa-linux).
|
||||
4. Launch `steam` and install the game like usual.
|
||||
5. Download and install your preferred IDE. For the [latest standalone Rider
|
||||
## 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 platfrms, _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
|
||||
|
@ -98,47 +102,67 @@ First-time setup on Windows:
|
|||
ln -s "/opt/JetBrains Rider-<version>/bin/rider.sh"
|
||||
./rider.sh
|
||||
```
|
||||
3. Clone the SMAPI repo in WSL:
|
||||
```sh
|
||||
git clone https://github.com/Pathoschild/SMAPI.git
|
||||
```
|
||||
3. Clone the SMAPI repo:
|
||||
```sh
|
||||
git clone https://github.com/Pathoschild/SMAPI.git
|
||||
```
|
||||
|
||||
To compile SMAPI in WSL:
|
||||
1. Run `./rider.sh` to open the Rider GUI.
|
||||
2. Use the GUI to compile the solution.
|
||||
|
||||
To launch the game:
|
||||
1. Open a WSL terminal.
|
||||
2. Run these commands to start Steam:
|
||||
### Launch the game
|
||||
1. Run these commands to start Steam:
|
||||
```sh
|
||||
export TERM=xterm
|
||||
steam
|
||||
```
|
||||
3. Launch the game through the Steam UI.
|
||||
2. Launch the game through the Steam UI.
|
||||
|
||||
#### Prepare the release
|
||||
1. Update the version numbers in `build/common.targets`, `Constants`, and the `manifest.json` for
|
||||
bundled mods. Make sure you use a [semantic version](https://semver.org). Recommended format:
|
||||
### Prepare the release
|
||||
1. Run `build/unix/set-smapi-version.sh` to set the SMAPI version. Make sure you use a [semantic
|
||||
version](https://semver.org). Recommended format:
|
||||
|
||||
build type | format | example
|
||||
:--------- | :----------------------- | :------
|
||||
dev build | `<version>-alpha.<date>` | `3.0.0-alpha.20171230`
|
||||
prerelease | `<version>-beta.<date>` | `3.0.0-beta.20171230`
|
||||
release | `<version>` | `3.0.0`
|
||||
2. In Windows:
|
||||
1. Rebuild the solution with the _release_ solution configuration.
|
||||
2. Copy the `bin/SMAPI installer` and `bin/SMAPI installer for developers` folders to Linux.
|
||||
4. In Linux:
|
||||
1. Rebuild the solution with the _release_ solution configuration.
|
||||
2. Add the `windows-install.*` files from Windows to the `bin/SMAPI installer` and
|
||||
`bin/SMAPI installer for developers` folders compiled on Linux.
|
||||
3. Rename the folders to `SMAPI <version> installer` and `SMAPI <version> installer for developers`.
|
||||
4. Zip the two folders.
|
||||
dev build | `<version>-alpha.<date>` | `4.0.0-alpha.20251230`
|
||||
prerelease | `<version>-beta.<date>` | `4.0.0-beta.20251230`
|
||||
release | `<version>` | `4.0.0`
|
||||
|
||||
### Custom Harmony build
|
||||
SMAPI uses [a custom build of Harmony](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.
|
||||
2. Run `build/unix/prepare-install-package.sh` to create the release package in the root `bin`
|
||||
folder.
|
||||
|
||||
### 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/set-smapi-version.ps1` in PowerShell to set the SMAPI version. 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. Run `build/windows/prepare-install-package.ps1` in PowerShell to create the release package
|
||||
folders in the root `bin` folder.
|
||||
|
||||
3. Launch WSL and run this script:
|
||||
```bash
|
||||
# edit to match the build created in steps 1-2
|
||||
# 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"
|
||||
```
|
||||
|
||||
## Release notes
|
||||
See [release notes](../release-notes.md).
|
||||
|
|
|
@ -54,5 +54,12 @@ namespace StardewModdingAPI.Installer.Framework
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ using StardewModdingAPI.Installer.Framework;
|
|||
using StardewModdingAPI.Internal.ConsoleWriting;
|
||||
using StardewModdingAPI.Toolkit;
|
||||
using StardewModdingAPI.Toolkit.Framework;
|
||||
using StardewModdingAPI.Toolkit.Framework.GameScanning;
|
||||
using StardewModdingAPI.Toolkit.Framework.ModScanning;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
|
||||
|
@ -633,18 +634,39 @@ namespace StardewModdingApi.Installer
|
|||
// use specified path
|
||||
if (specifiedPath != null)
|
||||
{
|
||||
string errorPrefix = $"You specified --game-path \"{specifiedPath}\", but";
|
||||
|
||||
var dir = new DirectoryInfo(specifiedPath);
|
||||
if (!dir.Exists)
|
||||
{
|
||||
this.PrintError($"You specified --game-path \"{specifiedPath}\", but that folder doesn't exist.");
|
||||
this.PrintError($"{errorPrefix} that folder doesn't exist.");
|
||||
return null;
|
||||
}
|
||||
if (!context.LooksLikeGameFolder(dir))
|
||||
|
||||
switch (context.GetGameFolderType(dir))
|
||||
{
|
||||
this.PrintError($"You specified --game-path \"{specifiedPath}\", but that folder doesn't contain the Stardew Valley executable.");
|
||||
return null;
|
||||
case GameFolderType.Valid:
|
||||
return dir;
|
||||
|
||||
case GameFolderType.Legacy154OrEarlier:
|
||||
this.PrintWarning($"{errorPrefix} that directory seems to have Stardew Valley 1.5.4 or earlier.");
|
||||
this.PrintWarning("Please update your game to the latest version to use SMAPI.");
|
||||
return null;
|
||||
|
||||
case GameFolderType.LegacyCompatibilityBranch:
|
||||
this.PrintWarning($"{errorPrefix} that directory seems to have the Stardew Valley legacy 'compatibility' branch.");
|
||||
this.PrintWarning("Unfortunately SMAPI is only compatible with the modern version of the game.");
|
||||
this.PrintWarning("Please update your game to the main branch to use SMAPI.");
|
||||
return null;
|
||||
|
||||
case GameFolderType.NoGameFound:
|
||||
this.PrintWarning($"{errorPrefix} that directory doesn't contain a Stardew Valley executable.");
|
||||
return null;
|
||||
|
||||
default:
|
||||
this.PrintWarning($"{errorPrefix} that directory doesn't seem to contain a valid game install.");
|
||||
return null;
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
// let user choose detected path
|
||||
|
@ -702,15 +724,32 @@ namespace StardewModdingApi.Installer
|
|||
this.PrintWarning("That directory doesn't seem to exist.");
|
||||
continue;
|
||||
}
|
||||
if (!context.LooksLikeGameFolder(directory))
|
||||
{
|
||||
this.PrintWarning("That directory doesn't contain a Stardew Valley executable.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// looks OK
|
||||
this.PrintInfo(" OK!");
|
||||
return directory;
|
||||
switch (context.GetGameFolderType(directory))
|
||||
{
|
||||
case GameFolderType.Valid:
|
||||
this.PrintInfo(" OK!");
|
||||
return directory;
|
||||
|
||||
case GameFolderType.Legacy154OrEarlier:
|
||||
this.PrintWarning("That directory seems to have Stardew Valley 1.5.4 or earlier.");
|
||||
this.PrintWarning("Please update your game to the latest version to use SMAPI.");
|
||||
continue;
|
||||
|
||||
case GameFolderType.LegacyCompatibilityBranch:
|
||||
this.PrintWarning("That directory seems to have the Stardew Valley legacy 'compatibility' branch.");
|
||||
this.PrintWarning("Unfortunately SMAPI is only compatible with the modern version of the game.");
|
||||
this.PrintWarning("Please update your game to the main branch to use SMAPI.");
|
||||
continue;
|
||||
|
||||
case GameFolderType.NoGameFound:
|
||||
this.PrintWarning("That directory doesn't contain a Stardew Valley executable.");
|
||||
continue;
|
||||
|
||||
default:
|
||||
this.PrintWarning("That directory doesn't seem to contain a valid game install.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,5 +17,4 @@
|
|||
|
||||
<Import Project="..\SMAPI.Internal\SMAPI.Internal.projitems" Label="Shared" />
|
||||
<Import Project="..\..\build\common.targets" />
|
||||
<Import Project="..\..\build\prepare-install-package.targets" />
|
||||
</Project>
|
||||
|
|
|
@ -14,22 +14,27 @@
|
|||
SMAPI lets you run Stardew Valley with mods. Don't forget to download mods separately.
|
||||
|
||||
|
||||
Player's guide
|
||||
Automated install
|
||||
--------------------------------
|
||||
See https://stardewvalleywiki.com/Modding:Player_Guide for help installing SMAPI, adding mods, etc.
|
||||
|
||||
|
||||
Manual install
|
||||
--------------------------------
|
||||
THIS IS NOT RECOMMENDED FOR MOST PLAYERS. See instructions above instead.
|
||||
THIS IS NOT RECOMMENDED FOR MOST PLAYERS. See the 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/macOS). You can change '.dat' to '.zip', it's just a normal zip file renamed to prevent
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
3. Copy `Stardew Valley.deps.json` in the game folder, and rename the copy to
|
||||
`StardewModdingAPI.deps.json`.
|
||||
|
||||
4.
|
||||
- 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.
|
||||
|
||||
|
@ -38,8 +43,5 @@ If you really want to install SMAPI manually, here's how.
|
|||
play with mods.
|
||||
|
||||
When installing on Linux or macOS:
|
||||
- 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/config.json` file and see instructions
|
||||
there for the 'ColorScheme' setting.
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd "`dirname "$0"`"
|
||||
internal/linux/SMAPI.Installer
|
|
@ -12,36 +12,6 @@ if %ERRORLEVEL% EQU 0 (
|
|||
exit
|
||||
)
|
||||
|
||||
REM make sure .NET 5 is installed
|
||||
SET hasNet5=1
|
||||
WHERE dotnet /q
|
||||
if !ERRORLEVEL! NEQ 0 (
|
||||
SET hasNet5=0
|
||||
) else (
|
||||
dotnet --info | findstr /C:"Microsoft.WindowsDesktop.App 5." 1>nul
|
||||
if !ERRORLEVEL! NEQ 0 (
|
||||
SET hasNet5=0
|
||||
)
|
||||
)
|
||||
if "%hasNet5%" == "0" (
|
||||
echo Oops! You don't have the required .NET version installed.
|
||||
echo.
|
||||
echo To install it:
|
||||
echo 1. Go to https://dotnet.microsoft.com/download/dotnet/5.0/runtime
|
||||
|
||||
if "%PROCESSOR_ARCHITECTURE%" == "ARM64" (
|
||||
echo 2. Under "Run desktop apps", click "Download Arm64".
|
||||
) else (
|
||||
echo 2. Under "Run desktop apps", click "Download x64".
|
||||
)
|
||||
|
||||
echo 3. Run the downloaded installer.
|
||||
echo 4. Restart your computer.
|
||||
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.
|
||||
|
@ -50,9 +20,16 @@ if not exist %installerDir%"internal\windows\SMAPI.Installer.dll" (
|
|||
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
|
||||
dotnet internal\windows\SMAPI.Installer.dll
|
||||
internal\windows\SMAPI.Installer.exe
|
||||
|
||||
REM keep window open if it failed
|
||||
if %ERRORLEVEL% NEQ 0 (
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd "`dirname "$0"`"
|
||||
|
||||
xattr -r -d com.apple.quarantine internal
|
||||
internal/macOS/SMAPI.Installer
|
|
@ -4,11 +4,13 @@
|
|||
"includedFrameworks": [
|
||||
{
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "5.0.7"
|
||||
"version": "5.0.0",
|
||||
"rollForward": "latestMinor"
|
||||
}
|
||||
],
|
||||
"configProperties": {
|
||||
"System.Runtime.TieredCompilation": false
|
||||
"System.Runtime.TieredCompilation": false,
|
||||
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net5.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "5.0.0"
|
||||
},
|
||||
"configProperties": {
|
||||
"System.Runtime.TieredCompilation": false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Move to script's directory
|
||||
cd "`dirname "$0"`"
|
||||
|
||||
# make sure .NET 5 is installed
|
||||
if ! command -v dotnet >/dev/null 2>&1; then
|
||||
echo "Oops! You must have .NET 5 installed to use SMAPI: https://dotnet.microsoft.com/download";
|
||||
read
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# run installer
|
||||
dotnet internal/unix/SMAPI.Installer.dll
|
|
@ -49,20 +49,13 @@ if [ ! -f "Stardew Valley.dll" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# .NET 5 must be installed
|
||||
if ! command -v dotnet >/dev/null 2>&1; then
|
||||
echo "Oops! You must have .NET 5 installed to use SMAPI: https://dotnet.microsoft.com/download";
|
||||
read
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
##########
|
||||
## Launch SMAPI
|
||||
##########
|
||||
# macOS
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
dotnet StardewModdingAPI.dll "$@"
|
||||
./StardewModdingAPI "$@"
|
||||
|
||||
# Linux
|
||||
else
|
||||
|
|
|
@ -315,7 +315,7 @@ namespace StardewModdingAPI.ModBuildConfig.Analyzer
|
|||
return false;
|
||||
|
||||
// conversion to implemented interface is OK
|
||||
if (fromType.AllInterfaces.Contains(toType))
|
||||
if (fromType.AllInterfaces.Contains(toType, SymbolEqualityComparer.Default))
|
||||
return false;
|
||||
|
||||
// avoid any other conversions
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"Name": "Console Commands",
|
||||
"Author": "SMAPI",
|
||||
"Version": "3.13.1",
|
||||
"Version": "3.13.2",
|
||||
"Description": "Adds SMAPI console commands that let you manipulate the game.",
|
||||
"UniqueID": "SMAPI.ConsoleCommands",
|
||||
"EntryDll": "ConsoleCommands.dll",
|
||||
"MinimumApiVersion": "3.13.1"
|
||||
"MinimumApiVersion": "3.13.2"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
// warning messages
|
||||
"warn.invalid-content-removed": "Nieprawidłowa zawartość została usunięta, aby zapobiec awarii (zobacz konsolę SMAPI po więcej informacji)."
|
||||
}
|
||||
{
|
||||
// warning messages
|
||||
"warn.invalid-content-removed": "Nieprawidłowa zawartość została usunięta, aby zapobiec awarii (zobacz konsolę SMAPI po więcej informacji)."
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"Name": "Error Handler",
|
||||
"Author": "SMAPI",
|
||||
"Version": "3.13.1",
|
||||
"Version": "3.13.2",
|
||||
"Description": "Handles some common vanilla errors to log more useful info or avoid breaking the game.",
|
||||
"UniqueID": "SMAPI.ErrorHandler",
|
||||
"EntryDll": "ErrorHandler.dll",
|
||||
"MinimumApiVersion": "3.13.1"
|
||||
"MinimumApiVersion": "3.13.2"
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"Name": "Save Backup",
|
||||
"Author": "SMAPI",
|
||||
"Version": "3.13.1",
|
||||
"Version": "3.13.2",
|
||||
"Description": "Automatically backs up all your saves once per day into its folder.",
|
||||
"UniqueID": "SMAPI.SaveBackup",
|
||||
"EntryDll": "SaveBackup.dll",
|
||||
"MinimumApiVersion": "3.13.1"
|
||||
"MinimumApiVersion": "3.13.2"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
namespace StardewModdingAPI.Toolkit.Framework.GameScanning
|
||||
{
|
||||
/// <summary>The detected validity for a Stardew Valley game folder based on file structure heuristics.</summary>
|
||||
public enum GameFolderType
|
||||
{
|
||||
/// <summary>The folder seems to contain a valid Stardew Valley 1.5.5+ install.</summary>
|
||||
Valid,
|
||||
|
||||
/// <summary>The folder doesn't contain Stardew Valley.</summary>
|
||||
NoGameFound,
|
||||
|
||||
/// <summary>The folder contains Stardew Valley 1.5.4 or earlier. This version uses XNA Framework and 32-bit .NET Framework 4.5.2 on Windows and Mono on Linux/macOS, and isn't compatible with current versions of SMAPI.</summary>
|
||||
Legacy154OrEarlier,
|
||||
|
||||
/// <summary>The folder contains Stardew Valley from the game's legacy compatibility branch, which backports newer changes to the <see cref="Legacy154OrEarlier"/> format.</summary>
|
||||
LegacyCompatibilityBranch,
|
||||
|
||||
/// <summary>The folder seems to contain Stardew Valley files, but they failed to load for unknown reasons (e.g. corrupted executable).</summary>
|
||||
InvalidUnknown
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
using System.Reflection;
|
||||
#if SMAPI_FOR_WINDOWS
|
||||
using Microsoft.Win32;
|
||||
#endif
|
||||
|
@ -54,11 +55,59 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning
|
|||
/// <param name="dir">The folder to check.</param>
|
||||
public bool LooksLikeGameFolder(DirectoryInfo dir)
|
||||
{
|
||||
return
|
||||
dir.Exists
|
||||
&& dir.EnumerateFiles("Stardew Valley.dll").Any();
|
||||
return this.GetGameFolderType(dir) == GameFolderType.Valid;
|
||||
}
|
||||
|
||||
/// <summary>Detect the validity of a game folder based on file structure heuristics.</summary>
|
||||
/// <param name="dir">The folder to check.</param>
|
||||
public GameFolderType GetGameFolderType(DirectoryInfo dir)
|
||||
{
|
||||
// no such folder
|
||||
if (!dir.Exists)
|
||||
return GameFolderType.NoGameFound;
|
||||
|
||||
// apparently valid
|
||||
if (dir.EnumerateFiles("Stardew Valley.dll").Any())
|
||||
return GameFolderType.Valid;
|
||||
|
||||
// doesn't contain any version of Stardew Valley
|
||||
FileInfo executable = new(Path.Combine(dir.FullName, "Stardew Valley.exe"));
|
||||
if (!executable.Exists)
|
||||
executable = new(Path.Combine(dir.FullName, "StardewValley.exe")); // pre-1.5.5 Linux/macOS executable
|
||||
if (!executable.Exists)
|
||||
return GameFolderType.NoGameFound;
|
||||
|
||||
// get assembly version
|
||||
Version version;
|
||||
try
|
||||
{
|
||||
version = AssemblyName.GetAssemblyName(executable.FullName).Version;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// The executable exists but it doesn't seem to be a valid assembly. This would
|
||||
// happen with Stardew Valley 1.5.5+, but that should have been flagged as a valid
|
||||
// folder before this point.
|
||||
return GameFolderType.InvalidUnknown;
|
||||
}
|
||||
|
||||
// ignore Stardew Valley 1.5.5+ at this point
|
||||
if (version.Major == 1 && version.Minor == 3 && version.Build == 37)
|
||||
return GameFolderType.InvalidUnknown;
|
||||
|
||||
// incompatible version
|
||||
if (version.Major == 1 && version.Minor < 4)
|
||||
{
|
||||
// Stardew Valley 1.5.4 and earlier have assembly versions <= 1.3.7853.31734
|
||||
if (version.Minor < 3 || version.Build <= 7853)
|
||||
return GameFolderType.Legacy154OrEarlier;
|
||||
|
||||
// Stardew Valley 1.5.5+ legacy compatibility branch
|
||||
return GameFolderType.LegacyCompatibilityBranch;
|
||||
}
|
||||
|
||||
return GameFolderType.InvalidUnknown;
|
||||
}
|
||||
|
||||
/*********
|
||||
** Private methods
|
||||
|
|
|
@ -215,6 +215,11 @@
|
|||
"~0.4.1 | Status": "AssumeBroken",
|
||||
"~0.4.1 | StatusReasonDetails": "causes freeze during game launch"
|
||||
},
|
||||
"UI Info Suite": {
|
||||
"ID": "Cdaragorn.UiInfoSuite",
|
||||
"~2.0.0 | Status": "AssumeBroken",
|
||||
"~2.0.0 | StatusReasonDetails": "causes lag, errors, or crashes in-game"
|
||||
},
|
||||
"Video Player": {
|
||||
"ID": "aedenthorn.VideoPlayer",
|
||||
"~0.2.5 | Status": "AssumeBroken",
|
||||
|
|
|
@ -214,7 +214,7 @@
|
|||
},
|
||||
"FromFile": {
|
||||
"title": "Source file",
|
||||
"description": "The relative file path in your content pack folder to load instead (like 'assets/dinosaur.png'), or multiple comma-delimited values. This can be a .json (data), .png (image), .tbin or .tmx (map), or .xnb file. This field supports tokens and capitalization doesn't matter.",
|
||||
"description": "The relative file path in your content pack folder to load instead (like 'assets/dinosaur.png'), or multiple comma-delimited values. This can be a .fnt (font), .json (data), .png (image), .tbin or .tmx (map), or .xnb file. This field supports tokens and capitalization doesn't matter.",
|
||||
"type": "string",
|
||||
"allOf": [
|
||||
{
|
||||
|
@ -223,12 +223,12 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"pattern": "\\.(json|png|tbin|tmx|xnb) *$"
|
||||
"pattern": "\\.(fnt|json|png|tbin|tmx|xnb) *$"
|
||||
}
|
||||
],
|
||||
"@errorMessages": {
|
||||
"allOf:indexes: 0": "Invalid value; must not contain directory climbing (like '../').",
|
||||
"allOf:indexes: 1": "Invalid value; must be a file path ending with .json, .png, .tbin, .tmx, or .xnb."
|
||||
"allOf:indexes: 1": "Invalid value; must be a file path ending with .fnt, .json, .png, .tbin, .tmx, or .xnb."
|
||||
}
|
||||
},
|
||||
"FromArea": {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28729.10
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31912.275
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".root", ".root", "{86C452BE-D2D8-45B4-B63F-E329EB06CEDA}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
|
@ -28,7 +28,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{09CF91E5
|
|||
ProjectSection(SolutionItems) = preProject
|
||||
..\build\common.targets = ..\build\common.targets
|
||||
..\build\find-game-folder.targets = ..\build\find-game-folder.targets
|
||||
..\build\prepare-install-package.targets = ..\build\prepare-install-package.targets
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{EB35A917-67B9-4EFA-8DFC-4FB49B3949BB}"
|
||||
|
@ -84,6 +83,24 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SMAPI.Toolkit.CoreInterface
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SMAPI.Web", "SMAPI.Web\SMAPI.Web.csproj", "{80EFD92F-728F-41E0-8A5B-9F6F49A91899}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "windows", "windows", "{4D661178-38FB-43E4-AA5F-9B0406919344}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\build\windows\finalize-install-package.sh = ..\build\windows\finalize-install-package.sh
|
||||
..\build\windows\prepare-install-package.ps1 = ..\build\windows\prepare-install-package.ps1
|
||||
..\build\windows\set-smapi-version.ps1 = ..\build\windows\set-smapi-version.ps1
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unix", "unix", "{CAA1488E-842B-433D-994D-1D3D0B5DD125}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\build\unix\prepare-install-package.sh = ..\build\unix\prepare-install-package.sh
|
||||
..\build\unix\set-smapi-version.sh = ..\build\unix\set-smapi-version.sh
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{3B5BF14D-F612-4C83-9EF6-E3EBFCD08766}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\build\windows\lib\in-place-regex.ps1 = ..\build\windows\lib\in-place-regex.ps1
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
SMAPI.Internal\SMAPI.Internal.projitems*{0634ea4c-3b8f-42db-aea6-ca9e4ef6e92f}*SharedItemsImports = 5
|
||||
|
@ -167,6 +184,9 @@ Global
|
|||
{0634EA4C-3B8F-42DB-AEA6-CA9E4EF6E92F} = {AE9A4D46-E910-4293-8BC4-673F85FFF6A5}
|
||||
{491E775B-EAD0-44D4-B6CA-F1FC3E316D33} = {AE9A4D46-E910-4293-8BC4-673F85FFF6A5}
|
||||
{CD53AD6F-97F4-4872-A212-50C2A0FD3601} = {AE9A4D46-E910-4293-8BC4-673F85FFF6A5}
|
||||
{4D661178-38FB-43E4-AA5F-9B0406919344} = {09CF91E5-5BAB-4650-A200-E5EA9A633046}
|
||||
{CAA1488E-842B-433D-994D-1D3D0B5DD125} = {09CF91E5-5BAB-4650-A200-E5EA9A633046}
|
||||
{3B5BF14D-F612-4C83-9EF6-E3EBFCD08766} = {4D661178-38FB-43E4-AA5F-9B0406919344}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {70143042-A862-47A8-A677-7C819DDC90DC}
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace StardewModdingAPI
|
|||
internal static int? LogScreenId { get; set; }
|
||||
|
||||
/// <summary>SMAPI's current raw semantic version.</summary>
|
||||
internal static string RawApiVersion = "3.13.1";
|
||||
internal static string RawApiVersion = "3.13.2";
|
||||
}
|
||||
|
||||
/// <summary>Contains SMAPI's constants and assumptions.</summary>
|
||||
|
|
|
@ -4,6 +4,8 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Reflection;
|
||||
using HarmonyLib;
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member: This is internal code to support rewriters that shouldn't be called directly.
|
||||
|
||||
namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
|
||||
{
|
||||
/// <summary>Maps Harmony 1.x <see cref="AccessTools"/> methods to Harmony 2.x to avoid breaking older mods.</summary>
|
||||
|
|
|
@ -5,6 +5,8 @@ using System.Reflection;
|
|||
using System.Reflection.Emit;
|
||||
using HarmonyLib;
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member: This is internal code to support rewriters that shouldn't be called directly.
|
||||
|
||||
namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
|
||||
{
|
||||
/// <summary>Maps Harmony 1.x <code>HarmonyInstance</code> methods to Harmony 2.x's <see cref="Harmony"/> to avoid breaking older mods.</summary>
|
||||
|
|
|
@ -3,6 +3,8 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Reflection;
|
||||
using HarmonyLib;
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member: This is internal code to support rewriters that shouldn't be called directly.
|
||||
|
||||
namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
|
||||
{
|
||||
/// <summary>Maps Harmony 1.x <see cref="HarmonyMethod"/> methods to Harmony 2.x to avoid breaking older mods.</summary>
|
||||
|
|
|
@ -2,6 +2,9 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
#pragma warning disable CS0109 // Member does not hide an inherited member, new keyword is not required: This is deliberate to support legacy XNA Framework platforms.
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member: This is internal code to support rewriters that shouldn't be called directly.
|
||||
|
||||
namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
|
||||
{
|
||||
/// <summary>Provides <see cref="SpriteBatch"/> method signatures that can be injected into mod code for compatibility with mods written for XNA Framework before Stardew Valley 1.5.5.</summary>
|
||||
|
|
|
@ -776,10 +776,10 @@ namespace StardewModdingAPI.Framework
|
|||
}
|
||||
if (!Game1.eventUp && Game1.farmEvent == null && Game1.currentBillboard == 0 && Game1.gameMode == 3 && !this.takingMapScreenshot && Game1.isOutdoorMapSmallerThanViewport())
|
||||
{
|
||||
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(0, 0, -Math.Min(Game1.viewport.X, GameRunner.MaxTextureSize), Game1.graphics.GraphicsDevice.Viewport.Height), Color.Black);
|
||||
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(-Game1.viewport.X + Game1.currentLocation.map.Layers[0].LayerWidth * 64, 0, Math.Min(GameRunner.MaxTextureSize, Game1.graphics.GraphicsDevice.Viewport.Width - (-Game1.viewport.X + Game1.currentLocation.map.Layers[0].LayerWidth * 64)), Game1.graphics.GraphicsDevice.Viewport.Height), Color.Black);
|
||||
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(0, 0, Game1.graphics.GraphicsDevice.Viewport.Width, -Math.Min(Game1.viewport.Y, GameRunner.MaxTextureSize)), Color.Black);
|
||||
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(0, -Game1.viewport.Y + Game1.currentLocation.map.Layers[0].LayerHeight * 64, Game1.graphics.GraphicsDevice.Viewport.Width, Math.Min(GameRunner.MaxTextureSize, Game1.graphics.GraphicsDevice.Viewport.Height - (-Game1.viewport.Y + Game1.currentLocation.map.Layers[0].LayerHeight * 64))), Color.Black);
|
||||
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(0, 0, -Game1.viewport.X, Game1.graphics.GraphicsDevice.Viewport.Height), Color.Black);
|
||||
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(-Game1.viewport.X + Game1.currentLocation.map.Layers[0].LayerWidth * 64, 0, Game1.graphics.GraphicsDevice.Viewport.Width - (-Game1.viewport.X + Game1.currentLocation.map.Layers[0].LayerWidth * 64), Game1.graphics.GraphicsDevice.Viewport.Height), Color.Black);
|
||||
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(0, 0, Game1.graphics.GraphicsDevice.Viewport.Width, -Game1.viewport.Y), Color.Black);
|
||||
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle(0, -Game1.viewport.Y + Game1.currentLocation.map.Layers[0].LayerHeight * 64, Game1.graphics.GraphicsDevice.Viewport.Width, Game1.graphics.GraphicsDevice.Viewport.Height - (-Game1.viewport.Y + Game1.currentLocation.map.Layers[0].LayerHeight * 64)), Color.Black);
|
||||
}
|
||||
Game1.spriteBatch.End();
|
||||
Game1.PushUIMode();
|
||||
|
|
|
@ -6,7 +6,7 @@ using StardewValley;
|
|||
namespace StardewModdingAPI
|
||||
{
|
||||
/// <summary>A unified button constant which includes all controller, keyboard, and mouse buttons.</summary>
|
||||
/// <remarks>Derived from <see cref="Keys"/>, <see cref="Buttons"/>, and <see cref="System.Windows.Forms.MouseButtons"/>.</remarks>
|
||||
/// <remarks>Derived from <see cref="Keys"/>, <see cref="Buttons"/>, and <c>System.Windows.Forms.MouseButtons</c>.</remarks>
|
||||
public enum SButton
|
||||
{
|
||||
/// <summary>No valid key.</summary>
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
|
||||
<!--copy dependency DLLs to bin folder so we can include them in installer bundle -->
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
||||
<!-- tiered compilation breaks Harmony -->
|
||||
<TieredCompilation>false</TieredCompilation>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\..\build\common.targets" />
|
||||
|
|
|
@ -105,7 +105,9 @@ namespace StardewModdingAPI.Utilities
|
|||
/// <summary>Get the keybind state relative to the previous tick.</summary>
|
||||
public SButtonState GetState()
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete: deliberate call to GetButtonState() for unit tests
|
||||
SButtonState[] states = this.Buttons.Select(this.GetButtonState).Distinct().ToArray();
|
||||
#pragma warning restore CS0618
|
||||
|
||||
// single state
|
||||
if (states.Length == 1)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
// short date format for SDate
|
||||
// tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2)
|
||||
"generic.date": "{{day}} {{seasonLowercase}}",
|
||||
"generic.date-with-year": "{{day}} {{seasonLowercase}} w roku {{year}}"
|
||||
}
|
||||
{
|
||||
// short date format for SDate
|
||||
// tokens: {{day}} (like 15), {{season}} (like Spring), {{seasonLowercase}} (like spring), {{year}} (like 2)
|
||||
"generic.date": "{{day}} {{seasonLowercase}}",
|
||||
"generic.date-with-year": "{{day}} {{seasonLowercase}} w roku {{year}}"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue