mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2026-01-06 17:10:13 +00:00
Rewrite active matching code for more fairness and robustness
This commit is contained in:
@@ -226,7 +226,7 @@ namespace ArchiSteamFarm {
|
|||||||
try {
|
try {
|
||||||
Bot.ArchiLogger.LogGenericTrace(Strings.Starting);
|
Bot.ArchiLogger.LogGenericTrace(Strings.Starting);
|
||||||
|
|
||||||
Dictionary<ulong, byte> triedSteamIDs = new Dictionary<ulong, byte>();
|
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 match = true;
|
||||||
|
|
||||||
@@ -255,7 +255,7 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "FunctionComplexityOverflow")]
|
[SuppressMessage("ReSharper", "FunctionComplexityOverflow")]
|
||||||
private async Task<bool> MatchActivelyRound(IReadOnlyCollection<Steam.Asset.EType> acceptedMatchableTypes, IDictionary<ulong, byte> triedSteamIDs) {
|
private async Task<bool> 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)) {
|
if ((acceptedMatchableTypes == null) || (acceptedMatchableTypes.Count == 0) || (triedSteamIDs == null)) {
|
||||||
Bot.ArchiLogger.LogNullError(nameof(acceptedMatchableTypes) + " || " + nameof(triedSteamIDs));
|
Bot.ArchiLogger.LogNullError(nameof(acceptedMatchableTypes) + " || " + nameof(triedSteamIDs));
|
||||||
return false;
|
return false;
|
||||||
@@ -284,7 +284,7 @@ namespace ArchiSteamFarm {
|
|||||||
byte emptyMatches = 0;
|
byte emptyMatches = 0;
|
||||||
HashSet<(uint AppID, Steam.Asset.EType Type)> skippedSetsThisRound = new HashSet<(uint AppID, Steam.Asset.EType Type)>();
|
HashSet<(uint AppID, Steam.Asset.EType Type)> skippedSetsThisRound = new HashSet<(uint AppID, Steam.Asset.EType Type)>();
|
||||||
|
|
||||||
foreach (ListedUser listedUser in listedUsers.Where(listedUser => listedUser.MatchEverything && acceptedMatchableTypes.Any(listedUser.MatchableTypes.Contains) && (!triedSteamIDs.TryGetValue(listedUser.SteamID, out byte tries) || (tries < byte.MaxValue)) && !Bot.IsBlacklistedFromTrades(listedUser.SteamID)).OrderBy(listedUser => triedSteamIDs.TryGetValue(listedUser.SteamID, out byte tries) ? tries : 0).ThenByDescending(listedUser => listedUser.Score).Take(MaxMatchedBotsHard)) {
|
foreach (ListedUser listedUser in listedUsers.Where(listedUser => listedUser.MatchEverything && acceptedMatchableTypes.Any(listedUser.MatchableTypes.Contains) && (!triedSteamIDs.TryGetValue(listedUser.SteamID, out (byte Tries, ISet<ulong> GivenAssetIDs, ISet<ulong> ReceivedAssetIDs) attempt) || (attempt.Tries < byte.MaxValue)) && !Bot.IsBlacklistedFromTrades(listedUser.SteamID)).OrderBy(listedUser => triedSteamIDs.TryGetValue(listedUser.SteamID, out (byte Tries, ISet<ulong> GivenAssetIDs, ISet<ulong> ReceivedAssetIDs) attempt) ? attempt.Tries : 0).ThenByDescending(listedUser => listedUser.Score).Take(MaxMatchedBotsHard)) {
|
||||||
Bot.ArchiLogger.LogGenericTrace(listedUser.SteamID + "...");
|
Bot.ArchiLogger.LogGenericTrace(listedUser.SteamID + "...");
|
||||||
|
|
||||||
HashSet<Steam.Asset> theirInventory = await Bot.ArchiWebHandler.GetInventory(listedUser.SteamID, tradable: true, wantedSets: ourInventoryState.Keys, skippedSets: skippedSetsThisRound).ConfigureAwait(false);
|
HashSet<Steam.Asset> theirInventory = await Bot.ArchiWebHandler.GetInventory(listedUser.SteamID, tradable: true, wantedSets: ourInventoryState.Keys, skippedSets: skippedSetsThisRound).ConfigureAwait(false);
|
||||||
@@ -298,6 +298,7 @@ namespace ArchiSteamFarm {
|
|||||||
|
|
||||||
for (byte i = 0; i < Trading.MaxTradesPerAccount; i++) {
|
for (byte i = 0; i < Trading.MaxTradesPerAccount; i++) {
|
||||||
byte itemsInTrade = 0;
|
byte itemsInTrade = 0;
|
||||||
|
HashSet<(uint AppID, Steam.Asset.EType Type)> skippedSetsThisTrade = new HashSet<(uint AppID, Steam.Asset.EType Type)>();
|
||||||
|
|
||||||
Dictionary<ulong, uint> classIDsToGive = new Dictionary<ulong, uint>();
|
Dictionary<ulong, uint> classIDsToGive = new Dictionary<ulong, uint>();
|
||||||
Dictionary<ulong, uint> classIDsToReceive = new Dictionary<ulong, uint>();
|
Dictionary<ulong, uint> classIDsToReceive = new Dictionary<ulong, uint>();
|
||||||
@@ -319,7 +320,7 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Skip this set from the remaining of this round
|
// Skip this set from the remaining of this round
|
||||||
skippedSetsThisUser.Add(ourInventoryStateSet.Key);
|
skippedSetsThisTrade.Add(ourInventoryStateSet.Key);
|
||||||
|
|
||||||
// Update our state based on given items
|
// Update our state based on given items
|
||||||
classIDsToGive[ourItem.Key] = classIDsToGive.TryGetValue(ourItem.Key, out uint givenAmount) ? givenAmount + 1 : 1;
|
classIDsToGive[ourItem.Key] = classIDsToGive.TryGetValue(ourItem.Key, out uint givenAmount) ? givenAmount + 1 : 1;
|
||||||
@@ -353,16 +354,35 @@ namespace ArchiSteamFarm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skippedSetsThisUser.Count == 0) {
|
if (skippedSetsThisTrade.Count == 0) {
|
||||||
Bot.ArchiLogger.LogGenericTrace(string.Format(Strings.ErrorIsEmpty, nameof(skippedSetsThisUser)));
|
Bot.ArchiLogger.LogGenericTrace(string.Format(Strings.ErrorIsEmpty, nameof(skippedSetsThisTrade)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
emptyMatches = 0;
|
|
||||||
|
|
||||||
HashSet<Steam.Asset> itemsToGive = Trading.GetItemsFromInventory(ourInventory, classIDsToGive);
|
HashSet<Steam.Asset> itemsToGive = Trading.GetItemsFromInventory(ourInventory, classIDsToGive);
|
||||||
HashSet<Steam.Asset> itemsToReceive = Trading.GetItemsFromInventory(theirInventory, classIDsToReceive);
|
HashSet<Steam.Asset> itemsToReceive = Trading.GetItemsFromInventory(theirInventory, classIDsToReceive);
|
||||||
|
|
||||||
|
if (triedSteamIDs.TryGetValue(listedUser.SteamID, out (byte Tries, ISet<ulong> GivenAssetIDs, ISet<ulong> ReceivedAssetIDs) previousAttempt)) {
|
||||||
|
Bot.ArchiLogger.LogGenericDebug("Previous: " + listedUser.SteamID + ": " + previousAttempt.Tries + " | " + string.Join(", ", previousAttempt.GivenAssetIDs) + " | " + string.Join(", ", previousAttempt.ReceivedAssetIDs)); // TODO: remove debug
|
||||||
|
if (itemsToGive.Select(item => item.AssetID).All(previousAttempt.GivenAssetIDs.Contains) && itemsToReceive.Select(item => item.AssetID).All(previousAttempt.ReceivedAssetIDs.Contains)) {
|
||||||
|
// This user didn't respond in our previous round, avoid him for remaining ones
|
||||||
|
triedSteamIDs[listedUser.SteamID] = (byte.MaxValue, previousAttempt.GivenAssetIDs, previousAttempt.ReceivedAssetIDs);
|
||||||
|
Bot.ArchiLogger.LogGenericDebug("Banned: " + listedUser.SteamID); // TODO: remove debug
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
previousAttempt.GivenAssetIDs.UnionWith(itemsToGive.Select(item => item.AssetID));
|
||||||
|
previousAttempt.ReceivedAssetIDs.UnionWith(itemsToReceive.Select(item => item.AssetID));
|
||||||
|
} else {
|
||||||
|
previousAttempt.GivenAssetIDs = new HashSet<ulong>(itemsToGive.Select(item => item.AssetID));
|
||||||
|
previousAttempt.ReceivedAssetIDs = new HashSet<ulong>(itemsToReceive.Select(item => item.AssetID));
|
||||||
|
Bot.ArchiLogger.LogGenericDebug("New: " + listedUser.SteamID + ": " + string.Join(", ", previousAttempt.GivenAssetIDs) + " | " + string.Join(", ", previousAttempt.ReceivedAssetIDs)); // TODO: remove debug
|
||||||
|
}
|
||||||
|
|
||||||
|
triedSteamIDs[listedUser.SteamID] = (++previousAttempt.Tries, previousAttempt.GivenAssetIDs, previousAttempt.ReceivedAssetIDs);
|
||||||
|
|
||||||
|
emptyMatches = 0;
|
||||||
|
|
||||||
Bot.ArchiLogger.LogGenericTrace(Bot.SteamID + " <- " + string.Join(", ", itemsToReceive.Select(item => item.RealAppID + "/" + item.Type + "-" + item.ClassID + " #" + item.Amount)) + " | " + string.Join(", ", itemsToGive.Select(item => item.RealAppID + "/" + item.Type + "-" + item.ClassID + " #" + item.Amount)) + " -> " + listedUser.SteamID);
|
Bot.ArchiLogger.LogGenericTrace(Bot.SteamID + " <- " + string.Join(", ", itemsToReceive.Select(item => item.RealAppID + "/" + item.Type + "-" + item.ClassID + " #" + item.Amount)) + " | " + string.Join(", ", itemsToGive.Select(item => item.RealAppID + "/" + item.Type + "-" + item.ClassID + " #" + item.Amount)) + " -> " + listedUser.SteamID);
|
||||||
|
|
||||||
(bool success, HashSet<ulong> mobileTradeOfferIDs) = await Bot.ArchiWebHandler.SendTradeOffer(listedUser.SteamID, itemsToGive, itemsToReceive, listedUser.TradeToken, true).ConfigureAwait(false);
|
(bool success, HashSet<ulong> mobileTradeOfferIDs) = await Bot.ArchiWebHandler.SendTradeOffer(listedUser.SteamID, itemsToGive, itemsToReceive, listedUser.TradeToken, true).ConfigureAwait(false);
|
||||||
@@ -379,15 +399,14 @@ namespace ArchiSteamFarm {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skippedSetsThisUser.UnionWith(skippedSetsThisTrade);
|
||||||
Bot.ArchiLogger.LogGenericTrace(Strings.Success);
|
Bot.ArchiLogger.LogGenericTrace(Strings.Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
triedSteamIDs[listedUser.SteamID] = triedSteamIDs.TryGetValue(listedUser.SteamID, out byte tries) ? ++tries : (byte) 1;
|
|
||||||
|
|
||||||
if (skippedSetsThisUser.Count == 0) {
|
if (skippedSetsThisUser.Count == 0) {
|
||||||
if (skippedSetsThisRound.Count == 0) {
|
if (skippedSetsThisRound.Count == 0) {
|
||||||
// If we didn't find any match on clean round, this user isn't going to have anything interesting for us anytime soon
|
// If we didn't find any match on clean round, this user isn't going to have anything interesting for us anytime soon
|
||||||
triedSteamIDs[listedUser.SteamID] = byte.MaxValue;
|
triedSteamIDs[listedUser.SteamID] = (byte.MaxValue, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++emptyMatches >= MaxMatchesBotsSoft) {
|
if (++emptyMatches >= MaxMatchesBotsSoft) {
|
||||||
|
|||||||
Reference in New Issue
Block a user