internal async Task OnHeartBeat() { // Request persona update if needed if ((DateTime.UtcNow > LastPersonaStateRequest.AddHours(MinPersonaStateTTL)) && (DateTime.UtcNow > LastAnnouncementCheck.AddHours(MinAnnouncementCheckTTL))) { LastPersonaStateRequest = DateTime.UtcNow; Bot.RequestPersonaStateUpdate(); } if (!ShouldSendHeartBeats || (DateTime.UtcNow < LastHeartBeat.AddMinutes(MinHeartBeatTTL))) { return; } await RequestsSemaphore.WaitAsync().ConfigureAwait(false); try { if (!ShouldSendHeartBeats || (DateTime.UtcNow < LastHeartBeat.AddMinutes(MinHeartBeatTTL))) { return; } const string request = URL + "/Api/HeartBeat"; Dictionary <string, string> data = new Dictionary <string, string>(2, StringComparer.Ordinal) { { "Guid", ASF.GlobalDatabase.Guid.ToString("N") }, { "SteamID", Bot.SteamID.ToString() } }; WebBrowser.BasicResponse response = await Bot.ArchiWebHandler.WebBrowser.UrlPost(request, data, requestOptions : WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false); if (response == null) { return; } if (response.StatusCode.IsClientErrorCode()) { LastHeartBeat = DateTime.MinValue; ShouldSendHeartBeats = false; return; } LastHeartBeat = DateTime.UtcNow; } finally { RequestsSemaphore.Release(); } }
internal async Task OnPersonaState(string nickname = null, string avatarHash = null) { if ((DateTime.UtcNow < LastAnnouncementCheck.AddHours(MinAnnouncementCheckTTL)) && (ShouldSendHeartBeats || (LastHeartBeat == DateTime.MinValue))) { return; } await RequestsSemaphore.WaitAsync().ConfigureAwait(false); try { if ((DateTime.UtcNow < LastAnnouncementCheck.AddHours(MinAnnouncementCheckTTL)) && (ShouldSendHeartBeats || (LastHeartBeat == DateTime.MinValue))) { return; } // Don't announce if we don't meet conditions bool?eligible = await IsEligibleForListing().ConfigureAwait(false); if (!eligible.HasValue) { // This is actually network failure, so we'll stop sending heartbeats but not record it as valid check ShouldSendHeartBeats = false; return; } if (!eligible.Value) { LastAnnouncementCheck = DateTime.UtcNow; ShouldSendHeartBeats = false; return; } string tradeToken = await Bot.ArchiHandler.GetTradeToken().ConfigureAwait(false); if (string.IsNullOrEmpty(tradeToken)) { // This is actually network failure, so we'll stop sending heartbeats but not record it as valid check ShouldSendHeartBeats = false; return; } HashSet <Steam.Asset.EType> acceptedMatchableTypes = Bot.BotConfig.MatchableTypes.Where(type => AcceptedMatchableTypes.Contains(type)).ToHashSet(); if (acceptedMatchableTypes.Count == 0) { Bot.ArchiLogger.LogNullError(nameof(acceptedMatchableTypes)); LastAnnouncementCheck = DateTime.UtcNow; ShouldSendHeartBeats = false; return; } HashSet <Steam.Asset> inventory = await Bot.ArchiWebHandler.GetInventory(tradable : true, wantedTypes : acceptedMatchableTypes).ConfigureAwait(false); if (inventory == null) { // This is actually inventory failure, so we'll stop sending heartbeats but not record it as valid check ShouldSendHeartBeats = false; return; } LastAnnouncementCheck = DateTime.UtcNow; // This is actual inventory if (inventory.Count < MinItemsCount) { ShouldSendHeartBeats = false; return; } const string request = URL + "/Api/Announce"; Dictionary <string, string> data = new Dictionary <string, string>(9, StringComparer.Ordinal) { { "AvatarHash", avatarHash ?? "" }, { "GamesCount", inventory.Select(item => item.RealAppID).Distinct().Count().ToString() }, { "Guid", ASF.GlobalDatabase.Guid.ToString("N") }, { "ItemsCount", inventory.Count.ToString() }, { "MatchableTypes", JsonConvert.SerializeObject(acceptedMatchableTypes) }, { "MatchEverything", Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.MatchEverything) ? "1" : "0" }, { "Nickname", nickname ?? "" }, { "SteamID", Bot.SteamID.ToString() }, { "TradeToken", tradeToken } }; WebBrowser.BasicResponse response = await Bot.ArchiWebHandler.WebBrowser.UrlPost(request, data, requestOptions : WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false); if (response == null) { return; } if (response.StatusCode.IsClientErrorCode()) { LastHeartBeat = DateTime.MinValue; ShouldSendHeartBeats = false; return; } LastHeartBeat = DateTime.UtcNow; ShouldSendHeartBeats = true; } finally { RequestsSemaphore.Release(); } }