mirror of
https://github.com/JustArchiNET/ArchiSteamFarm
synced 2024-11-10 07:04:27 +00:00
Closes #3060
This commit is contained in:
parent
b34f18497d
commit
f2ff2f4929
45 changed files with 156 additions and 616 deletions
38
.github/workflows/publish.yml
vendored
38
.github/workflows/publish.yml
vendored
|
@ -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:
|
||||
|
|
|
@ -11,13 +11,6 @@
|
|||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net481' OR '$(TargetFramework)' == 'netstandard2.1'">
|
||||
<!-- Madness is already included in netf build of ASF, so we don't need to emit it ourselves -->
|
||||
<PackageReference Update="JustArchiNET.Madness" IncludeAssets="compile" />
|
||||
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" ExcludeAssets="all" Private="false" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -9,11 +9,6 @@
|
|||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net481' OR '$(TargetFramework)' == 'netstandard2.1'">
|
||||
<!-- Madness is already included in netf build of ASF, so we don't need to emit it ourselves -->
|
||||
<PackageReference Update="JustArchiNET.Madness" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" ExcludeAssets="all" Private="false" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -11,17 +11,6 @@
|
|||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net481' OR '$(TargetFramework)' == 'netstandard2.1'">
|
||||
<!-- Madness is already included in netf build of ASF, so we don't need to emit it ourselves -->
|
||||
<PackageReference Update="JustArchiNET.Madness" IncludeAssets="compile" />
|
||||
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net481'">
|
||||
<Reference Include="System.Net.Http" HintPath="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8.1\System.Net.Http.dll" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" ExcludeAssets="all" Private="false" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -13,15 +13,6 @@
|
|||
<PackageReference Include="System.Linq.Async" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net481' OR '$(TargetFramework)' == 'netstandard2.1'">
|
||||
<!-- Madness is already included in netf build of ASF, so we don't need to emit it ourselves -->
|
||||
<PackageReference Update="JustArchiNET.Madness" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net481'">
|
||||
<Reference Include="System.Net.Http" HintPath="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8.1\System.Net.Http.dll" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" ExcludeAssets="all" Private="false" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -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<ListedUser> Users)? response = await Backend.GetListedUsersForMatching(ASF.GlobalConfig.LicenseID.Value, Bot, WebBrowser, ourInventory.Values, acceptedMatchableTypes).ConfigureAwait(false);
|
||||
|
||||
if (response == null) {
|
||||
|
|
|
@ -11,11 +11,6 @@
|
|||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net481' OR '$(TargetFramework)' == 'netstandard2.1'">
|
||||
<!-- Madness is already included in netf build of ASF, so we don't need to emit it ourselves -->
|
||||
<PackageReference Update="JustArchiNET.Madness" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" ExcludeAssets="all" Private="false" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -12,11 +12,6 @@
|
|||
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net481' OR '$(TargetFramework)' == 'netstandard2.1'">
|
||||
<!-- Madness is already included in netf build of ASF, so we don't need to emit it ourselves -->
|
||||
<PackageReference Update="JustArchiNET.Madness" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" ExcludeAssets="all" Private="false" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -23,32 +23,8 @@
|
|||
<PackageReference Include="System.Composition" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" />
|
||||
<PackageReference Include="System.Linq.Async" />
|
||||
<PackageReference Include="zxcvbn-core" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'net481'">
|
||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net481' OR '$(TargetFramework)' == 'netstandard2.1'">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cors" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.HttpOverrides" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.ResponseCaching" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebSockets" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net481'">
|
||||
<Reference Include="System.Net.Http" HintPath="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8.1\System.Net.Http.dll" />
|
||||
<Reference Include="System.Security" HintPath="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8.1\System.Security.dll" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
|
||||
<PackageReference Include="System.IO.FileSystem.AccessControl" />
|
||||
<PackageReference Include="zxcvbn-core" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -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<string> 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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<bool> 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";
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -186,6 +186,6 @@ public sealed class ASFController : ArchiController {
|
|||
message = success ? Strings.Success : Strings.WarningFailed;
|
||||
}
|
||||
|
||||
return Ok(new GenericResponse<string>(success, message!, version?.ToString()));
|
||||
return Ok(new GenericResponse<string>(success, message, version?.ToString()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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<ApiAuthenticationMiddleware>());
|
||||
|
@ -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
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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<MvcJsonOptions> 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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<PosixSignal, PosixSignalRegistration> RegisteredPosixSignals = new();
|
||||
#endif
|
||||
|
||||
private static readonly TaskCompletionSource<byte> ShutdownResetEvent = new();
|
||||
|
||||
#if !NETFRAMEWORK && !NETSTANDARD
|
||||
private static readonly ImmutableHashSet<PosixSignal> 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<AssemblyCopyrightAttribute>()?.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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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<uint>(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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<string, object?> 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<string, object?> 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<string, string>(1, StringComparer.Ordinal) { { sessionName, sessionID! } };
|
||||
data = new Dictionary<string, string>(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<string, string>(1, StringComparer.Ordinal) { { sessionName, sessionID! } };
|
||||
data = new Dictionary<string, string>(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<string, string> sessionValue = new(sessionName, sessionID!);
|
||||
KeyValuePair<string, string> 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<string, string>(1, StringComparer.Ordinal) { { sessionName, sessionID! } };
|
||||
data = new Dictionary<string, string>(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<string, object?> 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<AccessTokenResponse>? response = await UrlGetToJsonObjectWithSession<AccessTokenResponse>(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<string, object?> 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<string, string> 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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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<Bot> 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<uint, string>? 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)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<string> 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)) {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<HttpResponseMessage?> InternalGet(Uri request, IReadOnlyCollection<KeyValuePair<string, string>>? 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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,49 +33,6 @@
|
|||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(OS)' == 'Windows_NT' OR '$(ASFNetFramework)' != ''">
|
||||
<TargetFrameworks>$(TargetFrameworks);net481</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(ASFNetStandard)' != ''">
|
||||
<TargetFrameworks>$(TargetFrameworks);netstandard2.1</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net481' OR '$(TargetFramework)' == 'netstandard2.1'">
|
||||
<PackageReference Include="JustArchiNET.Madness" />
|
||||
<PackageReference Include="TA.System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray" />
|
||||
|
||||
<Using Include="JustArchiNET.Madness" />
|
||||
<Using Include="JustArchiNET.Madness.ArgumentExceptionMadness.ArgumentException" Alias="ArgumentException" />
|
||||
<Using Include="JustArchiNET.Madness.ArgumentNullExceptionMadness.ArgumentNullException" Alias="ArgumentNullException" />
|
||||
<Using Include="JustArchiNET.Madness.ArgumentOutOfRangeExceptionMadness.ArgumentOutOfRangeException" Alias="ArgumentOutOfRangeException" />
|
||||
<Using Include="JustArchiNET.Madness.ArrayMadness.Array" Alias="Array" />
|
||||
<Using Include="JustArchiNET.Madness.CancellationTokenSourceMadness.CancellationTokenSource" Alias="CancellationTokenSource" />
|
||||
<Using Include="JustArchiNET.Madness.ConvertMadness.Convert" Alias="Convert" />
|
||||
<Using Include="JustArchiNET.Madness.DirectoryInfoMadness.DirectoryInfo" Alias="DirectoryInfo" />
|
||||
<Using Include="JustArchiNET.Madness.DirectoryMadness.Directory" Alias="Directory" />
|
||||
<Using Include="JustArchiNET.Madness.EnumMadness.Enum" Alias="Enum" />
|
||||
<Using Include="JustArchiNET.Madness.EnvironmentMadness.Environment" Alias="Environment" />
|
||||
<Using Include="JustArchiNET.Madness.FileInfoMadness.FileInfo" Alias="FileInfo" />
|
||||
<Using Include="JustArchiNET.Madness.FileMadness.File" Alias="File" />
|
||||
<Using Include="JustArchiNET.Madness.FileMadness.UnixFileMode" Alias="UnixFileMode" />
|
||||
<Using Include="JustArchiNET.Madness.HashCodeMadness.HashCode" Alias="HashCode" />
|
||||
<Using Include="JustArchiNET.Madness.HMACSHA1Madness.HMACSHA1" Alias="HMACSHA1" />
|
||||
<Using Include="JustArchiNET.Madness.HttpRequestExceptionMadness.HttpRequestException" Alias="HttpRequestException" />
|
||||
<Using Include="JustArchiNET.Madness.OperatingSystemMadness.OperatingSystem" Alias="OperatingSystem" />
|
||||
<Using Include="JustArchiNET.Madness.PathMadness.Path" Alias="Path" />
|
||||
<Using Include="JustArchiNET.Madness.QuicExceptionMadness.QuicException" Alias="QuicException" />
|
||||
<Using Include="JustArchiNET.Madness.RandomMadness.Random" Alias="Random" />
|
||||
<Using Include="JustArchiNET.Madness.SHA256Madness.SHA256" Alias="SHA256" />
|
||||
<Using Include="JustArchiNET.Madness.SHA512Madness.SHA512" Alias="SHA512" />
|
||||
<Using Include="JustArchiNET.Madness.StringMadness.String" Alias="String" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
|
||||
<Using Include="JustArchiNET.Madness.NewtonsoftJsonMadness.JsonTextReader" Alias="JsonTextReader" />
|
||||
<Using Include="JustArchiNET.Madness.NewtonsoftJsonMadness.JsonTextWriter" Alias="JsonTextWriter" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(ASFVariant)' != ''">
|
||||
<DefineConstants>$(DefineConstants);ASF_VARIANT_$(ASFVariant.Replace('-', '_').ToUpperInvariant())</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -20,29 +20,7 @@
|
|||
<PackageVersion Include="System.Composition.AttributedModel" Version="8.0.0" />
|
||||
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3" />
|
||||
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
|
||||
<PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="8.0.0" />
|
||||
<PackageVersion Include="zxcvbn-core" Version="7.0.92" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'net481'">
|
||||
<PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net481' OR '$(TargetFramework)' == 'netstandard2.1'">
|
||||
<PackageVersion Include="JustArchiNET.Madness" Version="3.17.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Cors" Version="2.2.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Diagnostics" Version="2.2.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.HttpOverrides" Version="2.2.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.ResponseCaching" Version="2.2.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="3.1.32" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="3.1.32" />
|
||||
<PackageVersion Include="TA.System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
|
||||
<PackageVersion Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
Loading…
Reference in a new issue