Embrace madness (#2394)

* Embrace madness

* Remove unused code

* Misc

* Address Abry's note

* Update for Madness 0.3.0
This commit is contained in:
Łukasz Domeradzki 2021-08-07 14:03:46 +02:00 committed by GitHub
parent b47f290512
commit 9f281c6055
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 151 additions and 762 deletions

View file

@ -11,6 +11,7 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
<PackageReference Include="JustArchiNET.Madness" IncludeAssets="compile" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" IncludeAssets="compile" />
</ItemGroup>

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Generic;

View file

@ -11,6 +11,10 @@
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
<PackageReference Include="JustArchiNET.Madness" IncludeAssets="compile" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ArchiSteamFarm\ArchiSteamFarm.csproj" ExcludeAssets="all" Private="false" />
</ItemGroup>

View file

@ -20,16 +20,14 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using File = System.IO.File;
using Path = System.IO.Path;
#else
using System.IO;
using JustArchiNET.Madness;
using File = JustArchiNET.Madness.FileMadness.File;
#endif
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using ArchiSteamFarm.Core;
@ -86,7 +84,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper {
GlobalCache? globalCache;
try {
string json = await Compatibility.File.ReadAllTextAsync(SharedFilePath).ConfigureAwait(false);
string json = await File.ReadAllTextAsync(SharedFilePath).ConfigureAwait(false);
if (string.IsNullOrEmpty(json)) {
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(json)));

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Concurrent;

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Generic;

View file

@ -36,6 +36,7 @@
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
<PackageReference Include="IndexRange" />
<PackageReference Include="JustArchiNET.Madness" />
<PackageReference Include="Microsoft.AspNetCore.Cors" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" />
<PackageReference Include="Microsoft.AspNetCore.HttpOverrides" />

View file

@ -1,39 +0,0 @@
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
// |
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
// Contact: JustArchi@JustArchi.net
// |
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// |
// http://www.apache.org/licenses/LICENSE-2.0
// |
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#if NETFRAMEWORK
using System;
using System.Threading.Tasks;
namespace ArchiSteamFarm.Compatibility {
internal sealed class AsyncDisposableWrapper : IAsyncDisposable {
private readonly IDisposable Disposable;
internal AsyncDisposableWrapper(IDisposable disposable) => Disposable = disposable ?? throw new ArgumentNullException(nameof(disposable));
public ValueTask DisposeAsync() {
Disposable.Dispose();
return default(ValueTask);
}
}
}
#endif

View file

@ -1,74 +0,0 @@
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
// |
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
// Contact: JustArchi@JustArchi.net
// |
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// |
// http://www.apache.org/licenses/LICENSE-2.0
// |
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace ArchiSteamFarm.Compatibility {
[PublicAPI]
public static class File {
public static Task AppendAllTextAsync(string path, string contents) {
#if NETFRAMEWORK
System.IO.File.AppendAllText(path, contents);
return Task.CompletedTask;
#else
return System.IO.File.AppendAllTextAsync(path, contents);
#endif
}
public static void Move(string sourceFileName, string destFileName, bool overwrite) {
#if NETFRAMEWORK
if (overwrite && System.IO.File.Exists(destFileName)) {
System.IO.File.Delete(destFileName);
}
System.IO.File.Move(sourceFileName, destFileName);
#else
System.IO.File.Move(sourceFileName, destFileName, overwrite);
#endif
}
public static Task<byte[]> ReadAllBytesAsync(string path) =>
#if NETFRAMEWORK
Task.FromResult(System.IO.File.ReadAllBytes(path));
#else
System.IO.File.ReadAllBytesAsync(path);
#endif
public static Task<string> ReadAllTextAsync(string path) =>
#if NETFRAMEWORK
Task.FromResult(System.IO.File.ReadAllText(path));
#else
System.IO.File.ReadAllTextAsync(path);
#endif
public static Task WriteAllTextAsync(string path, string contents) {
#if NETFRAMEWORK
System.IO.File.WriteAllText(path, contents);
return Task.CompletedTask;
#else
return System.IO.File.WriteAllTextAsync(path, contents);
#endif
}
}
}

View file

@ -1,31 +0,0 @@
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
// |
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
// Contact: JustArchi@JustArchi.net
// |
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// |
// http://www.apache.org/licenses/LICENSE-2.0
// |
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#if NETFRAMEWORK
using JetBrains.Annotations;
namespace ArchiSteamFarm.Compatibility {
[PublicAPI]
public static class HashCode {
public static int Combine<T1, T2, T3>(T1 value1, T2 value2, T3 value3) => (value1, value2, value3).GetHashCode();
}
}
#endif

View file

@ -1,129 +0,0 @@
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
// |
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
// Contact: JustArchi@JustArchi.net
// |
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// |
// http://www.apache.org/licenses/LICENSE-2.0
// |
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#if NETFRAMEWORK
using System;
using System.Text;
#endif
using JetBrains.Annotations;
namespace ArchiSteamFarm.Compatibility {
[PublicAPI]
public static class Path {
public static string GetRelativePath(string relativeTo, string path) {
#if NETFRAMEWORK
if (string.IsNullOrEmpty(relativeTo)) {
throw new ArgumentNullException(nameof(relativeTo));
}
if (string.IsNullOrEmpty(path)) {
throw new ArgumentNullException(nameof(path));
}
StringComparison comparisonType = PathInternalNetCore.StringComparison;
relativeTo = System.IO.Path.GetFullPath(relativeTo);
path = System.IO.Path.GetFullPath(path);
// Need to check if the roots are different- if they are we need to return the "to" path.
if (!PathInternalNetCore.AreRootsEqual(relativeTo, path, comparisonType)) {
return path;
}
int commonLength = PathInternalNetCore.GetCommonPathLength(
relativeTo, path,
comparisonType == StringComparison.OrdinalIgnoreCase
);
// If there is nothing in common they can't share the same root, return the "to" path as is.
if (commonLength == 0) {
return path;
}
// Trailing separators aren't significant for comparison
int relativeToLength = relativeTo.Length;
if (PathInternalNetCore.EndsInDirectorySeparator(relativeTo)) {
relativeToLength--;
}
bool pathEndsInSeparator = PathInternalNetCore.EndsInDirectorySeparator(path);
int pathLength = path.Length;
if (pathEndsInSeparator) {
pathLength--;
}
// If we have effectively the same path, return "."
if ((relativeToLength == pathLength) && (commonLength >= relativeToLength)) {
return ".";
}
// We have the same root, we need to calculate the difference now using the
// common Length and Segment count past the length.
//
// Some examples:
//
// C:\Foo C:\Bar L3, S1 -> ..\Bar
// C:\Foo C:\Foo\Bar L6, S0 -> Bar
// C:\Foo\Bar C:\Bar\Bar L3, S2 -> ..\..\Bar\Bar
// C:\Foo\Foo C:\Foo\Bar L7, S1 -> ..\Bar
StringBuilder sb = new(); //StringBuilderCache.Acquire(Math.Max(relativeTo.Length, path.Length));
// Add parent segments for segments past the common on the "from" path
if (commonLength < relativeToLength) {
sb.Append("..");
for (int i = commonLength + 1; i < relativeToLength; i++) {
if (PathInternalNetCore.IsDirectorySeparator(relativeTo[i])) {
sb.Append(System.IO.Path.DirectorySeparatorChar);
sb.Append("..");
}
}
} else if (PathInternalNetCore.IsDirectorySeparator(path[commonLength])) {
// No parent segments and we need to eat the initial separator
// (C:\Foo C:\Foo\Bar case)
commonLength++;
}
// Now add the rest of the "to" path, adding back the trailing separator
int differenceLength = pathLength - commonLength;
if (pathEndsInSeparator) {
differenceLength++;
}
if (differenceLength > 0) {
if (sb.Length > 0) {
sb.Append(System.IO.Path.DirectorySeparatorChar);
}
sb.Append(path, commonLength, differenceLength);
}
return sb.ToString(); //StringBuilderCache.GetStringAndRelease(sb);
#else
return System.IO.Path.GetRelativePath(relativeTo, path);
#endif
}
}
}

View file

@ -1,173 +0,0 @@
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
// |
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
// Contact: JustArchi@JustArchi.net
// |
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// |
// http://www.apache.org/licenses/LICENSE-2.0
// |
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#if NETFRAMEWORK
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace ArchiSteamFarm.Compatibility {
internal static class PathInternalNetCore {
private const string ExtendedDevicePathPrefix = @"\\?\";
private const string UncExtendedPathPrefix = @"\\?\UNC\";
internal static StringComparison StringComparison => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
/// <summary>
/// Returns true if the two paths have the same root
/// </summary>
internal static bool AreRootsEqual(string first, string second, StringComparison comparisonType) {
int firstRootLength = GetRootLength(first);
int secondRootLength = GetRootLength(second);
return (firstRootLength == secondRootLength)
&& (string.Compare(
first,
0,
second,
0,
firstRootLength,
comparisonType
) == 0);
}
/// <summary>
/// Returns true if the path ends in a directory separator.
/// </summary>
internal static bool EndsInDirectorySeparator(string path) => (path.Length > 0) && IsDirectorySeparator(path[^1]);
/// <summary>
/// Get the common path length from the start of the string.
/// </summary>
internal static int GetCommonPathLength(string first, string second, bool ignoreCase) {
int commonChars = EqualStartingCharacterCount(first, second, ignoreCase);
// If nothing matches
if (commonChars == 0) {
return commonChars;
}
// Or we're a full string and equal length or match to a separator
if ((commonChars == first.Length)
&& ((commonChars == second.Length) || IsDirectorySeparator(second[commonChars]))) {
return commonChars;
}
if ((commonChars == second.Length) && IsDirectorySeparator(first[commonChars])) {
return commonChars;
}
// It's possible we matched somewhere in the middle of a segment e.g. C:\Foodie and C:\Foobar.
while ((commonChars > 0) && !IsDirectorySeparator(first[commonChars - 1])) {
commonChars--;
}
return commonChars;
}
/// <summary>
/// True if the given character is a directory separator.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsDirectorySeparator(char c) => (c == System.IO.Path.DirectorySeparatorChar) || (c == System.IO.Path.AltDirectorySeparatorChar);
/// <summary>
/// Gets the count of common characters from the left optionally ignoring case
/// </summary>
private static unsafe int EqualStartingCharacterCount(string first, string second, bool ignoreCase) {
if (string.IsNullOrEmpty(first) || string.IsNullOrEmpty(second)) {
return 0;
}
int commonChars = 0;
fixed (char* f = first)
fixed (char* s = second) {
char* l = f;
char* r = s;
char* leftEnd = l + first.Length;
char* rightEnd = r + second.Length;
while ((l != leftEnd) && (r != rightEnd)
&& ((*l == *r) || (ignoreCase &&
(char.ToUpperInvariant(*l) == char.ToUpperInvariant(*r))))) {
commonChars++;
l++;
r++;
}
}
return commonChars;
}
/// <summary>
/// Gets the length of the root of the path (drive, share, etc.).
/// </summary>
private static int GetRootLength(string path) {
int i = 0;
int volumeSeparatorLength = 2; // Length to the colon "C:"
int uncRootLength = 2; // Length to the start of the server name "\\"
bool extendedSyntax = path.StartsWith(ExtendedDevicePathPrefix, StringComparison.Ordinal);
bool extendedUncSyntax = path.StartsWith(UncExtendedPathPrefix, StringComparison.Ordinal);
if (extendedSyntax) {
// Shift the position we look for the root from to account for the extended prefix
if (extendedUncSyntax) {
// "\\" -> "\\?\UNC\"
uncRootLength = UncExtendedPathPrefix.Length;
} else {
// "C:" -> "\\?\C:"
volumeSeparatorLength += ExtendedDevicePathPrefix.Length;
}
}
if ((!extendedSyntax || extendedUncSyntax) && (path.Length > 0) && IsDirectorySeparator(path[0])) {
// UNC or simple rooted path (e.g. "\foo", NOT "\\?\C:\foo")
i = 1; // Drive rooted (\foo) is one character
if (extendedUncSyntax || ((path.Length > 1) && IsDirectorySeparator(path[1]))) {
// UNC (\\?\UNC\ or \\), scan past the next two directory separators at most
// (e.g. to \\?\UNC\Server\Share or \\Server\Share\)
i = uncRootLength;
int n = 2; // Maximum separators to skip
while ((i < path.Length) && (!IsDirectorySeparator(path[i]) || (--n > 0))) {
i++;
}
}
} else if ((path.Length >= volumeSeparatorLength) &&
(path[volumeSeparatorLength - 1] == System.IO.Path.VolumeSeparatorChar)) {
// Path is at least longer than where we expect a colon, and has a colon (\\?\A:, A:)
// If the colon is followed by a directory separator, move past it
i = volumeSeparatorLength;
if ((path.Length >= volumeSeparatorLength + 1) && IsDirectorySeparator(path[volumeSeparatorLength])) {
i++;
}
}
return i;
}
}
}
#endif

View file

@ -1,207 +0,0 @@
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
// |
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
// Contact: JustArchi@JustArchi.net
// |
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// |
// http://www.apache.org/licenses/LICENSE-2.0
// |
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#if NETFRAMEWORK
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net.WebSockets;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.Localization;
using Microsoft.AspNetCore.Hosting;
#endif
using System;
using System.Diagnostics;
using JetBrains.Annotations;
namespace ArchiSteamFarm.Compatibility {
[PublicAPI]
public static class StaticHelpers {
#if NETFRAMEWORK
private static readonly DateTime SavedProcessStartTime = DateTime.UtcNow;
#endif
#if NETFRAMEWORK
public static bool IsRunningOnMono => Type.GetType("Mono.Runtime") != null;
#else
public static bool IsRunningOnMono => false;
#endif
public static DateTime ProcessStartTime {
get {
#if NETFRAMEWORK
if (IsRunningOnMono) {
return SavedProcessStartTime;
}
#endif
using Process process = Process.GetCurrentProcess();
return process.StartTime;
}
}
#if NETFRAMEWORK
public static Task<byte[]> ComputeHashAsync(this HashAlgorithm hashAlgorithm, Stream inputStream) {
if (hashAlgorithm == null) {
throw new ArgumentNullException(nameof(hashAlgorithm));
}
return Task.FromResult(hashAlgorithm.ComputeHash(inputStream));
}
public static IAsyncDisposable ConfigureAwait(this IDisposable source, bool _) {
if (source == null) {
throw new ArgumentNullException(nameof(source));
}
return new AsyncDisposableWrapper(source);
}
public static IWebHostBuilder ConfigureWebHostDefaults(this IWebHostBuilder builder, Action<IWebHostBuilder> configure) {
if (configure == null) {
throw new ArgumentNullException(nameof(configure));
}
configure(builder);
return builder;
}
public static bool Contains(this string input, string value, StringComparison comparisonType) {
if (input == null) {
throw new ArgumentNullException(nameof(input));
}
return input.IndexOf(value, comparisonType) >= 0;
}
// ReSharper disable once UseDeconstructionOnParameter - we actually implement deconstruction here
public static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> kv, out TKey key, out TValue value) {
key = kv.Key;
value = kv.Value;
}
public static ValueTask DisposeAsync(this IDisposable disposable) {
if (disposable == null) {
throw new ArgumentNullException(nameof(disposable));
}
disposable.Dispose();
return default(ValueTask);
}
public static int IndexOf(this string source, char value, StringComparison comparisonType) {
if (source == null) {
throw new ArgumentNullException(nameof(source));
}
return source.IndexOf(value.ToString(), comparisonType);
}
public static async Task<int> ReadAsync(this Stream stream, ReadOnlyMemory<byte> buffer) {
if (stream == null) {
throw new ArgumentNullException(nameof(stream));
}
byte[] byteArray = buffer.ToArray();
return await stream.ReadAsync(byteArray, 0, byteArray.Length).ConfigureAwait(false);
}
public static async Task<WebSocketReceiveResult> ReceiveAsync(this WebSocket webSocket, byte[] buffer, CancellationToken cancellationToken) {
if (webSocket == null) {
throw new ArgumentNullException(nameof(webSocket));
}
return await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken).ConfigureAwait(false);
}
public static string Replace(this string source, string oldValue, string? newValue, StringComparison comparisonType) {
if (source == null) {
throw new ArgumentNullException(nameof(source));
}
if (oldValue == null) {
throw new ArgumentNullException(nameof(oldValue));
}
if (oldValue.Length == 0) {
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(oldValue)), nameof(oldValue));
}
int startIndex = 0;
while (true) {
if (startIndex >= source.Length) {
return source;
}
int index = source.IndexOf(oldValue, startIndex, comparisonType);
if (index < 0) {
return source;
}
startIndex = index;
source = source.Remove(index, oldValue.Length);
if (!string.IsNullOrEmpty(newValue)) {
source = source.Insert(index, newValue!);
startIndex += newValue!.Length;
}
}
}
public static async Task SendAsync(this WebSocket webSocket, byte[] buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) {
if (webSocket == null) {
throw new ArgumentNullException(nameof(webSocket));
}
await webSocket.SendAsync(new ArraySegment<byte>(buffer), messageType, endOfMessage, cancellationToken).ConfigureAwait(false);
}
public static string[] Split(this string text, char separator, StringSplitOptions options = StringSplitOptions.None) {
if (text == null) {
throw new ArgumentNullException(nameof(text));
}
return text.Split(new[] { separator }, options);
}
public static void TrimExcess<TKey, TValue>(this Dictionary<TKey, TValue> _) { } // no-op
public static async Task WriteAsync(this Stream stream, ReadOnlyMemory<byte> buffer) {
if (stream == null) {
throw new ArgumentNullException(nameof(stream));
}
byte[] byteArray = buffer.ToArray();
await stream.WriteAsync(byteArray, 0, byteArray.Length).ConfigureAwait(false);
}
#endif
}
}

View file

@ -1,35 +0,0 @@
// _ _ _ ____ _ _____
// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
// |
// Copyright 2015-2021 Łukasz "JustArchi" Domeradzki
// Contact: JustArchi@JustArchi.net
// |
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// |
// http://www.apache.org/licenses/LICENSE-2.0
// |
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#if NETFRAMEWORK
using System;
using JetBrains.Annotations;
namespace ArchiSteamFarm.Compatibility {
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Enum | AttributeTargets.Event | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Module | AttributeTargets.Property | AttributeTargets.Struct, AllowMultiple = true, Inherited = false)]
[PublicAPI]
public sealed class SupportedOSPlatformAttribute : Attribute {
public string PlatformName { get; }
public SupportedOSPlatformAttribute(string platformName) => PlatformName = platformName;
}
}
#endif

View file

@ -21,9 +21,9 @@
#if NETFRAMEWORK
using System.Runtime.InteropServices;
using ArchiSteamFarm.Compatibility;
using File = System.IO.File;
using Path = System.IO.Path;
using JustArchiNET.Madness;
using File = JustArchiNET.Madness.FileMadness.File;
using Path = JustArchiNET.Madness.PathMadness.Path;
#endif
using System;
using System.Collections.Concurrent;
@ -160,7 +160,7 @@ namespace ArchiSteamFarm.Core {
return false;
}
return Compatibility.Path.GetRelativePath(".", botName) == botName;
return Path.GetRelativePath(".", botName) == botName;
}
internal static async Task RestartOrExit() {
@ -941,7 +941,7 @@ namespace ArchiSteamFarm.Core {
return false;
}
string relativeFilePath = Compatibility.Path.GetRelativePath(targetDirectory, file);
string relativeFilePath = Path.GetRelativePath(targetDirectory, file);
if (string.IsNullOrEmpty(relativeFilePath)) {
ArchiLogger.LogNullError(nameof(relativeFilePath));
@ -986,7 +986,8 @@ namespace ArchiSteamFarm.Core {
Directory.CreateDirectory(targetBackupDirectory);
string targetBackupFile = Path.Combine(targetBackupDirectory, fileName);
Compatibility.File.Move(file, targetBackupFile, true);
File.Move(file, targetBackupFile, true);
}
// We can now get rid of directories that are empty
@ -1007,7 +1008,8 @@ namespace ArchiSteamFarm.Core {
if (File.Exists(file)) {
// This is possible only with files that we decided to leave in place during our backup function
string targetBackupFile = file + ".bak";
Compatibility.File.Move(file, targetBackupFile, true);
File.Move(file, targetBackupFile, true);
}
// Check if this file requires its own folder
@ -1021,7 +1023,8 @@ namespace ArchiSteamFarm.Core {
}
if (!Directory.Exists(directory)) {
Directory.CreateDirectory(directory);
// ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework
Directory.CreateDirectory(directory!);
}
// We're not interested in extracting placeholder files (but we still want directories created for them, done above)

View file

@ -20,8 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using File = System.IO.File;
using JustArchiNET.Madness;
#else
using System.Runtime.Versioning;
#endif
@ -44,6 +43,18 @@ namespace ArchiSteamFarm.Core {
// We need to keep this one assigned and not calculated on-demand
internal static readonly string ProcessFileName = Process.GetCurrentProcess().MainModule?.FileName ?? throw new InvalidOperationException(nameof(ProcessFileName));
internal static DateTime ProcessStartTime {
#if NETFRAMEWORK
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)) {
@ -227,7 +238,7 @@ namespace ArchiSteamFarm.Core {
}
// All windows variants have valid .NET Core build, and generic-netf is supported only on mono
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !StaticHelpers.IsRunningOnMono) {
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !RuntimeMadness.IsRunningOnMono) {
return false;
}

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Generic;
@ -64,7 +64,11 @@ namespace ArchiSteamFarm.Core {
private readonly Bot Bot;
private readonly SemaphoreSlim MatchActivelySemaphore = new(1, 1);
#pragma warning disable CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private readonly Timer MatchActivelyTimer;
#pragma warning restore CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private readonly SemaphoreSlim RequestsSemaphore = new(1, 1);
private DateTime LastAnnouncementCheck;

View file

@ -19,8 +19,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using System;
#if NETFRAMEWORK
using File = JustArchiNET.Madness.FileMadness.File;
#else
using System.IO;
#endif
using System;
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.Core;
@ -86,17 +90,17 @@ namespace ArchiSteamFarm.Helpers {
string newFilePath = FilePath + ".new";
if (File.Exists(FilePath)) {
string currentJson = await Compatibility.File.ReadAllTextAsync(FilePath!).ConfigureAwait(false);
string currentJson = await File.ReadAllTextAsync(FilePath!).ConfigureAwait(false);
if (json == currentJson) {
return;
}
await Compatibility.File.WriteAllTextAsync(newFilePath, json).ConfigureAwait(false);
await File.WriteAllTextAsync(newFilePath, json).ConfigureAwait(false);
File.Replace(newFilePath, FilePath!, null);
} else {
await Compatibility.File.WriteAllTextAsync(newFilePath, json).ConfigureAwait(false);
await File.WriteAllTextAsync(newFilePath, json).ConfigureAwait(false);
File.Move(newFilePath, FilePath!);
}
@ -141,17 +145,17 @@ namespace ArchiSteamFarm.Helpers {
try {
// 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
if (File.Exists(filePath)) {
string currentJson = await Compatibility.File.ReadAllTextAsync(filePath).ConfigureAwait(false);
string currentJson = await File.ReadAllTextAsync(filePath).ConfigureAwait(false);
if (json == currentJson) {
return true;
}
await Compatibility.File.WriteAllTextAsync(newFilePath, json).ConfigureAwait(false);
await File.WriteAllTextAsync(newFilePath, json).ConfigureAwait(false);
File.Replace(newFilePath, filePath, null);
} else {
await Compatibility.File.WriteAllTextAsync(newFilePath, json).ConfigureAwait(false);
await File.WriteAllTextAsync(newFilePath, json).ConfigureAwait(false);
File.Move(newFilePath, filePath);
}

View file

@ -20,9 +20,8 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using File = System.IO.File;
using Path = System.IO.Path;
using JustArchiNET.Madness;
using File = JustArchiNET.Madness.FileMadness.File;
#else
using Microsoft.Extensions.Hosting;
#endif
@ -100,7 +99,7 @@ namespace ArchiSteamFarm.IPC {
if (customConfigExists) {
if (Debugging.IsDebugConfigured) {
try {
string json = await Compatibility.File.ReadAllTextAsync(customConfigPath).ConfigureAwait(false);
string json = await File.ReadAllTextAsync(customConfigPath).ConfigureAwait(false);
if (!string.IsNullOrEmpty(json)) {
JObject jObject = JObject.Parse(json);

View file

@ -19,13 +19,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#if NETFRAMEWORK
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using ArchiSteamFarm.Compatibility;
using ArchiSteamFarm.Core;
using ArchiSteamFarm.IPC.Requests;
using ArchiSteamFarm.IPC.Responses;
@ -71,7 +73,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api {
uint memoryUsage = (uint) GC.GetTotalMemory(false) / 1024;
ASFResponse result = new(SharedInfo.BuildInfo.Variant, SharedInfo.BuildInfo.CanUpdate, ASF.GlobalConfig, memoryUsage, StaticHelpers.ProcessStartTime, SharedInfo.Version);
ASFResponse result = new(SharedInfo.BuildInfo.Variant, SharedInfo.BuildInfo.CanUpdate, ASF.GlobalConfig, memoryUsage, OS.ProcessStartTime, SharedInfo.Version);
return Ok(new GenericResponse<ASFResponse>(result));
}

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Generic;

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Concurrent;

View file

@ -20,16 +20,13 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
using Newtonsoft.Json.Converters;
using File = System.IO.File;
using Path = System.IO.Path;
#else
using System.IO;
#endif
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Reflection;
using ArchiSteamFarm.Core;

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.IO;

View file

@ -19,12 +19,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#if NETFRAMEWORK
using File = JustArchiNET.Madness.FileMadness.File;
#else
using File = System.IO.File;
#endif
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using ArchiSteamFarm.Compatibility;
using ArchiSteamFarm.Core;
using ArchiSteamFarm.Localization;
using JetBrains.Annotations;

View file

@ -20,9 +20,9 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using File = System.IO.File;
using Path = System.IO.Path;
using JustArchiNET.Madness;
using File = JustArchiNET.Madness.FileMadness.File;
using Path = JustArchiNET.Madness.PathMadness.Path;
#endif
using System;
using System.Collections;
@ -148,7 +148,11 @@ namespace ArchiSteamFarm.Steam {
private readonly CallbackManager CallbackManager;
private readonly SemaphoreSlim CallbackSemaphore = new(1, 1);
private readonly SemaphoreSlim GamesRedeemerInBackgroundSemaphore = new(1, 1);
#pragma warning disable CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private readonly Timer HeartBeatTimer;
#pragma warning restore CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private readonly SemaphoreSlim InitializationSemaphore = new(1, 1);
private readonly SemaphoreSlim MessagingSemaphore = new(1, 1);
private readonly ConcurrentDictionary<UserNotificationsCallback.EUserNotification, uint> PastNotifications = new();
@ -228,19 +232,34 @@ namespace ArchiSteamFarm.Steam {
[JsonProperty]
private string? AvatarHash;
#pragma warning disable CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private Timer? ConnectionFailureTimer;
#pragma warning restore CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private bool FirstTradeSent;
#pragma warning disable CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private Timer? GamesRedeemerInBackgroundTimer;
#pragma warning restore CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private byte HeartBeatFailures;
private byte InvalidPasswordFailures;
private EResult LastLogOnResult;
private DateTime LastLogonSessionReplaced;
private bool LibraryLocked;
private ulong MasterChatGroupID;
#pragma warning disable CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private Timer? PlayingWasBlockedTimer;
#pragma warning restore CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private bool ReconnectOnUserInitiated;
private bool SendCompleteTypesScheduled;
#pragma warning disable CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private Timer? SendItemsTimer;
#pragma warning restore CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private bool SteamParentalActive = true;
private SteamSaleEvent? SteamSaleEvent;
private string? TwoFactorCode;
@ -1907,7 +1926,7 @@ namespace ArchiSteamFarm.Steam {
ArchiLogger.LogGenericInfo(Strings.BotAuthenticatorConverting);
try {
string json = await Compatibility.File.ReadAllTextAsync(maFilePath).ConfigureAwait(false);
string json = await File.ReadAllTextAsync(maFilePath).ConfigureAwait(false);
if (string.IsNullOrEmpty(json)) {
ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(json)));
@ -2178,7 +2197,7 @@ namespace ArchiSteamFarm.Steam {
if (File.Exists(sentryFilePath)) {
try {
byte[] sentryFileContent = await Compatibility.File.ReadAllBytesAsync(sentryFilePath).ConfigureAwait(false);
byte[] sentryFileContent = await File.ReadAllBytesAsync(sentryFilePath).ConfigureAwait(false);
sentryFileHash = CryptoHelper.SHAHash(sentryFileContent);
} catch (Exception e) {
ArchiLogger.LogGenericException(e);
@ -3211,7 +3230,7 @@ namespace ArchiSteamFarm.Steam {
}
try {
await Compatibility.File.AppendAllTextAsync(filePath, logEntry + Environment.NewLine).ConfigureAwait(false);
await File.AppendAllTextAsync(filePath, logEntry + Environment.NewLine).ConfigureAwait(false);
} catch (Exception e) {
ArchiLogger.LogGenericException(e);
ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.Content, logEntry));

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Concurrent;
@ -83,7 +83,11 @@ namespace ArchiSteamFarm.Steam.Cards {
private readonly SemaphoreSlim FarmingInitializationSemaphore = new(1, 1);
private readonly SemaphoreSlim FarmingResetSemaphore = new(0, 1);
private readonly ConcurrentList<Game> GamesToFarm = new();
#pragma warning disable CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private readonly Timer? IdleFarmingTimer;
#pragma warning restore CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private readonly ConcurrentDictionary<uint, DateTime> LocallyIgnoredAppIDs = new();
private IEnumerable<ConcurrentDictionary<uint, DateTime>> SourcesOfIgnoredAppIDs {

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using HashCode = ArchiSteamFarm.Compatibility.HashCode;
using HashCode = JustArchiNET.Madness.HashCodeMadness.HashCode;
#endif
using System;
using Newtonsoft.Json;

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Generic;

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Concurrent;
@ -49,7 +49,6 @@ using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SteamKit2;
using Formatting = Newtonsoft.Json.Formatting;
namespace ArchiSteamFarm.Steam.Integration {
public sealed class ArchiWebHandler : IDisposable {

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.Buffers;

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Immutable;
@ -36,7 +36,10 @@ namespace ArchiSteamFarm.Steam.Integration {
private const byte MaxSingleQueuesDaily = 3; // This is only a failsafe for infinite queue clearing (in case IsDiscoveryQueueAvailable() would fail us)
private readonly Bot Bot;
#pragma warning disable CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private readonly Timer SaleEventTimer;
#pragma warning restore CA2213 // False positive, .NET Framework can't understand DisposeAsync()
internal SteamSaleEvent(Bot bot) {
Bot = bot ?? throw new ArgumentNullException(nameof(bot));

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Generic;
@ -53,7 +53,10 @@ namespace ArchiSteamFarm.Steam.Interaction {
private readonly ConcurrentHashSet<ulong> HandledGifts = new();
private readonly SemaphoreSlim TradingSemaphore = new(1, 1);
#pragma warning disable CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private Timer? CardsFarmerResumeTimer;
#pragma warning restore CA2213 // False positive, .NET Framework can't understand DisposeAsync()
private bool ProcessingGiftsScheduled;
private bool TradingScheduled;

View file

@ -19,6 +19,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#if NETFRAMEWORK
using JustArchiNET.Madness;
#endif
using System;
using System.Collections.Generic;
using System.Globalization;
@ -27,7 +30,6 @@ using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using ArchiSteamFarm.Compatibility;
using ArchiSteamFarm.Core;
using ArchiSteamFarm.Helpers;
using ArchiSteamFarm.Localization;
@ -3026,7 +3028,7 @@ namespace ArchiSteamFarm.Steam.Interaction {
}
ushort memoryInMegabytes = (ushort) (GC.GetTotalMemory(false) / 1024 / 1024);
TimeSpan uptime = DateTime.UtcNow.Subtract(StaticHelpers.ProcessStartTime.ToUniversalTime());
TimeSpan uptime = DateTime.UtcNow.Subtract(OS.ProcessStartTime);
return FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotStats, memoryInMegabytes, uptime.ToHumanReadable()));
}

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using HashCode = ArchiSteamFarm.Compatibility.HashCode;
using HashCode = JustArchiNET.Madness.HashCodeMadness.HashCode;
#endif
using System;
using System.ComponentModel;

View file

@ -20,8 +20,8 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using File = System.IO.File;
using JustArchiNET.Madness;
using File = JustArchiNET.Madness.FileMadness.File;
#else
using System.IO;
#endif
@ -452,7 +452,7 @@ namespace ArchiSteamFarm.Steam.Storage {
BotConfig? botConfig;
try {
json = await Compatibility.File.ReadAllTextAsync(filePath).ConfigureAwait(false);
json = await File.ReadAllTextAsync(filePath).ConfigureAwait(false);
if (string.IsNullOrEmpty(json)) {
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(json)));

View file

@ -19,11 +19,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#if NETFRAMEWORK
using File = JustArchiNET.Madness.FileMadness.File;
#else
using System.IO;
#endif
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using ArchiSteamFarm.Collections;
@ -155,7 +159,7 @@ namespace ArchiSteamFarm.Steam.Storage {
BotDatabase? botDatabase;
try {
string json = await Compatibility.File.ReadAllTextAsync(filePath).ConfigureAwait(false);
string json = await File.ReadAllTextAsync(filePath).ConfigureAwait(false);
if (string.IsNullOrEmpty(json)) {
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(json)));

View file

@ -19,13 +19,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#if NETFRAMEWORK
using File = JustArchiNET.Madness.FileMadness.File;
#else
using System.IO;
#endif
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using ArchiSteamFarm.Core;
@ -378,7 +382,7 @@ namespace ArchiSteamFarm.Storage {
GlobalConfig? globalConfig;
try {
json = await Compatibility.File.ReadAllTextAsync(filePath).ConfigureAwait(false);
json = await File.ReadAllTextAsync(filePath).ConfigureAwait(false);
if (string.IsNullOrEmpty(json)) {
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(json)));

View file

@ -20,8 +20,8 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using File = System.IO.File;
using JustArchiNET.Madness;
using File = JustArchiNET.Madness.FileMadness.File;
#else
using System.IO;
#endif
@ -188,7 +188,7 @@ namespace ArchiSteamFarm.Storage {
GlobalDatabase? globalDatabase;
try {
string json = await Compatibility.File.ReadAllTextAsync(filePath).ConfigureAwait(false);
string json = await File.ReadAllTextAsync(filePath).ConfigureAwait(false);
if (string.IsNullOrEmpty(json)) {
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsEmpty, nameof(json)));

View file

@ -20,7 +20,7 @@
// limitations under the License.
#if NETFRAMEWORK
using ArchiSteamFarm.Compatibility;
using JustArchiNET.Madness;
#endif
using System;
using System.IO;

View file

@ -19,6 +19,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#if NETFRAMEWORK
using JustArchiNET.Madness;
#endif
using System;
using System.Buffers;
using System.Collections.Generic;
@ -31,7 +34,6 @@ using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using ArchiSteamFarm.Compatibility;
using ArchiSteamFarm.Core;
using ArchiSteamFarm.Localization;
using ArchiSteamFarm.NLog;
@ -79,9 +81,13 @@ namespace ArchiSteamFarm.Web {
HttpClientHandler.UseProxy = true;
}
if (!StaticHelpers.IsRunningOnMono) {
#if NETFRAMEWORK
if (!RuntimeMadness.IsRunningOnMono) {
HttpClientHandler.MaxConnectionsPerServer = MaxConnections;
}
#else
HttpClientHandler.MaxConnectionsPerServer = MaxConnections;
#endif
HttpClient = GenerateDisposableHttpClient(extendedTimeout);
}
@ -714,9 +720,13 @@ namespace ArchiSteamFarm.Web {
ServicePointManager.Expect100Continue = false;
// Reuse ports if possible
if (!StaticHelpers.IsRunningOnMono) {
#if NETFRAMEWORK
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) {

View file

@ -29,6 +29,7 @@
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
<PackageVersion Include="IndexRange" Version="1.0.0" />
<PackageVersion Include="JustArchiNET.Madness" Version="0.3.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" />