From 285443f10f169b2600cbb128064af6ae42fec4a2 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Sun, 12 Mar 2023 15:44:49 +0000 Subject: [PATCH] Fix CA1310, CA1311 --- .editorconfig | 6 ++++++ OpenRA.Game/FileSystem/FileSystem.cs | 8 ++++---- OpenRA.Game/FileSystem/Folder.cs | 4 ++-- OpenRA.Game/GameRules/WeaponInfo.cs | 2 +- OpenRA.Game/Graphics/ChromeProvider.cs | 2 +- OpenRA.Game/Graphics/SequenceSet.cs | 2 +- OpenRA.Game/Map/Map.cs | 5 ++++- OpenRA.Game/Map/MapCache.cs | 8 ++++---- OpenRA.Game/MiniYaml.cs | 2 +- OpenRA.Game/Platform.cs | 6 +++--- OpenRA.Game/Scripting/ScriptMemberWrapper.cs | 2 +- OpenRA.Game/Translation.cs | 4 ++-- OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs | 2 +- OpenRA.Mods.Cnc/FileFormats/VxlReader.cs | 3 ++- OpenRA.Mods.Cnc/Installer/ExtractMixSourceAction.cs | 2 +- OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs | 6 +++--- OpenRA.Mods.Common/Commands/ChatCommands.cs | 2 +- .../Installer/SourceActions/DeleteSourceAction.cs | 2 +- .../Installer/SourceActions/ExtractBlastSourceAction.cs | 2 +- .../Installer/SourceActions/ExtractIscabSourceAction.cs | 2 +- .../Installer/SourceActions/ExtractMscabSourceAction.cs | 2 +- .../Installer/SourceActions/ExtractRawSourceAction.cs | 2 +- .../Installer/SourceActions/ExtractZipSourceAction.cs | 2 +- OpenRA.Mods.Common/Lint/CheckSequences.cs | 4 ++-- OpenRA.Mods.Common/Lint/CheckUnknownTraitFields.cs | 4 ++-- OpenRA.Mods.Common/Lint/CheckUnknownWeaponFields.cs | 4 ++-- OpenRA.Mods.Common/Lint/LintBuildablePrerequisites.cs | 2 +- OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs | 4 ++-- OpenRA.Mods.Common/SpriteLoaders/PngSheetLoader.cs | 2 +- .../Traits/PaletteEffects/RotationPaletteEffect.cs | 3 ++- OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs | 3 ++- OpenRA.Mods.Common/Traits/Player/TechTree.cs | 9 ++++----- OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs | 2 +- .../Rules/20230225/ExplicitSequenceFilenames.cs | 6 +++--- .../UtilityCommands/CheckExplicitInterfacesCommand.cs | 5 ++++- .../UtilityCommands/ExtractSettingsDocsCommand.cs | 2 +- .../UtilityCommands/ExtractTraitDocsCommand.cs | 4 ++-- .../UtilityCommands/ExtractWeaponDocsCommand.cs | 4 ++-- OpenRA.Mods.Common/Widgets/Logic/EncyclopediaLogic.cs | 2 +- .../Widgets/Logic/Ingame/IngameChatLogic.cs | 3 +-- .../Widgets/Logic/Ingame/ProductionTooltipLogic.cs | 2 +- OpenRA.Mods.Common/Widgets/Logic/TabCompletionLogic.cs | 2 +- OpenRA.Platforms.Default/Sdl2PlatformWindow.cs | 2 +- 43 files changed, 80 insertions(+), 67 deletions(-) diff --git a/.editorconfig b/.editorconfig index 826e720c92..435455fe31 100644 --- a/.editorconfig +++ b/.editorconfig @@ -670,6 +670,12 @@ dotnet_diagnostic.CA1304.severity = warning # Specify 'IFormatProvider'. dotnet_diagnostic.CA1305.severity = warning +# Specify 'StringComparison' for correctness. +dotnet_diagnostic.CA1310.severity = warning + +# Specify a culture or use an invariant version. +dotnet_diagnostic.CA1311.severity = warning + ### Portability and Interoperability Rules ### https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/interoperability-warnings diff --git a/OpenRA.Game/FileSystem/FileSystem.cs b/OpenRA.Game/FileSystem/FileSystem.cs index 7ac45d0a8e..ed6072c8a4 100644 --- a/OpenRA.Game/FileSystem/FileSystem.cs +++ b/OpenRA.Game/FileSystem/FileSystem.cs @@ -83,14 +83,14 @@ namespace OpenRA.FileSystem public void Mount(string name, string explicitName = null) { - var optional = name.StartsWith("~", StringComparison.Ordinal); + var optional = name.StartsWith('~'); if (optional) name = name[1..]; try { IReadOnlyPackage package; - if (name.StartsWith("$", StringComparison.Ordinal)) + if (name.StartsWith('$')) { name = name[1..]; @@ -295,7 +295,7 @@ namespace OpenRA.FileSystem public static string ResolveAssemblyPath(string path, Manifest manifest, InstalledMods installedMods) { var explicitSplit = path.IndexOf('|'); - if (explicitSplit > 0 && !path.StartsWith("^")) + if (explicitSplit > 0 && !path.StartsWith('^')) { var parent = path[..explicitSplit]; var filename = path[(explicitSplit + 1)..]; @@ -304,7 +304,7 @@ namespace OpenRA.FileSystem if (parentPath == null) return null; - if (parentPath.StartsWith("$", StringComparison.Ordinal)) + if (parentPath.StartsWith('$')) { if (!installedMods.TryGetValue(parentPath[1..], out var mod)) return null; diff --git a/OpenRA.Game/FileSystem/Folder.cs b/OpenRA.Game/FileSystem/Folder.cs index ff7d861141..a63cddf5d7 100644 --- a/OpenRA.Game/FileSystem/Folder.cs +++ b/OpenRA.Game/FileSystem/Folder.cs @@ -80,7 +80,7 @@ namespace OpenRA.FileSystem // in FileSystem.OpenPackage. Their internal name therefore contains the // full parent path too. We need to be careful to not add a second path // prefix to these hacked packages. - var filePath = filename.StartsWith(Name) ? filename : Path.Combine(Name, filename); + var filePath = filename.StartsWith(Name, StringComparison.Ordinal) ? filename : Path.Combine(Name, filename); Directory.CreateDirectory(Path.GetDirectoryName(filePath)); using (var s = File.Create(filePath)) @@ -94,7 +94,7 @@ namespace OpenRA.FileSystem // in FileSystem.OpenPackage. Their internal name therefore contains the // full parent path too. We need to be careful to not add a second path // prefix to these hacked packages. - var filePath = filename.StartsWith(Name) ? filename : Path.Combine(Name, filename); + var filePath = filename.StartsWith(Name, StringComparison.Ordinal) ? filename : Path.Combine(Name, filename); if (Directory.Exists(filePath)) Directory.Delete(filePath, true); else if (File.Exists(filePath)) diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 0d9cebff7d..b4b76807dc 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -159,7 +159,7 @@ namespace OpenRA.GameRules static object LoadWarheads(MiniYaml yaml) { var retList = new List(); - foreach (var node in yaml.Nodes.Where(n => n.Key.StartsWith("Warhead"))) + foreach (var node in yaml.Nodes.Where(n => n.Key.StartsWith("Warhead", StringComparison.Ordinal))) { var ret = Game.CreateObject(node.Value.Value + "Warhead"); if (ret == null) diff --git a/OpenRA.Game/Graphics/ChromeProvider.cs b/OpenRA.Game/Graphics/ChromeProvider.cs index a9adf85f5f..163fd70846 100644 --- a/OpenRA.Game/Graphics/ChromeProvider.cs +++ b/OpenRA.Game/Graphics/ChromeProvider.cs @@ -81,7 +81,7 @@ namespace OpenRA.Graphics .Select(s => MiniYaml.FromStream(fileSystem.Open(s), s))); foreach (var c in chrome) - if (!c.Key.StartsWith("^", StringComparison.Ordinal)) + if (!c.Key.StartsWith('^')) LoadCollection(c.Key, c.Value); } diff --git a/OpenRA.Game/Graphics/SequenceSet.cs b/OpenRA.Game/Graphics/SequenceSet.cs index 7a3b32c0cb..989912c9c2 100644 --- a/OpenRA.Game/Graphics/SequenceSet.cs +++ b/OpenRA.Game/Graphics/SequenceSet.cs @@ -94,7 +94,7 @@ namespace OpenRA.Graphics foreach (var node in nodes) { // Nodes starting with ^ are inheritable but never loaded directly - if (node.Key.StartsWith(ActorInfo.AbstractActorPrefix, StringComparison.Ordinal)) + if (node.Key.StartsWith(ActorInfo.AbstractActorPrefix)) continue; images[node.Key] = modData.SpriteSequenceLoader.ParseSequences(modData, tileSet, SpriteCache, node); diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 253bc5de18..2b386c1576 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -275,7 +275,10 @@ namespace OpenRA try { foreach (var filename in contents) - if (filename.EndsWith(".yaml") || filename.EndsWith(".bin") || filename.EndsWith(".lua") || (format >= 12 && filename == "map.png")) + if (filename.EndsWith(".yaml", StringComparison.Ordinal) || + filename.EndsWith(".bin", StringComparison.Ordinal) || + filename.EndsWith(".lua", StringComparison.Ordinal) || + (format >= 12 && filename == "map.png")) streams.Add(package.GetStream(filename)); // Take the SHA1 diff --git a/OpenRA.Game/Map/MapCache.cs b/OpenRA.Game/Map/MapCache.cs index 22e9f344c1..cb29969815 100644 --- a/OpenRA.Game/Map/MapCache.cs +++ b/OpenRA.Game/Map/MapCache.cs @@ -97,7 +97,7 @@ namespace OpenRA ? MapClassification.Unknown : Enum.Parse(kv.Value); IReadOnlyPackage package; - var optional = name.StartsWith("~", StringComparison.Ordinal); + var optional = name.StartsWith('~'); if (optional) name = name[1..]; @@ -106,7 +106,7 @@ namespace OpenRA // HACK: If the path is inside the support directory then we may need to create it // Assume that the path is a directory if there is not an existing file with the same name var resolved = Platform.ResolvePath(name); - if (resolved.StartsWith(Platform.SupportDir) && !File.Exists(resolved)) + if (resolved.StartsWith(Platform.SupportDir, StringComparison.Ordinal) && !File.Exists(resolved)) Directory.CreateDirectory(resolved); package = modData.ModFiles.OpenPackage(name); @@ -190,13 +190,13 @@ namespace OpenRA continue; var name = kv.Key; - var optional = name.StartsWith("~", StringComparison.Ordinal); + var optional = name.StartsWith('~'); if (optional) name = name[1..]; // Don't try to open the map directory in the support directory if it doesn't exist var resolved = Platform.ResolvePath(name); - if (resolved.StartsWith(Platform.SupportDir) && (!Directory.Exists(resolved) || !File.Exists(resolved))) + if (resolved.StartsWith(Platform.SupportDir, StringComparison.Ordinal) && (!Directory.Exists(resolved) || !File.Exists(resolved))) continue; using (var package = (IReadWritePackage)modData.ModFiles.OpenPackage(name)) diff --git a/OpenRA.Game/MiniYaml.cs b/OpenRA.Game/MiniYaml.cs index 5765f2621a..a28ca60fd0 100644 --- a/OpenRA.Game/MiniYaml.cs +++ b/OpenRA.Game/MiniYaml.cs @@ -438,7 +438,7 @@ namespace OpenRA foreach (var r in ResolveInherits(parent, tree, inherited)) MergeIntoResolved(r, resolved, resolvedKeys, tree, inherited); } - else if (n.Key.StartsWith("-", StringComparison.Ordinal)) + else if (n.Key.StartsWith('-')) { var removed = n.Key[1..]; if (resolved.RemoveAll(r => r.Key == removed) == 0) diff --git a/OpenRA.Game/Platform.cs b/OpenRA.Game/Platform.cs index 6717d720b3..008ba93256 100644 --- a/OpenRA.Game/Platform.cs +++ b/OpenRA.Game/Platform.cs @@ -109,14 +109,14 @@ namespace OpenRA var p = Process.Start(psi); string line; while ((line = p.StandardOutput.ReadLine()) != null) - if (line.StartsWith("Operating System: ")) + if (line.StartsWith("Operating System: ", StringComparison.Ordinal)) return line[18..] + suffix; } catch { } if (File.Exists("/etc/os-release")) foreach (var line in File.ReadLines("/etc/os-release")) - if (line.StartsWith("PRETTY_NAME=")) + if (line.StartsWith("PRETTY_NAME=", StringComparison.Ordinal)) return line[13..^1] + suffix; } else if (CurrentPlatform == PlatformType.OSX) @@ -134,7 +134,7 @@ namespace OpenRA while ((line = p.StandardOutput.ReadLine()) != null) { line = line.Trim(); - if (line.StartsWith("System Version: ")) + if (line.StartsWith("System Version: ", StringComparison.Ordinal)) return line[16..]; } } diff --git a/OpenRA.Game/Scripting/ScriptMemberWrapper.cs b/OpenRA.Game/Scripting/ScriptMemberWrapper.cs index 951e74a914..41b74ad34c 100644 --- a/OpenRA.Game/Scripting/ScriptMemberWrapper.cs +++ b/OpenRA.Game/Scripting/ScriptMemberWrapper.cs @@ -150,7 +150,7 @@ namespace OpenRA.Scripting // Remove the namespace and the trailing "Info" return types.SelectMany(i => i.GetGenericArguments()) .Select(g => g.Name.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault()) - .Select(s => s.EndsWith("Info") ? s.Remove(s.Length - 4, 4) : s) + .Select(s => s.EndsWith("Info", StringComparison.Ordinal) ? s.Remove(s.Length - 4, 4) : s) .ToArray(); } } diff --git a/OpenRA.Game/Translation.cs b/OpenRA.Game/Translation.cs index 520c1a0d94..9f1f062f62 100644 --- a/OpenRA.Game/Translation.cs +++ b/OpenRA.Game/Translation.cs @@ -86,9 +86,9 @@ namespace OpenRA { // Always load english strings to provide a fallback for missing translations. // It is important to load the english files first so the chosen language's files can override them. - var paths = translations.Where(t => t.EndsWith("en.ftl")).ToHashSet(); + var paths = translations.Where(t => t.EndsWith("en.ftl", StringComparison.Ordinal)).ToHashSet(); foreach (var t in translations) - if (t.EndsWith($"{language}.ftl")) + if (t.EndsWith($"{language}.ftl", StringComparison.Ordinal)) paths.Add(t); foreach (var path in paths) diff --git a/OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs b/OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs index 231a2338ef..44da4e6b2c 100644 --- a/OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs +++ b/OpenRA.Mods.Cnc/AudioLoaders/VocLoader.cs @@ -116,7 +116,7 @@ namespace OpenRA.Mods.Cnc.AudioLoaders { var vfh = VocFileHeader.Read(stream); - if (!vfh.Description.StartsWith("Creative Voice File")) + if (!vfh.Description.StartsWith("Creative Voice File", StringComparison.Ordinal)) throw new InvalidDataException("Voc header description not recognized"); if (vfh.DatablockOffset != 26) throw new InvalidDataException("Voc header offset is wrong"); diff --git a/OpenRA.Mods.Cnc/FileFormats/VxlReader.cs b/OpenRA.Mods.Cnc/FileFormats/VxlReader.cs index 7962452b80..cb150537d5 100644 --- a/OpenRA.Mods.Cnc/FileFormats/VxlReader.cs +++ b/OpenRA.Mods.Cnc/FileFormats/VxlReader.cs @@ -9,6 +9,7 @@ */ #endregion +using System; using System.Collections.Generic; using System.IO; @@ -111,7 +112,7 @@ namespace OpenRA.Mods.Cnc.FileFormats public VxlReader(Stream s) { - if (!s.ReadASCII(16).StartsWith("Voxel Animation")) + if (!s.ReadASCII(16).StartsWith("Voxel Animation", StringComparison.Ordinal)) throw new InvalidDataException("Invalid vxl header"); s.ReadUInt32(); diff --git a/OpenRA.Mods.Cnc/Installer/ExtractMixSourceAction.cs b/OpenRA.Mods.Cnc/Installer/ExtractMixSourceAction.cs index 57a7763a6a..5e2708413c 100644 --- a/OpenRA.Mods.Cnc/Installer/ExtractMixSourceAction.cs +++ b/OpenRA.Mods.Cnc/Installer/ExtractMixSourceAction.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Cnc.Installer public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List extracted, Action updateMessage) { // Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected source path - var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value)); + var sourcePath = actionYaml.Value.StartsWith('^') ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value)); using (var source = File.OpenRead(sourcePath)) { diff --git a/OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs b/OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs index e2eb2b4e73..acbff3e9d0 100644 --- a/OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs +++ b/OpenRA.Mods.Cnc/UtilityCommands/ImportGen1MapCommand.cs @@ -58,7 +58,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands var player = basic.GetValue("Player", string.Empty); if (!string.IsNullOrEmpty(player)) - singlePlayer = !player.StartsWith("Multi"); + singlePlayer = !player.StartsWith("Multi", StringComparison.Ordinal); var mapSection = file.GetSection("Map"); @@ -332,9 +332,9 @@ namespace OpenRA.Mods.Cnc.UtilityCommands var key = $"{loc % MapSize},{loc / MapSize}"; var value = $"{type},{parts[2]}"; var node = new MiniYamlNode(key, value); - if (type.StartsWith("sc")) + if (type.StartsWith("sc", StringComparison.Ordinal)) scorches.Add(node); - else if (type.StartsWith("cr")) + else if (type.StartsWith("cr", StringComparison.Ordinal)) craters.Add(node); } diff --git a/OpenRA.Mods.Common/Commands/ChatCommands.cs b/OpenRA.Mods.Common/Commands/ChatCommands.cs index 4531cdc967..6734c06740 100644 --- a/OpenRA.Mods.Common/Commands/ChatCommands.cs +++ b/OpenRA.Mods.Common/Commands/ChatCommands.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.Common.Commands public bool OnChat(string playername, string message) { - if (message.StartsWith("/")) + if (message.StartsWith('/')) { var name = message[1..].Split(' ')[0].ToLowerInvariant(); var command = Commands.FirstOrDefault(x => x.Key == name); diff --git a/OpenRA.Mods.Common/Installer/SourceActions/DeleteSourceAction.cs b/OpenRA.Mods.Common/Installer/SourceActions/DeleteSourceAction.cs index 1b8ba39322..16c2d38047 100644 --- a/OpenRA.Mods.Common/Installer/SourceActions/DeleteSourceAction.cs +++ b/OpenRA.Mods.Common/Installer/SourceActions/DeleteSourceAction.cs @@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Installer public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List extracted, Action updateMessage) { // Yaml path must be specified relative to a named directory (e.g. ^SupportDir) - if (!actionYaml.Value.StartsWith("^")) + if (!actionYaml.Value.StartsWith('^')) return; var sourcePath = Platform.ResolvePath(actionYaml.Value); diff --git a/OpenRA.Mods.Common/Installer/SourceActions/ExtractBlastSourceAction.cs b/OpenRA.Mods.Common/Installer/SourceActions/ExtractBlastSourceAction.cs index f8f9e32c55..6bdc76ddf6 100644 --- a/OpenRA.Mods.Common/Installer/SourceActions/ExtractBlastSourceAction.cs +++ b/OpenRA.Mods.Common/Installer/SourceActions/ExtractBlastSourceAction.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Installer public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List extracted, Action updateMessage) { // Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected source path - var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value)); + var sourcePath = actionYaml.Value.StartsWith('^') ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value)); using (var source = File.OpenRead(sourcePath)) { diff --git a/OpenRA.Mods.Common/Installer/SourceActions/ExtractIscabSourceAction.cs b/OpenRA.Mods.Common/Installer/SourceActions/ExtractIscabSourceAction.cs index 5f491eb08e..08dd1acc5d 100644 --- a/OpenRA.Mods.Common/Installer/SourceActions/ExtractIscabSourceAction.cs +++ b/OpenRA.Mods.Common/Installer/SourceActions/ExtractIscabSourceAction.cs @@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Installer public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List extracted, Action updateMessage) { // Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected source path - var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value)); + var sourcePath = actionYaml.Value.StartsWith('^') ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value)); var volumeNode = actionYaml.Nodes.FirstOrDefault(n => n.Key == "Volumes"); if (volumeNode == null) diff --git a/OpenRA.Mods.Common/Installer/SourceActions/ExtractMscabSourceAction.cs b/OpenRA.Mods.Common/Installer/SourceActions/ExtractMscabSourceAction.cs index 8c313a3a7b..eb8ee168e7 100644 --- a/OpenRA.Mods.Common/Installer/SourceActions/ExtractMscabSourceAction.cs +++ b/OpenRA.Mods.Common/Installer/SourceActions/ExtractMscabSourceAction.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Installer public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List extracted, Action updateMessage) { // Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected source path - var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value)); + var sourcePath = actionYaml.Value.StartsWith('^') ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value)); using (var source = File.OpenRead(sourcePath)) { diff --git a/OpenRA.Mods.Common/Installer/SourceActions/ExtractRawSourceAction.cs b/OpenRA.Mods.Common/Installer/SourceActions/ExtractRawSourceAction.cs index 434c55e25a..70c0f4e9ba 100644 --- a/OpenRA.Mods.Common/Installer/SourceActions/ExtractRawSourceAction.cs +++ b/OpenRA.Mods.Common/Installer/SourceActions/ExtractRawSourceAction.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Installer public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List extracted, Action updateMessage) { // Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected source path - var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value)); + var sourcePath = actionYaml.Value.StartsWith('^') ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value)); using (var source = File.OpenRead(sourcePath)) { diff --git a/OpenRA.Mods.Common/Installer/SourceActions/ExtractZipSourceAction.cs b/OpenRA.Mods.Common/Installer/SourceActions/ExtractZipSourceAction.cs index 968f4df3da..876bd7fa11 100644 --- a/OpenRA.Mods.Common/Installer/SourceActions/ExtractZipSourceAction.cs +++ b/OpenRA.Mods.Common/Installer/SourceActions/ExtractZipSourceAction.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Installer public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List extracted, Action updateMessage) { - var zipPath = actionYaml.Value.StartsWith("^") + var zipPath = actionYaml.Value.StartsWith('^') ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value)); diff --git a/OpenRA.Mods.Common/Lint/CheckSequences.cs b/OpenRA.Mods.Common/Lint/CheckSequences.cs index ae3362cb5b..4da8b8cd4d 100644 --- a/OpenRA.Mods.Common/Lint/CheckSequences.cs +++ b/OpenRA.Mods.Common/Lint/CheckSequences.cs @@ -95,7 +95,7 @@ namespace OpenRA.Mods.Common.Lint if (sequenceReference.Prefix) { // TODO: Remove prefixed sequence references and instead use explicit lists of lintable references. - if (!sequences.Sequences(i).Any(s => s.StartsWith(sequence))) + if (!sequences.Sequences(i).Any(s => s.StartsWith(sequence, StringComparison.Ordinal))) emitWarning($"Actor type `{actorInfo.Value.Name}` trait `{traitName}` field `{field.Name}` defines a prefix `{sequence}` that does not match any sequences on image `{i}`."); } else if (!sequences.HasSequence(i, sequence)) @@ -143,7 +143,7 @@ namespace OpenRA.Mods.Common.Lint if (sequenceReference.Prefix) { // TODO: Remove prefixed sequence references and instead use explicit lists of lintable references. - if (!sequences.Sequences(image).Any(s => s.StartsWith(sequence))) + if (!sequences.Sequences(image).Any(s => s.StartsWith(sequence, StringComparison.Ordinal))) emitWarning($"Weapon type `{weaponInfo.Key}` projectile field `{field.Name}` defines a prefix `{sequence}` that does not match any sequences on image `{image}`."); } else if (!sequences.HasSequence(image, sequence)) diff --git a/OpenRA.Mods.Common/Lint/CheckUnknownTraitFields.cs b/OpenRA.Mods.Common/Lint/CheckUnknownTraitFields.cs index 2615a22bb6..d30221174b 100644 --- a/OpenRA.Mods.Common/Lint/CheckUnknownTraitFields.cs +++ b/OpenRA.Mods.Common/Lint/CheckUnknownTraitFields.cs @@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Lint static string NormalizeName(string key) { var name = key.Split('@')[0]; - if (name.StartsWith("-", StringComparison.Ordinal)) + if (name.StartsWith('-')) return name[1..]; return name; @@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Lint foreach (var t in actor.Value.Nodes) { // Removals can never define children or values. - if (t.Key.StartsWith("-", StringComparison.Ordinal)) + if (t.Key.StartsWith('-')) { if (t.Value.Nodes.Length > 0) emitError($"{t.Location} `{t.Key}` defines child nodes, which are not valid for removals."); diff --git a/OpenRA.Mods.Common/Lint/CheckUnknownWeaponFields.cs b/OpenRA.Mods.Common/Lint/CheckUnknownWeaponFields.cs index 52a4068421..4707d52869 100644 --- a/OpenRA.Mods.Common/Lint/CheckUnknownWeaponFields.cs +++ b/OpenRA.Mods.Common/Lint/CheckUnknownWeaponFields.cs @@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Lint static string NormalizeName(string key) { var name = key.Split('@')[0]; - if (name.StartsWith("-", StringComparison.Ordinal)) + if (name.StartsWith('-')) return name[1..]; return name; @@ -52,7 +52,7 @@ namespace OpenRA.Mods.Common.Lint foreach (var field in weapon.Value.Nodes) { // Removals can never define children or values - if (field.Key.StartsWith("-", StringComparison.Ordinal)) + if (field.Key.StartsWith('-')) { if (field.Value.Nodes.Length > 0) emitError($"{field.Location} `{field.Key}` defines child nodes, which is not valid for removals."); diff --git a/OpenRA.Mods.Common/Lint/LintBuildablePrerequisites.cs b/OpenRA.Mods.Common/Lint/LintBuildablePrerequisites.cs index 52c3373565..8570def426 100644 --- a/OpenRA.Mods.Common/Lint/LintBuildablePrerequisites.cs +++ b/OpenRA.Mods.Common/Lint/LintBuildablePrerequisites.cs @@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Lint var bi = actorInfo.Value.TraitInfoOrDefault(); if (bi != null) foreach (var prereq in bi.Prerequisites) - if (!prereq.StartsWith("~disabled") && !providedPrereqs.Contains(prereq.Replace("!", "").Replace("~", ""))) + if (!prereq.StartsWith("~disabled", StringComparison.Ordinal) && !providedPrereqs.Contains(prereq.Replace("!", "").Replace("~", ""))) emitError($"Buildable actor `{actorInfo.Key}` has prereq `{prereq}` not provided by anything."); } catch (InvalidOperationException e) diff --git a/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs b/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs index a37b333552..c9d47cbe9f 100644 --- a/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs +++ b/OpenRA.Mods.Common/ServerTraits/LobbyCommands.cs @@ -207,7 +207,7 @@ namespace OpenRA.Mods.Common.Server lock (server.LobbyInfo) { // Kick command is always valid for the host - if (command.StartsWith("kick ")) + if (command.StartsWith("kick ", StringComparison.Ordinal)) return true; if (server.State == ServerState.GameStarted) @@ -215,7 +215,7 @@ namespace OpenRA.Mods.Common.Server server.SendLocalizedMessageTo(conn, StateUnchangedGameStarted, Translation.Arguments("command", command)); return false; } - else if (client.State == Session.ClientState.Ready && !(command.StartsWith("state") || command == "startgame")) + else if (client.State == Session.ClientState.Ready && !(command.StartsWith("state", StringComparison.Ordinal) || command == "startgame")) { server.SendLocalizedMessageTo(conn, StateUnchangedReady); return false; diff --git a/OpenRA.Mods.Common/SpriteLoaders/PngSheetLoader.cs b/OpenRA.Mods.Common/SpriteLoaders/PngSheetLoader.cs index f52bbb26a5..52aad5f2f6 100644 --- a/OpenRA.Mods.Common/SpriteLoaders/PngSheetLoader.cs +++ b/OpenRA.Mods.Common/SpriteLoaders/PngSheetLoader.cs @@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.SpriteLoaders List frameOffsets; // Prefer manual defined regions over auto sliced regions. - if (png.EmbeddedData.Any(meta => meta.Key.StartsWith("Frame["))) + if (png.EmbeddedData.Any(meta => meta.Key.StartsWith("Frame[", StringComparison.Ordinal))) RegionsFromFrames(png, out frameRegions, out frameOffsets); else RegionsFromSlices(png, out frameRegions, out frameOffsets); diff --git a/OpenRA.Mods.Common/Traits/PaletteEffects/RotationPaletteEffect.cs b/OpenRA.Mods.Common/Traits/PaletteEffects/RotationPaletteEffect.cs index 390268d5c5..c2c0c4dfc5 100644 --- a/OpenRA.Mods.Common/Traits/PaletteEffects/RotationPaletteEffect.cs +++ b/OpenRA.Mods.Common/Traits/PaletteEffects/RotationPaletteEffect.cs @@ -9,6 +9,7 @@ */ #endregion +using System; using System.Collections.Generic; using OpenRA.Graphics; using OpenRA.Traits; @@ -110,7 +111,7 @@ namespace OpenRA.Mods.Common.Traits { // PERF: Avoid LINQ. foreach (var pref in prefixes) - if (name.StartsWith(pref)) + if (name.StartsWith(pref, StringComparison.Ordinal)) return true; return false; diff --git a/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs b/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs index f9745620cf..e559df2ac7 100644 --- a/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs +++ b/OpenRA.Mods.Common/Traits/Player/PlayerStatistics.cs @@ -9,6 +9,7 @@ */ #endregion +using System; using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; @@ -116,7 +117,7 @@ namespace OpenRA.Mods.Common.Traits public void ResolveOrder(Actor self, Order order) { - if (order.OrderString.StartsWith("Dev")) + if (order.OrderString.StartsWith("Dev", StringComparison.Ordinal)) return; OrderCount++; diff --git a/OpenRA.Mods.Common/Traits/Player/TechTree.cs b/OpenRA.Mods.Common/Traits/Player/TechTree.cs index 219df4c98d..facb3a57b8 100644 --- a/OpenRA.Mods.Common/Traits/Player/TechTree.cs +++ b/OpenRA.Mods.Common/Traits/Player/TechTree.cs @@ -9,7 +9,6 @@ */ #endregion -using System; using System.Collections.Generic; using System.Linq; using OpenRA.Traits; @@ -66,7 +65,7 @@ namespace OpenRA.Mods.Common.Traits public bool HasPrerequisites(IEnumerable prerequisites) { var ownedPrereqs = GatherOwnedPrerequisites(Owner); - return prerequisites.All(p => !(p.Replace("~", "").StartsWith("!", StringComparison.Ordinal) + return prerequisites.All(p => !(p.Replace("~", "").StartsWith('!') ^ !ownedPrereqs.ContainsKey(p.Replace("!", "").Replace("~", "")))); } @@ -142,7 +141,7 @@ namespace OpenRA.Mods.Common.Traits foreach (var prereq in prerequisites) { var withoutTilde = prereq.Replace("~", ""); - if (withoutTilde.StartsWith("!", StringComparison.Ordinal) ^ !ownedPrerequisites.ContainsKey(withoutTilde.Replace("!", ""))) + if (withoutTilde.StartsWith('!') ^ !ownedPrerequisites.ContainsKey(withoutTilde.Replace("!", ""))) return false; } @@ -154,10 +153,10 @@ namespace OpenRA.Mods.Common.Traits // PERF: Avoid LINQ. foreach (var prereq in prerequisites) { - if (!prereq.StartsWith("~", StringComparison.Ordinal)) + if (!prereq.StartsWith('~')) continue; var withoutTilde = prereq.Replace("~", ""); - if (withoutTilde.StartsWith("!", StringComparison.Ordinal) ^ !ownedPrerequisites.ContainsKey(withoutTilde.Replace("!", ""))) + if (withoutTilde.StartsWith('!') ^ !ownedPrerequisites.ContainsKey(withoutTilde.Replace("!", ""))) return true; } diff --git a/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs index d087a917cd..e1acae47be 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorActorLayer.cs @@ -197,7 +197,7 @@ namespace OpenRA.Mods.Common.Traits void SyncMultiplayerCount() { var newCount = previews.Count(p => p.Info.Name == "mpspawn"); - var mp = Players.Players.Where(p => p.Key.StartsWith("Multi")).ToList(); + var mp = Players.Players.Where(p => p.Key.StartsWith("Multi", StringComparison.Ordinal)).ToList(); foreach (var kv in mp) { var name = kv.Key; diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/20230225/ExplicitSequenceFilenames.cs b/OpenRA.Mods.Common/UpdateRules/Rules/20230225/ExplicitSequenceFilenames.cs index 2e53038d57..62732081bf 100644 --- a/OpenRA.Mods.Common/UpdateRules/Rules/20230225/ExplicitSequenceFilenames.cs +++ b/OpenRA.Mods.Common/UpdateRules/Rules/20230225/ExplicitSequenceFilenames.cs @@ -192,7 +192,7 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules defaultTilesetFilenamesNode = defaultsNode.LastChildMatching("TilesetFilenames") ?? defaultTilesetFilenamesNode; } - if ((defaultFilenameNode == null || defaultTilesetFilenamesNode == null) && !imageNode.Key.StartsWith("^")) + if ((defaultFilenameNode == null || defaultTilesetFilenamesNode == null) && !imageNode.Key.StartsWith('^')) { var duplicateCount = new Dictionary(); var duplicateTilesetCount = new Dictionary(); @@ -372,7 +372,7 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules // Replace removals with masking foreach (var node in sequenceNode.Value.Nodes) - if (node.Key?.StartsWith("-") ?? false) + if (node.Key?.StartsWith('-') ?? false) node.Key = node.Key[1..]; var combineNode = sequenceNode.LastChildMatching("Combine"); @@ -389,7 +389,7 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules } var filename = string.IsNullOrEmpty(resolvedSequenceNode.Value.Value) ? imageName : resolvedSequenceNode.Value.Value; - if (filename.StartsWith("^")) + if (filename.StartsWith('^')) return; if (useTilesetExtension || useTilesetCode) diff --git a/OpenRA.Mods.Common/UtilityCommands/CheckExplicitInterfacesCommand.cs b/OpenRA.Mods.Common/UtilityCommands/CheckExplicitInterfacesCommand.cs index 08070db7ed..5420677b0b 100644 --- a/OpenRA.Mods.Common/UtilityCommands/CheckExplicitInterfacesCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/CheckExplicitInterfacesCommand.cs @@ -46,7 +46,10 @@ namespace OpenRA.Mods.Common.UtilityCommands var interfaceMembers = interfaceType.GetMembers(); foreach (var interfaceMember in interfaceMembers) { - if (interfaceMember.Name.StartsWith("get_") || interfaceMember.Name.StartsWith("set_") || interfaceMember.Name.StartsWith("add_") || interfaceMember.Name.StartsWith("remove_")) + if (interfaceMember.Name.StartsWith("get_", StringComparison.Ordinal) || + interfaceMember.Name.StartsWith("set_", StringComparison.Ordinal) || + interfaceMember.Name.StartsWith("add_", StringComparison.Ordinal) || + interfaceMember.Name.StartsWith("remove_", StringComparison.Ordinal)) continue; var interfaceMethod = interfaceMember as MethodInfo; diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractSettingsDocsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractSettingsDocsCommand.cs index 644f982ec6..9db86f82f9 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractSettingsDocsCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractSettingsDocsCommand.cs @@ -84,7 +84,7 @@ namespace OpenRA.Mods.Common.UtilityCommands } var value = field.GetValue(section.Value); - if (value != null && !value.ToString().StartsWith("System.")) + if (value != null && !value.ToString().StartsWith("System.", StringComparison.Ordinal)) { Console.WriteLine($"**Default Value:** {value}"); Console.WriteLine(); diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractTraitDocsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractTraitDocsCommand.cs index 09ec798a43..95ee951600 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractTraitDocsCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractTraitDocsCommand.cs @@ -54,7 +54,7 @@ namespace OpenRA.Mods.Common.UtilityCommands .Select(type => new { type.Namespace, - Name = type.Name.EndsWith("Info") ? type.Name[..^4] : type.Name, + Name = type.Name.EndsWith("Info", StringComparison.Ordinal) ? type.Name[..^4] : type.Name, Description = string.Join(" ", Utility.GetCustomAttributes(type, false).SelectMany(d => d.Lines)), RequiresTraits = RequiredTraitTypes(type) .Select(y => y.Name), @@ -80,7 +80,7 @@ namespace OpenRA.Mods.Common.UtilityCommands .Select(a => { var name = a.AttributeType.Name; - name = name.EndsWith("Attribute") ? name[..^9] : name; + name = name.EndsWith("Attribute", StringComparison.Ordinal) ? name[..^9] : name; return new { diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractWeaponDocsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractWeaponDocsCommand.cs index 594de64269..b9e8f285a8 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractWeaponDocsCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractWeaponDocsCommand.cs @@ -59,7 +59,7 @@ namespace OpenRA.Mods.Common.UtilityCommands .Select(type => new { type.Namespace, - Name = type.Name.EndsWith("Info") ? type.Name[..^4] : type.Name, + Name = type.Name.EndsWith("Info", StringComparison.Ordinal) ? type.Name[..^4] : type.Name, Description = string.Join(" ", Utility.GetCustomAttributes(type, false).SelectMany(d => d.Lines)), InheritedTypes = type.BaseTypes() .Select(y => y.Name) @@ -83,7 +83,7 @@ namespace OpenRA.Mods.Common.UtilityCommands .Select(a => { var name = a.AttributeType.Name; - name = name.EndsWith("Attribute") ? name[..^9] : name; + name = name.EndsWith("Attribute", StringComparison.Ordinal) ? name[..^9] : name; return new { diff --git a/OpenRA.Mods.Common/Widgets/Logic/EncyclopediaLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/EncyclopediaLogic.cs index 13bca8c43a..24261e5aaf 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/EncyclopediaLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/EncyclopediaLogic.cs @@ -150,7 +150,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (buildable != null) { var prerequisites = buildable.Prerequisites.Select(a => ActorName(modData.DefaultRules, a)) - .Where(s => !s.StartsWith("~", StringComparison.Ordinal) && !s.StartsWith("!", StringComparison.Ordinal)); + .Where(s => !s.StartsWith('~') && !s.StartsWith('!')); if (prerequisites.Any()) text += $"Requires {prerequisites.JoinWith(", ")}\n\n"; } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameChatLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameChatLogic.cs index 88fac61fd7..002fe47f56 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameChatLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameChatLogic.cs @@ -9,7 +9,6 @@ */ #endregion -using System; using System.Collections.Generic; using System.Linq; using OpenRA.Mods.Common.Commands; @@ -143,7 +142,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var team = teamChat && !disableTeamChat; if (chatText.Text != "") { - if (!chatText.Text.StartsWith("/", StringComparison.Ordinal)) + if (!chatText.Text.StartsWith('/')) { // This should never happen, but avoid a crash if it does somehow (chat will just stay open) if (!isObserver && orderManager.LocalClient == null && world.LocalPlayer == null) diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs index 88f693a064..4ed956369b 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs @@ -98,7 +98,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic } var prereqs = buildable.Prerequisites.Select(a => ActorName(mapRules, a)) - .Where(s => !s.StartsWith("~", StringComparison.Ordinal) && !s.StartsWith("!", StringComparison.Ordinal)); + .Where(s => !s.StartsWith('~') && !s.StartsWith('!')); var requiresSize = int2.Zero; if (prereqs.Any()) diff --git a/OpenRA.Mods.Common/Widgets/Logic/TabCompletionLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/TabCompletionLogic.cs index 93d1bdcd91..d31ebc4c69 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/TabCompletionLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/TabCompletionLogic.cs @@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic } var toComplete = ""; - if (text.StartsWith("/") && Commands != null) + if (text.StartsWith('/') && Commands != null) { prefix = "/"; suffix = ""; diff --git a/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs b/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs index 00affa0e6c..cb8420668b 100644 --- a/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs +++ b/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs @@ -209,7 +209,7 @@ namespace OpenRA.Platforms.Default var lines = p.StandardOutput.ReadToEnd().Split('\n'); foreach (var line in lines) - if (line.StartsWith("Xft.dpi") && int.TryParse(line.AsSpan(8), out var dpi)) + if (line.StartsWith("Xft.dpi", StringComparison.Ordinal) && int.TryParse(line.AsSpan(8), out var dpi)) windowScale = dpi / 96f; } catch { }