internal async Task OnPersonaState(SteamFriends.PersonaStateCallback callback) { if (callback == null) { ASF.ArchiLogger.LogNullError(nameof(callback)); return; } if (DateTime.UtcNow < LastAnnouncementCheck.AddHours(MinAnnouncementCheckTTL)) { return; } // Don't announce if we don't meet conditions if (!Bot.HasMobileAuthenticator || !Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.SteamTradeMatcher) || !await Bot.ArchiWebHandler.HasValidApiKey().ConfigureAwait(false) || !await Bot.ArchiWebHandler.HasPublicInventory().ConfigureAwait(false)) { LastAnnouncementCheck = DateTime.UtcNow; ShouldSendHeartBeats = false; return; } string nickname = callback.Name ?? ""; string avatarHash = ""; if ((callback.AvatarHash != null) && (callback.AvatarHash.Length > 0) && callback.AvatarHash.Any(singleByte => singleByte != 0)) { avatarHash = BitConverter.ToString(callback.AvatarHash).Replace("-", "").ToLowerInvariant(); if (avatarHash.All(singleChar => singleChar == '0')) { avatarHash = ""; } } bool matchEverything = Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.MatchEverything); await Semaphore.WaitAsync().ConfigureAwait(false); try { if (DateTime.UtcNow < LastAnnouncementCheck.AddHours(MinAnnouncementCheckTTL)) { return; } await Trading.LimitInventoryRequestsAsync().ConfigureAwait(false); HashSet <Steam.Item> inventory = await Bot.ArchiWebHandler.GetMySteamInventory(true, new HashSet <Steam.Item.EType> { Steam.Item.EType.TradingCard }).ConfigureAwait(false); // This is actually inventory failure, so we'll stop sending heartbeats but not record it as valid check if (inventory == null) { ShouldSendHeartBeats = false; return; } // This is actual inventory if (inventory.Count < MinCardsCount) { LastAnnouncementCheck = DateTime.UtcNow; ShouldSendHeartBeats = false; return; } string request = await GetURL().ConfigureAwait(false) + "/api/Announce"; Dictionary <string, string> data = new Dictionary <string, string>(6) { { "SteamID", Bot.SteamID.ToString() }, { "Guid", Program.GlobalDatabase.Guid.ToString("N") }, { "Nickname", nickname }, { "AvatarHash", avatarHash }, { "MatchEverything", matchEverything ? "1" : "0" }, { "CardsCount", inventory.Count.ToString() } }; // We don't need retry logic here if (await Program.WebBrowser.UrlPost(request, data).ConfigureAwait(false)) { LastAnnouncementCheck = DateTime.UtcNow; ShouldSendHeartBeats = true; } } finally { Semaphore.Release(); } }
internal async Task OnPersonaState(SteamFriends.PersonaStateCallback callback) { if (callback == null) { ASF.ArchiLogger.LogNullError(nameof(callback)); return; } // Don't announce if we don't meet conditions if (!Bot.HasMobileAuthenticator || !Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.SteamTradeMatcher) || !await Bot.ArchiWebHandler.HasValidApiKey().ConfigureAwait(false) || !await Bot.ArchiWebHandler.HasPublicInventory().ConfigureAwait(false)) { ShouldSendHeartBeats = false; return; } string nickname = callback.Name ?? ""; string avatarHash = ""; if ((callback.AvatarHash != null) && (callback.AvatarHash.Length > 0) && callback.AvatarHash.Any(singleByte => singleByte != 0)) { avatarHash = BitConverter.ToString(callback.AvatarHash).Replace("-", "").ToLowerInvariant(); if (avatarHash.All(singleChar => singleChar == '0')) { avatarHash = ""; } } bool matchEverything = Bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.MatchEverything); // Skip announcing if we already announced this bot with the same data if (ShouldSendHeartBeats && (LastNickname != null) && nickname.Equals(LastNickname) && (LastAvatarHash != null) && avatarHash.Equals(LastAvatarHash) && LastMatchEverything.HasValue && (matchEverything == LastMatchEverything.Value)) { return; } await Semaphore.WaitAsync().ConfigureAwait(false); try { // Skip announcing if we already announced this bot with the same data if (ShouldSendHeartBeats && (LastNickname != null) && nickname.Equals(LastNickname) && (LastAvatarHash != null) && avatarHash.Equals(LastAvatarHash) && LastMatchEverything.HasValue && (matchEverything == LastMatchEverything.Value)) { return; } await Trading.LimitInventoryRequestsAsync().ConfigureAwait(false); HashSet <Steam.Item> inventory = await Bot.ArchiWebHandler.GetMySteamInventory(true, new HashSet <Steam.Item.EType> { Steam.Item.EType.TradingCard }).ConfigureAwait(false); if ((inventory == null) || (inventory.Count == 0)) { // Don't announce, we have empty inventory ShouldSendHeartBeats = false; return; } // Even if following request fails, we want to send HeartBeats regardless ShouldSendHeartBeats = true; string request = await GetURL().ConfigureAwait(false) + "/api/Announce"; Dictionary <string, string> data = new Dictionary <string, string>(6) { { "SteamID", Bot.SteamID.ToString() }, { "Guid", Program.GlobalDatabase.Guid.ToString("N") }, { "Nickname", nickname }, { "AvatarHash", avatarHash }, { "MatchEverything", matchEverything ? "1" : "0" }, { "CardsCount", inventory.Count.ToString() } }; // We don't need retry logic here if (await Program.WebBrowser.UrlPost(request, data).ConfigureAwait(false)) { LastNickname = nickname; LastAvatarHash = avatarHash; LastMatchEverything = matchEverything; } } finally { Semaphore.Release(); } }