Add support for SteamAwards

This commit is contained in:
JustArchi
2017-12-21 19:38:45 +01:00
parent a9810dc3c1
commit c5e21b02aa
6 changed files with 108 additions and 7 deletions

View File

@@ -665,6 +665,15 @@ namespace ArchiSteamFarm {
return 0; return 0;
} }
internal async Task<HtmlDocument> GetSteamAwardsPage() {
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
return null;
}
const string request = SteamStoreURL + "/SteamAwards?l=english";
return await WebBrowser.UrlGetToHtmlDocumentRetry(request).ConfigureAwait(false);
}
internal async Task<byte?> GetTradeHoldDuration(ulong tradeID) { internal async Task<byte?> GetTradeHoldDuration(ulong tradeID) {
if (tradeID == 0) { if (tradeID == 0) {
Bot.ArchiLogger.LogNullError(nameof(tradeID)); Bot.ArchiLogger.LogNullError(nameof(tradeID));
@@ -1075,6 +1084,32 @@ namespace ArchiSteamFarm {
return true; return true;
} }
internal async Task<bool> SteamAwardsVote(byte voteID, uint appID) {
if ((voteID == 0) || (appID == 0)) {
Bot.ArchiLogger.LogNullError(nameof(voteID) + " || " + nameof(appID));
return false;
}
if (!await RefreshSessionIfNeeded().ConfigureAwait(false)) {
return false;
}
string sessionID = WebBrowser.CookieContainer.GetCookieValue(SteamStoreURL, "sessionid");
if (string.IsNullOrEmpty(sessionID)) {
Bot.ArchiLogger.LogNullError(nameof(sessionID));
return false;
}
const string request = SteamStoreURL + "/salevote";
Dictionary<string, string> data = new Dictionary<string, string>(3) {
{ "sessionid", sessionID },
{ "voteid", voteID.ToString() },
{ "appid", appID.ToString() }
};
return await WebBrowser.UrlPostRetry(request, data).ConfigureAwait(false);
}
internal async Task<bool> UnpackBooster(uint appID, ulong itemID) { internal async Task<bool> UnpackBooster(uint appID, ulong itemID) {
if ((appID == 0) || (itemID == 0)) { if ((appID == 0) || (itemID == 0)) {
Bot.ArchiLogger.LogNullError(nameof(appID) + " || " + nameof(itemID)); Bot.ArchiLogger.LogNullError(nameof(appID) + " || " + nameof(itemID));

View File

@@ -1352,7 +1352,7 @@ namespace ArchiSteamFarm {
SteamSaleEvent = null; SteamSaleEvent = null;
} }
if (BotConfig.AutoDiscoveryQueue) { if (BotConfig.AutoSteamSaleEvent) {
SteamSaleEvent = new SteamSaleEvent(this); SteamSaleEvent = new SteamSaleEvent(this);
} }
} }

View File

@@ -39,7 +39,7 @@ namespace ArchiSteamFarm {
internal readonly bool AcceptGifts; internal readonly bool AcceptGifts;
[JsonProperty(Required = Required.DisallowNull)] [JsonProperty(Required = Required.DisallowNull)]
internal readonly bool AutoDiscoveryQueue; internal readonly bool AutoSteamSaleEvent;
[JsonProperty] [JsonProperty]
internal readonly string CustomGamePlayedWhileFarming; internal readonly string CustomGamePlayedWhileFarming;

View File

@@ -31,20 +31,20 @@ namespace ArchiSteamFarm {
private const byte MaxSingleQueuesDaily = 3; // This is mainly a pre-caution for infinite queue clearing private const byte MaxSingleQueuesDaily = 3; // This is mainly a pre-caution for infinite queue clearing
private readonly Bot Bot; private readonly Bot Bot;
private readonly Timer SteamDiscoveryQueueTimer; private readonly Timer SaleEventTimer;
internal SteamSaleEvent(Bot bot) { internal SteamSaleEvent(Bot bot) {
Bot = bot ?? throw new ArgumentNullException(nameof(bot)); Bot = bot ?? throw new ArgumentNullException(nameof(bot));
SteamDiscoveryQueueTimer = new Timer( SaleEventTimer = new Timer(
async e => await ExploreDiscoveryQueue().ConfigureAwait(false), async e => await Task.WhenAll(ExploreDiscoveryQueue(), VoteForSteamAwards()).ConfigureAwait(false),
null, null,
TimeSpan.FromMinutes(1) + TimeSpan.FromSeconds(Program.LoadBalancingDelay * Bot.Bots.Count), // Delay TimeSpan.FromMinutes(1) + TimeSpan.FromSeconds(Program.LoadBalancingDelay * Bot.Bots.Count), // Delay
TimeSpan.FromHours(6.1) // Period TimeSpan.FromHours(6.1) // Period
); );
} }
public void Dispose() => SteamDiscoveryQueueTimer.Dispose(); public void Dispose() => SaleEventTimer.Dispose();
private async Task ExploreDiscoveryQueue() { private async Task ExploreDiscoveryQueue() {
if (!Bot.IsConnectedAndLoggedOn) { if (!Bot.IsConnectedAndLoggedOn) {
@@ -102,5 +102,56 @@ namespace ArchiSteamFarm {
bool result = text.StartsWith("You can get ", StringComparison.Ordinal); bool result = text.StartsWith("You can get ", StringComparison.Ordinal);
return result; return result;
} }
private async Task VoteForSteamAwards() {
HtmlDocument htmlDocument = await Bot.ArchiWebHandler.GetSteamAwardsPage().ConfigureAwait(false);
HtmlNodeCollection nominationNodes = htmlDocument?.DocumentNode.SelectNodes("//div[@class='vote_nominations store_horizontal_autoslider']");
if (nominationNodes == null) {
// Event ended, error or likewise
return;
}
foreach (HtmlNode nominationNode in nominationNodes) {
HtmlNode myVoteNode = nominationNode.SelectSingleNode("./div[@class='vote_nomination your_vote']");
if (myVoteNode != null) {
// Already voted
continue;
}
string voteIDText = nominationNode.GetAttributeValue("data-voteid", null);
if (string.IsNullOrEmpty(voteIDText)) {
Bot.ArchiLogger.LogNullError(nameof(voteIDText));
return;
}
if (!byte.TryParse(voteIDText, out byte voteID) || (voteID == 0)) {
Bot.ArchiLogger.LogNullError(nameof(voteID));
return;
}
HtmlNodeCollection voteNodes = nominationNode.SelectNodes("./div[starts-with(@class, 'vote_nomination')]");
if (voteNodes == null) {
Bot.ArchiLogger.LogNullError(nameof(voteNodes));
return;
}
// Random a game we'll actually vote for, we don't want to make GabeN angry by rigging votes...
HtmlNode voteNode = voteNodes[Utilities.RandomNext(voteNodes.Count)];
string appIDText = voteNode.GetAttributeValue("data-vote-appid", null);
if (string.IsNullOrEmpty(appIDText)) {
Bot.ArchiLogger.LogNullError(nameof(appIDText));
return;
}
if (!uint.TryParse(appIDText, out uint appID) || (appID == 0)) {
Bot.ArchiLogger.LogNullError(nameof(appID));
return;
}
await Bot.ArchiWebHandler.SteamAwardsVote(voteID, appID).ConfigureAwait(false);
}
}
} }
} }

View File

@@ -104,6 +104,21 @@ namespace ArchiSteamFarm {
} }
} }
internal static int RandomNext(int maxWithout) {
if (maxWithout <= 0) {
ASF.ArchiLogger.LogNullError(nameof(maxWithout));
return -1;
}
if (maxWithout == 1) {
return 0;
}
lock (Random) {
return Random.Next(maxWithout);
}
}
internal static string ReadLineMasked(char mask = '*') { internal static string ReadLineMasked(char mask = '*') {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();

View File

@@ -1,6 +1,6 @@
{ {
"AcceptGifts": false, "AcceptGifts": false,
"AutoDiscoveryQueue": false, "AutoSteamSaleEvent": false,
"CustomGamePlayedWhileFarming": null, "CustomGamePlayedWhileFarming": null,
"CustomGamePlayedWhileIdle": null, "CustomGamePlayedWhileIdle": null,
"DismissInventoryNotifications": false, "DismissInventoryNotifications": false,