diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5414b2e25..0f0a330d2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,8 +5,6 @@ on: [push, pull_request] env: CONFIGURATION: Release DOTNET_SDK_VERSION: 8.0 - NET_CORE_VERSION: net8.0 - NET_FRAMEWORK_VERSION: net481 NODE_JS_VERSION: 'lts/*' PLUGINS: ArchiSteamFarm.OfficialPlugins.ItemsMatcher ArchiSteamFarm.OfficialPlugins.MobileAuthenticator ArchiSteamFarm.OfficialPlugins.SteamTokenDumper @@ -54,8 +52,6 @@ jobs: include: - os: ubuntu-latest variant: generic - - os: windows-latest - variant: generic-netf - os: ubuntu-latest variant: linux-arm - os: ubuntu-latest @@ -131,19 +127,15 @@ jobs: - name: Prepare for publishing on Unix if: startsWith(matrix.os, 'macos-') || startsWith(matrix.os, 'ubuntu-') - env: - TARGET_FRAMEWORK: ${{ (endsWith(matrix.variant, '-netf') && env.NET_FRAMEWORK_VERSION) || env.NET_CORE_VERSION }} shell: bash run: | set -euo pipefail dotnet restore - dotnet build ArchiSteamFarm -c "$CONFIGURATION" -f "$TARGET_FRAMEWORK" -p:ContinuousIntegrationBuild=true -p:TargetLatestRuntimePatch=false -p:UseAppHost=false --no-restore --nologo + dotnet build ArchiSteamFarm -c "$CONFIGURATION" -p:ContinuousIntegrationBuild=true -p:TargetLatestRuntimePatch=false -p:UseAppHost=false --no-restore --nologo - name: Prepare for publishing on Windows if: startsWith(matrix.os, 'windows-') - env: - TARGET_FRAMEWORK: ${{ (endsWith(matrix.variant, '-netf') && env.NET_FRAMEWORK_VERSION) || env.NET_CORE_VERSION }} shell: pwsh run: | Set-StrictMode -Version Latest @@ -151,7 +143,7 @@ jobs: $ProgressPreference = 'SilentlyContinue' dotnet restore - dotnet build ArchiSteamFarm -c "$env:CONFIGURATION" -f "$env:TARGET_FRAMEWORK" -p:ContinuousIntegrationBuild=true -p:TargetLatestRuntimePatch=false -p:UseAppHost=false --no-restore --nologo + dotnet build ArchiSteamFarm -c "$env:CONFIGURATION" -p:ContinuousIntegrationBuild=true -p:TargetLatestRuntimePatch=false -p:UseAppHost=false --no-restore --nologo - name: Prepare ArchiSteamFarm.OfficialPlugins.SteamTokenDumper on Unix if: startsWith(matrix.os, 'macos-') || startsWith(matrix.os, 'ubuntu-') @@ -184,13 +176,12 @@ jobs: if: startsWith(matrix.os, 'macos-') || startsWith(matrix.os, 'ubuntu-') env: MAX_JOBS: 4 - TARGET_FRAMEWORK: ${{ (endsWith(matrix.variant, '-netf') && env.NET_FRAMEWORK_VERSION) || env.NET_CORE_VERSION }} shell: bash run: | set -euo pipefail publish() { - dotnet publish "$1" -c "$CONFIGURATION" -f "$TARGET_FRAMEWORK" -o "out/${1}/${TARGET_FRAMEWORK}" -p:ContinuousIntegrationBuild=true -p:TargetLatestRuntimePatch=false -p:UseAppHost=false --no-restore --nologo + dotnet publish "$1" -c "$CONFIGURATION" -o "out/${1}" -p:ContinuousIntegrationBuild=true -p:TargetLatestRuntimePatch=false -p:UseAppHost=false --no-restore --nologo } for plugin in $PLUGINS; do @@ -207,7 +198,6 @@ jobs: if: startsWith(matrix.os, 'windows-') env: MAX_JOBS: 4 - TARGET_FRAMEWORK: ${{ (endsWith(matrix.variant, '-netf') && env.NET_FRAMEWORK_VERSION) || env.NET_CORE_VERSION }} shell: pwsh run: | Set-StrictMode -Version Latest @@ -223,7 +213,7 @@ jobs: Set-Location "$env:GITHUB_WORKSPACE" - dotnet publish "$plugin" -c "$env:CONFIGURATION" -f "$env:TARGET_FRAMEWORK" -o "out\$plugin\$env:TARGET_FRAMEWORK" -p:ContinuousIntegrationBuild=true -p:TargetLatestRuntimePatch=false -p:UseAppHost=false --no-restore --nologo + dotnet publish "$plugin" -c "$env:CONFIGURATION" -o "out\$plugin" -p:ContinuousIntegrationBuild=true -p:TargetLatestRuntimePatch=false -p:UseAppHost=false --no-restore --nologo if ($LastExitCode -ne 0) { throw "Last command failed." @@ -248,7 +238,6 @@ jobs: - name: Publish ASF-${{ matrix.variant }} on Unix if: startsWith(matrix.os, 'macos-') || startsWith(matrix.os, 'ubuntu-') env: - TARGET_FRAMEWORK: ${{ (endsWith(matrix.variant, '-netf') && env.NET_FRAMEWORK_VERSION) || env.NET_CORE_VERSION }} VARIANT: ${{ matrix.variant }} shell: bash run: | @@ -260,13 +249,13 @@ jobs: variantArgs="-p:PublishSingleFile=true -p:PublishTrimmed=true -r $VARIANT --self-contained" fi - dotnet publish ArchiSteamFarm -c "$CONFIGURATION" -f "$TARGET_FRAMEWORK" -o "out/${VARIANT}" "-p:ASFVariant=${VARIANT}" -p:ContinuousIntegrationBuild=true --no-restore --nologo $variantArgs + dotnet publish ArchiSteamFarm -c "$CONFIGURATION" -o "out/${VARIANT}" "-p:ASFVariant=${VARIANT}" -p:ContinuousIntegrationBuild=true --no-restore --nologo $variantArgs # If we're including official plugins for this framework, copy them to output directory for plugin in $PLUGINS; do - if [ -d "out/${plugin}/${TARGET_FRAMEWORK}" ]; then + if [ -d "out/${plugin}" ]; then mkdir -p "out/${VARIANT}/plugins/${plugin}" - cp -pR "out/${plugin}/${TARGET_FRAMEWORK}/"* "out/${VARIANT}/plugins/${plugin}" + cp -pR "out/${plugin}/"* "out/${VARIANT}/plugins/${plugin}" fi done @@ -328,7 +317,6 @@ jobs: - name: Publish ASF-${{ matrix.variant }} on Windows if: startsWith(matrix.os, 'windows-') env: - TARGET_FRAMEWORK: ${{ (endsWith(matrix.variant, '-netf') && env.NET_FRAMEWORK_VERSION) || env.NET_CORE_VERSION }} VARIANT: ${{ matrix.variant }} shell: pwsh run: | @@ -342,7 +330,7 @@ jobs: $variantArgs = '-p:PublishSingleFile=true', '-p:PublishTrimmed=true', '-r', "$env:VARIANT", '--self-contained' } - dotnet publish ArchiSteamFarm -c "$env:CONFIGURATION" -f "$env:TARGET_FRAMEWORK" -o "out\$env:VARIANT" "-p:ASFVariant=$env:VARIANT" -p:ContinuousIntegrationBuild=true --no-restore --nologo $variantArgs + dotnet publish ArchiSteamFarm -c "$env:CONFIGURATION" -o "out\$env:VARIANT" "-p:ASFVariant=$env:VARIANT" -p:ContinuousIntegrationBuild=true --no-restore --nologo $variantArgs if ($LastExitCode -ne 0) { throw "Last command failed." @@ -350,12 +338,12 @@ jobs: # If we're including official plugins for this framework, copy them to output directory foreach ($plugin in $env:PLUGINS.Split([char[]] $null, [System.StringSplitOptions]::RemoveEmptyEntries)) { - if (Test-Path "out\$plugin\$env:TARGET_FRAMEWORK" -PathType Container) { + if (Test-Path "out\$plugin" -PathType Container) { if (!(Test-Path "out\$env:VARIANT\plugins\$plugin" -PathType Container)) { New-Item -ItemType Directory -Path "out\$env:VARIANT\plugins\$plugin" > $null } - Copy-Item "out\$plugin\$env:TARGET_FRAMEWORK\*" "out\$env:VARIANT\plugins\$plugin" -Recurse + Copy-Item "out\$plugin\*" "out\$env:VARIANT\plugins\$plugin" -Recurse } } @@ -430,12 +418,6 @@ jobs: name: ubuntu-latest_ASF-generic path: out - - name: Download ASF-generic-netf artifact from windows-latest - uses: actions/download-artifact@v3.0.2 - with: - name: windows-latest_ASF-generic-netf - path: out - - name: Download ASF-linux-arm artifact from ubuntu-latest uses: actions/download-artifact@v3.0.2 with: diff --git a/ArchiSteamFarm.CustomPlugins.ExamplePlugin/ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj b/ArchiSteamFarm.CustomPlugins.ExamplePlugin/ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj index 759c8bf96..e815540bf 100644 --- a/ArchiSteamFarm.CustomPlugins.ExamplePlugin/ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj +++ b/ArchiSteamFarm.CustomPlugins.ExamplePlugin/ArchiSteamFarm.CustomPlugins.ExamplePlugin.csproj @@ -11,13 +11,6 @@ - - - - - - - diff --git a/ArchiSteamFarm.CustomPlugins.PeriodicGC/ArchiSteamFarm.CustomPlugins.PeriodicGC.csproj b/ArchiSteamFarm.CustomPlugins.PeriodicGC/ArchiSteamFarm.CustomPlugins.PeriodicGC.csproj index 0d78c9416..537ab8005 100644 --- a/ArchiSteamFarm.CustomPlugins.PeriodicGC/ArchiSteamFarm.CustomPlugins.PeriodicGC.csproj +++ b/ArchiSteamFarm.CustomPlugins.PeriodicGC/ArchiSteamFarm.CustomPlugins.PeriodicGC.csproj @@ -9,11 +9,6 @@ - - - - - diff --git a/ArchiSteamFarm.CustomPlugins.SignInWithSteam/ArchiSteamFarm.CustomPlugins.SignInWithSteam.csproj b/ArchiSteamFarm.CustomPlugins.SignInWithSteam/ArchiSteamFarm.CustomPlugins.SignInWithSteam.csproj index eed290f6d..842515d4a 100644 --- a/ArchiSteamFarm.CustomPlugins.SignInWithSteam/ArchiSteamFarm.CustomPlugins.SignInWithSteam.csproj +++ b/ArchiSteamFarm.CustomPlugins.SignInWithSteam/ArchiSteamFarm.CustomPlugins.SignInWithSteam.csproj @@ -11,17 +11,6 @@ - - - - - - - - - - - diff --git a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/ArchiSteamFarm.OfficialPlugins.ItemsMatcher.csproj b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/ArchiSteamFarm.OfficialPlugins.ItemsMatcher.csproj index 06340d0b4..c8601cfc5 100644 --- a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/ArchiSteamFarm.OfficialPlugins.ItemsMatcher.csproj +++ b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/ArchiSteamFarm.OfficialPlugins.ItemsMatcher.csproj @@ -13,15 +13,6 @@ - - - - - - - - - diff --git a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs index 1e0e84182..7aab6bff1 100644 --- a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs +++ b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs @@ -342,8 +342,7 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Localization.Strings.ListingAnnouncing, Bot.SteamID, nickname ?? Bot.SteamID.ToString(CultureInfo.InvariantCulture), assetsForListing.Count)); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - BasicResponse? response = await Backend.AnnounceForListing(Bot.SteamID, WebBrowser, assetsForListing, acceptedMatchableTypes, (uint) inventory.Count, matchEverything, tradeToken!, nickname, avatarHash).ConfigureAwait(false); + BasicResponse? response = await Backend.AnnounceForListing(Bot.SteamID, WebBrowser, assetsForListing, acceptedMatchableTypes, (uint) inventory.Count, matchEverything, tradeToken, nickname, avatarHash).ConfigureAwait(false); if (response == null) { // This is actually a network failure, so we'll stop sending heartbeats but not record it as valid check @@ -383,12 +382,7 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { LastAnnouncement = DateTime.UtcNow.AddYears(1); return; -#if NETFRAMEWORK || NETSTANDARD - case (HttpStatusCode) 429: -#else case HttpStatusCode.TooManyRequests: -#endif - // ArchiNet told us to try again later LastAnnouncement = DateTime.UtcNow.AddDays(1); @@ -682,7 +676,6 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { return; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework (HttpStatusCode StatusCode, ImmutableHashSet Users)? response = await Backend.GetListedUsersForMatching(ASF.GlobalConfig.LicenseID.Value, Bot, WebBrowser, ourInventory.Values, acceptedMatchableTypes).ConfigureAwait(false); if (response == null) { diff --git a/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator.csproj b/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator.csproj index a330ad16e..d6a3bbc92 100644 --- a/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator.csproj +++ b/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator.csproj @@ -11,11 +11,6 @@ - - - - - diff --git a/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator/Commands.cs b/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator/Commands.cs index 4c193ddc4..0ae7d3089 100644 --- a/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator/Commands.cs +++ b/ArchiSteamFarm.OfficialPlugins.MobileAuthenticator/Commands.cs @@ -157,8 +157,7 @@ internal static class Commands { return bot.Commands.FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(mobileAuthenticator.GenerateTokenForTime))); } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - CTwoFactor_FinalizeAddAuthenticator_Response? response = await mobileAuthenticatorHandler.FinalizeAuthenticator(bot.SteamID, activationCode, code!, steamTime).ConfigureAwait(false); + CTwoFactor_FinalizeAddAuthenticator_Response? response = await mobileAuthenticatorHandler.FinalizeAuthenticator(bot.SteamID, activationCode, code, steamTime).ConfigureAwait(false); if (response == null) { return bot.Commands.FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(mobileAuthenticatorHandler.FinalizeAuthenticator))); diff --git a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.csproj b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.csproj index d196d6a70..fc7c1085d 100644 --- a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.csproj +++ b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper.csproj @@ -12,11 +12,6 @@ - - - - - diff --git a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SteamTokenDumperPlugin.cs b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SteamTokenDumperPlugin.cs index 85a324f34..8afde37c0 100644 --- a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SteamTokenDumperPlugin.cs +++ b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SteamTokenDumperPlugin.cs @@ -621,12 +621,7 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotC GlobalCache.Reset(true); break; -#if NETFRAMEWORK || NETSTANDARD - case (HttpStatusCode) 429: -#else case HttpStatusCode.TooManyRequests: -#endif - // SteamDB told us to try again later #pragma warning disable CA5394 // This call isn't used in a security-sensitive manner TimeSpan startIn = TimeSpan.FromMinutes(Random.Shared.Next(SharedInfo.MinimumMinutesBeforeFirstUpload, SharedInfo.MaximumMinutesBeforeFirstUpload)); diff --git a/ArchiSteamFarm/ArchiSteamFarm.csproj b/ArchiSteamFarm/ArchiSteamFarm.csproj index 18f51791e..43626d1ab 100644 --- a/ArchiSteamFarm/ArchiSteamFarm.csproj +++ b/ArchiSteamFarm/ArchiSteamFarm.csproj @@ -23,32 +23,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/ArchiSteamFarm/Core/ASF.cs b/ArchiSteamFarm/Core/ASF.cs index 6d96eb2bf..00fedf570 100644 --- a/ArchiSteamFarm/Core/ASF.cs +++ b/ArchiSteamFarm/Core/ASF.cs @@ -268,7 +268,7 @@ public static class ASF { } string targetFile = $"{SharedInfo.ASF}-{SharedInfo.BuildInfo.Variant}.zip"; - GitHub.ReleaseResponse.Asset? binaryAsset = releaseResponse.Assets.FirstOrDefault(asset => !string.IsNullOrEmpty(asset.Name) && asset.Name!.Equals(targetFile, StringComparison.OrdinalIgnoreCase)); + GitHub.ReleaseResponse.Asset? binaryAsset = releaseResponse.Assets.FirstOrDefault(asset => !string.IsNullOrEmpty(asset.Name) && asset.Name.Equals(targetFile, StringComparison.OrdinalIgnoreCase)); if (binaryAsset == null) { ArchiLogger.LogGenericWarning(Strings.ErrorUpdateNoAssetForThisVersion); @@ -298,7 +298,7 @@ public static class ASF { } if (!string.IsNullOrEmpty(releaseResponse.ChangelogPlainText)) { - ArchiLogger.LogGenericInfo(releaseResponse.ChangelogPlainText!); + ArchiLogger.LogGenericInfo(releaseResponse.ChangelogPlainText); } ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.UpdateDownloadingNewVersion, newVersion, binaryAsset.Size / 1024 / 1024)); @@ -310,7 +310,7 @@ public static class ASF { BinaryResponse? response; try { - response = await WebBrowser.UrlGetToBinary(binaryAsset.DownloadURL!, progressReporter: progressReporter).ConfigureAwait(false); + response = await WebBrowser.UrlGetToBinary(binaryAsset.DownloadURL, progressReporter: progressReporter).ConfigureAwait(false); } finally { progressReporter.ProgressChanged -= OnProgressChanged; } @@ -404,7 +404,6 @@ public static class ASF { private static HashSet GetLoadedAssembliesNames() { Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework return loadedAssemblies.Select(static loadedAssembly => loadedAssembly.FullName).Where(static name => !string.IsNullOrEmpty(name)).ToHashSet(StringComparer.Ordinal)!; } @@ -1018,10 +1017,8 @@ public static class ASF { return false; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!Directory.Exists(directory!)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - Directory.CreateDirectory(directory!); + if (!Directory.Exists(directory)) { + Directory.CreateDirectory(directory); } // We're not interested in extracting placeholder files (but we still want directories created for them, done above) diff --git a/ArchiSteamFarm/Core/GeneratedRegexes.cs b/ArchiSteamFarm/Core/GeneratedRegexes.cs index 3ed1bb476..8d5ed8d54 100644 --- a/ArchiSteamFarm/Core/GeneratedRegexes.cs +++ b/ArchiSteamFarm/Core/GeneratedRegexes.cs @@ -30,12 +30,6 @@ internal static partial class GeneratedRegexes { private const string DigitsPattern = @"\d+"; private const string NonAsciiPattern = @"[^\u0000-\u007F]+"; -#if NETFRAMEWORK || NETSTANDARD - internal static Regex CdKey() => new(CdKeyPattern, DefaultOptions); - internal static Regex Decimal() => new(DecimalPattern, DefaultOptions); - internal static Regex Digits() => new(DigitsPattern, DefaultOptions); - internal static Regex NonAscii() => new(NonAsciiPattern, DefaultOptions); -#else [GeneratedRegex(CdKeyPattern, DefaultOptions)] internal static partial Regex CdKey(); @@ -47,5 +41,4 @@ internal static partial class GeneratedRegexes { [GeneratedRegex(NonAsciiPattern, DefaultOptions)] internal static partial Regex NonAscii(); -#endif } diff --git a/ArchiSteamFarm/Core/NativeMethods.cs b/ArchiSteamFarm/Core/NativeMethods.cs index d8f08219b..58c369908 100644 --- a/ArchiSteamFarm/Core/NativeMethods.cs +++ b/ArchiSteamFarm/Core/NativeMethods.cs @@ -29,67 +29,37 @@ internal static partial class NativeMethods { [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] [SupportedOSPlatform("Windows")] [return: MarshalAs(UnmanagedType.Bool)] -#if NETFRAMEWORK || NETSTANDARD - [DllImport("kernel32.dll")] - internal static extern bool GetConsoleMode(nint hConsoleHandle, out EConsoleMode lpMode); -#else [LibraryImport("kernel32.dll")] internal static partial bool GetConsoleMode(nint hConsoleHandle, out EConsoleMode lpMode); -#endif [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] [SupportedOSPlatform("FreeBSD")] [SupportedOSPlatform("Linux")] [SupportedOSPlatform("MacOS")] -#if NETFRAMEWORK || NETSTANDARD - [DllImport("libc", EntryPoint = "geteuid", SetLastError = true)] - internal static extern uint GetEuid(); -#else [LibraryImport("libc", EntryPoint = "geteuid", SetLastError = true)] internal static partial uint GetEuid(); -#endif [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] [SupportedOSPlatform("Windows")] -#if NETFRAMEWORK || NETSTANDARD - [DllImport("kernel32.dll")] - internal static extern nint GetStdHandle(EStandardHandle nStdHandle); -#else [LibraryImport("kernel32.dll")] internal static partial nint GetStdHandle(EStandardHandle nStdHandle); -#endif [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] [SupportedOSPlatform("Windows")] [return: MarshalAs(UnmanagedType.Bool)] -#if NETFRAMEWORK || NETSTANDARD - [DllImport("kernel32.dll")] - internal static extern bool SetConsoleMode(nint hConsoleHandle, EConsoleMode dwMode); -#else [LibraryImport("kernel32.dll")] internal static partial bool SetConsoleMode(nint hConsoleHandle, EConsoleMode dwMode); -#endif [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] [SupportedOSPlatform("Windows")] -#if NETFRAMEWORK || NETSTANDARD - [DllImport("kernel32.dll")] - internal static extern EExecutionState SetThreadExecutionState(EExecutionState executionState); -#else [LibraryImport("kernel32.dll")] internal static partial EExecutionState SetThreadExecutionState(EExecutionState executionState); -#endif [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] [SupportedOSPlatform("Windows")] [return: MarshalAs(UnmanagedType.Bool)] -#if NETFRAMEWORK || NETSTANDARD - [DllImport("user32.dll")] - internal static extern void ShowWindow(nint hWnd, EShowWindow nCmdShow); -#else [LibraryImport("user32.dll")] internal static partial void ShowWindow(nint hWnd, EShowWindow nCmdShow); -#endif [Flags] [SupportedOSPlatform("Windows")] diff --git a/ArchiSteamFarm/Core/OS.cs b/ArchiSteamFarm/Core/OS.cs index a4d5f2ff2..c91708a82 100644 --- a/ArchiSteamFarm/Core/OS.cs +++ b/ArchiSteamFarm/Core/OS.cs @@ -43,22 +43,17 @@ internal static class OS { internal static readonly string ProcessFileName = Environment.ProcessPath ?? throw new InvalidOperationException(nameof(ProcessFileName)); internal static DateTime ProcessStartTime { -#if NETFRAMEWORK || NETSTANDARD - get => RuntimeMadness.ProcessStartTime.ToUniversalTime(); -#else get { using Process process = Process.GetCurrentProcess(); return process.StartTime.ToUniversalTime(); } -#endif } internal static string Version { get { if (!string.IsNullOrEmpty(BackingVersion)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - return BackingVersion!; + return BackingVersion; } string framework = RuntimeInformation.FrameworkDescription.Trim(); @@ -67,15 +62,11 @@ internal static class OS { framework = "Unknown Framework"; } -#if NETFRAMEWORK || NETSTANDARD - string runtime = RuntimeInformation.OSArchitecture.ToString(); -#else string runtime = RuntimeInformation.RuntimeIdentifier.Trim(); if (runtime.Length == 0) { runtime = "Unknown Runtime"; } -#endif string description = RuntimeInformation.OSDescription.Trim(); @@ -210,38 +201,6 @@ internal static class OS { return true; } - if (SharedInfo.BuildInfo.Variant.EndsWith("-netf", StringComparison.Ordinal)) { -#if NETFRAMEWORK || NETSTANDARD - // All Windows variants (7+) have valid .NET Core build - if (OperatingSystem.IsWindows()) { - return false; - } - - // Non-Windows variants of generic-netf are supported only in Mono - if (!RuntimeMadness.IsRunningOnMono) { - return false; - } - - // Platforms not supported by .NET Core - return RuntimeInformation.OSArchitecture switch { - // Sadly we can't tell a difference between ARMv6 and ARMv7 reliably, we'll believe that this linux-arm user knows what he's doing and he's indeed in need of generic-netf on ARMv6 - Architecture.Arm => true, - - // Apart from real x86, this also covers all unknown architectures, such as sparc, ppc64, and anything else Mono might support, we're fine with that - Architecture.X86 => true, - - // Everything else is covered by .NET Core - _ => false - }; -#else - - // .NET Framework build running on .NET Core? Very funny - only if somebody lied during build process - ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.WarningUnknownValuePleaseReport, nameof(SharedInfo.BuildInfo.Variant), SharedInfo.BuildInfo.Variant)); - - return false; -#endif - } - if (SharedInfo.BuildInfo.Variant == "generic") { // Generic is supported everywhere return true; diff --git a/ArchiSteamFarm/Core/Utilities.cs b/ArchiSteamFarm/Core/Utilities.cs index e0d84d4a4..1b0f8b6da 100644 --- a/ArchiSteamFarm/Core/Utilities.cs +++ b/ArchiSteamFarm/Core/Utilities.cs @@ -81,11 +81,7 @@ public static class Utilities { CookieCollection cookies = cookieContainer.GetCookies(uri); -#if NETFRAMEWORK || NETSTANDARD - return cookies.Count > 0 ? (from Cookie cookie in cookies where cookie.Name == name select cookie.Value).FirstOrDefault() : null; -#else return cookies.Count > 0 ? cookies.FirstOrDefault(cookie => cookie.Name == name)?.Value : null; -#endif } [PublicAPI] diff --git a/ArchiSteamFarm/Helpers/CrossProcessFileBasedSemaphore.cs b/ArchiSteamFarm/Helpers/CrossProcessFileBasedSemaphore.cs index a39fccbe0..900b16ae7 100644 --- a/ArchiSteamFarm/Helpers/CrossProcessFileBasedSemaphore.cs +++ b/ArchiSteamFarm/Helpers/CrossProcessFileBasedSemaphore.cs @@ -173,10 +173,8 @@ internal sealed class CrossProcessFileBasedSemaphore : IAsyncDisposable, ICrossP return; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!Directory.Exists(directoryPath!)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - DirectoryInfo directoryInfo = Directory.CreateDirectory(directoryPath!); + if (!Directory.Exists(directoryPath)) { + DirectoryInfo directoryInfo = Directory.CreateDirectory(directoryPath); if (OperatingSystem.IsWindows()) { try { diff --git a/ArchiSteamFarm/Helpers/SerializableFile.cs b/ArchiSteamFarm/Helpers/SerializableFile.cs index bde253596..8ae18a42b 100644 --- a/ArchiSteamFarm/Helpers/SerializableFile.cs +++ b/ArchiSteamFarm/Helpers/SerializableFile.cs @@ -81,11 +81,15 @@ public abstract class SerializableFile : IDisposable { string json = JsonConvert.SerializeObject(this, Debugging.IsUserDebugging ? Formatting.Indented : Formatting.None); + if (string.IsNullOrEmpty(json)) { + throw new InvalidOperationException(nameof(json)); + } + // We always want to write entire content to temporary file first, in order to never load corrupted data, also when target file doesn't exist string newFilePath = $"{FilePath}.new"; if (File.Exists(FilePath)) { - string currentJson = await File.ReadAllTextAsync(FilePath!).ConfigureAwait(false); + string currentJson = await File.ReadAllTextAsync(FilePath).ConfigureAwait(false); if (json == currentJson) { return; @@ -93,11 +97,11 @@ public abstract class SerializableFile : IDisposable { await File.WriteAllTextAsync(newFilePath, json).ConfigureAwait(false); - File.Replace(newFilePath, FilePath!, null); + File.Replace(newFilePath, FilePath, null); } else { await File.WriteAllTextAsync(newFilePath, json).ConfigureAwait(false); - File.Move(newFilePath, FilePath!); + File.Move(newFilePath, FilePath); } } catch (Exception e) { ASF.ArchiLogger.LogGenericException(e); @@ -125,8 +129,13 @@ public abstract class SerializableFile : IDisposable { } internal static async Task Write(string filePath, string json) { - ArgumentException.ThrowIfNullOrEmpty(filePath); - ArgumentException.ThrowIfNullOrEmpty(json); + if (string.IsNullOrEmpty(filePath)) { + throw new ArgumentNullException(nameof(filePath)); + } + + if (string.IsNullOrEmpty(json)) { + throw new ArgumentNullException(nameof(json)); + } string newFilePath = $"{filePath}.new"; diff --git a/ArchiSteamFarm/IPC/ArchiKestrel.cs b/ArchiSteamFarm/IPC/ArchiKestrel.cs index 0bf203085..be9ed535b 100644 --- a/ArchiSteamFarm/IPC/ArchiKestrel.cs +++ b/ArchiSteamFarm/IPC/ArchiKestrel.cs @@ -19,10 +19,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#if NETFRAMEWORK || NETSTANDARD -using IHost = Microsoft.AspNetCore.Hosting.IWebHost; -using HostBuilder = Microsoft.AspNetCore.Hosting.WebHostBuilder; -#endif using System; using System.IO; using System.Threading.Tasks; diff --git a/ArchiSteamFarm/IPC/Controllers/Api/ASFController.cs b/ArchiSteamFarm/IPC/Controllers/Api/ASFController.cs index 8ce9bb533..539b84e47 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/ASFController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/ASFController.cs @@ -186,6 +186,6 @@ public sealed class ASFController : ArchiController { message = success ? Strings.Success : Strings.WarningFailed; } - return Ok(new GenericResponse(success, message!, version?.ToString())); + return Ok(new GenericResponse(success, message, version?.ToString())); } } diff --git a/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs b/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs index 0ed186635..47d3dec41 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs @@ -62,10 +62,8 @@ public sealed class CommandController : ArchiController { string command = request.Command; string? commandPrefix = ASF.GlobalConfig != null ? ASF.GlobalConfig.CommandPrefix : GlobalConfig.DefaultCommandPrefix; - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!string.IsNullOrEmpty(commandPrefix) && command.StartsWith(commandPrefix!, StringComparison.Ordinal)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (command.Length == commandPrefix!.Length) { + if (!string.IsNullOrEmpty(commandPrefix) && command.StartsWith(commandPrefix, StringComparison.Ordinal)) { + if (command.Length == commandPrefix.Length) { // If the message starts with command prefix and is of the same length as command prefix, then it's just empty command trigger, useless return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(command)))); } diff --git a/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs b/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs index 59d3ccce4..0313224e8 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs @@ -96,7 +96,7 @@ public sealed class NLogController : ArchiController { } if (!HttpContext.WebSockets.IsWebSocketRequest) { - return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError!, $"{nameof(HttpContext.WebSockets.IsWebSocketRequest)}: {HttpContext.WebSockets.IsWebSocketRequest}"))); + return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(HttpContext.WebSockets.IsWebSocketRequest)}: {HttpContext.WebSockets.IsWebSocketRequest}"))); } // From now on we can return only EmptyResult as the response stream is already being used by existing websocket connection diff --git a/ArchiSteamFarm/IPC/Controllers/Api/TypeController.cs b/ArchiSteamFarm/IPC/Controllers/Api/TypeController.cs index 942d847c5..d66cb3005 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/TypeController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/TypeController.cs @@ -67,8 +67,7 @@ public sealed class TypeController : ArchiController { string? unifiedName = field.FieldType.GetUnifiedName(); if (!string.IsNullOrEmpty(unifiedName)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - body[jsonProperty.PropertyName ?? field.Name] = unifiedName!; + body[jsonProperty.PropertyName ?? field.Name] = unifiedName; } } } @@ -80,8 +79,7 @@ public sealed class TypeController : ArchiController { string? unifiedName = property.PropertyType.GetUnifiedName(); if (!string.IsNullOrEmpty(unifiedName)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - body[jsonProperty.PropertyName ?? property.Name] = unifiedName!; + body[jsonProperty.PropertyName ?? property.Name] = unifiedName; } } } @@ -104,10 +102,7 @@ public sealed class TypeController : ArchiController { continue; } - // ReSharper disable RedundantSuppressNullableWarningExpression - required for .NET Framework - body[valueText!] = valueObjText!; - - // ReSharper restore RedundantSuppressNullableWarningExpression - required for .NET Framework + body[valueText] = valueObjText; } } diff --git a/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs b/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs index 5f242eab1..3513e2102 100644 --- a/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs +++ b/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs @@ -19,9 +19,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#if NETFRAMEWORK || NETSTANDARD -using MvcNewtonsoftJsonOptions = Microsoft.AspNetCore.Mvc.MvcJsonOptions; -#endif using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/ArchiSteamFarm/IPC/Responses/GenericResponse.cs b/ArchiSteamFarm/IPC/Responses/GenericResponse.cs index 409ff9182..9a86557a2 100644 --- a/ArchiSteamFarm/IPC/Responses/GenericResponse.cs +++ b/ArchiSteamFarm/IPC/Responses/GenericResponse.cs @@ -63,9 +63,7 @@ public class GenericResponse { public GenericResponse(bool success, string? message = null) { Success = success; - - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - Message = !string.IsNullOrEmpty(message) ? message! : success ? "OK" : Strings.WarningFailed; + Message = !string.IsNullOrEmpty(message) ? message : success ? "OK" : Strings.WarningFailed; } [JsonConstructor] diff --git a/ArchiSteamFarm/IPC/Startup.cs b/ArchiSteamFarm/IPC/Startup.cs index 041aa5519..073251172 100644 --- a/ArchiSteamFarm/IPC/Startup.cs +++ b/ArchiSteamFarm/IPC/Startup.cs @@ -19,12 +19,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#if NETFRAMEWORK || NETSTANDARD -using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json.Converters; -using IWebHostEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment; -using IMvcBuilder = Microsoft.Extensions.DependencyInjection.IMvcCoreBuilder; -#endif using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -126,8 +120,7 @@ internal sealed class Startup { continue; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - physicalPath = Path.Combine(assemblyDirectory!, plugin.PhysicalPath); + physicalPath = Path.Combine(assemblyDirectory, plugin.PhysicalPath); } if (!Directory.Exists(physicalPath)) { @@ -162,9 +155,7 @@ internal sealed class Startup { ); // Use routing for our API controllers, this should be called once we're done with all the static files mess -#if !NETFRAMEWORK && !NETSTANDARD app.UseRouting(); -#endif // We want to protect our API with IPCPassword and additional security, this should be called after routing, so the middleware won't have to deal with API endpoints that do not exist app.UseWhen(static context => context.Request.Path.StartsWithSegments("/Api", StringComparison.OrdinalIgnoreCase), static appBuilder => appBuilder.UseMiddleware()); @@ -181,11 +172,7 @@ internal sealed class Startup { app.UseWebSockets(); // Finally register proper API endpoints once we're done with routing -#if NETFRAMEWORK || NETSTANDARD - app.UseMvcWithDefaultRoute(); -#else app.UseEndpoints(static endpoints => endpoints.MapControllers()); -#endif // Add support for swagger, responsible for automatic API documentation generation, this should be on the end, once we're done with API app.UseSwagger(); @@ -341,17 +328,6 @@ internal sealed class Startup { mvc.AddControllersAsServices(); -#if NETFRAMEWORK || NETSTANDARD - // Use latest compatibility version for MVC - mvc.SetCompatibilityVersion(CompatibilityVersion.Latest); - - // Add standard formatters - mvc.AddFormatterMappings(); - - // Add API explorer for swagger - mvc.AddApiExplorer(); -#endif - mvc.AddNewtonsoftJson( static options => { // Fix default contract resolver to use original names and not a camel case @@ -360,11 +336,6 @@ internal sealed class Startup { if (Debugging.IsUserDebugging) { options.SerializerSettings.Formatting = Formatting.Indented; } - -#if NETFRAMEWORK || NETSTANDARD - // .NET Framework serializes Version as object by default, serialize it as string just like .NET Core - options.SerializerSettings.Converters.Add(new VersionConverter()); -#endif } ); } diff --git a/ArchiSteamFarm/IPC/WebUtilities.cs b/ArchiSteamFarm/IPC/WebUtilities.cs index 406dbed9f..f762be6dd 100644 --- a/ArchiSteamFarm/IPC/WebUtilities.cs +++ b/ArchiSteamFarm/IPC/WebUtilities.cs @@ -19,10 +19,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#if NETFRAMEWORK || NETSTANDARD -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.DependencyInjection; -#endif using System; using System.Diagnostics.CodeAnalysis; using System.IO; @@ -35,26 +31,6 @@ using Newtonsoft.Json; namespace ArchiSteamFarm.IPC; internal static class WebUtilities { -#if NETFRAMEWORK || NETSTANDARD - internal static IMvcCoreBuilder AddControllers(this IServiceCollection services) { - ArgumentNullException.ThrowIfNull(services); - - return services.AddMvcCore(); - } - - internal static IMvcCoreBuilder AddNewtonsoftJson(this IMvcCoreBuilder mvc, Action setupAction) { - ArgumentNullException.ThrowIfNull(mvc); - ArgumentNullException.ThrowIfNull(setupAction); - - // Add JSON formatters that will be used as default ones if no specific formatters are asked for - mvc.AddJsonFormatters(); - - mvc.AddJsonOptions(setupAction); - - return mvc; - } -#endif - internal static string? GetUnifiedName(this Type type) { ArgumentNullException.ThrowIfNull(type); diff --git a/ArchiSteamFarm/NLog/Logging.cs b/ArchiSteamFarm/NLog/Logging.cs index 89495e723..a71c37cf4 100644 --- a/ArchiSteamFarm/NLog/Logging.cs +++ b/ArchiSteamFarm/NLog/Logging.cs @@ -106,8 +106,7 @@ internal static class Logging { Console.Write(Bot.FormatBotResponse(Strings.UserInputDeviceConfirmation, botName)); result = ConsoleReadLine(); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (string.IsNullOrEmpty(result) || result!.Equals("Y", StringComparison.OrdinalIgnoreCase) || result.Equals("N", StringComparison.OrdinalIgnoreCase)) { + if (string.IsNullOrEmpty(result) || result.Equals("Y", StringComparison.OrdinalIgnoreCase) || result.Equals("N", StringComparison.OrdinalIgnoreCase)) { break; } } @@ -159,8 +158,7 @@ internal static class Logging { ConsoleSemaphore.Release(); } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - return !string.IsNullOrEmpty(result) ? result!.Trim() : null; + return !string.IsNullOrEmpty(result) ? result.Trim() : null; } internal static void InitCoreLoggers(bool uniqueInstance) { @@ -383,12 +381,8 @@ internal static class Logging { string? commandPrefix = ASF.GlobalConfig != null ? ASF.GlobalConfig.CommandPrefix : GlobalConfig.DefaultCommandPrefix; - // ReSharper disable RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!string.IsNullOrEmpty(commandPrefix) && command!.StartsWith(commandPrefix!, StringComparison.Ordinal)) { - // ReSharper restore RedundantSuppressNullableWarningExpression - required for .NET Framework - - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (command.Length == commandPrefix!.Length) { + if (!string.IsNullOrEmpty(commandPrefix) && command.StartsWith(commandPrefix, StringComparison.Ordinal)) { + if (command.Length == commandPrefix.Length) { // If the message starts with command prefix and is of the same length as command prefix, then it's just empty command trigger, useless continue; } @@ -406,8 +400,7 @@ internal static class Logging { Console.WriteLine($@"<> {Strings.Executing}"); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - string? response = await targetBot.Commands.Response(EAccess.Owner, command!).ConfigureAwait(false); + string? response = await targetBot.Commands.Response(EAccess.Owner, command).ConfigureAwait(false); if (string.IsNullOrEmpty(response)) { ASF.ArchiLogger.LogNullError(response); diff --git a/ArchiSteamFarm/NLog/Targets/SteamTarget.cs b/ArchiSteamFarm/NLog/Targets/SteamTarget.cs index 42d259bb4..ecd744e65 100644 --- a/ArchiSteamFarm/NLog/Targets/SteamTarget.cs +++ b/ArchiSteamFarm/NLog/Targets/SteamTarget.cs @@ -78,8 +78,7 @@ internal sealed class SteamTarget : AsyncTaskTarget { string? botName = BotName?.Render(logEvent); if (!string.IsNullOrEmpty(botName)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - bot = Bot.GetBot(botName!); + bot = Bot.GetBot(botName); if (bot?.IsConnectedAndLoggedOn != true) { return; diff --git a/ArchiSteamFarm/Plugins/PluginsCore.cs b/ArchiSteamFarm/Plugins/PluginsCore.cs index 20aac09de..bdb7b465c 100644 --- a/ArchiSteamFarm/Plugins/PluginsCore.cs +++ b/ArchiSteamFarm/Plugins/PluginsCore.cs @@ -66,10 +66,9 @@ public static class PluginsCore { // At the same time it'd be the best if we avoided all special characters, such as '/' found e.g. in base64, as we can't be sure that it's not a prohibited character in regards to native OS implementation // Because of that, SHA256 is sufficient for our case, as it generates alphanumeric characters only, and is barely 256-bit long. We don't need any kind of complex cryptography or collision detection here, any hashing will do, and the shorter the better if (!string.IsNullOrEmpty(Program.NetworkGroup)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - objectName += $"-{Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(Program.NetworkGroup!)))}"; + objectName += $"-{Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(Program.NetworkGroup)))}"; } else if (!string.IsNullOrEmpty(ASF.GlobalConfig.WebProxyText)) { - objectName += $"-{Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(ASF.GlobalConfig.WebProxyText!)))}"; + objectName += $"-{Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(ASF.GlobalConfig.WebProxyText)))}"; } string resourceName = OS.GetOsResourceName(objectName); diff --git a/ArchiSteamFarm/Program.cs b/ArchiSteamFarm/Program.cs index 1b8fe4355..749adb96f 100644 --- a/ArchiSteamFarm/Program.cs +++ b/ArchiSteamFarm/Program.cs @@ -26,6 +26,7 @@ using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; +using System.Net.Quic; using System.Reflection; using System.Runtime.InteropServices; using System.Text; @@ -42,9 +43,6 @@ using ArchiSteamFarm.Web; using Newtonsoft.Json; using NLog; using SteamKit2; -#if !NETFRAMEWORK && !NETSTANDARD -using System.Net.Quic; -#endif namespace ArchiSteamFarm; @@ -58,15 +56,9 @@ internal static class Program { internal static bool ShutdownSequenceInitialized { get; private set; } internal static bool SteamParentalGeneration { get; private set; } = true; -#if !NETFRAMEWORK && !NETSTANDARD private static readonly Dictionary RegisteredPosixSignals = new(); -#endif - private static readonly TaskCompletionSource ShutdownResetEvent = new(); - -#if !NETFRAMEWORK && !NETSTANDARD private static readonly ImmutableHashSet SupportedPosixSignals = ImmutableHashSet.Create(PosixSignal.SIGINT, PosixSignal.SIGTERM); -#endif private static bool IgnoreUnsupportedEnvironment; private static bool InputCryptkeyManually; @@ -182,15 +174,11 @@ internal static class Program { AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; TaskScheduler.UnobservedTaskException += OnUnobservedTaskException; -#if NETFRAMEWORK || NETSTANDARD - RuntimeMadness.Initialize(); -#else if (OperatingSystem.IsFreeBSD() || OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { foreach (PosixSignal signal in SupportedPosixSignals) { RegisteredPosixSignals[signal] = PosixSignalRegistration.Create(signal, OnPosixSignal); } } -#endif Console.CancelKeyPress += OnCancelKeyPress; @@ -304,8 +292,7 @@ internal static class Program { string? copyright = Assembly.GetExecutingAssembly().GetCustomAttribute()?.Copyright; if (!string.IsNullOrEmpty(copyright)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - ASF.ArchiLogger.LogGenericInfo(copyright!); + ASF.ArchiLogger.LogGenericInfo(copyright); } if (IgnoreUnsupportedEnvironment) { @@ -333,8 +320,7 @@ internal static class Program { return false; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - ArchiCryptoHelper.SetEncryptionKey(cryptkey!); + ArchiCryptoHelper.SetEncryptionKey(cryptkey); } if (!Directory.Exists(SharedInfo.ConfigDirectory)) { @@ -378,7 +364,7 @@ internal static class Program { if (!string.IsNullOrEmpty(globalConfig.CurrentCulture)) { try { // GetCultureInfo() would be better but we can't use it for specifying neutral cultures such as "en" - CultureInfo culture = CultureInfo.CreateSpecificCulture(globalConfig.CurrentCulture!); + CultureInfo culture = CultureInfo.CreateSpecificCulture(globalConfig.CurrentCulture); CultureInfo.DefaultThreadCurrentCulture = CultureInfo.DefaultThreadCurrentUICulture = culture; } catch (Exception e) { ASF.ArchiLogger.LogGenericWarningException(e); @@ -393,8 +379,7 @@ internal static class Program { if (!string.IsNullOrEmpty(latestJson)) { ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.AutomaticFileMigration, globalConfigFile)); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - await SerializableFile.Write(globalConfigFile, latestJson!).ConfigureAwait(false); + await SerializableFile.Write(globalConfigFile, latestJson).ConfigureAwait(false); ASF.ArchiLogger.LogGenericInfo(Strings.Done); } @@ -477,7 +462,6 @@ internal static class Program { ShutdownSequenceInitialized = true; -#if !NETFRAMEWORK && !NETSTANDARD if (OperatingSystem.IsFreeBSD() || OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { // Unregister from registered signals foreach (PosixSignalRegistration registration in RegisteredPosixSignals.Values) { @@ -486,7 +470,6 @@ internal static class Program { RegisteredPosixSignals.Clear(); } -#endif // Sockets created by IPC might still be running for a short while after complete app shutdown // Ensure that IPC is stopped before we finalize shutdown sequence @@ -522,7 +505,6 @@ internal static class Program { private static async void OnCancelKeyPress(object? sender, ConsoleCancelEventArgs e) => await Exit(130).ConfigureAwait(false); -#if !NETFRAMEWORK && !NETSTANDARD private static async void OnPosixSignal(PosixSignalContext signal) { ArgumentNullException.ThrowIfNull(signal); @@ -539,7 +521,6 @@ internal static class Program { throw new InvalidOperationException(nameof(signal.Signal)); } } -#endif private static async void OnProcessExit(object? sender, EventArgs e) => await Shutdown().ConfigureAwait(false); @@ -695,15 +676,13 @@ internal static class Program { string? envCryptKey = Environment.GetEnvironmentVariable(SharedInfo.EnvironmentVariableCryptKey); if (!string.IsNullOrEmpty(envCryptKey)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - HandleCryptKeyArgument(envCryptKey!); + HandleCryptKeyArgument(envCryptKey); } string? envCryptKeyFile = Environment.GetEnvironmentVariable(SharedInfo.EnvironmentVariableCryptKeyFile); if (!string.IsNullOrEmpty(envCryptKeyFile)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!await HandleCryptKeyFileArgument(envCryptKeyFile!).ConfigureAwait(false)) { + if (!await HandleCryptKeyFileArgument(envCryptKeyFile).ConfigureAwait(false)) { return false; } } @@ -711,15 +690,13 @@ internal static class Program { string? envNetworkGroup = Environment.GetEnvironmentVariable(SharedInfo.EnvironmentVariableNetworkGroup); if (!string.IsNullOrEmpty(envNetworkGroup)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - HandleNetworkGroupArgument(envNetworkGroup!); + HandleNetworkGroupArgument(envNetworkGroup); } string? envPath = Environment.GetEnvironmentVariable(SharedInfo.EnvironmentVariablePath); if (!string.IsNullOrEmpty(envPath)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!HandlePathArgument(envPath!)) { + if (!HandlePathArgument(envPath)) { return false; } } diff --git a/ArchiSteamFarm/SharedInfo.cs b/ArchiSteamFarm/SharedInfo.cs index 87acc0132..275878d0e 100644 --- a/ArchiSteamFarm/SharedInfo.cs +++ b/ArchiSteamFarm/SharedInfo.cs @@ -80,8 +80,7 @@ public static class SharedInfo { internal static string HomeDirectory { get { if (!string.IsNullOrEmpty(CachedHomeDirectory)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - return CachedHomeDirectory!; + return CachedHomeDirectory; } // We're aiming to handle two possible cases here, classic publish and single-file publish which is possible with OS-specific builds @@ -110,9 +109,6 @@ public static class SharedInfo { #elif ASF_VARIANT_GENERIC internal static bool CanUpdate => true; internal static string Variant => "generic"; -#elif ASF_VARIANT_GENERIC_NETF - internal static bool CanUpdate => true; - internal static string Variant => "generic-netf"; #elif ASF_VARIANT_LINUX_ARM internal static bool CanUpdate => true; internal static string Variant => "linux-arm"; diff --git a/ArchiSteamFarm/Steam/Bot.cs b/ArchiSteamFarm/Steam/Bot.cs index c4fd04b4d..b72acddbd 100644 --- a/ArchiSteamFarm/Steam/Bot.cs +++ b/ArchiSteamFarm/Steam/Bot.cs @@ -270,8 +270,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { return; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - JwtSecurityToken? jwtToken = Utilities.ReadJwtToken(value!); + JwtSecurityToken? jwtToken = Utilities.ReadJwtToken(value); if (jwtToken == null) { return; @@ -1124,7 +1123,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { break; } - if (packageData.ProhibitRunInCountries.Contains(IPCountryCode!)) { + if (packageData.ProhibitRunInCountries.Contains(IPCountryCode)) { // We are restricted by this package, we can only be saved by another package that is not restricted DateTime regionRestrictedUntilPackage = ownedPackageData.TimeCreated.AddMonths(RegionRestrictionPlayableBlockMonths); @@ -1195,8 +1194,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { if (!string.IsNullOrEmpty(releaseState)) { // We must convert this to uppercase, since Valve doesn't stick to any convention and we can have a case mismatch - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - switch (releaseState!.ToUpperInvariant()) { + switch (releaseState.ToUpperInvariant()) { case "RELEASED": break; case "PRELOADONLY" or "PRERELEASE": @@ -1215,8 +1213,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { } // We must convert this to uppercase, since Valve doesn't stick to any convention and we can have a case mismatch - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - switch (type!.ToUpperInvariant()) { + switch (type.ToUpperInvariant()) { case "APPLICATION" or "EPISODE" or "GAME" or "MOD" or "MOVIE" or "SERIES" or "TOOL" or "VIDEO": // Types that can be idled return (appID, DateTime.MinValue, true); @@ -1239,8 +1236,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { return (appID, DateTime.MinValue, true); } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - string[] dlcAppIDsTexts = listOfDlc!.Split(SharedInfo.ListElementSeparators, StringSplitOptions.RemoveEmptyEntries); + string[] dlcAppIDsTexts = listOfDlc.Split(SharedInfo.ListElementSeparators, StringSplitOptions.RemoveEmptyEntries); foreach (string dlcAppIDsText in dlcAppIDsTexts) { if (!uint.TryParse(dlcAppIDsText, out uint dlcAppID) || (dlcAppID == 0)) { @@ -1267,8 +1263,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { return null; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!string.IsNullOrEmpty(ASF.GlobalConfig?.DefaultBot) && Bots.TryGetValue(ASF.GlobalConfig!.DefaultBot!, out Bot? targetBot)) { + if (!string.IsNullOrEmpty(ASF.GlobalConfig?.DefaultBot) && Bots.TryGetValue(ASF.GlobalConfig.DefaultBot, out Bot? targetBot)) { return targetBot; } @@ -1350,8 +1345,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { string? prohibitRunInCountriesText = productInfo.KeyValues["extended"]["prohibitrunincountries"].AsString(); if (!string.IsNullOrEmpty(prohibitRunInCountriesText)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - prohibitRunInCountries = prohibitRunInCountriesText!.Split(' ', StringSplitOptions.RemoveEmptyEntries); + prohibitRunInCountries = prohibitRunInCountriesText.Split(' ', StringSplitOptions.RemoveEmptyEntries); } result[productInfo.ID] = new PackageData(changeNumber, validUntil, appIDs?.ToImmutableHashSet(), prohibitRunInCountries?.ToImmutableHashSet(StringComparer.Ordinal)); @@ -1390,7 +1384,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { string? gameName = null; if (!string.IsNullOrEmpty(BotConfig.CustomGamePlayedWhileFarming)) { - gameName = string.Format(CultureInfo.CurrentCulture, BotConfig.CustomGamePlayedWhileFarming!, game.AppID, game.GameName); + gameName = string.Format(CultureInfo.CurrentCulture, BotConfig.CustomGamePlayedWhileFarming, game.AppID, game.GameName); } await ArchiHandler.PlayGames(new HashSet(1) { game.PlayableAppID }, gameName).ConfigureAwait(false); @@ -1404,7 +1398,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { string? gameName = null; if (!string.IsNullOrEmpty(BotConfig.CustomGamePlayedWhileFarming)) { - gameName = string.Format(CultureInfo.CurrentCulture, BotConfig.CustomGamePlayedWhileFarming!, string.Join(", ", games.Select(static game => game.AppID)), string.Join(", ", games.Select(static game => game.GameName))); + gameName = string.Format(CultureInfo.CurrentCulture, BotConfig.CustomGamePlayedWhileFarming, string.Join(", ", games.Select(static game => game.AppID)), string.Join(", ", games.Select(static game => game.GameName))); } await ArchiHandler.PlayGames(games.Select(static game => game.PlayableAppID).ToHashSet(), gameName).ConfigureAwait(false); @@ -1570,7 +1564,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { if (!force && !string.IsNullOrEmpty(AccessToken) && AccessTokenValidUntil.HasValue && (AccessTokenValidUntil.Value > now.AddMinutes(MinimumAccessTokenValidityMinutes))) { // We can use the tokens we already have - if (await ArchiWebHandler.Init(SteamID, SteamClient.Universe, AccessToken!, SteamParentalActive ? BotConfig.SteamParentalCode : null).ConfigureAwait(false)) { + if (await ArchiWebHandler.Init(SteamID, SteamClient.Universe, AccessToken, SteamParentalActive ? BotConfig.SteamParentalCode : null).ConfigureAwait(false)) { InitRefreshTokensTimer(AccessTokenValidUntil.Value); return true; @@ -1590,7 +1584,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { AccessTokenGenerateResult response; try { - response = await SteamClient.Authentication.GenerateAccessTokenForAppAsync(SteamID, RefreshToken!, true).ConfigureAwait(false); + response = await SteamClient.Authentication.GenerateAccessTokenForAppAsync(SteamID, RefreshToken, true).ConfigureAwait(false); } catch (Exception e) { // The request has failed, in almost all cases this means our refresh token is no longer valid, relog needed ArchiLogger.LogGenericWarningException(e); @@ -1666,8 +1660,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { if (!string.IsNullOrEmpty(latestJson)) { ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.AutomaticFileMigration, configFilePath)); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - await SerializableFile.Write(configFilePath, latestJson!).ConfigureAwait(false); + await SerializableFile.Write(configFilePath, latestJson).ConfigureAwait(false); ASF.ArchiLogger.LogGenericInfo(Strings.Done); } @@ -1823,8 +1816,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { string? input = await Logging.GetUserInput(inputType, BotName).ConfigureAwait(false); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (string.IsNullOrEmpty(input) || !SetUserInput(inputType, input!)) { + if (string.IsNullOrEmpty(input) || !SetUserInput(inputType, input)) { ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(input))); Stop(); @@ -1951,11 +1943,10 @@ public sealed class Bot : IAsyncDisposable, IDisposable { string? key = game.Key as string; - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework if (string.IsNullOrEmpty(key)) { invalid = true; ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(key))); - } else if (!Utilities.IsValidCdKey(key!)) { + } else if (!Utilities.IsValidCdKey(key)) { invalid = true; ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, key)); } @@ -2103,8 +2094,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { } // URIs to foil badges are the same as for normal badges except they end with "?border=1" - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - string appIDText = badgeUri!.Split('?', StringSplitOptions.RemoveEmptyEntries)[0].Split('/', StringSplitOptions.RemoveEmptyEntries)[^1]; + string appIDText = badgeUri.Split('?', StringSplitOptions.RemoveEmptyEntries)[0].Split('/', StringSplitOptions.RemoveEmptyEntries)[^1]; if (!uint.TryParse(appIDText, out uint appID) || (appID == 0)) { ArchiLogger.LogNullError(appID); @@ -2168,8 +2158,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { string? authCode = await Logging.GetUserInput(ASF.EUserInputType.SteamGuard, BotName).ConfigureAwait(false); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (string.IsNullOrEmpty(authCode) || !SetUserInput(ASF.EUserInputType.SteamGuard, authCode!)) { + if (string.IsNullOrEmpty(authCode) || !SetUserInput(ASF.EUserInputType.SteamGuard, authCode)) { ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(authCode))); Stop(); @@ -2182,8 +2171,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { string? twoFactorCode = await Logging.GetUserInput(ASF.EUserInputType.TwoFactorAuthentication, BotName).ConfigureAwait(false); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (string.IsNullOrEmpty(twoFactorCode) || !SetUserInput(ASF.EUserInputType.TwoFactorAuthentication, twoFactorCode!)) { + if (string.IsNullOrEmpty(twoFactorCode) || !SetUserInput(ASF.EUserInputType.TwoFactorAuthentication, twoFactorCode)) { ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(twoFactorCode))); Stop(); @@ -2335,8 +2323,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { string? steamLogin = await Logging.GetUserInput(ASF.EUserInputType.Login, BotName).ConfigureAwait(false); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (string.IsNullOrEmpty(steamLogin) || !SetUserInput(ASF.EUserInputType.Login, steamLogin!)) { + if (string.IsNullOrEmpty(steamLogin) || !SetUserInput(ASF.EUserInputType.Login, steamLogin)) { ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(steamLogin))); return false; @@ -2351,8 +2338,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { string? steamPassword = await Logging.GetUserInput(ASF.EUserInputType.Password, BotName).ConfigureAwait(false); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (string.IsNullOrEmpty(steamPassword) || !SetUserInput(ASF.EUserInputType.Password, steamPassword!)) { + if (string.IsNullOrEmpty(steamPassword) || !SetUserInput(ASF.EUserInputType.Password, steamPassword)) { ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(steamPassword))); return false; @@ -2380,13 +2366,11 @@ public sealed class Bot : IAsyncDisposable, IDisposable { if (BotConfig.PasswordFormat.HasTransformation()) { if (!string.IsNullOrEmpty(accessToken)) { - // ReSharper disable RedundantSuppressNullableWarningExpression - required for .NET Framework - accessToken = await ArchiCryptoHelper.Decrypt(BotConfig.PasswordFormat, accessToken!).ConfigureAwait(false); + accessToken = await ArchiCryptoHelper.Decrypt(BotConfig.PasswordFormat, accessToken).ConfigureAwait(false); } if (!string.IsNullOrEmpty(refreshToken)) { - // ReSharper disable RedundantSuppressNullableWarningExpression - required for .NET Framework - refreshToken = await ArchiCryptoHelper.Decrypt(BotConfig.PasswordFormat, refreshToken!).ConfigureAwait(false); + refreshToken = await ArchiCryptoHelper.Decrypt(BotConfig.PasswordFormat, refreshToken).ConfigureAwait(false); } } @@ -2621,7 +2605,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { } // Steam login and password fields can contain ASCII characters only, including spaces - string username = GeneratedRegexes.NonAscii().Replace(BotConfig.SteamLogin!, ""); + string username = GeneratedRegexes.NonAscii().Replace(BotConfig.SteamLogin, ""); if (string.IsNullOrEmpty(username)) { ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(BotConfig.SteamLogin))); @@ -2634,8 +2618,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { string? password = await BotConfig.GetDecryptedSteamPassword().ConfigureAwait(false); if (!string.IsNullOrEmpty(password)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - password = GeneratedRegexes.NonAscii().Replace(password!, ""); + password = GeneratedRegexes.NonAscii().Replace(password, ""); if (string.IsNullOrEmpty(password)) { ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(BotConfig.SteamPassword))); @@ -3190,8 +3173,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { if (!string.IsNullOrEmpty(steamParentalCode)) { // We were able to automatically generate it, potentially with help of the config if (BotConfig.SteamParentalCode != steamParentalCode) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!SetUserInput(ASF.EUserInputType.SteamParentalCode, steamParentalCode!)) { + if (!SetUserInput(ASF.EUserInputType.SteamParentalCode, steamParentalCode)) { ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(steamParentalCode))); Stop(); @@ -3205,8 +3187,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { steamParentalCode = await Logging.GetUserInput(ASF.EUserInputType.SteamParentalCode, BotName).ConfigureAwait(false); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (string.IsNullOrEmpty(steamParentalCode) || !SetUserInput(ASF.EUserInputType.SteamParentalCode, steamParentalCode!)) { + if (string.IsNullOrEmpty(steamParentalCode) || !SetUserInput(ASF.EUserInputType.SteamParentalCode, steamParentalCode)) { ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(steamParentalCode))); Stop(); @@ -3458,8 +3439,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { break; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - CStore_RegisterCDKey_Response? response = await Actions.RedeemKey(key!).ConfigureAwait(false); + CStore_RegisterCDKey_Response? response = await Actions.RedeemKey(key).ConfigureAwait(false); if (response == null) { continue; @@ -3472,8 +3452,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { if ((purchaseResultDetail == EPurchaseResultDetail.CannotRedeemCodeFromClient) || ((purchaseResultDetail == EPurchaseResultDetail.BadActivationCode) && assumeWalletKeyOnBadActivationCode)) { // If it's a wallet code, we try to redeem it first, then handle the inner result as our primary one - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - (EResult Result, EPurchaseResultDetail? PurchaseResult, string? BalanceText)? walletResult = await ArchiWebHandler.RedeemWalletKey(key!).ConfigureAwait(false); + (EResult Result, EPurchaseResultDetail? PurchaseResult, string? BalanceText)? walletResult = await ArchiWebHandler.RedeemWalletKey(key).ConfigureAwait(false); if (walletResult != null) { result = walletResult.Value.Result; @@ -3521,12 +3500,10 @@ public sealed class Bot : IAsyncDisposable, IDisposable { break; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - BotDatabase.RemoveGameToRedeemInBackground(key!); + BotDatabase.RemoveGameToRedeemInBackground(key); // If user omitted the name or intentionally provided the same name as key, replace it with the Steam result - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (name!.Equals(key, StringComparison.OrdinalIgnoreCase) && (items?.Count > 0)) { + if (name.Equals(key, StringComparison.OrdinalIgnoreCase) && (items?.Count > 0)) { name = string.Join(", ", items.Values); } @@ -3813,7 +3790,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { BotDatabase.AccessToken = ArchiCryptoHelper.Encrypt(BotConfig.PasswordFormat, accessToken); if (!string.IsNullOrEmpty(refreshToken)) { - BotDatabase.RefreshToken = ArchiCryptoHelper.Encrypt(BotConfig.PasswordFormat, refreshToken!); + BotDatabase.RefreshToken = ArchiCryptoHelper.Encrypt(BotConfig.PasswordFormat, refreshToken); } } else { BotDatabase.AccessToken = accessToken; @@ -3856,8 +3833,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable { if (!string.IsNullOrEmpty(steamParentalCode)) { byte i = 0; - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - byte[] password = new byte[steamParentalCode!.Length]; + byte[] password = new byte[steamParentalCode.Length]; foreach (char character in steamParentalCode.TakeWhile(static character => character is >= '0' and <= '9')) { password[i++] = (byte) character; diff --git a/ArchiSteamFarm/Steam/Cards/CardsFarmer.cs b/ArchiSteamFarm/Steam/Cards/CardsFarmer.cs index 855d80e7e..9bf9be0f3 100644 --- a/ArchiSteamFarm/Steam/Cards/CardsFarmer.cs +++ b/ArchiSteamFarm/Steam/Cards/CardsFarmer.cs @@ -470,8 +470,7 @@ public sealed class CardsFarmer : IAsyncDisposable, IDisposable { continue; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - string[] appIDSplitted = appIDText!.Split('_'); + string[] appIDSplitted = appIDText.Split('_'); if (appIDSplitted.Length < 5) { Bot.ArchiLogger.LogNullError(appIDSplitted); diff --git a/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs b/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs index 85cd6b493..4ecb9e2a4 100644 --- a/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs +++ b/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs @@ -307,8 +307,7 @@ public sealed class ArchiWebHandler : IDisposable { } // Interpret the reason and see if we should try again - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - switch (response.Content!.ErrorCode) { + switch (response.Content.ErrorCode) { case EResult.DuplicateRequest: case EResult.ServiceUnavailable: response = null; @@ -317,8 +316,7 @@ public sealed class ArchiWebHandler : IDisposable { } // This is actually client error with a reason, so it doesn't make sense to retry - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - throw new HttpRequestException(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, response.Content!.ErrorText), null, response.StatusCode); + throw new HttpRequestException(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, response.Content.ErrorText), null, response.StatusCode); } } } finally { @@ -413,9 +411,7 @@ public sealed class ArchiWebHandler : IDisposable { } Dictionary arguments = new(2, StringComparer.Ordinal) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - { "access_token", accessToken! }, - + { "access_token", accessToken }, { "steamid", Bot.SteamID } }; @@ -478,8 +474,7 @@ public sealed class ArchiWebHandler : IDisposable { } Dictionary arguments = new(StringComparer.Ordinal) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - { "key", steamApiKey! } + { "key", steamApiKey } }; if (activeOnly.HasValue) { @@ -594,8 +589,7 @@ public sealed class ArchiWebHandler : IDisposable { return null; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - parsedTags.Add(new Tag(identifier!, value)); + parsedTags.Add(new Tag(identifier, value)); } parsedDescription.Tags = parsedTags.ToImmutableHashSet(); @@ -774,8 +768,7 @@ public sealed class ArchiWebHandler : IDisposable { } // This is actually client error with a reason, so it doesn't make sense to retry - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, response.Content!.ErrorText)); + Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, response.Content.ErrorText)); return (false, tradeOfferIDs, mobileTradeOfferIDs); } @@ -1116,11 +1109,9 @@ public sealed class ArchiWebHandler : IDisposable { }; if (data != null) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - data[sessionName] = sessionID!; + data[sessionName] = sessionID; } else { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - data = new Dictionary(1, StringComparer.Ordinal) { { sessionName, sessionID! } }; + data = new Dictionary(1, StringComparer.Ordinal) { { sessionName, sessionID } }; } } @@ -1228,11 +1219,9 @@ public sealed class ArchiWebHandler : IDisposable { }; if (data != null) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - data[sessionName] = sessionID!; + data[sessionName] = sessionID; } else { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - data = new Dictionary(1, StringComparer.Ordinal) { { sessionName, sessionID! } }; + data = new Dictionary(1, StringComparer.Ordinal) { { sessionName, sessionID } }; } } @@ -1339,8 +1328,7 @@ public sealed class ArchiWebHandler : IDisposable { _ => throw new InvalidOperationException(nameof(session)) }; - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - KeyValuePair sessionValue = new(sessionName, sessionID!); + KeyValuePair sessionValue = new(sessionName, sessionID); if (data != null) { data.Remove(sessionValue); @@ -1454,11 +1442,9 @@ public sealed class ArchiWebHandler : IDisposable { }; if (data != null) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - data[sessionName] = sessionID!; + data[sessionName] = sessionID; } else { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - data = new Dictionary(1, StringComparer.Ordinal) { { sessionName, sessionID! } }; + data = new Dictionary(1, StringComparer.Ordinal) { { sessionName, sessionID } }; } } @@ -1599,8 +1585,7 @@ public sealed class ArchiWebHandler : IDisposable { } // This is actually client error with a reason, so it doesn't make sense to retry - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, response.Content!.ErrorText)); + Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, response.Content.ErrorText)); return (false, false); } @@ -1846,15 +1831,12 @@ public sealed class ArchiWebHandler : IDisposable { } Dictionary arguments = new(!string.IsNullOrEmpty(tradeToken) ? 3 : 2, StringComparer.Ordinal) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - { "key", steamApiKey! }, - + { "key", steamApiKey }, { "steamid_target", steamID } }; if (!string.IsNullOrEmpty(tradeToken)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - arguments["trade_offer_access_token"] = tradeToken!; + arguments["trade_offer_access_token"] = tradeToken; } KeyValue? response = null; @@ -1954,8 +1936,7 @@ public sealed class ArchiWebHandler : IDisposable { return null; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (giftCardIDText!.Length <= 13) { + if (giftCardIDText.Length <= 13) { Bot.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(giftCardIDText))); return null; @@ -2231,8 +2212,7 @@ public sealed class ArchiWebHandler : IDisposable { // Unlock Steam Parental if needed if (!string.IsNullOrEmpty(parentalCode)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!await UnlockParentalAccount(parentalCode!).ConfigureAwait(false)) { + if (!await UnlockParentalAccount(parentalCode).ConfigureAwait(false)) { return false; } } @@ -2635,8 +2615,7 @@ public sealed class ArchiWebHandler : IDisposable { ObjectResponse? response = await UrlGetToJsonObjectWithSession(request).ConfigureAwait(false); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - return !string.IsNullOrEmpty(response?.Content?.Data.WebAPIToken) ? (true, response!.Content!.Data.WebAPIToken) : (false, null); + return !string.IsNullOrEmpty(response?.Content?.Data.WebAPIToken) ? (true, response.Content.Data.WebAPIToken) : (false, null); } private async Task<(bool Success, string? Result)> ResolveApiKey() { @@ -2711,9 +2690,7 @@ public sealed class ArchiWebHandler : IDisposable { } Dictionary arguments = new(2, StringComparer.Ordinal) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - { "key", steamApiKey! }, - + { "key", steamApiKey }, { "steamids", Bot.SteamID } }; @@ -2815,9 +2792,7 @@ public sealed class ArchiWebHandler : IDisposable { Dictionary data = new(2, StringComparer.Ordinal) { { "pin", parentalCode }, - - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - { "sessionid", sessionID! } + { "sessionid", sessionID } }; // This request doesn't go through UrlPostRetryWithSession as we have no access to session refresh capability (this is in fact session initialization) diff --git a/ArchiSteamFarm/Steam/Integration/SteamChatMessage.cs b/ArchiSteamFarm/Steam/Integration/SteamChatMessage.cs index dd052b325..91f8707d8 100644 --- a/ArchiSteamFarm/Steam/Integration/SteamChatMessage.cs +++ b/ArchiSteamFarm/Steam/Integration/SteamChatMessage.cs @@ -47,8 +47,7 @@ internal static class SteamChatMessage { if (!string.IsNullOrEmpty(steamMessagePrefix)) { // We must escape our message prefix if needed - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - steamMessagePrefix = Escape(steamMessagePrefix!); + steamMessagePrefix = Escape(steamMessagePrefix); prefixBytes = GetMessagePrefixBytes(steamMessagePrefix); diff --git a/ArchiSteamFarm/Steam/Interaction/Commands.cs b/ArchiSteamFarm/Steam/Interaction/Commands.cs index 7a4451e60..52b03ac87 100644 --- a/ArchiSteamFarm/Steam/Interaction/Commands.cs +++ b/ArchiSteamFarm/Steam/Interaction/Commands.cs @@ -343,13 +343,11 @@ public sealed class Commands { string? commandPrefix = ASF.GlobalConfig != null ? ASF.GlobalConfig.CommandPrefix : GlobalConfig.DefaultCommandPrefix; if (!string.IsNullOrEmpty(commandPrefix)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!message.StartsWith(commandPrefix!, StringComparison.Ordinal)) { + if (!message.StartsWith(commandPrefix, StringComparison.Ordinal)) { string? pluginsResponse = await PluginsCore.OnBotMessage(Bot, steamID, message).ConfigureAwait(false); if (!string.IsNullOrEmpty(pluginsResponse)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!await Bot.SendMessage(steamID, pluginsResponse!).ConfigureAwait(false)) { + if (!await Bot.SendMessage(steamID, pluginsResponse).ConfigureAwait(false)) { Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(Bot.SendMessage))); Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.Content, pluginsResponse)); } @@ -358,8 +356,7 @@ public sealed class Commands { return; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (message.Length == commandPrefix!.Length) { + if (message.Length == commandPrefix.Length) { // If the message starts with command prefix and is of the same length as command prefix, then it's just empty command trigger, useless return; } @@ -395,8 +392,7 @@ public sealed class Commands { response = FormatBotResponse(Strings.ErrorAccessDenied); } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!await Bot.SendMessage(steamID, response!).ConfigureAwait(false)) { + if (!await Bot.SendMessage(steamID, response).ConfigureAwait(false)) { Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(Bot.SendMessage))); Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.Content, response)); } @@ -415,13 +411,11 @@ public sealed class Commands { string? commandPrefix = ASF.GlobalConfig != null ? ASF.GlobalConfig.CommandPrefix : GlobalConfig.DefaultCommandPrefix; if (!string.IsNullOrEmpty(commandPrefix)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!message.StartsWith(commandPrefix!, StringComparison.Ordinal)) { + if (!message.StartsWith(commandPrefix, StringComparison.Ordinal)) { string? pluginsResponse = await PluginsCore.OnBotMessage(Bot, steamID, message).ConfigureAwait(false); if (!string.IsNullOrEmpty(pluginsResponse)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!await Bot.SendMessage(chatGroupID, chatID, pluginsResponse!).ConfigureAwait(false)) { + if (!await Bot.SendMessage(chatGroupID, chatID, pluginsResponse).ConfigureAwait(false)) { Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(Bot.SendMessage))); Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.Content, pluginsResponse)); } @@ -430,8 +424,7 @@ public sealed class Commands { return; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (message.Length == commandPrefix!.Length) { + if (message.Length == commandPrefix.Length) { // If the message starts with command prefix and is of the same length as command prefix, then it's just empty command trigger, useless return; } @@ -469,8 +462,7 @@ public sealed class Commands { response = FormatBotResponse(Strings.ErrorAccessDenied); } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!await Bot.SendMessage(chatGroupID, chatID, response!).ConfigureAwait(false)) { + if (!await Bot.SendMessage(chatGroupID, chatID, response).ConfigureAwait(false)) { Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, nameof(Bot.SendMessage))); Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.Content, response)); } @@ -2304,8 +2296,7 @@ public sealed class Commands { string? previousKey = key; while (!string.IsNullOrEmpty(key)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - string startingKey = key!; + string startingKey = key; using (IEnumerator botsEnumerator = Bot.Bots.Where(bot => (bot.Value != Bot) && bot.Value.IsConnectedAndLoggedOn && ((access >= EAccess.Owner) || ((steamID != 0) && (bot.Value.GetAccess(steamID) >= EAccess.Operator)))).OrderByDescending(bot => Bot.BotsComparer?.Compare(bot.Key, Bot.BotName) > 0).ThenBy(static bot => bot.Key, Bot.BotsComparer).Select(static bot => bot.Value).GetEnumerator()) { Bot? currentBot = Bot; @@ -2316,8 +2307,7 @@ public sealed class Commands { previousKey = key; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (redeemFlags.HasFlag(ERedeemFlags.Validate) && !Utilities.IsValidCdKey(key!)) { + if (redeemFlags.HasFlag(ERedeemFlags.Validate) && !Utilities.IsValidCdKey(key)) { // Next key key = keysEnumerator.MoveNext() ? keysEnumerator.Current : null; @@ -2336,8 +2326,7 @@ public sealed class Commands { Dictionary? items = null; if (!skipRequest) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - CStore_RegisterCDKey_Response? redeemResult = await currentBot.Actions.RedeemKey(key!).ConfigureAwait(false); + CStore_RegisterCDKey_Response? redeemResult = await currentBot.Actions.RedeemKey(key).ConfigureAwait(false); if (redeemResult != null) { result = (EResult) redeemResult.purchase_receipt_info.purchase_status; @@ -2364,8 +2353,7 @@ public sealed class Commands { if ((purchaseResultDetail == EPurchaseResultDetail.CannotRedeemCodeFromClient) || ((purchaseResultDetail == EPurchaseResultDetail.BadActivationCode) && assumeWalletKeyOnBadActivationCode)) { // If it's a wallet code, we try to redeem it first, then handle the inner result as our primary one - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - (EResult Result, EPurchaseResultDetail? PurchaseResult, string? BalanceText)? walletResult = await currentBot.ArchiWebHandler.RedeemWalletKey(key!).ConfigureAwait(false); + (EResult Result, EPurchaseResultDetail? PurchaseResult, string? BalanceText)? walletResult = await currentBot.ArchiWebHandler.RedeemWalletKey(key).ConfigureAwait(false); if (walletResult != null) { result = walletResult.Value.Result; @@ -2390,8 +2378,7 @@ public sealed class Commands { case EPurchaseResultDetail.NoDetail: // OK case EPurchaseResultDetail.Timeout: if ((result != EResult.Timeout) && (purchaseResultDetail != EPurchaseResultDetail.Timeout)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - unusedKeys.Remove(key!); + unusedKeys.Remove(key); } // Next key @@ -2428,8 +2415,7 @@ public sealed class Commands { bool alreadyHandled = false; foreach (Bot innerBot in Bot.Bots.Where(bot => (bot.Value != currentBot) && (!redeemFlags.HasFlag(ERedeemFlags.SkipInitial) || (bot.Value != Bot)) && !triedBots.Contains(bot.Value) && !rateLimitedBots.Contains(bot.Value) && bot.Value.IsConnectedAndLoggedOn && ((access >= EAccess.Owner) || ((steamID != 0) && (bot.Value.GetAccess(steamID) >= EAccess.Operator))) && ((items.Count == 0) || items.Keys.Any(packageID => !bot.Value.OwnedPackageIDs.ContainsKey(packageID)))).OrderBy(static bot => bot.Key, Bot.BotsComparer).Select(static bot => bot.Value)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - CStore_RegisterCDKey_Response? redeemResponse = await innerBot.Actions.RedeemKey(key!).ConfigureAwait(false); + CStore_RegisterCDKey_Response? redeemResponse = await innerBot.Actions.RedeemKey(key).ConfigureAwait(false); if (redeemResponse == null) { response.AppendLine(FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotRedeem, key, $"{EResult.Timeout}/{EPurchaseResultDetail.Timeout}"), innerBot.BotName)); @@ -2449,8 +2435,7 @@ public sealed class Commands { // This key is already handled, as we either redeemed it or we're sure it's dupe/invalid alreadyHandled = true; - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - unusedKeys.Remove(key!); + unusedKeys.Remove(key); break; case EPurchaseResultDetail.RateLimited: @@ -2488,8 +2473,7 @@ public sealed class Commands { default: ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.WarningUnknownValuePleaseReport, nameof(purchaseResultDetail), purchaseResultDetail)); - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - unusedKeys.Remove(key!); + unusedKeys.Remove(key); // Next key key = keysEnumerator.MoveNext() ? keysEnumerator.Current : null; @@ -3165,8 +3149,7 @@ public sealed class Commands { GlobalConfig.EUpdateChannel channel = ASF.GlobalConfig?.UpdateChannel ?? GlobalConfig.DefaultUpdateChannel; if (!string.IsNullOrEmpty(channelText)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - if (!Enum.TryParse(channelText!, true, out channel) || (channel == GlobalConfig.EUpdateChannel.None)) { + if (!Enum.TryParse(channelText, true, out channel) || (channel == GlobalConfig.EUpdateChannel.None)) { return FormatStaticResponse(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(channelText))); } } diff --git a/ArchiSteamFarm/Steam/Security/MobileAuthenticator.cs b/ArchiSteamFarm/Steam/Security/MobileAuthenticator.cs index 38000adb9..01e893d0a 100644 --- a/ArchiSteamFarm/Steam/Security/MobileAuthenticator.cs +++ b/ArchiSteamFarm/Steam/Security/MobileAuthenticator.cs @@ -130,8 +130,7 @@ public sealed class MobileAuthenticator : IDisposable { // Build the alphanumeric code uint fullCode = BitConverter.ToUInt32(bytes, 0) & 0x7fffffff; - // ReSharper disable once BuiltInTypeReferenceStyleForMemberAccess - required for .NET Framework - return String.Create( + return string.Create( CodeDigits, fullCode, static (buffer, state) => { for (byte i = 0; i < CodeDigits; i++) { buffer[i] = CodeCharacters[(byte) (state % CodeCharacters.Count)]; @@ -170,8 +169,7 @@ public sealed class MobileAuthenticator : IDisposable { return null; } - // ReSharper disable RedundantSuppressNullableWarningExpression - required for .NET Framework - ConfirmationsResponse? response = await Bot.ArchiWebHandler.GetConfirmations(deviceID!, confirmationHash!, time).ConfigureAwait(false); + ConfirmationsResponse? response = await Bot.ArchiWebHandler.GetConfirmations(deviceID, confirmationHash, time).ConfigureAwait(false); if (response?.Success != true) { return null; @@ -253,10 +251,7 @@ public sealed class MobileAuthenticator : IDisposable { return false; } - // ReSharper disable RedundantSuppressNullableWarningExpression - required for .NET Framework - bool? result = await Bot.ArchiWebHandler.HandleConfirmations(deviceID!, confirmationHash!, time, confirmations, accept).ConfigureAwait(false); - - // ReSharper restore RedundantSuppressNullableWarningExpression - required for .NET Framework + bool? result = await Bot.ArchiWebHandler.HandleConfirmations(deviceID, confirmationHash, time, confirmations, accept).ConfigureAwait(false); if (!result.HasValue) { // Request timed out @@ -272,10 +267,7 @@ public sealed class MobileAuthenticator : IDisposable { // In this case, we'll accept all pending confirmations one-by-one, synchronously (as Steam can't handle them in parallel) // We totally ignore actual result returned by those calls, abort only if request timed out foreach (Confirmation confirmation in confirmations) { - // ReSharper disable RedundantSuppressNullableWarningExpression - required for .NET Framework - bool? confirmationResult = await Bot.ArchiWebHandler.HandleConfirmation(deviceID!, confirmationHash!, time, confirmation.ID, confirmation.Nonce, accept).ConfigureAwait(false); - - // ReSharper restore RedundantSuppressNullableWarningExpression - required for .NET Framework + bool? confirmationResult = await Bot.ArchiWebHandler.HandleConfirmation(deviceID, confirmationHash, time, confirmation.ID, confirmation.Nonce, accept).ConfigureAwait(false); if (!confirmationResult.HasValue) { return false; @@ -338,8 +330,7 @@ public sealed class MobileAuthenticator : IDisposable { byte bufferSize = 8; if (!string.IsNullOrEmpty(tag)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - bufferSize += (byte) Math.Min(32, tag!.Length); + bufferSize += (byte) Math.Min(32, tag.Length); } byte[] timeArray = BitConverter.GetBytes(time); @@ -353,8 +344,7 @@ public sealed class MobileAuthenticator : IDisposable { Array.Copy(timeArray, buffer, 8); if (!string.IsNullOrEmpty(tag)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - Array.Copy(Encoding.UTF8.GetBytes(tag!), 0, buffer, 8, bufferSize - 8); + Array.Copy(Encoding.UTF8.GetBytes(tag), 0, buffer, 8, bufferSize - 8); } #pragma warning disable CA5350 // This is actually a fair warning, but there is nothing we can do about Steam using weak cryptographic algorithms diff --git a/ArchiSteamFarm/Steam/Storage/BotConfig.cs b/ArchiSteamFarm/Steam/Storage/BotConfig.cs index 9604e5553..ee66c2d14 100644 --- a/ArchiSteamFarm/Steam/Storage/BotConfig.cs +++ b/ArchiSteamFarm/Steam/Storage/BotConfig.cs @@ -522,11 +522,11 @@ public sealed class BotConfig { return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(SteamMasterClanID), SteamMasterClanID)); } - if (!string.IsNullOrEmpty(SteamParentalCode) && ((SteamParentalCode!.Length != SteamParentalCodeLength) || SteamParentalCode.Any(static character => character is < '0' or > '9'))) { + if (!string.IsNullOrEmpty(SteamParentalCode) && ((SteamParentalCode.Length != SteamParentalCodeLength) || SteamParentalCode.Any(static character => character is < '0' or > '9'))) { return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(SteamParentalCode), SteamParentalCode)); } - if (!string.IsNullOrEmpty(SteamTradeToken) && (SteamTradeToken!.Length != SteamTradeTokenLength)) { + if (!string.IsNullOrEmpty(SteamTradeToken) && (SteamTradeToken.Length != SteamTradeTokenLength)) { return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(SteamTradeToken), SteamTradeToken)); } @@ -557,7 +557,7 @@ public sealed class BotConfig { return SteamPassword; } - string? result = await ArchiCryptoHelper.Decrypt(PasswordFormat, SteamPassword!).ConfigureAwait(false); + string? result = await ArchiCryptoHelper.Decrypt(PasswordFormat, SteamPassword).ConfigureAwait(false); if (string.IsNullOrEmpty(result)) { ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(SteamPassword))); @@ -604,8 +604,7 @@ public sealed class BotConfig { if (!valid) { if (!string.IsNullOrEmpty(errorMessage)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - ASF.ArchiLogger.LogGenericError(errorMessage!); + ASF.ArchiLogger.LogGenericError(errorMessage); } return (null, null); @@ -617,13 +616,12 @@ public sealed class BotConfig { HashSet disallowedValues = new(StringComparer.InvariantCultureIgnoreCase) { "account" }; if (!string.IsNullOrEmpty(botConfig.SteamLogin)) { - disallowedValues.Add(botConfig.SteamLogin!); + disallowedValues.Add(botConfig.SteamLogin); } Utilities.InBackground( () => { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - (bool isWeak, string? reason) = Utilities.TestPasswordStrength(decryptedSteamPassword!, disallowedValues); + (bool isWeak, string? reason) = Utilities.TestPasswordStrength(decryptedSteamPassword, disallowedValues); if (isWeak) { if (string.IsNullOrEmpty(botName)) { diff --git a/ArchiSteamFarm/Storage/GlobalConfig.cs b/ArchiSteamFarm/Storage/GlobalConfig.cs index 2e708b777..1e287b4b2 100644 --- a/ArchiSteamFarm/Storage/GlobalConfig.cs +++ b/ArchiSteamFarm/Storage/GlobalConfig.cs @@ -155,7 +155,7 @@ public sealed class GlobalConfig { Uri uri; try { - uri = new Uri(WebProxyText!); + uri = new Uri(WebProxyText); } catch (UriFormatException e) { ASF.ArchiLogger.LogGenericException(e); @@ -472,7 +472,7 @@ public sealed class GlobalConfig { return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(OptimizationMode), OptimizationMode)); } - if (!string.IsNullOrEmpty(SteamMessagePrefix) && !SteamChatMessage.IsValidPrefix(SteamMessagePrefix!)) { + if (!string.IsNullOrEmpty(SteamMessagePrefix) && !SteamChatMessage.IsValidPrefix(SteamMessagePrefix)) { return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(SteamMessagePrefix), SteamMessagePrefix)); } @@ -523,8 +523,7 @@ public sealed class GlobalConfig { if (!valid) { if (!string.IsNullOrEmpty(errorMessage)) { - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - ASF.ArchiLogger.LogGenericError(errorMessage!); + ASF.ArchiLogger.LogGenericError(errorMessage); } return (null, null); @@ -535,7 +534,7 @@ public sealed class GlobalConfig { case ArchiCryptoHelper.EHashingMethod.PlainText when !string.IsNullOrEmpty(globalConfig.IPCPassword): Utilities.InBackground( () => { - (bool isWeak, string? reason) = Utilities.TestPasswordStrength(globalConfig.IPCPassword!, ForbiddenIPCPasswordPhrases); + (bool isWeak, string? reason) = Utilities.TestPasswordStrength(globalConfig.IPCPassword, ForbiddenIPCPasswordPhrases); if (isWeak) { ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningWeakIPCPassword, reason)); diff --git a/ArchiSteamFarm/Web/GitHub.cs b/ArchiSteamFarm/Web/GitHub.cs index 9c50bc509..32df3e8bb 100644 --- a/ArchiSteamFarm/Web/GitHub.cs +++ b/ArchiSteamFarm/Web/GitHub.cs @@ -125,8 +125,7 @@ internal static class GitHub { return null; } - // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - result[versionText!] = dateTime.ToUniversalTime(); + result[versionText] = dateTime.ToUniversalTime(); } return result; @@ -270,7 +269,7 @@ internal static class GitHub { return null; } - return BackingChangelog = ExtractChangelogFromBody(MarkdownBody!); + return BackingChangelog = ExtractChangelogFromBody(MarkdownBody); } } diff --git a/ArchiSteamFarm/Web/WebBrowser.cs b/ArchiSteamFarm/Web/WebBrowser.cs index 3513e6f8f..d7380f6ec 100644 --- a/ArchiSteamFarm/Web/WebBrowser.cs +++ b/ArchiSteamFarm/Web/WebBrowser.cs @@ -66,14 +66,9 @@ public sealed class WebBrowser : IDisposable { HttpClientHandler = new HttpClientHandler { AllowAutoRedirect = false, // This must be false if we want to handle custom redirection schemes such as "steammobile://" - -#if NETFRAMEWORK || NETSTANDARD - AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip, -#else AutomaticDecompression = DecompressionMethods.All, -#endif - - CookieContainer = CookieContainer + CookieContainer = CookieContainer, + MaxConnectionsPerServer = MaxConnections }; if (webProxy != null) { @@ -86,14 +81,6 @@ public sealed class WebBrowser : IDisposable { } } -#if NETFRAMEWORK || NETSTANDARD - if (!RuntimeMadness.IsRunningOnMono) { - HttpClientHandler.MaxConnectionsPerServer = MaxConnections; - } -#else - HttpClientHandler.MaxConnectionsPerServer = MaxConnections; -#endif - HttpClient = GenerateDisposableHttpClient(extendedTimeout); } @@ -107,9 +94,7 @@ public sealed class WebBrowser : IDisposable { byte connectionTimeout = ASF.GlobalConfig?.ConnectionTimeout ?? GlobalConfig.DefaultConnectionTimeout; HttpClient result = new(HttpClientHandler, false) { -#if !NETFRAMEWORK && !NETSTANDARD DefaultRequestVersion = HttpVersion.Version30, -#endif Timeout = TimeSpan.FromSeconds(extendedTimeout ? ExtendedTimeout : connectionTimeout) }; @@ -710,13 +695,7 @@ public sealed class WebBrowser : IDisposable { ServicePointManager.Expect100Continue = false; // Reuse ports if possible -#if NETFRAMEWORK || NETSTANDARD - if (!RuntimeMadness.IsRunningOnMono) { - ServicePointManager.ReusePort = true; - } -#else ServicePointManager.ReusePort = true; -#endif } private async Task InternalGet(Uri request, IReadOnlyCollection>? headers = null, Uri? referer = null, ERequestOptions requestOptions = ERequestOptions.None, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) { @@ -745,9 +724,7 @@ public sealed class WebBrowser : IDisposable { while (true) { using (HttpRequestMessage requestMessage = new(httpMethod, request)) { -#if !NETFRAMEWORK && !NETSTANDARD requestMessage.Version = HttpClient.DefaultRequestVersion; -#endif if (headers != null) { foreach ((string header, string value) in headers) { diff --git a/ArchiSteamFarm/Web/WebBrowserUtilities.cs b/ArchiSteamFarm/Web/WebBrowserUtilities.cs index 78a80567b..072cc7785 100644 --- a/ArchiSteamFarm/Web/WebBrowserUtilities.cs +++ b/ArchiSteamFarm/Web/WebBrowserUtilities.cs @@ -35,7 +35,7 @@ internal static class WebBrowserUtilities { // We're going to create compressed stream and copy original content to it MemoryStream compressionOutput = new(); - (Stream compressionInput, string contentEncoding) = GetBestSupportedCompressionMethod(compressionOutput); + BrotliStream compressionInput = new(compressionOutput, CompressionLevel.SmallestSize, true); await using (compressionInput.ConfigureAwait(false)) { await content.CopyToAsync(compressionInput).ConfigureAwait(false); @@ -51,18 +51,8 @@ internal static class WebBrowserUtilities { } // Inform the server that we're sending compressed data - result.Headers.ContentEncoding.Add(contentEncoding); + result.Headers.ContentEncoding.Add("br"); return result; } - - private static (Stream CompressionInput, string ContentEncoding) GetBestSupportedCompressionMethod(Stream output) { - ArgumentNullException.ThrowIfNull(output); - -#if NETFRAMEWORK || NETSTANDARD - return (new GZipStream(output, CompressionLevel.Optimal, true), "gzip"); -#else - return (new BrotliStream(output, CompressionLevel.SmallestSize, true), "br"); -#endif - } } diff --git a/Directory.Build.props b/Directory.Build.props index 79b644648..034fe2d08 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -33,49 +33,6 @@ true - - $(TargetFrameworks);net481 - - - - $(TargetFrameworks);netstandard2.1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(DefineConstants);ASF_VARIANT_$(ASFVariant.Replace('-', '_').ToUpperInvariant()) diff --git a/Directory.Packages.props b/Directory.Packages.props index 44a56895c..8aa056571 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -20,29 +20,7 @@ + - - - - - - - - - - - - - - - - - - - - - - -