mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2026-01-16 08:25:28 +00:00
Add workarounds for #335
This commit is contained in:
@@ -345,14 +345,48 @@ namespace ArchiSteamFarm {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<bool> HandleConfirmations(string deviceID, string confirmationHash, uint time, HashSet<MobileAuthenticator.Confirmation> confirmations, bool accept) {
|
internal async Task<bool?> HandleConfirmation(string deviceID, string confirmationHash, uint time, uint confirmationID, ulong confirmationKey, bool accept) {
|
||||||
if (string.IsNullOrEmpty(deviceID) || string.IsNullOrEmpty(confirmationHash) || (time == 0) || (confirmations == null) || (confirmations.Count == 0)) {
|
if (string.IsNullOrEmpty(deviceID) || string.IsNullOrEmpty(confirmationHash) || (time == 0) || (confirmationID == 0) || (confirmationKey == 0)) {
|
||||||
Logging.LogNullError(nameof(deviceID) + " || " + nameof(confirmationHash) + " || " + nameof(time) + " || " + nameof(confirmations), Bot.BotName);
|
Logging.LogNullError(nameof(deviceID) + " || " + nameof(confirmationHash) + " || " + nameof(time) + " || " + nameof(confirmationID) + " || " + nameof(confirmationKey), Bot.BotName);
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||||
return false;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
string request = SteamCommunityURL + "/mobileconf/ajaxop?op=" + (accept ? "allow" : "cancel") + "&p=" + deviceID + "&a=" + SteamID + "&k=" + WebUtility.UrlEncode(confirmationHash) + "&t=" + time + "&m=android&tag=conf&cid=" + confirmationID + "&ck=" + confirmationKey;
|
||||||
|
|
||||||
|
string json = await WebBrowser.UrlGetToContentRetry(request).ConfigureAwait(false);
|
||||||
|
if (string.IsNullOrEmpty(json)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Steam.ConfirmationResponse response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = JsonConvert.DeserializeObject<Steam.ConfirmationResponse>(json);
|
||||||
|
} catch (JsonException e) {
|
||||||
|
Logging.LogGenericException(e, Bot.BotName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response != null) {
|
||||||
|
return response.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logging.LogNullError(nameof(response), Bot.BotName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal async Task<bool?> HandleConfirmations(string deviceID, string confirmationHash, uint time, HashSet<MobileAuthenticator.Confirmation> confirmations, bool accept) {
|
||||||
|
if (string.IsNullOrEmpty(deviceID) || string.IsNullOrEmpty(confirmationHash) || (time == 0) || (confirmations == null) || (confirmations.Count == 0)) {
|
||||||
|
Logging.LogNullError(nameof(deviceID) + " || " + nameof(confirmationHash) + " || " + nameof(time) + " || " + nameof(confirmations), Bot.BotName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string request = SteamCommunityURL + "/mobileconf/multiajaxop";
|
string request = SteamCommunityURL + "/mobileconf/multiajaxop";
|
||||||
@@ -374,7 +408,7 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
string json = await WebBrowser.UrlPostToContentRetry(request, data).ConfigureAwait(false);
|
string json = await WebBrowser.UrlPostToContentRetry(request, data).ConfigureAwait(false);
|
||||||
if (string.IsNullOrEmpty(json)) {
|
if (string.IsNullOrEmpty(json)) {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Steam.ConfirmationResponse response;
|
Steam.ConfirmationResponse response;
|
||||||
@@ -383,7 +417,7 @@ namespace ArchiSteamFarm {
|
|||||||
response = JsonConvert.DeserializeObject<Steam.ConfirmationResponse>(json);
|
response = JsonConvert.DeserializeObject<Steam.ConfirmationResponse>(json);
|
||||||
} catch (JsonException e) {
|
} catch (JsonException e) {
|
||||||
Logging.LogGenericException(e, Bot.BotName);
|
Logging.LogGenericException(e, Bot.BotName);
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
@@ -391,7 +425,7 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Logging.LogNullError(nameof(response), Bot.BotName);
|
Logging.LogNullError(nameof(response), Bot.BotName);
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<Dictionary<uint, string>> GetOwnedGames() {
|
internal async Task<Dictionary<uint, string>> GetOwnedGames() {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ using Newtonsoft.Json;
|
|||||||
namespace ArchiSteamFarm {
|
namespace ArchiSteamFarm {
|
||||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||||
internal sealed class MobileAuthenticator {
|
internal sealed class MobileAuthenticator : IDisposable {
|
||||||
internal sealed class Confirmation {
|
internal sealed class Confirmation {
|
||||||
internal readonly uint ID;
|
internal readonly uint ID;
|
||||||
internal readonly ulong Key;
|
internal readonly ulong Key;
|
||||||
@@ -66,7 +66,7 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
private static short SteamTimeDifference;
|
private static short SteamTimeDifference;
|
||||||
|
|
||||||
internal bool HasCorrectDeviceID => !string.IsNullOrEmpty(DeviceID) && !DeviceID.Equals("ERROR"); // "ERROR" is being used by SteamDesktopAuthenticator
|
private readonly SemaphoreSlim ConfirmationsSemaphore = new SemaphoreSlim(1);
|
||||||
|
|
||||||
#pragma warning disable 649
|
#pragma warning disable 649
|
||||||
[JsonProperty(PropertyName = "shared_secret", Required = Required.Always)]
|
[JsonProperty(PropertyName = "shared_secret", Required = Required.Always)]
|
||||||
@@ -81,6 +81,8 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
private Bot Bot;
|
private Bot Bot;
|
||||||
|
|
||||||
|
internal bool HasCorrectDeviceID => !string.IsNullOrEmpty(DeviceID) && !DeviceID.Equals("ERROR"); // "ERROR" is being used by SteamDesktopAuthenticator
|
||||||
|
|
||||||
private MobileAuthenticator() { }
|
private MobileAuthenticator() { }
|
||||||
|
|
||||||
internal void Init(Bot bot) {
|
internal void Init(Bot bot) {
|
||||||
@@ -111,19 +113,45 @@ namespace ArchiSteamFarm {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint time = await GetSteamTime().ConfigureAwait(false);
|
await ConfirmationsSemaphore.WaitAsync().ConfigureAwait(false);
|
||||||
if (time == 0) {
|
|
||||||
Logging.LogNullError(nameof(time), Bot.BotName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string confirmationHash = GenerateConfirmationKey(time, "conf");
|
try {
|
||||||
if (!string.IsNullOrEmpty(confirmationHash)) {
|
uint time = await GetSteamTime().ConfigureAwait(false);
|
||||||
return await Bot.ArchiWebHandler.HandleConfirmations(DeviceID, confirmationHash, time, confirmations, accept).ConfigureAwait(false);
|
if (time == 0) {
|
||||||
}
|
Logging.LogNullError(nameof(time), Bot.BotName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Logging.LogNullError(nameof(confirmationHash), Bot.BotName);
|
string confirmationHash = GenerateConfirmationKey(time, "conf");
|
||||||
return false;
|
if (string.IsNullOrEmpty(confirmationHash)) {
|
||||||
|
Logging.LogNullError(nameof(confirmationHash), Bot.BotName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool? result = await Bot.ArchiWebHandler.HandleConfirmations(DeviceID, confirmationHash, time, confirmations, accept).ConfigureAwait(false);
|
||||||
|
if (!result.HasValue) { // Request timed out
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.Value) { // Request succeeded
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our multi request failed, this is almost always Steam fuckup that happens randomly
|
||||||
|
// In this case, we'll accept all pending confirmations one-by-one, synchronously (as Steam can't handle them in parallel)
|
||||||
|
// We totally ignore actual result returned by those calls, abort only if request timed out
|
||||||
|
|
||||||
|
foreach (Confirmation confirmation in confirmations) {
|
||||||
|
bool? confirmationResult = await Bot.ArchiWebHandler.HandleConfirmation(DeviceID, confirmationHash, time, confirmation.ID, confirmation.Key, accept).ConfigureAwait(false);
|
||||||
|
if (!confirmationResult.HasValue) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} finally {
|
||||||
|
ConfirmationsSemaphore.Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<Steam.ConfirmationDetails> GetConfirmationDetails(Confirmation confirmation) {
|
internal async Task<Steam.ConfirmationDetails> GetConfirmationDetails(Confirmation confirmation) {
|
||||||
@@ -332,7 +360,9 @@ namespace ArchiSteamFarm {
|
|||||||
hash = hmac.ComputeHash(buffer);
|
hash = hmac.ComputeHash(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Convert.ToBase64String(hash, Base64FormattingOptions.None);
|
return Convert.ToBase64String(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose() => ConfirmationsSemaphore.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user