예제 #1
0
        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();
            }
        }
예제 #2
0
        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();
            }
        }