Add farming time approximation

Because @MaduRUDE asked nicely
This commit is contained in:
JustArchi 2016-12-26 22:07:49 +01:00
parent 9b56734bad
commit 33edc81116
13 changed files with 5571 additions and 16 deletions

View file

@ -35,6 +35,8 @@ using SteamKit2.Internal;
namespace ArchiSteamFarm {
internal sealed class ArchiHandler : ClientMsgHandler {
internal const byte MaxGamesPlayedConcurrently = 32; // This is limit introduced by Steam Network
private readonly ArchiLogger ArchiLogger;
internal ArchiHandler(ArchiLogger archiLogger) {

View file

@ -79,6 +79,10 @@
<HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Humanizer, Version=2.1.0.0, Culture=neutral, PublicKeyToken=979442b78dfc278e, processorArchitecture=MSIL">
<HintPath>..\packages\Humanizer.Core.2.1.0\lib\netstandard1.0\Humanizer.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.2-beta1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>

View file

@ -2039,7 +2039,7 @@ namespace ArchiSteamFarm {
gamesToPlay.Add(gameID);
if (gamesToPlay.Count >= CardsFarmer.MaxGamesPlayedConcurrently) {
if (gamesToPlay.Count >= ArchiHandler.MaxGamesPlayedConcurrently) {
break;
}
}
@ -2368,7 +2368,7 @@ namespace ArchiSteamFarm {
response.Append("appIDs " + string.Join(", ", CardsFarmer.CurrentGamesFarming.Select(game => game.AppID)));
}
response.Append(" and has a total of " + CardsFarmer.GamesToFarm.Count + " games (" + CardsFarmer.GamesToFarm.Sum(game => game.CardsRemaining) + " cards) left to farm.");
response.Append(" and has a total of " + CardsFarmer.GamesToFarm.Count + " games (" + CardsFarmer.GamesToFarm.Sum(game => game.CardsRemaining) + " cards, about " + CardsFarmer.TimeRemaining.ToHumanReadable() + ") left to farm.");
return response.ToString();
}

View file

@ -152,13 +152,13 @@ namespace ArchiSteamFarm {
// User might not know what he's doing
// Ensure that he can't screw core ASF variables
if (botConfig.GamesPlayedWhileIdle.Count <= CardsFarmer.MaxGamesPlayedConcurrently) {
if (botConfig.GamesPlayedWhileIdle.Count <= ArchiHandler.MaxGamesPlayedConcurrently) {
return botConfig;
}
Program.ArchiLogger.LogGenericWarning("Playing more than " + CardsFarmer.MaxGamesPlayedConcurrently + " games concurrently is not possible, only first " + CardsFarmer.MaxGamesPlayedConcurrently + " entries from GamesPlayedWhileIdle will be used");
Program.ArchiLogger.LogGenericWarning("Playing more than " + ArchiHandler.MaxGamesPlayedConcurrently + " games concurrently is not possible, only first " + ArchiHandler.MaxGamesPlayedConcurrently + " entries from GamesPlayedWhileIdle will be used");
HashSet<uint> validGames = new HashSet<uint>(botConfig.GamesPlayedWhileIdle.Take(CardsFarmer.MaxGamesPlayedConcurrently));
HashSet<uint> validGames = new HashSet<uint>(botConfig.GamesPlayedWhileIdle.Take(ArchiHandler.MaxGamesPlayedConcurrently));
botConfig.GamesPlayedWhileIdle.IntersectWith(validGames);
botConfig.GamesPlayedWhileIdle.TrimExcess();

View file

@ -34,7 +34,7 @@ using Newtonsoft.Json;
namespace ArchiSteamFarm {
internal sealed class CardsFarmer : IDisposable {
internal const byte MaxGamesPlayedConcurrently = 32; // This is limit introduced by Steam Network
private const byte HoursToBump = 2; // How many hours are required for restricted accounts
private static readonly HashSet<uint> UntrustedAppIDs = new HashSet<uint> { 440, 570, 730 };
@ -56,6 +56,13 @@ namespace ArchiSteamFarm {
private bool NowFarming;
private bool StickyPause;
[JsonProperty]
internal TimeSpan TimeRemaining => new TimeSpan(
Bot.BotConfig.CardDropsRestricted ? (int) Math.Ceiling(GamesToFarm.Count / (float) ArchiHandler.MaxGamesPlayedConcurrently * HoursToBump) : 0,
30 * GamesToFarm.Sum(game => game.CardsRemaining),
0
);
internal CardsFarmer(Bot bot) {
if (bot == null) {
throw new ArgumentNullException(nameof(bot));
@ -95,8 +102,8 @@ namespace ArchiSteamFarm {
// If we have Complex algorithm and some games to boost, it's also worth to make a re-check, but only in this case
// That's because we would check for new games after our current round anyway, and having extra games in the queue right away doesn't change anything
// Therefore, there is no need for extra restart of CardsFarmer if we have no games under 2 hours in current round
if (Bot.BotConfig.CardDropsRestricted && (GamesToFarm.Count > 0) && (GamesToFarm.Min(game => game.HoursPlayed) < 2)) {
// Therefore, there is no need for extra restart of CardsFarmer if we have no games under HoursToBump hours in current round
if (Bot.BotConfig.CardDropsRestricted && (GamesToFarm.Count > 0) && (GamesToFarm.Min(game => game.HoursPlayed) < HoursToBump)) {
await StopFarming().ConfigureAwait(false);
StartFarming().Forget();
}
@ -165,7 +172,7 @@ namespace ArchiSteamFarm {
return;
}
Bot.ArchiLogger.LogGenericInfo("We have a total of " + GamesToFarm.Count + " games (" + GamesToFarm.Sum(game => game.CardsRemaining) + " cards) to farm on this account...");
Bot.ArchiLogger.LogGenericInfo("We have a total of " + GamesToFarm.Count + " games (" + GamesToFarm.Sum(game => game.CardsRemaining) + " cards, about " + TimeRemaining.ToHumanReadable() + ") to farm on this account...");
// This is the last moment for final check if we can farm
if (!Bot.IsPlayingPossible) {
@ -183,7 +190,7 @@ namespace ArchiSteamFarm {
if (Bot.BotConfig.CardDropsRestricted) { // If we have restricted card drops, we use complex algorithm
Bot.ArchiLogger.LogGenericInfo("Chosen farming algorithm: Complex");
while (GamesToFarm.Count > 0) {
HashSet<Game> gamesToFarmSolo = GamesToFarm.Count > 1 ? new HashSet<Game>(GamesToFarm.Where(game => game.HoursPlayed >= 2)) : new HashSet<Game>(GamesToFarm);
HashSet<Game> gamesToFarmSolo = GamesToFarm.Count > 1 ? new HashSet<Game>(GamesToFarm.Where(game => game.HoursPlayed >= HoursToBump)) : new HashSet<Game>(GamesToFarm);
if (gamesToFarmSolo.Count > 0) {
while (gamesToFarmSolo.Count > 0) {
Game game = gamesToFarmSolo.First();
@ -195,7 +202,7 @@ namespace ArchiSteamFarm {
}
}
} else {
if (FarmMultiple(GamesToFarm.OrderByDescending(game => game.HoursPlayed).Take(MaxGamesPlayedConcurrently))) {
if (FarmMultiple(GamesToFarm.OrderByDescending(game => game.HoursPlayed).Take(ArchiHandler.MaxGamesPlayedConcurrently))) {
Bot.ArchiLogger.LogGenericInfo("Done farming: " + string.Join(", ", GamesToFarm.Select(game => game.AppID)));
} else {
NowFarming = false;
@ -533,8 +540,8 @@ namespace ArchiSteamFarm {
return false;
}
if (maxHour >= 2) {
Bot.ArchiLogger.LogGenericError("Received request for past-2h games!");
if (maxHour >= HoursToBump) {
Bot.ArchiLogger.LogGenericError("Received request for already boosted games!");
return true;
}
@ -602,7 +609,7 @@ namespace ArchiSteamFarm {
GamesToFarm.Remove(game);
TimeSpan timeSpan = TimeSpan.FromHours(game.HoursPlayed);
Bot.ArchiLogger.LogGenericInfo("Done farming: " + game.AppID + " (" + game.GameName + ") after " + timeSpan.ToString(@"hh\:mm") + " hours of playtime!");
Bot.ArchiLogger.LogGenericInfo("Done farming: " + game.AppID + " (" + game.GameName + ") after " + timeSpan.ToHumanReadable() + " of playtime!");
return true;
}

View file

@ -27,6 +27,7 @@ using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using Humanizer;
namespace ArchiSteamFarm {
internal static class Utilities {
@ -71,5 +72,7 @@ namespace ArchiSteamFarm {
return Random.Next(maxWithout);
}
}
internal static string ToHumanReadable(this TimeSpan timeSpan) => timeSpan.Humanize(3, true);
}
}

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Costura.Fody" version="2.0.0-beta0018" targetFramework="net461" developmentDependency="true" />
<package id="Fody" version="1.30.0-beta01" targetFramework="net461" developmentDependency="true" />
<package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="net461" />
<package id="Humanizer.Core" version="2.1.0" targetFramework="net461" />
<package id="Newtonsoft.Json" version="9.0.2-beta1" targetFramework="net461" />
<package id="NLog" version="5.0.0-beta03" targetFramework="net461" />
<package id="protobuf-net" version="2.0.0.668" targetFramework="net45" />

View file

@ -4,4 +4,13 @@
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NLog" publicKeyToken="5120e14c03d0593c" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View file

@ -48,6 +48,10 @@
<HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Humanizer, Version=2.1.0.0, Culture=neutral, PublicKeyToken=979442b78dfc278e, processorArchitecture=MSIL">
<HintPath>..\packages\Humanizer.Core.2.1.0\lib\netstandard1.0\Humanizer.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.2-beta1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Costura.Fody" version="2.0.0-beta0018" targetFramework="net461" developmentDependency="true" />
<package id="Fody" version="1.30.0-beta01" targetFramework="net461" developmentDependency="true" />
<package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="net461" />
<package id="Humanizer.Core" version="2.1.0" targetFramework="net461" />
<package id="Newtonsoft.Json" version="9.0.2-beta1" targetFramework="net461" />
<package id="NLog" version="5.0.0-beta03" targetFramework="net461" />
<package id="NLog.Windows.Forms" version="4.2.3" targetFramework="net461" />

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff