summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2020-08-02 16:38:51 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2020-08-02 16:38:51 -0400
commit8da88b8fe5b41739c5cd0df3280b9770fc7f10a4 (patch)
treeaed3679d01ee546726851982862daac2bad38b41 /src
parentba0dff819f2e65b16a0c7bc7a9233fdb101994d0 (diff)
parentb96bcb21894257f06716e6a51102f74d2aba5178 (diff)
downloadSMAPI-8da88b8fe5b41739c5cd0df3280b9770fc7f10a4.tar.gz
SMAPI-8da88b8fe5b41739c5cd0df3280b9770fc7f10a4.tar.bz2
SMAPI-8da88b8fe5b41739c5cd0df3280b9770fc7f10a4.zip
Merge branch 'develop' into stable
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI.Installer/InteractiveInstaller.cs4
-rw-r--r--src/SMAPI.Installer/Program.cs2
-rw-r--r--src/SMAPI.Installer/assets/unix-launcher.sh70
-rw-r--r--src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj2
-rw-r--r--src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs10
-rw-r--r--src/SMAPI.ModBuildConfig/build/smapi.targets10
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/Framework/Commands/ArgumentParser.cs2
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/ClearCommand.cs2
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/Framework/ItemData/SearchableItem.cs8
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs18
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/manifest.json4
-rw-r--r--src/SMAPI.Mods.SaveBackup/manifest.json4
-rw-r--r--src/SMAPI.Tests/SMAPI.Tests.csproj2
-rw-r--r--src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs2
-rw-r--r--src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs2
-rw-r--r--src/SMAPI.Toolkit/Framework/ModData/ModDataModel.cs2
-rw-r--r--src/SMAPI.Toolkit/Framework/ModData/ModDataRecord.cs4
-rw-r--r--src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs51
-rw-r--r--src/SMAPI.Toolkit/ModToolkit.cs2
-rw-r--r--src/SMAPI.Toolkit/SMAPI.Toolkit.csproj2
-rw-r--r--src/SMAPI.Toolkit/SemanticVersion.cs6
-rw-r--r--src/SMAPI.Toolkit/Serialization/InternalExtensions.cs2
-rw-r--r--src/SMAPI.Web/Controllers/JsonValidatorController.cs6
-rw-r--r--src/SMAPI.Web/Controllers/ModsApiController.cs4
-rw-r--r--src/SMAPI.Web/Framework/Caching/Mods/ModCacheMemoryRepository.cs2
-rw-r--r--src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs2
-rw-r--r--src/SMAPI.Web/SMAPI.Web.csproj10
-rw-r--r--src/SMAPI.Web/wwwroot/schemas/content-patcher.json4
-rw-r--r--src/SMAPI/Constants.cs2
-rw-r--r--src/SMAPI/Framework/CommandManager.cs2
-rw-r--r--src/SMAPI/Framework/Content/AssetDataForMap.cs2
-rw-r--r--src/SMAPI/Framework/Content/AssetInfo.cs2
-rw-r--r--src/SMAPI/Framework/Content/ContentCache.cs2
-rw-r--r--src/SMAPI/Framework/ContentCoordinator.cs4
-rw-r--r--src/SMAPI/Framework/ContentManagers/BaseContentManager.cs6
-rw-r--r--src/SMAPI/Framework/ContentManagers/GameContentManager.cs4
-rw-r--r--src/SMAPI/Framework/ContentManagers/ModContentManager.cs2
-rw-r--r--src/SMAPI/Framework/DeprecationManager.cs2
-rw-r--r--src/SMAPI/Framework/Events/ManagedEvent.cs7
-rw-r--r--src/SMAPI/Framework/GameVersion.cs4
-rw-r--r--src/SMAPI/Framework/ModLoading/Framework/BaseInstructionHandler.cs2
-rw-r--r--src/SMAPI/Framework/ModLoading/ModMetadata.cs4
-rw-r--r--src/SMAPI/Framework/ModLoading/ModResolver.cs2
-rw-r--r--src/SMAPI/Framework/Models/SConfig.cs4
-rw-r--r--src/SMAPI/Framework/Networking/MultiplayerPeer.cs2
-rw-r--r--src/SMAPI/Framework/PerformanceMonitoring/PerformanceCounterCollection.cs2
-rw-r--r--src/SMAPI/Framework/PerformanceMonitoring/PerformanceMonitor.cs2
-rw-r--r--src/SMAPI/Framework/SCore.cs16
-rw-r--r--src/SMAPI/Framework/SGame.cs8
-rw-r--r--src/SMAPI/Framework/SMultiplayer.cs2
-rw-r--r--src/SMAPI/Framework/Translator.cs6
-rw-r--r--src/SMAPI/Metadata/CoreAssetPropagator.cs8
-rw-r--r--src/SMAPI/Program.cs2
-rw-r--r--src/SMAPI/SMAPI.csproj2
-rw-r--r--src/SMAPI/Translation.cs2
55 files changed, 188 insertions, 154 deletions
diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs
index 1457848b..dc96e2e8 100644
--- a/src/SMAPI.Installer/InteractiveInstaller.cs
+++ b/src/SMAPI.Installer/InteractiveInstaller.cs
@@ -468,7 +468,7 @@ namespace StardewModdingApi.Installer
}
// find target folder
- ModFolder targetMod = targetMods.FirstOrDefault(p => p.Manifest?.UniqueID?.Equals(sourceMod.Manifest.UniqueID, StringComparison.InvariantCultureIgnoreCase) == true);
+ ModFolder targetMod = targetMods.FirstOrDefault(p => p.Manifest?.UniqueID?.Equals(sourceMod.Manifest.UniqueID, StringComparison.OrdinalIgnoreCase) == true);
DirectoryInfo defaultTargetFolder = new DirectoryInfo(Path.Combine(paths.ModsPath, sourceMod.Directory.Name));
DirectoryInfo targetFolder = targetMod?.Directory ?? defaultTargetFolder;
this.PrintDebug(targetFolder.FullName == defaultTargetFolder.FullName
@@ -808,7 +808,7 @@ namespace StardewModdingApi.Installer
continue; // should never happen
// delete packaged mods (newer version bundled into SMAPI)
- if (isDir && packagedModNames.Contains(entry.Name, StringComparer.InvariantCultureIgnoreCase))
+ if (isDir && packagedModNames.Contains(entry.Name, StringComparer.OrdinalIgnoreCase))
{
this.PrintDebug($" Deleting {entry.Name} because it's bundled into SMAPI...");
this.InteractivelyDelete(entry.FullName);
diff --git a/src/SMAPI.Installer/Program.cs b/src/SMAPI.Installer/Program.cs
index b7fa45f5..dc6c97f4 100644
--- a/src/SMAPI.Installer/Program.cs
+++ b/src/SMAPI.Installer/Program.cs
@@ -67,7 +67,7 @@ namespace StardewModdingApi.Installer
AssemblyName name = new AssemblyName(e.Name);
foreach (FileInfo dll in new DirectoryInfo(Program.InternalFilesPath).EnumerateFiles("*.dll"))
{
- if (name.Name.Equals(AssemblyName.GetAssemblyName(dll.FullName).Name, StringComparison.InvariantCultureIgnoreCase))
+ if (name.Name.Equals(AssemblyName.GetAssemblyName(dll.FullName).Name, StringComparison.OrdinalIgnoreCase))
return Assembly.LoadFrom(dll.FullName);
}
return null;
diff --git a/src/SMAPI.Installer/assets/unix-launcher.sh b/src/SMAPI.Installer/assets/unix-launcher.sh
index b72eed22..1d97d487 100644
--- a/src/SMAPI.Installer/assets/unix-launcher.sh
+++ b/src/SMAPI.Installer/assets/unix-launcher.sh
@@ -46,80 +46,64 @@ else
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 $*"
+ LAUNCHER="./StardewModdingAPI.bin.x86_64"
else
ln -sf mcs.bin.x86 mcs
cp StardewValley.bin.x86 StardewModdingAPI.bin.x86
- LAUNCHER="./StardewModdingAPI.bin.x86 $*"
+ LAUNCHER="./StardewModdingAPI.bin.x86"
fi
+ export LAUNCHER
# 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"
+ COMMAND="type -p"
fi
# 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; do
if $COMMAND "$terminal" 2>/dev/null; then
- # Find the true shell behind x-terminal-emulator
- if [ "$(basename "$(readlink -f $(which "$terminal"))")" != "x-terminal-emulator" ]; then
- export LAUNCHTERM=$terminal
- break;
- else
- export LAUNCHTERM="$(basename "$(readlink -f $(which x-terminal-emulator))")"
- # Remember that we're using x-terminal-emulator just in case it points outside the $PATH
- export XTE=1
- break;
- fi
+ export LAUNCHTERM=$terminal
+ break;
fi
done
- # if no terminal was found, run in current shell or with no output
- if [ -z "$LAUNCHTERM" ]; then
- sh -c 'TERM=xterm $LAUNCHER'
- if [ $? -eq 127 ]; then
- $LAUNCHER --no-terminal
- fi
- exit
+ # find the true shell behind x-terminal-emulator
+ if [ "$LAUNCHTERM" = "x-terminal-emulator" ]; then
+ export LAUNCHTERM="$(basename "$(readlink -f $(COMMAND x-terminal-emulator))")"
fi
# run in selected terminal and account for quirks
case $LAUNCHTERM in
- terminator)
- # Terminator converts -e to -x when used through x-terminal-emulator for some reason
- if $XTE; then
- terminator -e "sh -c 'TERM=xterm $LAUNCHER'"
- else
- terminator -x "sh -c 'TERM=xterm $LAUNCHER'"
- fi
+ terminal|termite)
+ # LAUNCHTERM consumes only one argument after -e
+ # options containing space characters are unsupported
+ exec $LAUNCHTERM -e "env TERM=xterm $LAUNCHER $@"
;;
- kitty)
- # Kitty overrides the TERM varible unless you set it explicitly
- kitty -o term=xterm $LAUNCHER
+ xterm|konsole|alacritty)
+ # LAUNCHTERM consumes all arguments after -e
+ exec $LAUNCHTERM -e env TERM=xterm $LAUNCHER "$@"
;;
- alacritty)
- # Alacritty doesn't like the double quotes or the variable
- if [ "$ARCH" == "x86_64" ]; then
- alacritty -e sh -c 'TERM=xterm ./StardewModdingAPI.bin.x86_64 $*'
- else
- alacritty -e sh -c 'TERM=xterm ./StardewModdingAPI.bin.x86 $*'
- fi
+ terminator|xfce4-terminal|mate-terminal)
+ # LAUNCHTERM consumes all arguments after -x
+ exec $LAUNCHTERM -x env TERM=xterm $LAUNCHER "$@"
;;
- xterm|xfce4-terminal|gnome-terminal|terminal|termite|mate-terminal)
- $LAUNCHTERM -e "sh -c 'TERM=xterm $LAUNCHER'"
+ gnome-terminal)
+ # LAUNCHTERM consumes all arguments after --
+ exec $LAUNCHTERM -- env TERM=xterm $LAUNCHER "$@"
;;
- konsole)
- konsole -p Environment=TERM=xterm -e "$LAUNCHER"
+ kitty)
+ # LAUNCHTERM consumes all trailing arguments
+ exec $LAUNCHTERM env TERM=xterm $LAUNCHER "$@"
;;
*)
# If we don't know the terminal, just try to run it in the current shell.
- sh -c 'TERM=xterm $LAUNCHER'
+ env TERM=xterm $LAUNCHER "$@"
# if THAT fails, launch with no output
if [ $? -eq 127 ]; then
- $LAUNCHER --no-terminal
+ exec $LAUNCHER --no-terminal "$@"
fi
esac
fi
diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj b/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj
index 5ae6574d..9c230203 100644
--- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj
+++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/SMAPI.ModBuildConfig.Analyzer.Tests.csproj
@@ -9,7 +9,7 @@
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="2.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="NUnit" Version="3.12.0" />
- <PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
+ <PackageReference Include="NUnit3TestAdapter" Version="3.17.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
diff --git a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs
index f0363a3e..636c3669 100644
--- a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs
+++ b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs
@@ -33,7 +33,7 @@ namespace StardewModdingAPI.ModBuildConfig.Framework
/// <exception cref="UserErrorException">The mod package isn't valid.</exception>
public ModFileManager(string projectDir, string targetDir, Regex[] ignoreFilePatterns, bool validateRequiredModFiles)
{
- this.Files = new Dictionary<string, FileInfo>(StringComparer.InvariantCultureIgnoreCase);
+ this.Files = new Dictionary<string, FileInfo>(StringComparer.OrdinalIgnoreCase);
// validate paths
if (!Directory.Exists(projectDir))
@@ -68,7 +68,7 @@ namespace StardewModdingAPI.ModBuildConfig.Framework
/// <summary>Get the files in the mod package.</summary>
public IDictionary<string, FileInfo> GetFiles()
{
- return new Dictionary<string, FileInfo>(this.Files, StringComparer.InvariantCultureIgnoreCase);
+ return new Dictionary<string, FileInfo>(this.Files, StringComparer.OrdinalIgnoreCase);
}
/// <summary>Get a semantic version from the mod manifest.</summary>
@@ -165,8 +165,8 @@ namespace StardewModdingAPI.ModBuildConfig.Framework
|| this.EqualsInvariant(file.Name, "Newtonsoft.Json.xml")
// code analysis files
- || file.Name.EndsWith(".CodeAnalysisLog.xml", StringComparison.InvariantCultureIgnoreCase)
- || file.Name.EndsWith(".lastcodeanalysissucceeded", StringComparison.InvariantCultureIgnoreCase)
+ || file.Name.EndsWith(".CodeAnalysisLog.xml", StringComparison.OrdinalIgnoreCase)
+ || file.Name.EndsWith(".lastcodeanalysissucceeded", StringComparison.OrdinalIgnoreCase)
// OS metadata files
|| this.EqualsInvariant(file.Name, ".DS_Store")
@@ -183,7 +183,7 @@ namespace StardewModdingAPI.ModBuildConfig.Framework
{
if (str == null)
return other == null;
- return str.Equals(other, StringComparison.InvariantCultureIgnoreCase);
+ return str.Equals(other, StringComparison.OrdinalIgnoreCase);
}
}
}
diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets
index bfee3b33..03db7490 100644
--- a/src/SMAPI.ModBuildConfig/build/smapi.targets
+++ b/src/SMAPI.ModBuildConfig/build/smapi.targets
@@ -20,12 +20,12 @@
<ModZipPath Condition="'$(ModZipPath)' == ''">$(TargetDir)</ModZipPath>
<EnableModDeploy Condition="'$(EnableModDeploy)' == ''">true</EnableModDeploy>
<EnableModZip Condition="'$(EnableModZip)' == ''">true</EnableModZip>
- <EnableHarmony Condition="'$(EnableModZip)' == ''">false</EnableHarmony>
- <EnableGameDebugging Condition="$(EnableGameDebugging) == ''">true</EnableGameDebugging>
+ <EnableHarmony Condition="'$(EnableHarmony)' == ''">false</EnableHarmony>
+ <EnableGameDebugging Condition="'$(EnableGameDebugging)' == ''">true</EnableGameDebugging>
<CopyModReferencesToBuildOutput Condition="'$(CopyModReferencesToBuildOutput)' == '' OR ('$(CopyModReferencesToBuildOutput)' != 'true' AND '$(CopyModReferencesToBuildOutput)' != 'false')">false</CopyModReferencesToBuildOutput>
</PropertyGroup>
- <PropertyGroup Condition="$(OS) == 'Windows_NT' AND $(EnableGameDebugging) == 'true'">
+ <PropertyGroup Condition="'$(OS)' == 'Windows_NT' AND '$(EnableGameDebugging)' == 'true'">
<!-- enable game debugging -->
<StartAction>Program</StartAction>
<StartProgram>$(GamePath)\StardewModdingAPI.exe</StartProgram>
@@ -47,7 +47,7 @@
</ItemGroup>
<!-- Windows -->
- <ItemGroup Condition="$(OS) == 'Windows_NT'">
+ <ItemGroup Condition="'$(OS)' == 'Windows_NT'">
<Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" Private="$(CopyModReferencesToBuildOutput)" />
<Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" Private="$(CopyModReferencesToBuildOutput)" />
<Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" Private="$(CopyModReferencesToBuildOutput)" />
@@ -56,7 +56,7 @@
</ItemGroup>
<!-- Linux/Mac -->
- <ItemGroup Condition="$(OS) != 'Windows_NT'">
+ <ItemGroup Condition="'$(OS)' != 'Windows_NT'">
<Reference Include="MonoGame.Framework" HintPath="$(GamePath)\MonoGame.Framework.dll" Private="$(CopyModReferencesToBuildOutput)" />
</ItemGroup>
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/ArgumentParser.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/ArgumentParser.cs
index 9c7082c9..e84445d7 100644
--- a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/ArgumentParser.cs
+++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/ArgumentParser.cs
@@ -64,7 +64,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands
this.LogError($"Argument {index} ({name}) is required.");
return false;
}
- if (oneOf?.Any() == true && !oneOf.Contains(this.Args[index], StringComparer.InvariantCultureIgnoreCase))
+ if (oneOf?.Any() == true && !oneOf.Contains(this.Args[index], StringComparer.OrdinalIgnoreCase))
{
this.LogError($"Argument {index} ({name}) must be one of {string.Join(", ", oneOf)}.");
return false;
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/ClearCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/ClearCommand.cs
index e9545575..1190a4ab 100644
--- a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/ClearCommand.cs
+++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/ClearCommand.cs
@@ -56,7 +56,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World
return;
// get target location
- GameLocation location = Game1.locations.FirstOrDefault(p => p.Name != null && p.Name.Equals(locationName, StringComparison.InvariantCultureIgnoreCase));
+ GameLocation location = Game1.locations.FirstOrDefault(p => p.Name != null && p.Name.Equals(locationName, StringComparison.OrdinalIgnoreCase));
if (location == null && locationName == "current")
location = Game1.currentLocation;
if (location == null)
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/ItemData/SearchableItem.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/ItemData/SearchableItem.cs
index b618a308..d9e63126 100644
--- a/src/SMAPI.Mods.ConsoleCommands/Framework/ItemData/SearchableItem.cs
+++ b/src/SMAPI.Mods.ConsoleCommands/Framework/ItemData/SearchableItem.cs
@@ -44,8 +44,8 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.ItemData
public bool NameContains(string substring)
{
return
- this.Name.IndexOf(substring, StringComparison.InvariantCultureIgnoreCase) != -1
- || this.DisplayName.IndexOf(substring, StringComparison.InvariantCultureIgnoreCase) != -1;
+ this.Name.IndexOf(substring, StringComparison.OrdinalIgnoreCase) != -1
+ || this.DisplayName.IndexOf(substring, StringComparison.OrdinalIgnoreCase) != -1;
}
/// <summary>Get whether the item name is exactly equal to a case-insensitive string.</summary>
@@ -53,8 +53,8 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.ItemData
public bool NameEquivalentTo(string name)
{
return
- this.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)
- || this.DisplayName.Equals(name, StringComparison.InvariantCultureIgnoreCase);
+ this.Name.Equals(name, StringComparison.OrdinalIgnoreCase)
+ || this.DisplayName.Equals(name, StringComparison.OrdinalIgnoreCase);
}
}
}
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs
index 6a17213c..37f5f8d1 100644
--- a/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs
+++ b/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs
@@ -77,7 +77,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework
// furniture
foreach (int id in this.TryLoad<int, string>("Data\\Furniture").Keys)
{
- if (id == 1466 || id == 1468)
+ if (id == 1466 || id == 1468 || id == 1680)
yield return this.TryCreate(ItemType.Furniture, id, () => new TV(id, Vector2.Zero));
else
yield return this.TryCreate(ItemType.Furniture, id, () => new Furniture(id, Vector2.Zero));
@@ -192,7 +192,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework
SObject input = this.TryCreate(ItemType.Object, -1, () => new SObject(pair.Key, 1))?.Item as SObject;
if (input == null || input.Category != SObject.FishCategory)
continue;
- Color color = TailoringMenu.GetDyeColor(input) ?? Color.Orange;
+ Color color = this.GetRoeColor(input);
// yield roe
SObject roe = null;
@@ -259,12 +259,24 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework
{
try
{
- return new SearchableItem(type, id, createItem());
+ var item = createItem();
+ item.getDescription(); // force-load item data, so it crashes here if it's invalid
+ return new SearchableItem(type, id, item);
}
catch
{
return null; // if some item data is invalid, just don't include it
}
}
+
+ /// <summary>Get the color to use a given fish's roe.</summary>
+ /// <param name="fish">The fish whose roe to color.</param>
+ /// <remarks>Derived from <see cref="StardewValley.Buildings.FishPond.GetFishProduce"/>.</remarks>
+ private Color GetRoeColor(SObject fish)
+ {
+ return fish.ParentSheetIndex == 698 // sturgeon
+ ? new Color(61, 55, 42)
+ : (TailoringMenu.GetDyeColor(fish) ?? Color.Orange);
+ }
}
}
diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json
index 7300cdf8..1be55776 100644
--- a/src/SMAPI.Mods.ConsoleCommands/manifest.json
+++ b/src/SMAPI.Mods.ConsoleCommands/manifest.json
@@ -1,9 +1,9 @@
{
"Name": "Console Commands",
"Author": "SMAPI",
- "Version": "3.6.1",
+ "Version": "3.6.2",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll",
- "MinimumApiVersion": "3.6.1"
+ "MinimumApiVersion": "3.6.2"
}
diff --git a/src/SMAPI.Mods.SaveBackup/manifest.json b/src/SMAPI.Mods.SaveBackup/manifest.json
index cffd780d..c57ac162 100644
--- a/src/SMAPI.Mods.SaveBackup/manifest.json
+++ b/src/SMAPI.Mods.SaveBackup/manifest.json
@@ -1,9 +1,9 @@
{
"Name": "Save Backup",
"Author": "SMAPI",
- "Version": "3.6.1",
+ "Version": "3.6.2",
"Description": "Automatically backs up all your saves once per day into its folder.",
"UniqueID": "SMAPI.SaveBackup",
"EntryDll": "SaveBackup.dll",
- "MinimumApiVersion": "3.6.1"
+ "MinimumApiVersion": "3.6.2"
}
diff --git a/src/SMAPI.Tests/SMAPI.Tests.csproj b/src/SMAPI.Tests/SMAPI.Tests.csproj
index b1548e3a..6896808d 100644
--- a/src/SMAPI.Tests/SMAPI.Tests.csproj
+++ b/src/SMAPI.Tests/SMAPI.Tests.csproj
@@ -16,7 +16,7 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Moq" Version="4.14.1" />
+ <PackageReference Include="Moq" Version="4.14.5" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NUnit" Version="3.12.0" />
</ItemGroup>
diff --git a/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs b/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs
index 34e2e1b8..89a22eaf 100644
--- a/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs
+++ b/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs
@@ -233,7 +233,7 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki
// parse
// Specified on the wiki in the form "remote version → mapped version; another remote version → mapped version"
- IDictionary<string, string> map = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
+ IDictionary<string, string> map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (string pair in raw.Split(';'))
{
string[] versions = pair.Split('→');
diff --git a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs
index 4eec3424..450d600a 100644
--- a/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs
+++ b/src/SMAPI.Toolkit/Framework/GameScanning/GameScanner.cs
@@ -30,7 +30,7 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning
.GetCustomInstallPaths(platform)
.Concat(this.GetDefaultInstallPaths(platform))
.Select(PathUtilities.NormalizePathSeparators)
- .Distinct(StringComparer.InvariantCultureIgnoreCase);
+ .Distinct(StringComparer.OrdinalIgnoreCase);
// yield valid folders
foreach (string path in paths)
diff --git a/src/SMAPI.Toolkit/Framework/ModData/ModDataModel.cs b/src/SMAPI.Toolkit/Framework/ModData/ModDataModel.cs
index 8b40c301..2167d3e5 100644
--- a/src/SMAPI.Toolkit/Framework/ModData/ModDataModel.cs
+++ b/src/SMAPI.Toolkit/Framework/ModData/ModDataModel.cs
@@ -68,7 +68,7 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
foreach (string part in parts.Take(parts.Length - 1))
{
// 'default'
- if (part.Equals("Default", StringComparison.InvariantCultureIgnoreCase))
+ if (part.Equals("Default", StringComparison.OrdinalIgnoreCase))
{
isDefault = true;
continue;
diff --git a/src/SMAPI.Toolkit/Framework/ModData/ModDataRecord.cs b/src/SMAPI.Toolkit/Framework/ModData/ModDataRecord.cs
index c892d820..3201c421 100644
--- a/src/SMAPI.Toolkit/Framework/ModData/ModDataRecord.cs
+++ b/src/SMAPI.Toolkit/Framework/ModData/ModDataRecord.cs
@@ -46,13 +46,13 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
public bool HasID(string id)
{
// try main ID
- if (this.ID.Equals(id, StringComparison.InvariantCultureIgnoreCase))
+ if (this.ID.Equals(id, StringComparison.OrdinalIgnoreCase))
return true;
// try former IDs
foreach (string formerID in this.FormerIDs)
{
- if (formerID.Equals(id, StringComparison.InvariantCultureIgnoreCase))
+ if (formerID.Equals(id, StringComparison.OrdinalIgnoreCase))
return true;
}
diff --git a/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs b/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs
index f4857c7d..6d6b6417 100644
--- a/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs
+++ b/src/SMAPI.Toolkit/Framework/ModScanning/ModScanner.cs
@@ -18,22 +18,48 @@ namespace StardewModdingAPI.Toolkit.Framework.ModScanning
private readonly JsonHelper JsonHelper;
/// <summary>A list of filesystem entry names to ignore when checking whether a folder should be treated as a mod.</summary>
- private readonly HashSet<Regex> IgnoreFilesystemEntries = new HashSet<Regex>
+ private readonly HashSet<Regex> IgnoreFilesystemNames = new HashSet<Regex>
{
- // OS metadata files
new Regex(@"^__folder_managed_by_vortex$", RegexOptions.Compiled | RegexOptions.IgnoreCase), // Vortex mod manager
new Regex(@"(?:^\._|^\.DS_Store$|^__MACOSX$|^mcs$)", RegexOptions.Compiled | RegexOptions.IgnoreCase), // MacOS
- new Regex(@"^(?:desktop\.ini|Thumbs\.db)$", RegexOptions.Compiled | RegexOptions.IgnoreCase), // Windows
- new Regex(@"\.(?:url|lnk)$", RegexOptions.Compiled | RegexOptions.IgnoreCase), // Windows shortcut files
+ new Regex(@"^(?:desktop\.ini|Thumbs\.db)$", RegexOptions.Compiled | RegexOptions.IgnoreCase) // Windows
+ };
- // other
- new Regex(@"\.(?:bmp|gif|jpeg|jpg|png|psd|tif)$", RegexOptions.Compiled | RegexOptions.IgnoreCase), // image files
- new Regex(@"\.(?:md|rtf|txt)$", RegexOptions.Compiled | RegexOptions.IgnoreCase), // text files
- new Regex(@"\.(?:backup|bak|old)$", RegexOptions.Compiled | RegexOptions.IgnoreCase) // backup file
+ /// <summary>A list of file extensions to ignore when searching for mod files.</summary>
+ private readonly HashSet<string> IgnoreFileExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
+ {
+ // text
+ ".doc",
+ ".docx",
+ ".md",
+ ".rtf",
+ ".txt",
+
+ // images
+ ".bmp",
+ ".gif",
+ ".jpeg",
+ ".jpg",
+ ".png",
+ ".psd",
+ ".tif",
+
+ // archives
+ ".rar",
+ ".zip",
+
+ // backup files
+ ".backup",
+ ".bak",
+ ".old",
+
+ // Windows shortcut files
+ ".url",
+ ".lnk"
};
/// <summary>The extensions for files which an XNB mod may contain. If a mod doesn't have a <c>manifest.json</c> and contains *only* these file extensions, it should be considered an XNB mod.</summary>
- private readonly HashSet<string> PotentialXnbModExtensions = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
+ private readonly HashSet<string> PotentialXnbModExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
// XNB files
".xgs",
@@ -258,7 +284,12 @@ namespace StardewModdingAPI.Toolkit.Framework.ModScanning
/// <param name="entry">The file or folder.</param>
private bool IsRelevant(FileSystemInfo entry)
{
- return !this.IgnoreFilesystemEntries.Any(p => p.IsMatch(entry.Name));
+ // ignored file extension
+ if (entry is FileInfo file && this.IgnoreFileExtensions.Contains(file.Extension))
+ return false;
+
+ // ignored entry name
+ return !this.IgnoreFilesystemNames.Any(p => p.IsMatch(entry.Name));
}
/// <summary>Get whether a file is potentially part of an XNB mod.</summary>
diff --git a/src/SMAPI.Toolkit/ModToolkit.cs b/src/SMAPI.Toolkit/ModToolkit.cs
index 08fe0fed..695a2c52 100644
--- a/src/SMAPI.Toolkit/ModToolkit.cs
+++ b/src/SMAPI.Toolkit/ModToolkit.cs
@@ -22,7 +22,7 @@ namespace StardewModdingAPI.Toolkit
private readonly string UserAgent;
/// <summary>Maps vendor keys (like <c>Nexus</c>) to their mod URL template (where <c>{0}</c> is the mod ID). This doesn't affect update checks, which defer to the remote web API.</summary>
- private readonly IDictionary<string, string> VendorModUrls = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
+ private readonly IDictionary<string, string> VendorModUrls = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
["Chucklefish"] = "https://community.playstarbound.com/resources/{0}",
["GitHub"] = "https://github.com/{0}/releases",
diff --git a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj
index 71ea0f12..9e9d824a 100644
--- a/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj
+++ b/src/SMAPI.Toolkit/SMAPI.Toolkit.csproj
@@ -8,7 +8,7 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="HtmlAgilityPack" Version="1.11.23" />
+ <PackageReference Include="HtmlAgilityPack" Version="1.11.24" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Pathoschild.Http.FluentClient" Version="4.0.0" />
<PackageReference Include="System.Management" Version="4.5.0" Condition="'$(OS)' == 'Windows_NT'" />
diff --git a/src/SMAPI.Toolkit/SemanticVersion.cs b/src/SMAPI.Toolkit/SemanticVersion.cs
index 86db2820..1a76bec3 100644
--- a/src/SMAPI.Toolkit/SemanticVersion.cs
+++ b/src/SMAPI.Toolkit/SemanticVersion.cs
@@ -278,9 +278,9 @@ namespace StardewModdingAPI.Toolkit
if (curParts[i] != otherParts[i])
{
// unofficial is always lower-precedence
- if (otherParts[i].Equals("unofficial", StringComparison.InvariantCultureIgnoreCase))
+ if (otherParts[i].Equals("unofficial", StringComparison.OrdinalIgnoreCase))
return curNewer;
- if (curParts[i].Equals("unofficial", StringComparison.InvariantCultureIgnoreCase))
+ if (curParts[i].Equals("unofficial", StringComparison.OrdinalIgnoreCase))
return curOlder;
// compare numerically if possible
@@ -295,7 +295,7 @@ namespace StardewModdingAPI.Toolkit
}
// fallback (this should never happen)
- return string.Compare(this.ToString(), new SemanticVersion(otherMajor, otherMinor, otherPatch, otherPlatformRelease, otherTag).ToString(), StringComparison.InvariantCultureIgnoreCase);
+ return string.Compare(this.ToString(), new SemanticVersion(otherMajor, otherMinor, otherPatch, otherPlatformRelease, otherTag).ToString(), StringComparison.OrdinalIgnoreCase);
}
/// <summary>Assert that the current version is valid.</summary>
diff --git a/src/SMAPI.Toolkit/Serialization/InternalExtensions.cs b/src/SMAPI.Toolkit/Serialization/InternalExtensions.cs
index 9aba53bf..10f88dde 100644
--- a/src/SMAPI.Toolkit/Serialization/InternalExtensions.cs
+++ b/src/SMAPI.Toolkit/Serialization/InternalExtensions.cs
@@ -12,7 +12,7 @@ namespace StardewModdingAPI.Toolkit.Serialization
/// <param name="fieldName">The field name.</param>
public static T ValueIgnoreCase<T>(this JObject obj, string fieldName)
{
- JToken token = obj.GetValue(fieldName, StringComparison.InvariantCultureIgnoreCase);
+ JToken token = obj.GetValue(fieldName, StringComparison.OrdinalIgnoreCase);
return token != null
? token.Value<T>()
: default(T);
diff --git a/src/SMAPI.Web/Controllers/JsonValidatorController.cs b/src/SMAPI.Web/Controllers/JsonValidatorController.cs
index 5f83eafd..6ba97749 100644
--- a/src/SMAPI.Web/Controllers/JsonValidatorController.cs
+++ b/src/SMAPI.Web/Controllers/JsonValidatorController.cs
@@ -280,7 +280,7 @@ namespace StardewModdingAPI.Web.Controllers
IDictionary<string, string> errors = this.GetExtensionField<Dictionary<string, string>>(error.Schema, "@errorMessages");
if (errors == null)
return null;
- errors = new Dictionary<string, string>(errors, StringComparer.InvariantCultureIgnoreCase);
+ errors = new Dictionary<string, string>(errors, StringComparer.OrdinalIgnoreCase);
// match error by type and message
foreach ((string target, string errorMessage) in errors)
@@ -289,7 +289,7 @@ namespace StardewModdingAPI.Web.Controllers
continue;
string[] parts = target.Split(':', 2);
- if (parts[0].Equals(error.ErrorType.ToString(), StringComparison.InvariantCultureIgnoreCase) && Regex.IsMatch(error.Message, parts[1]))
+ if (parts[0].Equals(error.ErrorType.ToString(), StringComparison.OrdinalIgnoreCase) && Regex.IsMatch(error.Message, parts[1]))
return errorMessage?.Trim();
}
@@ -313,7 +313,7 @@ namespace StardewModdingAPI.Web.Controllers
{
foreach ((string curKey, JToken value) in schema.ExtensionData)
{
- if (curKey.Equals(key, StringComparison.InvariantCultureIgnoreCase))
+ if (curKey.Equals(key, StringComparison.OrdinalIgnoreCase))
return value.ToObject<T>();
}
}
diff --git a/src/SMAPI.Web/Controllers/ModsApiController.cs b/src/SMAPI.Web/Controllers/ModsApiController.cs
index db669bf9..cd5b6779 100644
--- a/src/SMAPI.Web/Controllers/ModsApiController.cs
+++ b/src/SMAPI.Web/Controllers/ModsApiController.cs
@@ -118,9 +118,9 @@ namespace StardewModdingAPI.Web.Controllers
{
// cross-reference data
ModDataRecord record = this.ModDatabase.Get(search.ID);
- WikiModEntry wikiEntry = wikiData.FirstOrDefault(entry => entry.ID.Contains(search.ID.Trim(), StringComparer.InvariantCultureIgnoreCase));
+ WikiModEntry wikiEntry = wikiData.FirstOrDefault(entry => entry.ID.Contains(search.ID.Trim(), StringComparer.OrdinalIgnoreCase));
UpdateKey[] updateKeys = this.GetUpdateKeys(search.UpdateKeys, record, wikiEntry).ToArray();
- ModOverrideConfig overrides = this.Config.Value.ModOverrides.FirstOrDefault(p => p.ID.Equals(search.ID?.Trim(), StringComparison.InvariantCultureIgnoreCase));
+ ModOverrideConfig overrides = this.Config.Value.ModOverrides.FirstOrDefault(p => p.ID.Equals(search.ID?.Trim(), StringComparison.OrdinalIgnoreCase));
bool allowNonStandardVersions = overrides?.AllowNonStandardVersions ?? false;
// get latest versions
diff --git a/src/SMAPI.Web/Framework/Caching/Mods/ModCacheMemoryRepository.cs b/src/SMAPI.Web/Framework/Caching/Mods/ModCacheMemoryRepository.cs
index 6b0ec1ec..9769793c 100644
--- a/src/SMAPI.Web/Framework/Caching/Mods/ModCacheMemoryRepository.cs
+++ b/src/SMAPI.Web/Framework/Caching/Mods/ModCacheMemoryRepository.cs
@@ -13,7 +13,7 @@ namespace StardewModdingAPI.Web.Framework.Caching.Mods
** Fields
*********/
/// <summary>The cached mod data indexed by <c>{site key}:{ID}</c>.</summary>
- private readonly IDictionary<string, Cached<IModPage>> Mods = new Dictionary<string, Cached<IModPage>>(StringComparer.InvariantCultureIgnoreCase);
+ private readonly IDictionary<string, Cached<IModPage>> Mods = new Dictionary<string, Cached<IModPage>>(StringComparer.OrdinalIgnoreCase);
/*********
diff --git a/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs b/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs
index 2f1eb854..671f077c 100644
--- a/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs
+++ b/src/SMAPI.Web/Framework/Clients/GitHub/GitHubClient.cs
@@ -150,7 +150,7 @@ namespace StardewModdingAPI.Web.Framework.Clients.GitHub
/// <exception cref="ArgumentException">The repository key is invalid.</exception>
private void AssertKeyFormat(string repo)
{
- if (repo == null || !repo.Contains("/") || repo.IndexOf("/", StringComparison.InvariantCultureIgnoreCase) != repo.LastIndexOf("/", StringComparison.InvariantCultureIgnoreCase))
+ if (repo == null || !repo.Contains("/") || repo.IndexOf("/", StringComparison.OrdinalIgnoreCase) != repo.LastIndexOf("/", StringComparison.OrdinalIgnoreCase))
throw new ArgumentException($"The value '{repo}' isn't a valid GitHub repository key, must be a username and project name like 'Pathoschild/SMAPI'.", nameof(repo));
}
}
diff --git a/src/SMAPI.Web/SMAPI.Web.csproj b/src/SMAPI.Web/SMAPI.Web.csproj
index c6c0f774..23e0340d 100644
--- a/src/SMAPI.Web/SMAPI.Web.csproj
+++ b/src/SMAPI.Web/SMAPI.Web.csproj
@@ -12,14 +12,14 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Azure.Storage.Blobs" Version="12.4.2" />
- <PackageReference Include="Hangfire.AspNetCore" Version="1.7.11" />
+ <PackageReference Include="Azure.Storage.Blobs" Version="12.4.4" />
+ <PackageReference Include="Hangfire.AspNetCore" Version="1.7.12" />
<PackageReference Include="Hangfire.MemoryStorage" Version="1.7.0" />
- <PackageReference Include="HtmlAgilityPack" Version="1.11.23" />
- <PackageReference Include="Humanizer.Core" Version="2.8.11" />
+ <PackageReference Include="HtmlAgilityPack" Version="1.11.24" />
+ <PackageReference Include="Humanizer.Core" Version="2.8.26" />
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
<PackageReference Include="Markdig" Version="0.20.0" />
- <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.2" />
+ <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.6" />
<PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.13" />
<PackageReference Include="Pathoschild.FluentNexus" Version="1.0.1" />
<PackageReference Include="Pathoschild.Http.FluentClient" Version="4.0.0" />
diff --git a/src/SMAPI.Web/wwwroot/schemas/content-patcher.json b/src/SMAPI.Web/wwwroot/schemas/content-patcher.json
index 726b50be..6e8a4e52 100644
--- a/src/SMAPI.Web/wwwroot/schemas/content-patcher.json
+++ b/src/SMAPI.Web/wwwroot/schemas/content-patcher.json
@@ -11,9 +11,9 @@
"title": "Format version",
"description": "The format version. You should always use the latest version to enable the latest features and avoid obsolete behavior.",
"type": "string",
- "const": "1.14.0",
+ "const": "1.15.0",
"@errorMessages": {
- "const": "Incorrect value '@value'. This should be set to the latest format version, currently '1.14.0'."
+ "const": "Incorrect value '@value'. This should be set to the latest format version, currently '1.15.0'."
}
},
"ConfigSchema": {
diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs
index a7e44de6..c1c99150 100644
--- a/src/SMAPI/Constants.cs
+++ b/src/SMAPI/Constants.cs
@@ -20,7 +20,7 @@ namespace StardewModdingAPI
** Public
****/
/// <summary>SMAPI's current semantic version.</summary>
- public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.6.1");
+ public static ISemanticVersion ApiVersion { get; } = new Toolkit.SemanticVersion("3.6.2");
/// <summary>The minimum supported version of Stardew Valley.</summary>
public static ISemanticVersion MinimumGameVersion { get; } = new GameVersion("1.4.1");
diff --git a/src/SMAPI/Framework/CommandManager.cs b/src/SMAPI/Framework/CommandManager.cs
index eaa91c86..2b91d394 100644
--- a/src/SMAPI/Framework/CommandManager.cs
+++ b/src/SMAPI/Framework/CommandManager.cs
@@ -13,7 +13,7 @@ namespace StardewModdingAPI.Framework
** Fields
*********/
/// <summary>The commands registered with SMAPI.</summary>
- private readonly IDictionary<string, Command> Commands = new Dictionary<string, Command>(StringComparer.InvariantCultureIgnoreCase);
+ private readonly IDictionary<string, Command> Commands = new Dictionary<string, Command>(StringComparer.OrdinalIgnoreCase);
/*********
diff --git a/src/SMAPI/Framework/Content/AssetDataForMap.cs b/src/SMAPI/Framework/Content/AssetDataForMap.cs
index f66013ba..dee5b034 100644
--- a/src/SMAPI/Framework/Content/AssetDataForMap.cs
+++ b/src/SMAPI/Framework/Content/AssetDataForMap.cs
@@ -67,7 +67,7 @@ namespace StardewModdingAPI.Framework.Content
{
// change ID if needed so new tilesheets are added after vanilla ones (to avoid errors in hardcoded game logic)
string id = sourceSheet.Id;
- if (!id.StartsWith("z_", StringComparison.InvariantCultureIgnoreCase))
+ if (!id.StartsWith("z_", StringComparison.OrdinalIgnoreCase))
id = $"z_{id}";
// change ID if it conflicts with an existing tilesheet
diff --git a/src/SMAPI/Framework/Content/AssetInfo.cs b/src/SMAPI/Framework/Content/AssetInfo.cs
index 9b685e72..ed009499 100644
--- a/src/SMAPI/Framework/Content/AssetInfo.cs
+++ b/src/SMAPI/Framework/Content/AssetInfo.cs
@@ -47,7 +47,7 @@ namespace StardewModdingAPI.Framework.Content
public bool AssetNameEquals(string path)
{
path = this.GetNormalizedPath(path);
- return this.AssetName.Equals(path, StringComparison.InvariantCultureIgnoreCase);
+ return this.AssetName.Equals(path, StringComparison.OrdinalIgnoreCase);
}
diff --git a/src/SMAPI/Framework/Content/ContentCache.cs b/src/SMAPI/Framework/Content/ContentCache.cs
index b0933ac6..2052f6bf 100644
--- a/src/SMAPI/Framework/Content/ContentCache.cs
+++ b/src/SMAPI/Framework/Content/ContentCache.cs
@@ -89,7 +89,7 @@ namespace StardewModdingAPI.Framework.Content
public string NormalizeKey(string key)
{
key = this.NormalizePathSeparators(key);
- return key.EndsWith(".xnb", StringComparison.InvariantCultureIgnoreCase)
+ return key.EndsWith(".xnb", StringComparison.OrdinalIgnoreCase)
? key.Substring(0, key.Length - 4)
: this.NormalizeAssetNameForPlatform(key);
}
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs
index 47ef30d4..479ffa7f 100644
--- a/src/SMAPI/Framework/ContentCoordinator.cs
+++ b/src/SMAPI/Framework/ContentCoordinator.cs
@@ -229,7 +229,7 @@ namespace StardewModdingAPI.Framework
public IEnumerable<string> InvalidateCache(Func<string, Type, bool> predicate, bool dispose = false)
{
// invalidate cache & track removed assets
- IDictionary<string, Type> removedAssets = new Dictionary<string, Type>(StringComparer.InvariantCultureIgnoreCase);
+ IDictionary<string, Type> removedAssets = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
this.ContentManagerLock.InReadLock(() =>
{
// cached assets
@@ -263,7 +263,7 @@ namespace StardewModdingAPI.Framework
if (removedAssets.Any())
{
IDictionary<string, bool> propagated = this.CoreAssets.Propagate(this.MainContentManager, removedAssets.ToDictionary(p => p.Key, p => p.Value)); // use an intercepted content manager
- this.Monitor.Log($"Invalidated {removedAssets.Count} asset names ({string.Join(", ", removedAssets.Keys.OrderBy(p => p, StringComparer.InvariantCultureIgnoreCase))}); propagated {propagated.Count(p => p.Value)} core assets.", LogLevel.Trace);
+ this.Monitor.Log($"Invalidated {removedAssets.Count} asset names ({string.Join(", ", removedAssets.Keys.OrderBy(p => p, StringComparer.OrdinalIgnoreCase))}); propagated {propagated.Count(p => p.Value)} core assets.", LogLevel.Trace);
}
else
this.Monitor.Log("Invalidated 0 cache entries.", LogLevel.Trace);
diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
index 36f2f650..a8de013a 100644
--- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
@@ -87,7 +87,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
this.IsNamespaced = isNamespaced;
// get asset data
- this.LanguageCodes = this.GetKeyLocales().ToDictionary(p => p.Value, p => p.Key, StringComparer.InvariantCultureIgnoreCase);
+ this.LanguageCodes = this.GetKeyLocales().ToDictionary(p => p.Value, p => p.Key, StringComparer.OrdinalIgnoreCase);
this.BaseDisposableReferences = reflection.GetField<List<IDisposable>>(this, "disposableAssets").GetValue();
}
@@ -192,7 +192,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <returns>Returns the invalidated asset names and instances.</returns>
public IDictionary<string, object> InvalidateCache(Func<string, Type, bool> predicate, bool dispose = false)
{
- IDictionary<string, object> removeAssets = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);
+ IDictionary<string, object> removeAssets = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
this.Cache.Remove((key, asset) =>
{
this.ParseCacheKey(key, out string assetName, out _);
@@ -295,7 +295,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
// handle localized key
if (!string.IsNullOrWhiteSpace(cacheKey))
{
- int lastSepIndex = cacheKey.LastIndexOf(".", StringComparison.InvariantCulture);
+ int lastSepIndex = cacheKey.LastIndexOf(".", StringComparison.Ordinal);
if (lastSepIndex >= 0)
{
string suffix = cacheKey.Substring(lastSepIndex + 1, cacheKey.Length - lastSepIndex - 1);
diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
index eaaf0e6f..f20580e1 100644
--- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
@@ -123,7 +123,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
base.OnLocaleChanged();
// find assets for which a translatable version was loaded
- HashSet<string> removeAssetNames = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
+ HashSet<string> removeAssetNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (string key in this.IsLocalizableLookup.Where(p => p.Value).Select(p => p.Key))
removeAssetNames.Add(this.TryParseExplicitLanguageAssetKey(key, out string assetName, out _) ? assetName : key);
@@ -134,7 +134,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|| (this.TryParseExplicitLanguageAssetKey(key, out string assetName, out _) && removeAssetNames.Contains(assetName))
)
.Select(p => p.Key)
- .OrderBy(p => p, StringComparer.InvariantCultureIgnoreCase)
+ .OrderBy(p => p, StringComparer.OrdinalIgnoreCase)
.ToArray();
if (invalidated.Any())
this.Monitor.Log($"Invalidated {invalidated.Length} asset names: {string.Join(", ", invalidated)} for locale change.", LogLevel.Trace);
diff --git a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs
index cfda55b9..26ddb067 100644
--- a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs
@@ -372,7 +372,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
break;
}
}
- if (contentKey.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase))
+ if (contentKey.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
contentKey = contentKey.Substring(0, contentKey.Length - 4);
try
diff --git a/src/SMAPI/Framework/DeprecationManager.cs b/src/SMAPI/Framework/DeprecationManager.cs
index 636b1979..11fae0b2 100644
--- a/src/SMAPI/Framework/DeprecationManager.cs
+++ b/src/SMAPI/Framework/DeprecationManager.cs
@@ -11,7 +11,7 @@ namespace StardewModdingAPI.Framework
** Fields
*********/
/// <summary>The deprecations which have already been logged (as 'mod name::noun phrase::version').</summary>
- private readonly HashSet<string> LoggedDeprecations = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
+ private readonly HashSet<string> LoggedDeprecations = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
/// <summary>Encapsulates monitoring and logging for a given module.</summary>
private readonly IMonitor Monitor;
diff --git a/src/SMAPI/Framework/Events/ManagedEvent.cs b/src/SMAPI/Framework/Events/ManagedEvent.cs
index 08ac1131..8b25a9b5 100644
--- a/src/SMAPI/Framework/Events/ManagedEvent.cs
+++ b/src/SMAPI/Framework/Events/ManagedEvent.cs
@@ -106,19 +106,20 @@ namespace StardewModdingAPI.Framework.Events
// update cached data
// (This is debounced here to avoid repeatedly sorting when handlers are added/removed,
// and keeping a separate cached list allows changes during enumeration.)
- if (this.CachedHandlers == null)
+ var handlers = this.CachedHandlers; // iterate local copy in case a mod adds/removes a handler while handling the event
+ if (handlers == null)
{
if (this.HasNewHandlers && this.Handlers.Any(p => p.Priority != EventPriority.Normal))
this.Handlers.Sort();
- this.CachedHandlers = this.Handlers.ToArray();
+ this.CachedHandlers = handlers = this.Handlers.ToArray();
this.HasNewHandlers = false;
}
// raise event
this.PerformanceMonitor.Track(this.EventName, () =>
{
- foreach (ManagedEventHandler<TEventArgs> handler in this.CachedHandlers)
+ foreach (ManagedEventHandler<TEventArgs> handler in handlers)
{
if (match != null && !match(handler.SourceMod))
continue;
diff --git a/src/SMAPI/Framework/GameVersion.cs b/src/SMAPI/Framework/GameVersion.cs
index 07957624..3ed60920 100644
--- a/src/SMAPI/Framework/GameVersion.cs
+++ b/src/SMAPI/Framework/GameVersion.cs
@@ -10,7 +10,7 @@ namespace StardewModdingAPI.Framework
** Private methods
*********/
/// <summary>A mapping of game to semantic versions.</summary>
- private static readonly IDictionary<string, string> VersionMap = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
+ private static readonly IDictionary<string, string> VersionMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
["1.0"] = "1.0.0",
["1.01"] = "1.0.1",
@@ -64,7 +64,7 @@ namespace StardewModdingAPI.Framework
{
foreach (var mapping in GameVersion.VersionMap)
{
- if (mapping.Value.Equals(semanticVersion, StringComparison.InvariantCultureIgnoreCase))
+ if (mapping.Value.Equals(semanticVersion, StringComparison.OrdinalIgnoreCase))
return mapping.Key;
}
diff --git a/src/SMAPI/Framework/ModLoading/Framework/BaseInstructionHandler.cs b/src/SMAPI/Framework/ModLoading/Framework/BaseInstructionHandler.cs
index 79fb45b8..fde37d68 100644
--- a/src/SMAPI/Framework/ModLoading/Framework/BaseInstructionHandler.cs
+++ b/src/SMAPI/Framework/ModLoading/Framework/BaseInstructionHandler.cs
@@ -18,7 +18,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework
public ISet<InstructionHandleResult> Flags { get; } = new HashSet<InstructionHandleResult>();
/// <summary>The brief noun phrases indicating what the handler matched for the current module.</summary>
- public ISet<string> Phrases { get; } = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
+ public ISet<string> Phrases { get; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
/*********
diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs
index 30701552..3ad1bd38 100644
--- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs
+++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs
@@ -173,7 +173,7 @@ namespace StardewModdingAPI.Framework.ModLoading
{
return
this.HasID()
- && string.Equals(this.Manifest.UniqueID.Trim(), id?.Trim(), StringComparison.InvariantCultureIgnoreCase);
+ && string.Equals(this.Manifest.UniqueID.Trim(), id?.Trim(), StringComparison.OrdinalIgnoreCase);
}
/// <summary>Get the defined update keys.</summary>
@@ -192,7 +192,7 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <param name="includeOptional">Whether to include optional dependencies.</param>
public IEnumerable<string> GetRequiredModIds(bool includeOptional = false)
{
- HashSet<string> required = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
+ HashSet<string> required = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
// yield dependencies
if (this.Manifest?.Dependencies != null)
diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs
index e73bc47d..8bbeb2a3 100644
--- a/src/SMAPI/Framework/ModLoading/ModResolver.cs
+++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs
@@ -190,7 +190,7 @@ namespace StardewModdingAPI.Framework.ModLoading
// validate IDs are unique
{
var duplicatesByID = mods
- .GroupBy(mod => mod.Manifest?.UniqueID?.Trim(), mod => mod, StringComparer.InvariantCultureIgnoreCase)
+ .GroupBy(mod => mod.Manifest?.UniqueID?.Trim(), mod => mod, StringComparer.OrdinalIgnoreCase)
.Where(p => p.Count() > 1);
foreach (var group in duplicatesByID)
{
diff --git a/src/SMAPI/Framework/Models/SConfig.cs b/src/SMAPI/Framework/Models/SConfig.cs
index a98d8c54..1c682f96 100644
--- a/src/SMAPI/Framework/Models/SConfig.cs
+++ b/src/SMAPI/Framework/Models/SConfig.cs
@@ -25,7 +25,7 @@ namespace StardewModdingAPI.Framework.Models
};
/// <summary>The default values for <see cref="SuppressUpdateChecks"/>, to log changes if different.</summary>
- private static readonly HashSet<string> DefaultSuppressUpdateChecks = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
+ private static readonly HashSet<string> DefaultSuppressUpdateChecks = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"SMAPI.ConsoleCommands",
"SMAPI.SaveBackup"
@@ -84,7 +84,7 @@ namespace StardewModdingAPI.Framework.Models
custom[pair.Key] = value;
}
- HashSet<string> curSuppressUpdateChecks = new HashSet<string>(this.SuppressUpdateChecks ?? new string[0], StringComparer.InvariantCultureIgnoreCase);
+ HashSet<string> curSuppressUpdateChecks = new HashSet<string>(this.SuppressUpdateChecks ?? new string[0], StringComparer.OrdinalIgnoreCase);
if (SConfig.DefaultSuppressUpdateChecks.Count != curSuppressUpdateChecks.Count || SConfig.DefaultSuppressUpdateChecks.Any(p => !curSuppressUpdateChecks.Contains(p)))
custom[nameof(this.SuppressUpdateChecks)] = "[" + string.Join(", ", this.SuppressUpdateChecks ?? new string[0]) + "]";
diff --git a/src/SMAPI/Framework/Networking/MultiplayerPeer.cs b/src/SMAPI/Framework/Networking/MultiplayerPeer.cs
index b4e39379..6b45b04a 100644
--- a/src/SMAPI/Framework/Networking/MultiplayerPeer.cs
+++ b/src/SMAPI/Framework/Networking/MultiplayerPeer.cs
@@ -71,7 +71,7 @@ namespace StardewModdingAPI.Framework.Networking
return null;
id = id.Trim();
- return this.Mods.FirstOrDefault(mod => mod.ID != null && mod.ID.Equals(id, StringComparison.InvariantCultureIgnoreCase));
+ return this.Mods.FirstOrDefault(mod => mod.ID != null && mod.ID.Equals(id, StringComparison.OrdinalIgnoreCase));
}
/// <summary>Send a message to the given peer, bypassing the game's normal validation to allow messages before the connection is approved.</summary>
diff --git a/src/SMAPI/Framework/PerformanceMonitoring/PerformanceCounterCollection.cs b/src/SMAPI/Framework/PerformanceMonitoring/PerformanceCounterCollection.cs
index 0bb78c74..29a06794 100644
--- a/src/SMAPI/Framework/PerformanceMonitoring/PerformanceCounterCollection.cs
+++ b/src/SMAPI/Framework/PerformanceMonitoring/PerformanceCounterCollection.cs
@@ -189,7 +189,7 @@ namespace StardewModdingAPI.Framework.PerformanceMonitoring
public void ResetSource(string source)
{
foreach (var i in this.PerformanceCounters)
- if (i.Value.Source.Equals(source, StringComparison.InvariantCultureIgnoreCase))
+ if (i.Value.Source.Equals(source, StringComparison.OrdinalIgnoreCase))
i.Value.Reset();
}
diff --git a/src/SMAPI/Framework/PerformanceMonitoring/PerformanceMonitor.cs b/src/SMAPI/Framework/PerformanceMonitoring/PerformanceMonitor.cs
index dfc4f31a..3f2608aa 100644
--- a/src/SMAPI/Framework/PerformanceMonitoring/PerformanceMonitor.cs
+++ b/src/SMAPI/Framework/PerformanceMonitoring/PerformanceMonitor.cs
@@ -23,7 +23,7 @@ namespace StardewModdingAPI.Framework.PerformanceMonitoring
private readonly Stopwatch InvocationStopwatch = new Stopwatch();
/// <summary>The underlying performance counter collections.</summary>
- private readonly IDictionary<string, PerformanceCounterCollection> Collections = new Dictionary<string, PerformanceCounterCollection>(StringComparer.InvariantCultureIgnoreCase);
+ private readonly IDictionary<string, PerformanceCounterCollection> Collections = new Dictionary<string, PerformanceCounterCollection>(StringComparer.OrdinalIgnoreCase);
/*********
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index 2b04b1dc..72ef9095 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -451,7 +451,7 @@ namespace StardewModdingAPI.Framework
{
string[] looseFiles = new DirectoryInfo(this.ModsPath).GetFiles().Select(p => p.Name).ToArray();
if (looseFiles.Any())
- this.Monitor.Log($" Ignored loose files: {string.Join(", ", looseFiles.OrderBy(p => p, StringComparer.InvariantCultureIgnoreCase))}", LogLevel.Trace);
+ this.Monitor.Log($" Ignored loose files: {string.Join(", ", looseFiles.OrderBy(p => p, StringComparer.OrdinalIgnoreCase))}", LogLevel.Trace);
}
// load manifests
@@ -650,7 +650,7 @@ namespace StardewModdingAPI.Framework
{
try
{
- HashSet<string> suppressUpdateChecks = new HashSet<string>(this.Settings.SuppressUpdateChecks, StringComparer.InvariantCultureIgnoreCase);
+ HashSet<string> suppressUpdateChecks = new HashSet<string>(this.Settings.SuppressUpdateChecks, StringComparer.OrdinalIgnoreCase);
// prepare search model
List<ModSearchEntryModel> searchMods = new List<ModSearchEntryModel>();
@@ -756,7 +756,7 @@ namespace StardewModdingAPI.Framework
using (AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.Platform, this.Monitor, this.Settings.ParanoidWarnings))
{
// init
- HashSet<string> suppressUpdateChecks = new HashSet<string>(this.Settings.SuppressUpdateChecks, StringComparer.InvariantCultureIgnoreCase);
+ HashSet<string> suppressUpdateChecks = new HashSet<string>(this.Settings.SuppressUpdateChecks, StringComparer.OrdinalIgnoreCase);
InterfaceProxyFactory proxyFactory = new InterfaceProxyFactory();
void LogSkip(IModMetadata mod, string errorPhrase, string errorDetails)
{
@@ -1103,8 +1103,8 @@ namespace StardewModdingAPI.Framework
// find skipped dependencies
KeyValuePair<IModMetadata, Tuple<string, string>>[] skippedDependencies;
{
- HashSet<string> skippedDependencyIds = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
- HashSet<string> skippedModIds = new HashSet<string>(from mod in skippedMods where mod.Key.HasID() select mod.Key.Manifest.UniqueID, StringComparer.InvariantCultureIgnoreCase);
+ HashSet<string> skippedDependencyIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+ HashSet<string> skippedModIds = new HashSet<string>(from mod in skippedMods where mod.Key.HasID() select mod.Key.Manifest.UniqueID, StringComparer.OrdinalIgnoreCase);
foreach (IModMetadata mod in skippedMods.Keys)
{
foreach (string requiredId in skippedModIds.Intersect(mod.GetRequiredModIds()))
@@ -1351,8 +1351,8 @@ namespace StardewModdingAPI.Framework
foreach (string locale in translations.Keys.ToArray())
{
// handle duplicates
- HashSet<string> keys = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
- HashSet<string> duplicateKeys = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
+ HashSet<string> keys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+ HashSet<string> duplicateKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (string key in translations[locale].Keys.ToArray())
{
if (!keys.Add(key))
@@ -1458,7 +1458,7 @@ namespace StardewModdingAPI.Framework
foreach (FileInfo logFile in logsDir.EnumerateFiles())
{
// skip non-SMAPI file
- if (!logFile.Name.StartsWith(Constants.LogNamePrefix, StringComparison.InvariantCultureIgnoreCase))
+ if (!logFile.Name.StartsWith(Constants.LogNamePrefix, StringComparison.OrdinalIgnoreCase))
continue;
// skip crash log
diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs
index 4d310185..abb766f2 100644
--- a/src/SMAPI/Framework/SGame.cs
+++ b/src/SMAPI/Framework/SGame.cs
@@ -197,8 +197,14 @@ namespace StardewModdingAPI.Framework
/// <summary>Load content when the game is launched.</summary>
protected override void LoadContent()
{
+ // load content
base.LoadContent();
Game1.mapDisplayDevice = new SDisplayDevice(Game1.content, this.GraphicsDevice);
+
+ // log GPU info
+#if SMAPI_FOR_WINDOWS
+ this.Monitor.Log($"Running on GPU: {this.GraphicsDevice?.Adapter?.Description ?? "<unknown>"}");
+#endif
}
/// <summary>Initialize just before the game's first update tick.</summary>
@@ -235,7 +241,7 @@ namespace StardewModdingAPI.Framework
private void OnModMessageReceived(ModMessageModel message)
{
// get mod IDs to notify
- HashSet<string> modIDs = new HashSet<string>(message.ToModIDs ?? this.ModRegistry.GetAll().Select(p => p.Manifest.UniqueID), StringComparer.InvariantCultureIgnoreCase);
+ HashSet<string> modIDs = new HashSet<string>(message.ToModIDs ?? this.ModRegistry.GetAll().Select(p => p.Manifest.UniqueID), StringComparer.OrdinalIgnoreCase);
if (message.FromPlayerID == Game1.player?.UniqueMultiplayerID)
modIDs.Remove(message.FromModID); // don't send a broadcast back to the sender
diff --git a/src/SMAPI/Framework/SMultiplayer.cs b/src/SMAPI/Framework/SMultiplayer.cs
index 8c444e45..f3b5e9b9 100644
--- a/src/SMAPI/Framework/SMultiplayer.cs
+++ b/src/SMAPI/Framework/SMultiplayer.cs
@@ -373,7 +373,7 @@ namespace StardewModdingAPI.Framework
// filter by mod ID
if (toModIDs != null)
{
- HashSet<string> sendToMods = new HashSet<string>(toModIDs, StringComparer.InvariantCultureIgnoreCase);
+ HashSet<string> sendToMods = new HashSet<string>(toModIDs, StringComparer.OrdinalIgnoreCase);
if (sendToSelf && toModIDs.All(id => this.ModRegistry.Get(id) == null))
sendToSelf = false;
diff --git a/src/SMAPI/Framework/Translator.cs b/src/SMAPI/Framework/Translator.cs
index f2738633..11ec983b 100644
--- a/src/SMAPI/Framework/Translator.cs
+++ b/src/SMAPI/Framework/Translator.cs
@@ -12,7 +12,7 @@ namespace StardewModdingAPI.Framework
** Fields
*********/
/// <summary>The translations for each locale.</summary>
- private readonly IDictionary<string, IDictionary<string, string>> All = new Dictionary<string, IDictionary<string, string>>(StringComparer.InvariantCultureIgnoreCase);
+ private readonly IDictionary<string, IDictionary<string, string>> All = new Dictionary<string, IDictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
/// <summary>The translations for the current locale, with locale fallback taken into account.</summary>
private IDictionary<string, Translation> ForLocale;
@@ -45,7 +45,7 @@ namespace StardewModdingAPI.Framework
this.Locale = locale.ToLower().Trim();
this.LocaleEnum = localeEnum;
- this.ForLocale = new Dictionary<string, Translation>(StringComparer.InvariantCultureIgnoreCase);
+ this.ForLocale = new Dictionary<string, Translation>(StringComparer.OrdinalIgnoreCase);
foreach (string next in this.GetRelevantLocales(this.Locale))
{
// skip if locale not defined
@@ -90,7 +90,7 @@ namespace StardewModdingAPI.Framework
// reset translations
this.All.Clear();
foreach (var pair in translations)
- this.All[pair.Key] = new Dictionary<string, string>(pair.Value, StringComparer.InvariantCultureIgnoreCase);
+ this.All[pair.Key] = new Dictionary<string, string>(pair.Value, StringComparer.OrdinalIgnoreCase);
// rebuild cache
this.SetLocale(this.Locale, this.LocaleEnum);
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs
index fa6541cb..5c77bf66 100644
--- a/src/SMAPI/Metadata/CoreAssetPropagator.cs
+++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs
@@ -84,7 +84,7 @@ namespace StardewModdingAPI.Metadata
});
// reload assets
- IDictionary<string, bool> propagated = assets.ToDictionary(p => p.Key, p => false, StringComparer.InvariantCultureIgnoreCase);
+ IDictionary<string, bool> propagated = assets.ToDictionary(p => p.Key, p => false, StringComparer.OrdinalIgnoreCase);
foreach (var bucket in buckets)
{
switch (bucket.Key)
@@ -779,7 +779,7 @@ namespace StardewModdingAPI.Metadata
private void ReloadNpcSprites(LocalizedContentManager content, IEnumerable<string> keys, IDictionary<string, bool> propagated)
{
// get NPCs
- HashSet<string> lookup = new HashSet<string>(keys, StringComparer.InvariantCultureIgnoreCase);
+ HashSet<string> lookup = new HashSet<string>(keys, StringComparer.OrdinalIgnoreCase);
var characters =
(
from npc in this.GetCharacters()
@@ -806,7 +806,7 @@ namespace StardewModdingAPI.Metadata
private void ReloadNpcPortraits(LocalizedContentManager content, IEnumerable<string> keys, IDictionary<string, bool> propagated)
{
// get NPCs
- HashSet<string> lookup = new HashSet<string>(keys, StringComparer.InvariantCultureIgnoreCase);
+ HashSet<string> lookup = new HashSet<string>(keys, StringComparer.OrdinalIgnoreCase);
var characters =
(
from npc in this.GetCharacters()
@@ -1031,7 +1031,7 @@ namespace StardewModdingAPI.Metadata
if (string.IsNullOrWhiteSpace(key) || string.IsNullOrWhiteSpace(rawSubstring))
return false;
- return key.StartsWith(this.NormalizeAssetNameIgnoringEmpty(rawSubstring), StringComparison.InvariantCultureIgnoreCase);
+ return key.StartsWith(this.NormalizeAssetNameIgnoringEmpty(rawSubstring), StringComparison.OrdinalIgnoreCase);
}
/// <summary>Get whether a normalized asset key is in the given folder.</summary>
diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs
index 9438f11e..6f3c8c55 100644
--- a/src/SMAPI/Program.cs
+++ b/src/SMAPI/Program.cs
@@ -67,7 +67,7 @@ namespace StardewModdingAPI
AssemblyName name = new AssemblyName(e.Name);
foreach (FileInfo dll in new DirectoryInfo(Program.DllSearchPath).EnumerateFiles("*.dll"))
{
- if (name.Name.Equals(AssemblyName.GetAssemblyName(dll.FullName).Name, StringComparison.InvariantCultureIgnoreCase))
+ if (name.Name.Equals(AssemblyName.GetAssemblyName(dll.FullName).Name, StringComparison.OrdinalIgnoreCase))
return Assembly.LoadFrom(dll.FullName);
}
return null;
diff --git a/src/SMAPI/SMAPI.csproj b/src/SMAPI/SMAPI.csproj
index 4af4527b..a3dbf52f 100644
--- a/src/SMAPI/SMAPI.csproj
+++ b/src/SMAPI/SMAPI.csproj
@@ -13,7 +13,7 @@
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="LargeAddressAware" Version="1.0.4" />
+ <PackageReference Include="LargeAddressAware" Version="1.0.5" />
<PackageReference Include="Mono.Cecil" Version="0.11.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Platonymous.TMXTile" Version="1.3.8" />
diff --git a/src/SMAPI/Translation.cs b/src/SMAPI/Translation.cs
index 2196c8a5..149f6728 100644
--- a/src/SMAPI/Translation.cs
+++ b/src/SMAPI/Translation.cs
@@ -67,7 +67,7 @@ namespace StardewModdingAPI
return this;
// get dictionary of tokens
- IDictionary<string, string> tokenLookup = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
+ IDictionary<string, string> tokenLookup = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
{
// from dictionary
if (tokens is IDictionary inputLookup)