mirror of
https://github.com/JustArchiNET/ArchiSteamFarm.git
synced 2025-12-16 14:30:31 +00:00
Add more farming orders
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
Reference in New Issue
Block a user