mirror of
https://github.com/JustArchiNET/ArchiSteamFarm
synced 2024-11-10 07:04:27 +00:00
Embrace madness (#2394)
* Embrace madness * Remove unused code * Misc * Address Abry's note * Update for Madness 0.3.0
This commit is contained in:
parent
b47f290512
commit
9f281c6055
42 changed files with 151 additions and 762 deletions
|
@ -11,6 +11,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
|
||||
<PackageReference Include="JustArchiNET.Madness" IncludeAssets="compile" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" IncludeAssets="compile" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
using JustArchiNET.Madness;
|
||||
#endif
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
using JustArchiNET.Madness;
|
||||
#endif
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
using JustArchiNET.Madness;
|
||||
#endif
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
using JustArchiNET.Madness;
|
||||
#endif
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
using JustArchiNET.Madness;
|
||||
#endif
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
using JustArchiNET.Madness;
|
||||
#endif
|
||||
using System;
|
||||
using System.IO;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
using JustArchiNET.Madness;
|
||||
#endif
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
using JustArchiNET.Madness;
|
||||
#endif
|
||||
using System;
|
||||
using System.Buffers;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using ArchiSteamFarm.Compatibility;
|
||||
using JustArchiNET.Madness;
|
||||
#endif
|
||||
using System;
|
||||
using System.IO;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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" />
|
||||
|
|
Loading…
Reference in a new issue