Add more farming orders

This commit is contained in:
JustArchi
2016-07-30 20:55:43 +02:00
parent 53dcd22cea
commit d517562467
5 changed files with 110 additions and 36 deletions

View File

@@ -26,6 +26,7 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IP/@EntryIndexedValue">IP</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IP/@EntryIndexedValue">IP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OK/@EntryIndexedValue">OK</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OK/@EntryIndexedValue">OK</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PICS/@EntryIndexedValue">PICS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PIN/@EntryIndexedValue">PIN</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PIN/@EntryIndexedValue">PIN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SC/@EntryIndexedValue">SC</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SC/@EntryIndexedValue">SC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SMS/@EntryIndexedValue">SMS</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SMS/@EntryIndexedValue">SMS</s:String>

View File

@@ -36,8 +36,14 @@ namespace ArchiSteamFarm {
internal sealed class BotConfig { internal sealed class BotConfig {
internal enum EFarmingOrder : byte { internal enum EFarmingOrder : byte {
Unordered, Unordered,
MostCardDropRemainingFirst, AppIDsAscending,
FewestCardDropRemainingFirst AppIDsDescending,
CardDropsAscending,
CardDropsDescending,
HoursAscending,
HoursDescending,
NamesAscending,
NamesDescending
} }
[JsonProperty(Required = Required.DisallowNull)] [JsonProperty(Required = Required.DisallowNull)]

View File

@@ -38,18 +38,22 @@ namespace ArchiSteamFarm {
[JsonProperty] [JsonProperty]
internal readonly uint AppID; internal readonly uint AppID;
[JsonProperty]
internal readonly string GameName;
[JsonProperty] [JsonProperty]
internal float HoursPlayed; internal float HoursPlayed;
[JsonProperty] [JsonProperty]
internal byte CardsRemaining; internal byte CardsRemaining;
internal Game(uint appID, float hoursPlayed, byte cardsRemaining) { internal Game(uint appID, string gameName, float hoursPlayed, byte cardsRemaining) {
if ((appID == 0) || (hoursPlayed < 0)) { if ((appID == 0) || string.IsNullOrEmpty(gameName) || (hoursPlayed < 0)) {
throw new ArgumentOutOfRangeException(nameof(appID) + " || " + nameof(hoursPlayed)); throw new ArgumentOutOfRangeException(nameof(appID) + " || " + nameof(gameName) + " || " + nameof(hoursPlayed));
} }
AppID = appID; AppID = appID;
GameName = gameName;
HoursPlayed = hoursPlayed; HoursPlayed = hoursPlayed;
CardsRemaining = cardsRemaining; CardsRemaining = cardsRemaining;
} }
@@ -304,7 +308,7 @@ namespace ArchiSteamFarm {
} }
} }
GamesToFarm.Clear(); GamesToFarm.ClearAndTrim();
CheckPage(htmlDocument); CheckPage(htmlDocument);
if (maxPages == 1) { if (maxPages == 1) {
@@ -326,23 +330,40 @@ namespace ArchiSteamFarm {
} }
private void SortGamesToFarm() { private void SortGamesToFarm() {
List<Game> gamesToFarm; IOrderedEnumerable<Game> gamesToFarm;
switch (Bot.BotConfig.FarmingOrder) { switch (Bot.BotConfig.FarmingOrder) {
case BotConfig.EFarmingOrder.MostCardDropRemainingFirst: case BotConfig.EFarmingOrder.Unordered:
gamesToFarm = GamesToFarm.OrderByDescending(g => g.CardsRemaining).ToList(); return;
case BotConfig.EFarmingOrder.AppIDsAscending:
gamesToFarm = GamesToFarm.OrderBy(g => g.AppID);
break; break;
case BotConfig.EFarmingOrder.AppIDsDescending:
case BotConfig.EFarmingOrder.FewestCardDropRemainingFirst: gamesToFarm = GamesToFarm.OrderByDescending(g => g.AppID);
gamesToFarm = GamesToFarm.OrderBy(g => g.CardsRemaining).ToList(); 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; break;
default: default:
Logging.LogGenericError("Unhandled case: " + Bot.BotConfig.FarmingOrder, Bot.BotName);
return; return;
} }
GamesToFarm.Clear(); GamesToFarm.ReplaceWith(gamesToFarm);
GamesToFarm.AddRange(gamesToFarm);
GamesToFarm.TrimExcess();
} }
private void CheckPage(HtmlDocument htmlDocument) { private void CheckPage(HtmlDocument htmlDocument) {
@@ -352,7 +373,7 @@ namespace ArchiSteamFarm {
} }
HtmlNodeCollection htmlNodes = htmlDocument.DocumentNode.SelectNodes("//div[@class='badge_title_stats']"); 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; return;
} }
@@ -367,21 +388,7 @@ namespace ArchiSteamFarm {
continue; // e.g. Holiday Sale 2015 continue; // e.g. Holiday Sale 2015
} }
string progress = progressNode.InnerText; // AppIDs
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;
}
}
string steamLink = farmingNode.GetAttributeValue("href", null); string steamLink = farmingNode.GetAttributeValue("href", null);
if (string.IsNullOrEmpty(steamLink)) { if (string.IsNullOrEmpty(steamLink)) {
@@ -413,6 +420,8 @@ namespace ArchiSteamFarm {
continue; continue;
} }
// Hours
HtmlNode timeNode = htmlNode.SelectSingleNode(".//div[@class='badge_title_stats_playtime']"); HtmlNode timeNode = htmlNode.SelectSingleNode(".//div[@class='badge_title_stats_playtime']");
if (timeNode == null) { if (timeNode == null) {
Logging.LogNullError(nameof(timeNode), Bot.BotName); 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));
} }
} }

View File

@@ -102,13 +102,17 @@ namespace ArchiSteamFarm {
} }
} }
internal void AddRange(IEnumerable<T> items) { internal void ReplaceWith(IEnumerable<T> items) {
Lock.EnterWriteLock(); Lock.EnterWriteLock();
try { try {
HashSet.Clear();
foreach (T item in items) { foreach (T item in items) {
HashSet.Add(item); HashSet.Add(item);
} }
HashSet.TrimExcess();
} finally { } finally {
Lock.ExitWriteLock(); Lock.ExitWriteLock();
} }

View File

@@ -43,8 +43,14 @@ namespace ConfigGenerator {
internal enum EFarmingOrder : byte { internal enum EFarmingOrder : byte {
Unordered, Unordered,
MostCardDropRemainingFirst, AppIDsAscending,
FewestCardDropRemainingFirst AppIDsDescending,
CardDropsAscending,
CardDropsDescending,
HoursAscending,
HoursDescending,
NamesAscending,
NamesDescending
} }
[JsonProperty(Required = Required.DisallowNull)] [JsonProperty(Required = Required.DisallowNull)]