Compare commits

..

13 Commits

Author SHA1 Message Date
JustArchi
e325d58944 Translations update 2020-06-08 14:34:19 +02:00
JustArchi
185dde9d34 Address possible .NET Core tmp path change in #1812 2020-06-08 14:29:52 +02:00
dependabot-preview[bot]
04afb5b891 Bump MSTest.TestFramework from 2.1.1 to 2.1.2
Bumps [MSTest.TestFramework](https://github.com/microsoft/testfx) from 2.1.1 to 2.1.2.
- [Release notes](https://github.com/microsoft/testfx/releases)
- [Commits](https://github.com/microsoft/testfx/compare/v2.1.1...v2.1.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-08 12:16:16 +00:00
dependabot-preview[bot]
a7442e61b1 Bump MSTest.TestAdapter from 2.1.1 to 2.1.2
Bumps [MSTest.TestAdapter](https://github.com/microsoft/testfx) from 2.1.1 to 2.1.2.
- [Release notes](https://github.com/microsoft/testfx/releases)
- [Commits](https://github.com/microsoft/testfx/compare/v2.1.1...v2.1.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-08 11:53:38 +00:00
dependabot-preview[bot]
2a35de0afd Bump ASF-ui from 1dd2f37 to 84b84eb
Bumps [ASF-ui](https://github.com/JustArchiNET/ASF-ui) from `1dd2f37` to `84b84eb`.
- [Release notes](https://github.com/JustArchiNET/ASF-ui/releases)
- [Commits](1dd2f3797c...84b84eb0fa)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-08 01:22:32 +00:00
JustArchi
5351e61687 Open SteamApps and SteamFriends for optional plugin usage 2020-06-07 21:07:19 +02:00
JustArchi
e83c468fba Misc 2020-06-07 21:06:41 +02:00
JustArchi
70cf69d9db Misc 2020-06-07 20:00:57 +02:00
JustArchi
a84d16a1dd Expose ASF's PackagesData for optional plugin usage 2020-06-07 20:00:06 +02:00
Vitaliy
ea3347b36d Accept HttpContent as data in WebBrowser (#1828) 2020-06-07 17:09:01 +02:00
JustArchi
2865259a6a Enable SK2 debug only with debugging config, not just debug build 2020-06-06 22:06:32 +02:00
JustArchi
cb6c5e2de2 Make it possible for WebBrowser to post custom data
While this isn't required for ASF (at least right now), it'll allow plugins to use ASF's WebBrowser for sending e.g. json to third-party endpoints.
2020-06-06 16:34:20 +02:00
JustArchi
a6a8dfb78b Bump 2020-06-06 15:06:32 +02:00
13 changed files with 78 additions and 47 deletions

2
ASF-ui

Submodule ASF-ui updated: 1dd2f3797c...810095a335

View File

@@ -8,8 +8,8 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
</ItemGroup>
<ItemGroup>

View File

@@ -913,7 +913,7 @@ namespace ArchiSteamFarm {
}
}
WebBrowser.ObjectResponse<T> response = await WebLimitRequest(host, async () => await WebBrowser.UrlPostToJsonObject<T>(host + request, data, referer).ConfigureAwait(false)).ConfigureAwait(false);
WebBrowser.ObjectResponse<T> response = await WebLimitRequest(host, async () => await WebBrowser.UrlPostToJsonObject<T, Dictionary<string, string>>(host + request, data, referer).ConfigureAwait(false)).ConfigureAwait(false);
if (response == null) {
return null;
@@ -1028,7 +1028,7 @@ namespace ArchiSteamFarm {
}
}
WebBrowser.ObjectResponse<T> response = await WebLimitRequest(host, async () => await WebBrowser.UrlPostToJsonObject<T>(host + request, data, referer).ConfigureAwait(false)).ConfigureAwait(false);
WebBrowser.ObjectResponse<T> response = await WebLimitRequest(host, async () => await WebBrowser.UrlPostToJsonObject<T, List<KeyValuePair<string, string>>>(host + request, data, referer).ConfigureAwait(false)).ConfigureAwait(false);
if (response == null) {
return null;

View File

@@ -86,10 +86,18 @@ namespace ArchiSteamFarm {
[PublicAPI]
public readonly Commands Commands;
[JsonIgnore]
[PublicAPI]
public readonly SteamApps SteamApps;
[JsonIgnore]
[PublicAPI]
public readonly SteamConfiguration SteamConfiguration;
[JsonIgnore]
[PublicAPI]
public readonly SteamFriends SteamFriends;
[JsonProperty]
[PublicAPI]
public uint GamesToRedeemInBackgroundCount => BotDatabase?.GamesToRedeemInBackgroundCount ?? 0;
@@ -110,8 +118,6 @@ namespace ArchiSteamFarm {
internal readonly BotDatabase BotDatabase;
internal readonly ConcurrentDictionary<uint, (EPaymentMethod PaymentMethod, DateTime TimeCreated, ulong AccessToken)> OwnedPackageIDs = new ConcurrentDictionary<uint, (EPaymentMethod PaymentMethod, DateTime TimeCreated, ulong AccessToken)>();
internal readonly SteamApps SteamApps;
internal readonly SteamFriends SteamFriends;
internal bool CanReceiveSteamCards => !IsAccountLimited && !IsAccountLocked;
internal bool IsAccountLimited => AccountFlags.HasFlag(EAccountFlags.LimitedUser) || AccountFlags.HasFlag(EAccountFlags.LimitedUserForce);
@@ -234,7 +240,7 @@ namespace ArchiSteamFarm {
// Initialize
SteamClient = new SteamClient(SteamConfiguration, botName);
if (Debugging.IsUserDebugging && Directory.Exists(SharedInfo.DebugDirectory)) {
if (Debugging.IsDebugConfigured && Directory.Exists(SharedInfo.DebugDirectory)) {
string debugListenerPath = Path.Combine(SharedInfo.DebugDirectory, botName);
try {
@@ -2363,7 +2369,7 @@ namespace ArchiSteamFarm {
foreach (SteamApps.LicenseListCallback.License license in callback.LicenseList.Where(license => license.PackageID != 0)) {
OwnedPackageIDs[license.PackageID] = (license.PaymentMethod, license.TimeCreated, license.AccessToken);
if (!ASF.GlobalDatabase.PackagesData.TryGetValue(license.PackageID, out (uint ChangeNumber, HashSet<uint> AppIDs) packageData) || (packageData.ChangeNumber < license.LastChangeNumber) || (packageData.AppIDs == null)) {
if (!ASF.GlobalDatabase.PackagesDataReadOnly.TryGetValue(license.PackageID, out (uint ChangeNumber, HashSet<uint> AppIDs) packageData) || (packageData.ChangeNumber < license.LastChangeNumber) || (packageData.AppIDs == null)) {
packagesToRefresh[license.PackageID] = (uint) license.LastChangeNumber;
}
}

View File

@@ -84,10 +84,10 @@ namespace ArchiSteamFarm {
}
}
[JsonProperty(PropertyName = "_LoginKey")]
[JsonProperty(PropertyName = "_" + nameof(LoginKey))]
private string BackingLoginKey;
[JsonProperty(PropertyName = "_MobileAuthenticator")]
[JsonProperty(PropertyName = "_" + nameof(MobileAuthenticator))]
private MobileAuthenticator BackingMobileAuthenticator;
private BotDatabase([NotNull] string filePath) {

View File

@@ -35,14 +35,19 @@ using Newtonsoft.Json;
namespace ArchiSteamFarm {
public sealed class GlobalDatabase : SerializableFile {
[JsonProperty(Required = Required.DisallowNull)]
[PublicAPI]
public readonly Guid Guid = Guid.NewGuid();
[JsonProperty(Required = Required.DisallowNull)]
internal readonly ConcurrentDictionary<uint, (uint ChangeNumber, HashSet<uint> AppIDs)> PackagesData = new ConcurrentDictionary<uint, (uint ChangeNumber, HashSet<uint> AppIDs)>();
[JsonIgnore]
[PublicAPI]
public IReadOnlyDictionary<uint, (uint ChangeNumber, HashSet<uint> AppIDs)> PackagesDataReadOnly => PackagesData;
[JsonProperty(Required = Required.DisallowNull)]
internal readonly InMemoryServerListProvider ServerListProvider = new InMemoryServerListProvider();
[JsonProperty(Required = Required.DisallowNull)]
private readonly ConcurrentDictionary<uint, (uint ChangeNumber, HashSet<uint> AppIDs)> PackagesData = new ConcurrentDictionary<uint, (uint ChangeNumber, HashSet<uint> AppIDs)>();
private readonly SemaphoreSlim PackagesRefreshSemaphore = new SemaphoreSlim(1, 1);
internal uint CellID {
@@ -58,7 +63,7 @@ namespace ArchiSteamFarm {
}
}
[JsonProperty(PropertyName = "_CellID", Required = Required.DisallowNull)]
[JsonProperty(PropertyName = "_" + nameof(CellID), Required = Required.DisallowNull)]
private uint BackingCellID;
private GlobalDatabase([NotNull] string filePath) : this() {

View File

@@ -324,15 +324,17 @@ namespace ArchiSteamFarm {
Logging.EnableTraceLogging();
DebugLog.AddListener(new Debugging.DebugListener());
DebugLog.Enabled = true;
if (Debugging.IsDebugConfigured) {
DebugLog.AddListener(new Debugging.DebugListener());
DebugLog.Enabled = true;
if (Directory.Exists(SharedInfo.DebugDirectory)) {
try {
Directory.Delete(SharedInfo.DebugDirectory, true);
await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync
} catch (Exception e) {
ASF.ArchiLogger.LogGenericException(e);
if (Directory.Exists(SharedInfo.DebugDirectory)) {
try {
Directory.Delete(SharedInfo.DebugDirectory, true);
await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync
} catch (Exception e) {
ASF.ArchiLogger.LogGenericException(e);
}
}
}

View File

@@ -25,6 +25,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using AngleSharp;
@@ -284,7 +285,7 @@ namespace ArchiSteamFarm {
[ItemCanBeNull]
[PublicAPI]
public async Task<BasicResponse> UrlPost(string request, IReadOnlyCollection<KeyValuePair<string, string>> data = null, string referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) {
public async Task<BasicResponse> UrlPost<T>(string request, T data = null, string referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where T : class {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
ArchiLogger.LogNullError(nameof(request) + " || " + nameof(maxTries));
@@ -321,7 +322,7 @@ namespace ArchiSteamFarm {
[ItemCanBeNull]
[PublicAPI]
public async Task<HtmlDocumentResponse> UrlPostToHtmlDocument(string request, IReadOnlyCollection<KeyValuePair<string, string>> data = null, string referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) {
public async Task<HtmlDocumentResponse> UrlPostToHtmlDocument<T>(string request, T data = null, string referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where T : class {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
ArchiLogger.LogNullError(nameof(request) + " || " + nameof(maxTries));
@@ -366,21 +367,21 @@ namespace ArchiSteamFarm {
[ItemCanBeNull]
[PublicAPI]
public async Task<ObjectResponse<T>> UrlPostToJsonObject<T>(string request, IReadOnlyCollection<KeyValuePair<string, string>> data = null, string referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where T : class {
public async Task<ObjectResponse<TResult>> UrlPostToJsonObject<TResult, TData>(string request, TData data = null, string referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where TResult : class where TData : class {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
ArchiLogger.LogNullError(nameof(request) + " || " + nameof(maxTries));
return null;
}
ObjectResponse<T> result = null;
ObjectResponse<TResult> result = null;
for (byte i = 0; i < maxTries; i++) {
await using StreamResponse response = await UrlPostToStream(request, data, referer, requestOptions | ERequestOptions.ReturnClientErrors, 1).ConfigureAwait(false);
if (response?.StatusCode.IsClientErrorCode() == true) {
if (requestOptions.HasFlag(ERequestOptions.ReturnClientErrors)) {
result = new ObjectResponse<T>(response);
result = new ObjectResponse<TResult>(response);
}
break;
@@ -390,21 +391,21 @@ namespace ArchiSteamFarm {
continue;
}
T obj;
TResult obj;
try {
using StreamReader steamReader = new StreamReader(response.Content);
using JsonReader jsonReader = new JsonTextReader(steamReader);
JsonSerializer serializer = new JsonSerializer();
obj = serializer.Deserialize<T>(jsonReader);
obj = serializer.Deserialize<TResult>(jsonReader);
} catch (Exception e) {
ArchiLogger.LogGenericWarningException(e);
continue;
}
return new ObjectResponse<T>(response, obj);
return new ObjectResponse<TResult>(response, obj);
}
if (maxTries > 1) {
@@ -567,7 +568,7 @@ namespace ArchiSteamFarm {
return null;
}
return await InternalRequest(new Uri(request), HttpMethod.Get, null, referer, httpCompletionOption).ConfigureAwait(false);
return await InternalRequest<object>(new Uri(request), HttpMethod.Get, null, referer, httpCompletionOption).ConfigureAwait(false);
}
private async Task<HttpResponseMessage> InternalHead(string request, string referer = null) {
@@ -577,10 +578,10 @@ namespace ArchiSteamFarm {
return null;
}
return await InternalRequest(new Uri(request), HttpMethod.Head, null, referer).ConfigureAwait(false);
return await InternalRequest<object>(new Uri(request), HttpMethod.Head, null, referer).ConfigureAwait(false);
}
private async Task<HttpResponseMessage> InternalPost(string request, IReadOnlyCollection<KeyValuePair<string, string>> data = null, string referer = null, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) {
private async Task<HttpResponseMessage> InternalPost<T>(string request, T data = null, string referer = null, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead) where T : class {
if (string.IsNullOrEmpty(request)) {
ArchiLogger.LogNullError(nameof(request));
@@ -590,7 +591,7 @@ namespace ArchiSteamFarm {
return await InternalRequest(new Uri(request), HttpMethod.Post, data, referer, httpCompletionOption).ConfigureAwait(false);
}
private async Task<HttpResponseMessage> InternalRequest(Uri requestUri, HttpMethod httpMethod, IReadOnlyCollection<KeyValuePair<string, string>> data = null, string referer = null, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead, byte maxRedirections = MaxTries) {
private async Task<HttpResponseMessage> InternalRequest<T>(Uri requestUri, HttpMethod httpMethod, T data = null, string referer = null, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead, byte maxRedirections = MaxTries) where T : class {
if ((requestUri == null) || (httpMethod == null)) {
ArchiLogger.LogNullError(nameof(requestUri) + " || " + nameof(httpMethod));
@@ -605,10 +606,27 @@ namespace ArchiSteamFarm {
#endif
if (data != null) {
try {
request.Content = new FormUrlEncodedContent(data);
} catch (UriFormatException) {
request.Content = new StringContent(string.Join("&", data.Select(kv => WebUtility.UrlEncode(kv.Key) + "=" + WebUtility.UrlEncode(kv.Value))), null, "application/x-www-form-urlencoded");
switch (data) {
case HttpContent content:
request.Content = content;
break;
case IReadOnlyCollection<KeyValuePair<string, string>> dictionary:
try {
request.Content = new FormUrlEncodedContent(dictionary);
} catch (UriFormatException) {
request.Content = new StringContent(string.Join("&", dictionary.Select(kv => WebUtility.UrlEncode(kv.Key) + "=" + WebUtility.UrlEncode(kv.Value))), null, "application/x-www-form-urlencoded");
}
break;
case string text:
request.Content = new StringContent(text);
break;
default:
request.Content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
break;
}
}
@@ -732,7 +750,7 @@ namespace ArchiSteamFarm {
}
[ItemCanBeNull]
private async Task<StreamResponse> UrlPostToStream(string request, IReadOnlyCollection<KeyValuePair<string, string>> data = null, string referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) {
private async Task<StreamResponse> UrlPostToStream<T>(string request, T data = null, string referer = null, ERequestOptions requestOptions = ERequestOptions.None, byte maxTries = MaxTries) where T : class {
if (string.IsNullOrEmpty(request) || (maxTries == 0)) {
ArchiLogger.LogNullError(nameof(request) + " || " + nameof(maxTries));

View File

@@ -70,8 +70,8 @@ if [ -n "${DOTNET_RUNNING_IN_CONTAINER-}" ] && [ "$DOTNET_RUNNING_IN_CONTAINER"
while [ "$loops" -gt 0 ]; do
sleep 10
if [ -d "/var/tmp/.net/ArchiSteamFarm" ]; then
find "/var/tmp/.net/ArchiSteamFarm" -mindepth 2 -maxdepth 2 -name '*\\*' | while IFS="" read -r broken_path; do
if [ -d "/var/tmp/.net" ]; then
find "/var/tmp/.net" -mindepth 2 -name '*\\*' | while IFS="" read -r broken_path; do
fixed_path="$(echo "$broken_path" | sed 's/\\/\//g')"
mkdir -p "$(dirname "$fixed_path")"

View File

@@ -70,8 +70,8 @@ if [ -n "${DOTNET_RUNNING_IN_CONTAINER-}" ] && [ "$DOTNET_RUNNING_IN_CONTAINER"
while [ "$loops" -gt 0 ]; do
sleep 10
if [ -d "/var/tmp/.net/ArchiSteamFarm" ]; then
find "/var/tmp/.net/ArchiSteamFarm" -mindepth 2 -maxdepth 2 -name '*\\*' | while IFS="" read -r broken_path; do
if [ -d "/var/tmp/.net" ]; then
find "/var/tmp/.net" -mindepth 2 -name '*\\*' | while IFS="" read -r broken_path; do
fixed_path="$(echo "$broken_path" | sed 's/\\/\//g')"
mkdir -p "$(dirname "$fixed_path")"

View File

@@ -70,8 +70,8 @@ if [ -n "${DOTNET_RUNNING_IN_CONTAINER-}" ] && [ "$DOTNET_RUNNING_IN_CONTAINER"
while [ "$loops" -gt 0 ]; do
sleep 10
if [ -d "/var/tmp/.net/ArchiSteamFarm" ]; then
find "/var/tmp/.net/ArchiSteamFarm" -mindepth 2 -maxdepth 2 -name '*\\*' | while IFS="" read -r broken_path; do
if [ -d "/var/tmp/.net" ]; then
find "/var/tmp/.net" -mindepth 2 -name '*\\*' | while IFS="" read -r broken_path; do
fixed_path="$(echo "$broken_path" | sed 's/\\/\//g')"
mkdir -p "$(dirname "$fixed_path")"

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>4.2.2.0</Version>
<Version>4.2.2.1</Version>
</PropertyGroup>
<PropertyGroup>

2
wiki

Submodule wiki updated: bc6f295df5...508359a397