From d51756246758ae17596f7993e75a23f008a1ffea Mon Sep 17 00:00:00 2001 From: JustArchi Date: Sat, 30 Jul 2016 20:55:43 +0200 Subject: [PATCH] Add more farming orders --- ArchiSteamFarm.sln.DotSettings | 1 + ArchiSteamFarm/BotConfig.cs | 10 ++- ArchiSteamFarm/CardsFarmer.cs | 119 ++++++++++++++++++++-------- ArchiSteamFarm/ConcurrentHashSet.cs | 6 +- ConfigGenerator/BotConfig.cs | 10 ++- 5 files changed, 110 insertions(+), 36 deletions(-) diff --git a/ArchiSteamFarm.sln.DotSettings b/ArchiSteamFarm.sln.DotSettings index 1fdf4fa5c..97fbadc55 100644 --- a/ArchiSteamFarm.sln.DotSettings +++ b/ArchiSteamFarm.sln.DotSettings @@ -26,6 +26,7 @@ ID IP OK + PICS PIN SC SMS diff --git a/ArchiSteamFarm/BotConfig.cs b/ArchiSteamFarm/BotConfig.cs index b8495dcfc..d21c90b81 100644 --- a/ArchiSteamFarm/BotConfig.cs +++ b/ArchiSteamFarm/BotConfig.cs @@ -36,8 +36,14 @@ namespace ArchiSteamFarm { internal sealed class BotConfig { internal enum EFarmingOrder : byte { Unordered, - MostCardDropRemainingFirst, - FewestCardDropRemainingFirst + AppIDsAscending, + AppIDsDescending, + CardDropsAscending, + CardDropsDescending, + HoursAscending, + HoursDescending, + NamesAscending, + NamesDescending } [JsonProperty(Required = Required.DisallowNull)] diff --git a/ArchiSteamFarm/CardsFarmer.cs b/ArchiSteamFarm/CardsFarmer.cs index 9f26df1fa..ccd64fd77 100755 --- a/ArchiSteamFarm/CardsFarmer.cs +++ b/ArchiSteamFarm/CardsFarmer.cs @@ -38,18 +38,22 @@ namespace ArchiSteamFarm { [JsonProperty] internal readonly uint AppID; + [JsonProperty] + internal readonly string GameName; + [JsonProperty] internal float HoursPlayed; [JsonProperty] internal byte CardsRemaining; - internal Game(uint appID, float hoursPlayed, byte cardsRemaining) { - if ((appID == 0) || (hoursPlayed < 0)) { - throw new ArgumentOutOfRangeException(nameof(appID) + " || " + nameof(hoursPlayed)); + internal Game(uint appID, string gameName, float hoursPlayed, byte cardsRemaining) { + if ((appID == 0) || string.IsNullOrEmpty(gameName) || (hoursPlayed < 0)) { + throw new ArgumentOutOfRangeException(nameof(appID) + " || " + nameof(gameName) + " || " + nameof(hoursPlayed)); } AppID = appID; + GameName = gameName; HoursPlayed = hoursPlayed; CardsRemaining = cardsRemaining; } @@ -304,7 +308,7 @@ namespace ArchiSteamFarm { } } - GamesToFarm.Clear(); + GamesToFarm.ClearAndTrim(); CheckPage(htmlDocument); if (maxPages == 1) { @@ -326,23 +330,40 @@ namespace ArchiSteamFarm { } private void SortGamesToFarm() { - List gamesToFarm; + IOrderedEnumerable gamesToFarm; switch (Bot.BotConfig.FarmingOrder) { - case BotConfig.EFarmingOrder.MostCardDropRemainingFirst: - gamesToFarm = GamesToFarm.OrderByDescending(g => g.CardsRemaining).ToList(); + case BotConfig.EFarmingOrder.Unordered: + return; + case BotConfig.EFarmingOrder.AppIDsAscending: + gamesToFarm = GamesToFarm.OrderBy(g => g.AppID); break; - - case BotConfig.EFarmingOrder.FewestCardDropRemainingFirst: - gamesToFarm = GamesToFarm.OrderBy(g => g.CardsRemaining).ToList(); + case BotConfig.EFarmingOrder.AppIDsDescending: + gamesToFarm = GamesToFarm.OrderByDescending(g => g.AppID); + break; + case BotConfig.EFarmingOrder.CardDropsAscending: + gamesToFarm = GamesToFarm.OrderBy(g => g.CardsRemaining); + break; + case BotConfig.EFarmingOrder.CardDropsDescending: + gamesToFarm = GamesToFarm.OrderByDescending(g => g.CardsRemaining); + break; + case BotConfig.EFarmingOrder.HoursAscending: + gamesToFarm = GamesToFarm.OrderBy(g => g.HoursPlayed); + break; + case BotConfig.EFarmingOrder.HoursDescending: + gamesToFarm = GamesToFarm.OrderByDescending(g => g.HoursPlayed); + break; + case BotConfig.EFarmingOrder.NamesAscending: + gamesToFarm = GamesToFarm.OrderBy(g => g.GameName); + break; + case BotConfig.EFarmingOrder.NamesDescending: + gamesToFarm = GamesToFarm.OrderByDescending(g => g.GameName); break; - default: + Logging.LogGenericError("Unhandled case: " + Bot.BotConfig.FarmingOrder, Bot.BotName); return; } - GamesToFarm.Clear(); - GamesToFarm.AddRange(gamesToFarm); - GamesToFarm.TrimExcess(); + GamesToFarm.ReplaceWith(gamesToFarm); } private void CheckPage(HtmlDocument htmlDocument) { @@ -352,7 +373,7 @@ namespace ArchiSteamFarm { } HtmlNodeCollection htmlNodes = htmlDocument.DocumentNode.SelectNodes("//div[@class='badge_title_stats']"); - if (htmlNodes == null) { // For example a page full of non-games badges + if (htmlNodes == null) { // No eligible badges return; } @@ -367,21 +388,7 @@ namespace ArchiSteamFarm { continue; // e.g. Holiday Sale 2015 } - string progress = progressNode.InnerText; - if (string.IsNullOrEmpty(progress)) { - Logging.LogNullError(nameof(progress), Bot.BotName); - return; - } - - byte cardsRemaining = 0; - - Match progressMatch = Regex.Match(progress, @"\d+"); - if (progressMatch.Success) { - if (!byte.TryParse(progressMatch.Value, out cardsRemaining)) { - Logging.LogNullError(nameof(cardsRemaining), Bot.BotName); - return; - } - } + // AppIDs string steamLink = farmingNode.GetAttributeValue("href", null); if (string.IsNullOrEmpty(steamLink)) { @@ -413,6 +420,8 @@ namespace ArchiSteamFarm { continue; } + // Hours + HtmlNode timeNode = htmlNode.SelectSingleNode(".//div[@class='badge_title_stats_playtime']"); if (timeNode == null) { Logging.LogNullError(nameof(timeNode), Bot.BotName); @@ -435,7 +444,55 @@ namespace ArchiSteamFarm { } } - GamesToFarm.Add(new Game(appID, hours, cardsRemaining)); + // Cards + + string progress = progressNode.InnerText; + if (string.IsNullOrEmpty(progress)) { + Logging.LogNullError(nameof(progress), Bot.BotName); + return; + } + + byte cardsRemaining = 0; + + Match progressMatch = Regex.Match(progress, @"\d+"); + if (progressMatch.Success) { + if (!byte.TryParse(progressMatch.Value, out cardsRemaining)) { + Logging.LogNullError(nameof(cardsRemaining), Bot.BotName); + return; + } + } + + // Names + + HtmlNode nameNode = htmlNode.SelectSingleNode("(.//div[@class='card_drop_info_body'])[last()]"); + if (nameNode == null) { + Logging.LogNullError(nameof(nameNode), Bot.BotName); + return; + } + + string name = nameNode.InnerText; + if (string.IsNullOrEmpty(name)) { + Logging.LogNullError(nameof(name), Bot.BotName); + return; + } + + int nameStartIndex = name.IndexOf(" by playing ", StringComparison.Ordinal); + if (nameStartIndex < 0) { + Logging.LogNullError(nameof(nameStartIndex)); + return; + } + + nameStartIndex += 12; + + int nameEndIndex = name.LastIndexOf('.'); + if (nameEndIndex < nameStartIndex) { + Logging.LogNullError(nameof(nameEndIndex)); + return; + } + + name = name.Substring(nameStartIndex, nameEndIndex - nameStartIndex); + + GamesToFarm.Add(new Game(appID, name, hours, cardsRemaining)); } } diff --git a/ArchiSteamFarm/ConcurrentHashSet.cs b/ArchiSteamFarm/ConcurrentHashSet.cs index c5eb05faf..3e7df1c00 100644 --- a/ArchiSteamFarm/ConcurrentHashSet.cs +++ b/ArchiSteamFarm/ConcurrentHashSet.cs @@ -102,13 +102,17 @@ namespace ArchiSteamFarm { } } - internal void AddRange(IEnumerable items) { + internal void ReplaceWith(IEnumerable items) { Lock.EnterWriteLock(); try { + HashSet.Clear(); + foreach (T item in items) { HashSet.Add(item); } + + HashSet.TrimExcess(); } finally { Lock.ExitWriteLock(); } diff --git a/ConfigGenerator/BotConfig.cs b/ConfigGenerator/BotConfig.cs index bddc94c0f..b993a3941 100644 --- a/ConfigGenerator/BotConfig.cs +++ b/ConfigGenerator/BotConfig.cs @@ -43,8 +43,14 @@ namespace ConfigGenerator { internal enum EFarmingOrder : byte { Unordered, - MostCardDropRemainingFirst, - FewestCardDropRemainingFirst + AppIDsAscending, + AppIDsDescending, + CardDropsAscending, + CardDropsDescending, + HoursAscending, + HoursDescending, + NamesAscending, + NamesDescending } [JsonProperty(Required = Required.DisallowNull)]