mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-25 02:36:48 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74881094ab | ||
|
|
ee98282475 | ||
|
|
e49ec14c41 | ||
|
|
56f4604819 | ||
|
|
56eb5ba8a8 | ||
|
|
8206dff4c1 | ||
|
|
f7426a4439 | ||
|
|
c478ca691d | ||
|
|
a3ff3cafa4 | ||
|
|
313d353ae5 | ||
|
|
dabf391576 |
Submodule ASF-WebConfigGenerator updated: 6ca5f94e21...5efdaf96ac
2
ASF-ui
2
ASF-ui
Submodule ASF-ui updated: 452d296a0f...b74e43068e
@@ -57,7 +57,6 @@ namespace ArchiSteamFarm {
|
||||
private const string ISteamApps = "ISteamApps";
|
||||
private const string ISteamUserAuth = "ISteamUserAuth";
|
||||
private const string ITwoFactorService = "ITwoFactorService";
|
||||
private const byte MinSessionValidityInSeconds = GlobalConfig.DefaultConnectionTimeout / 6;
|
||||
private const string SteamCommunityHost = "steamcommunity.com";
|
||||
private const string SteamHelpHost = "help.steampowered.com";
|
||||
private const string SteamStoreHost = "store.steampowered.com";
|
||||
@@ -2393,14 +2392,16 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
|
||||
private async Task<bool?> IsSessionExpired() {
|
||||
if (DateTime.UtcNow < LastSessionCheck.AddSeconds(MinSessionValidityInSeconds)) {
|
||||
DateTime triggeredAt = DateTime.UtcNow;
|
||||
|
||||
if (triggeredAt <= LastSessionCheck) {
|
||||
return LastSessionCheck != LastSessionRefresh;
|
||||
}
|
||||
|
||||
await SessionSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
try {
|
||||
if (DateTime.UtcNow < LastSessionCheck.AddSeconds(MinSessionValidityInSeconds)) {
|
||||
if (triggeredAt <= LastSessionCheck) {
|
||||
return LastSessionCheck != LastSessionRefresh;
|
||||
}
|
||||
|
||||
@@ -2522,15 +2523,15 @@ namespace ArchiSteamFarm {
|
||||
|
||||
DateTime triggeredAt = DateTime.UtcNow;
|
||||
|
||||
if (triggeredAt < LastSessionRefresh.AddSeconds(MinSessionValidityInSeconds)) {
|
||||
return true;
|
||||
if (triggeredAt <= LastSessionCheck) {
|
||||
return LastSessionCheck == LastSessionRefresh;
|
||||
}
|
||||
|
||||
await SessionSemaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
try {
|
||||
if (triggeredAt < LastSessionRefresh.AddSeconds(MinSessionValidityInSeconds)) {
|
||||
return true;
|
||||
if (triggeredAt <= LastSessionCheck) {
|
||||
return LastSessionCheck == LastSessionRefresh;
|
||||
}
|
||||
|
||||
if (!Bot.IsConnectedAndLoggedOn) {
|
||||
@@ -2540,10 +2541,14 @@ namespace ArchiSteamFarm {
|
||||
Bot.ArchiLogger.LogGenericInfo(Strings.RefreshingOurSession);
|
||||
bool result = await Bot.RefreshSession().ConfigureAwait(false);
|
||||
|
||||
DateTime now = DateTime.UtcNow;
|
||||
|
||||
if (result) {
|
||||
LastSessionCheck = LastSessionRefresh = DateTime.UtcNow;
|
||||
LastSessionRefresh = now;
|
||||
}
|
||||
|
||||
LastSessionCheck = now;
|
||||
|
||||
return result;
|
||||
} finally {
|
||||
SessionSemaphore.Release();
|
||||
|
||||
@@ -23,6 +23,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -122,8 +123,6 @@ namespace ArchiSteamFarm {
|
||||
internal readonly ArchiHandler ArchiHandler;
|
||||
internal readonly BotDatabase BotDatabase;
|
||||
|
||||
internal readonly ConcurrentDictionary<uint, (EPaymentMethod PaymentMethod, DateTime TimeCreated)> OwnedPackageIDs = new ConcurrentDictionary<uint, (EPaymentMethod PaymentMethod, DateTime TimeCreated)>();
|
||||
|
||||
internal bool CanReceiveSteamCards => !IsAccountLimited && !IsAccountLocked;
|
||||
internal bool IsAccountLimited => AccountFlags.HasFlag(EAccountFlags.LimitedUser) || AccountFlags.HasFlag(EAccountFlags.LimitedUserForce);
|
||||
internal bool IsAccountLocked => AccountFlags.HasFlag(EAccountFlags.Lockdown);
|
||||
@@ -195,6 +194,7 @@ namespace ArchiSteamFarm {
|
||||
[PublicAPI]
|
||||
public ECurrencyCode WalletCurrency { get; private set; }
|
||||
|
||||
internal ImmutableDictionary<uint, (EPaymentMethod PaymentMethod, DateTime TimeCreated)> OwnedPackageIDs { get; private set; } = ImmutableDictionary<uint, (EPaymentMethod PaymentMethod, DateTime TimeCreated)>.Empty;
|
||||
internal bool PlayingBlocked { get; private set; }
|
||||
internal bool PlayingWasBlocked { get; private set; }
|
||||
|
||||
@@ -2160,7 +2160,6 @@ namespace ArchiSteamFarm {
|
||||
|
||||
ArchiLogger.LogGenericInfo(Strings.BotDisconnected);
|
||||
|
||||
OwnedPackageIDs.Clear();
|
||||
PastNotifications.Clear();
|
||||
|
||||
Actions.OnDisconnected();
|
||||
@@ -2384,16 +2383,21 @@ namespace ArchiSteamFarm {
|
||||
return;
|
||||
}
|
||||
|
||||
bool initialLogin = OwnedPackageIDs.Count == 0;
|
||||
if (callback.LicenseList.Count == 0) {
|
||||
ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsEmpty, nameof(callback.LicenseList)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Commands.OnNewLicenseList();
|
||||
OwnedPackageIDs.Clear();
|
||||
|
||||
Dictionary<uint, (EPaymentMethod PaymentMethod, DateTime TimeCreated)> ownedPackageIDs = new Dictionary<uint, (EPaymentMethod PaymentMethod, DateTime TimeCreated)>();
|
||||
|
||||
Dictionary<uint, ulong> packageAccessTokens = new Dictionary<uint, ulong>();
|
||||
Dictionary<uint, uint> packagesToRefresh = new Dictionary<uint, uint>();
|
||||
|
||||
foreach (SteamApps.LicenseListCallback.License license in callback.LicenseList.GroupBy(license => license.PackageID, (packageID, licenses) => licenses.OrderByDescending(license => license.TimeCreated).First())) {
|
||||
OwnedPackageIDs[license.PackageID] = (license.PaymentMethod, license.TimeCreated);
|
||||
ownedPackageIDs[license.PackageID] = (license.PaymentMethod, license.TimeCreated);
|
||||
|
||||
if (!ASF.GlobalDatabase.PackageAccessTokensReadOnly.TryGetValue(license.PackageID, out ulong packageAccessToken) || (packageAccessToken != license.AccessToken)) {
|
||||
packageAccessTokens[license.PackageID] = license.AccessToken;
|
||||
@@ -2405,6 +2409,8 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
}
|
||||
|
||||
OwnedPackageIDs = ownedPackageIDs.ToImmutableDictionary();
|
||||
|
||||
if (packageAccessTokens.Count > 0) {
|
||||
ASF.GlobalDatabase.RefreshPackageAccessTokens(packageAccessTokens);
|
||||
}
|
||||
@@ -2415,11 +2421,6 @@ namespace ArchiSteamFarm {
|
||||
ArchiLogger.LogGenericTrace(Strings.Done);
|
||||
}
|
||||
|
||||
if (initialLogin && CardsFarmer.Paused) {
|
||||
// Emit initial game playing status in this case
|
||||
await ResetGamesPlayed().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await CardsFarmer.OnNewGameAdded().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -2623,6 +2624,11 @@ namespace ArchiSteamFarm {
|
||||
);
|
||||
}
|
||||
|
||||
if (CardsFarmer.Paused) {
|
||||
// Emit initial game playing status in this case
|
||||
Utilities.InBackground(ResetGamesPlayed);
|
||||
}
|
||||
|
||||
SteamPICSChanges.OnBotLoggedOn();
|
||||
|
||||
await PluginsCore.OnBotLoggedOn(this).ConfigureAwait(false);
|
||||
|
||||
@@ -36,12 +36,12 @@ using SteamKit2;
|
||||
namespace ArchiSteamFarm {
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
public sealed class GlobalConfig {
|
||||
internal const byte DefaultConnectionTimeout = 90;
|
||||
internal const byte DefaultLoginLimiterDelay = 10;
|
||||
|
||||
private const bool DefaultAutoRestart = true;
|
||||
private const string DefaultCommandPrefix = "!";
|
||||
private const byte DefaultConfirmationsLimiterDelay = 10;
|
||||
private const byte DefaultConnectionTimeout = 90;
|
||||
private const string DefaultCurrentCulture = null;
|
||||
private const bool DefaultDebug = false;
|
||||
private const byte DefaultFarmingDelay = 15;
|
||||
|
||||
@@ -136,8 +136,8 @@ namespace ArchiSteamFarm {
|
||||
return globalDatabase;
|
||||
}
|
||||
|
||||
internal HashSet<uint> GetPackageIDs(uint appID, ICollection<uint> packageIDs) {
|
||||
if ((appID == 0) || (packageIDs == null) || (packageIDs.Count == 0)) {
|
||||
internal HashSet<uint> GetPackageIDs(uint appID, IEnumerable<uint> packageIDs) {
|
||||
if ((appID == 0) || (packageIDs == null)) {
|
||||
ASF.ArchiLogger.LogNullError(nameof(appID) + " || " + nameof(packageIDs));
|
||||
|
||||
return null;
|
||||
|
||||
@@ -325,10 +325,11 @@ namespace ArchiSteamFarm {
|
||||
|
||||
Dictionary<ulong, (byte Tries, ISet<ulong> GivenAssetIDs, ISet<ulong> ReceivedAssetIDs)> triedSteamIDs = new Dictionary<ulong, (byte Tries, ISet<ulong> GivenAssetIDs, ISet<ulong> ReceivedAssetIDs)>();
|
||||
|
||||
bool match = true;
|
||||
bool shouldContinueMatching = true;
|
||||
bool tradedSomething = false;
|
||||
|
||||
for (byte i = 0; (i < MaxMatchingRounds) && match; i++) {
|
||||
if (i > 0) {
|
||||
for (byte i = 0; (i < MaxMatchingRounds) && shouldContinueMatching; i++) {
|
||||
if ((i > 0) && tradedSomething) {
|
||||
// After each round we wait at least 5 minutes for all bots to react
|
||||
await Task.Delay(5 * 60 * 1000).ConfigureAwait(false);
|
||||
}
|
||||
@@ -341,7 +342,7 @@ namespace ArchiSteamFarm {
|
||||
|
||||
using (await Bot.Actions.GetTradingLock().ConfigureAwait(false)) {
|
||||
Bot.ArchiLogger.LogGenericInfo(string.Format(Strings.ActivelyMatchingItems, i));
|
||||
match = await MatchActivelyRound(acceptedMatchableTypes, triedSteamIDs).ConfigureAwait(false);
|
||||
(shouldContinueMatching, tradedSomething) = await MatchActivelyRound(acceptedMatchableTypes, triedSteamIDs).ConfigureAwait(false);
|
||||
Bot.ArchiLogger.LogGenericInfo(string.Format(Strings.DoneActivelyMatchingItems, i));
|
||||
}
|
||||
}
|
||||
@@ -352,11 +353,11 @@ namespace ArchiSteamFarm {
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> MatchActivelyRound(IReadOnlyCollection<Steam.Asset.EType> acceptedMatchableTypes, IDictionary<ulong, (byte Tries, ISet<ulong> GivenAssetIDs, ISet<ulong> ReceivedAssetIDs)> triedSteamIDs) {
|
||||
private async Task<(bool ShouldContinueMatching, bool TradedSomething)> MatchActivelyRound(IReadOnlyCollection<Steam.Asset.EType> acceptedMatchableTypes, IDictionary<ulong, (byte Tries, ISet<ulong> GivenAssetIDs, ISet<ulong> ReceivedAssetIDs)> triedSteamIDs) {
|
||||
if ((acceptedMatchableTypes == null) || (acceptedMatchableTypes.Count == 0) || (triedSteamIDs == null)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(acceptedMatchableTypes) + " || " + nameof(triedSteamIDs));
|
||||
|
||||
return false;
|
||||
return (false, false);
|
||||
}
|
||||
|
||||
HashSet<Steam.Asset> ourInventory;
|
||||
@@ -364,17 +365,17 @@ namespace ArchiSteamFarm {
|
||||
try {
|
||||
ourInventory = await Bot.ArchiWebHandler.GetInventoryAsync().Where(item => acceptedMatchableTypes.Contains(item.Type)).ToHashSetAsync().ConfigureAwait(false);
|
||||
} catch (HttpRequestException) {
|
||||
return false;
|
||||
return (false, false);
|
||||
} catch (Exception e) {
|
||||
Bot.ArchiLogger.LogGenericException(e);
|
||||
|
||||
return false;
|
||||
return (false, false);
|
||||
}
|
||||
|
||||
if (ourInventory.Count == 0) {
|
||||
Bot.ArchiLogger.LogGenericTrace(string.Format(Strings.ErrorIsEmpty, nameof(ourInventory)));
|
||||
|
||||
return false;
|
||||
return (false, false);
|
||||
}
|
||||
|
||||
(Dictionary<(uint RealAppID, Steam.Asset.EType Type, Steam.Asset.ERarity Rarity), Dictionary<ulong, uint>> ourFullState, Dictionary<(uint RealAppID, Steam.Asset.EType Type, Steam.Asset.ERarity Rarity), Dictionary<ulong, uint>> ourTradableState) = Trading.GetDividedInventoryState(ourInventory);
|
||||
@@ -383,7 +384,7 @@ namespace ArchiSteamFarm {
|
||||
// User doesn't have any more dupes in the inventory
|
||||
Bot.ArchiLogger.LogGenericTrace(string.Format(Strings.ErrorIsEmpty, nameof(ourFullState) + " || " + nameof(ourTradableState)));
|
||||
|
||||
return false;
|
||||
return (false, false);
|
||||
}
|
||||
|
||||
ImmutableHashSet<ListedUser> listedUsers = await GetListedUsers().ConfigureAwait(false);
|
||||
@@ -391,7 +392,7 @@ namespace ArchiSteamFarm {
|
||||
if ((listedUsers == null) || (listedUsers.Count == 0)) {
|
||||
Bot.ArchiLogger.LogGenericTrace(string.Format(Strings.ErrorIsEmpty, nameof(listedUsers)));
|
||||
|
||||
return false;
|
||||
return (false, false);
|
||||
}
|
||||
|
||||
byte totalMatches = 0;
|
||||
@@ -462,7 +463,7 @@ namespace ArchiSteamFarm {
|
||||
if (!ourFullSet.TryGetValue(classID, out uint fullAmount) || (fullAmount == 0) || (fullAmount < amount)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(fullAmount));
|
||||
|
||||
return false;
|
||||
return (false, skippedSetsThisRound.Count > 0);
|
||||
}
|
||||
|
||||
if (fullAmount > amount) {
|
||||
@@ -474,7 +475,7 @@ namespace ArchiSteamFarm {
|
||||
if (!ourTradableSet.TryGetValue(classID, out uint tradableAmount) || (tradableAmount == 0) || (tradableAmount < amount)) {
|
||||
Bot.ArchiLogger.LogNullError(nameof(tradableAmount));
|
||||
|
||||
return false;
|
||||
return (false, skippedSetsThisRound.Count > 0);
|
||||
}
|
||||
|
||||
if (fullAmount > amount) {
|
||||
@@ -600,7 +601,7 @@ namespace ArchiSteamFarm {
|
||||
// Failsafe
|
||||
Bot.ArchiLogger.LogGenericError(string.Format(Strings.WarningFailedWithError, Strings.ErrorAborted));
|
||||
|
||||
return false;
|
||||
return (false, skippedSetsThisRound.Count > 0);
|
||||
}
|
||||
|
||||
if (triedSteamIDs.TryGetValue(listedUser.SteamID, out (byte Tries, ISet<ulong> GivenAssetIDs, ISet<ulong> ReceivedAssetIDs) previousAttempt)) {
|
||||
@@ -630,7 +631,7 @@ namespace ArchiSteamFarm {
|
||||
if (!twoFactorSuccess) {
|
||||
Bot.ArchiLogger.LogGenericTrace(Strings.WarningFailed);
|
||||
|
||||
return false;
|
||||
return (false, skippedSetsThisRound.Count > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -675,7 +676,7 @@ namespace ArchiSteamFarm {
|
||||
Bot.ArchiLogger.LogGenericInfo(string.Format(Strings.ActivelyMatchingItemsRound, skippedSetsThisRound.Count));
|
||||
|
||||
// Keep matching when we either traded something this round (so it makes sense for a refresh) or if we didn't try all available bots yet (so it makes sense to keep going)
|
||||
return (skippedSetsThisRound.Count > 0) || triedSteamIDs.Values.All(data => data.Tries < 2);
|
||||
return ((totalMatches > 0) && ((skippedSetsThisRound.Count > 0) || triedSteamIDs.Values.All(data => data.Tries < 2)), skippedSetsThisRound.Count > 0);
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "ClassCannotBeInstantiated")]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>4.2.2.9</Version>
|
||||
<Version>4.2.3.2</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
2
wiki
2
wiki
Submodule wiki updated: 93cf188ae6...31e95fe1d8
Reference in New Issue
Block a user