public void InitializesInstancesCorrectly() { SteamID sid = new SteamID(); sid.SetFromSteam3String("[g:1:1234]"); Assert.Equal(EUniverse.Public, sid.AccountUniverse); Assert.Equal(EAccountType.Clan, sid.AccountType); Assert.Equal(0u, sid.AccountInstance); Assert.Equal(1234u, sid.AccountID); sid.SetFromSteam3String("[T:1:1234]"); Assert.Equal(EUniverse.Public, sid.AccountUniverse); Assert.Equal(EAccountType.Chat, sid.AccountType); Assert.Equal(0u, sid.AccountInstance); Assert.Equal(1234u, sid.AccountID); sid.SetFromSteam3String("[c:1:1234]"); Assert.Equal(EUniverse.Public, sid.AccountUniverse); Assert.Equal(EAccountType.Chat, sid.AccountType); Assert.Equal((uint)SteamID.ChatInstanceFlags.Clan, sid.AccountInstance); Assert.Equal(1234u, sid.AccountID); sid.SetFromSteam3String("[L:1:1234]"); Assert.Equal(EUniverse.Public, sid.AccountUniverse); Assert.Equal(EAccountType.Chat, sid.AccountType); Assert.Equal(( uint )SteamID.ChatInstanceFlags.Lobby, sid.AccountInstance); Assert.Equal(1234u, sid.AccountID); }
// Renders from a "[U:1:263966176]" form. public static SteamID FromSteamID3(string steamID3) { var id = new SteamID(); id.SetFromSteam3String(steamID3); return(id); }
public void SetFromSteam3StringCorrectParse() { SteamID sidUser = new SteamID(); sidUser.SetFromSteam3String("[U:1:123]"); Assert.Equal(123u, sidUser.AccountID); Assert.Equal(EUniverse.Public, sidUser.AccountUniverse); Assert.Equal(1u, sidUser.AccountInstance); Assert.Equal(EAccountType.Individual, sidUser.AccountType); SteamID sidAnonGSUser = new SteamID(); sidAnonGSUser.SetFromSteam3String("[A:1:123:456]"); Assert.Equal(123u, sidAnonGSUser.AccountID); Assert.Equal(EUniverse.Public, sidAnonGSUser.AccountUniverse); Assert.Equal(456u, sidAnonGSUser.AccountInstance); Assert.Equal(EAccountType.AnonGameServer, sidAnonGSUser.AccountType); SteamID sidLobby = new SteamID(); sidLobby.SetFromSteam3String("[L:1:123]"); Assert.Equal(123u, sidLobby.AccountID); Assert.Equal(EUniverse.Public, sidLobby.AccountUniverse); Assert.True(((SteamID.ChatInstanceFlags)sidLobby.AccountInstance).HasFlag(SteamID.ChatInstanceFlags.Lobby)); Assert.Equal(EAccountType.Chat, sidLobby.AccountType); SteamID sidClanChat = new SteamID(); sidClanChat.SetFromSteam3String("[c:1:123]"); Assert.Equal(123u, sidClanChat.AccountID); Assert.Equal(EUniverse.Public, sidClanChat.AccountUniverse); Assert.True(((SteamID.ChatInstanceFlags)sidClanChat.AccountInstance).HasFlag(SteamID.ChatInstanceFlags.Clan)); Assert.Equal(EAccountType.Chat, sidClanChat.AccountType); }
private static async Task <bool> UpdateUserSteamFrinedsAsync([NotNull] string userId, KeylolDbContext dbContext, KeylolUserManager userManager, RedisProvider redis) { var cacheKey = UserSteamFriendRecordsCrawlerStampCacheKey(userId); var redisDb = redis.GetDatabase(); var cacheResult = await redisDb.StringGetAsync(cacheKey); if (cacheResult.HasValue) { return(false); } await redisDb.StringSetAsync(cacheKey, DateTime.Now.ToTimestamp(), UserSteamFriendsUpdatePeriod); try { var steamId = new SteamID(); steamId.SetFromSteam3String(await userManager.GetSteamIdAsync(userId)); var result = JObject.Parse(await HttpClient.GetStringAsync( $"http://api.steampowered.com/ISteamUser/GetFriendList/v1/?key={ApiKey}&format=json&steamid={steamId.ConvertToUInt64()}&relationship=friend")); var oldRecords = (await dbContext.UserSteamFriendRecords.Where(r => r.UserId == userId).ToListAsync()) .ToDictionary(r => r.FriendSteamId, r => r); foreach (var friend in result["friendslist"]["friends"]) { var friendSteamId = (new SteamID(ulong.Parse((string)friend["steamid"]))).Render(true); UserSteamFriendRecord record; if (oldRecords.TryGetValue(friendSteamId, out record)) { oldRecords.Remove(friendSteamId); } else { record = new UserSteamFriendRecord { UserId = userId, FriendSteamId = friendSteamId }; dbContext.UserSteamFriendRecords.Add(record); if (friend["friend_since"] != null) { record.FriendSince = Helpers.DateTimeFromTimeStamp((ulong)friend["friend_since"]); } } } dbContext.UserSteamFriendRecords.RemoveRange(oldRecords.Values); await dbContext.SaveChangesAsync(); return(true); } catch (Exception) { await redisDb.KeyExpireAsync(cacheKey, SilenceTime); return(false); } }
public void AddFriend(string botId, string steamId) { var botInstance = SteamBot.BotInstances?.SingleOrDefault(b => b.Id == botId); if (botInstance == null) { return; } var id = new SteamID(); id.SetFromSteam3String(steamId); botInstance.SteamFriends.AddFriend(id); }
public string GetUserProfileName(string botId, string steamId) { var botInstance = SteamBot.BotInstances?.SingleOrDefault(b => b.Id == botId); if (botInstance == null) { return(null); } var id = new SteamID(); id.SetFromSteam3String(steamId); return(botInstance.SteamFriends.GetFriendPersonaName(id)); }
public string GetUserAvatarHash(string botId, string steamId) { var botInstance = SteamBot.BotInstances?.SingleOrDefault(b => b.Id == botId); if (botInstance == null) { return(null); } var id = new SteamID(); id.SetFromSteam3String(steamId); return(BitConverter.ToString(botInstance.SteamFriends.GetFriendAvatar(id)) .Replace("-", string.Empty).ToLower()); }
public void SetFromSteam3StringHandlesInvalid() { SteamID sid = new SteamID(); bool setFromNullString = sid.SetFromSteam3String(null); Assert.False(setFromNullString); bool setFromEmptyString = sid.SetFromSteam3String(""); Assert.False(setFromEmptyString); bool setFromInvalidString = sid.SetFromSteam3String("NOT A STEAMID!"); Assert.False(setFromInvalidString); bool setFromInvalidAccountId = sid.SetFromSteam3String("STEAM_0:1:999999999999999999999999999999"); Assert.False(setFromInvalidAccountId); bool setFromSteam2String = sid.SetFromSteam3String("STEAM_0:1:4491990"); Assert.False(setFromSteam2String); }
public async Task LinkAsync(string idArg) { SocketUser sender = Context.User; UserData user = new UserData(sender.Id); SteamID steamId = new SteamID(); // Checks steamid input to determine what type of id it is if (idArg.Contains("STEAM_")) { steamId.SetFromString(idArg, EUniverse.Public); } else if (ulong.TryParse(idArg, out ulong id)) { steamId.SetFromUInt64(id); } else if (Regex.Match(idArg, @"^\[{1}\b[A-Z]\:{1}[0-9]\b").Success) { steamId.SetFromSteam3String(idArg); } else { await Error(); } // Stores the steamid to an int64 user.SteamId = steamId.ConvertToUInt64(); // Creates an user. Returns true if an error accures // Duplicates do not need to be checked both discord and steam ids are unique bool errored = await user.Create(); var persona = await Program.SteamWebManager.GetUserName(user.SteamId); Console.WriteLine($"{persona}"); // If errored bot responds the the error messaged set in user or confirms linked accounts // These are made to be more user friendly if (errored) { await ReplyAsync(user.err); } else { await ReplyAsync($"Account Linked! {sender.Mention} -> {persona}"); } }
public void SetFromOldStyleSteam3StringCorrectParse() { SteamID sidMultiseat = new SteamID(); sidMultiseat.SetFromSteam3String("[M:1:123(456)]"); Assert.Equal(123u, sidMultiseat.AccountID); Assert.Equal(EUniverse.Public, sidMultiseat.AccountUniverse); Assert.Equal(456u, sidMultiseat.AccountInstance); Assert.Equal(EAccountType.Multiseat, sidMultiseat.AccountType); SteamID sidAnonGSUser = new SteamID(); sidAnonGSUser.SetFromSteam3String("[A:1:123(456)]"); Assert.Equal(123u, sidAnonGSUser.AccountID); Assert.Equal(EUniverse.Public, sidAnonGSUser.AccountUniverse); Assert.Equal(456u, sidAnonGSUser.AccountInstance); Assert.Equal(EAccountType.AnonGameServer, sidAnonGSUser.AccountType); }
public void Steam3StringSymmetric() { var steamIds = new[] { "[U:1:123]", "[U:1:123:2]", "[G:1:626]", "[A:2:165:1234]", }; foreach (var steamId in steamIds) { SteamID sid = new SteamID(); bool parsed = sid.SetFromSteam3String(steamId); Assert.True(parsed); Assert.Equal(steamId, sid.Render(steam3: true)); } }
public void SendChatMessage(string botId, string steamId, string message, bool logMessage) { var botInstance = SteamBot.BotInstances?.SingleOrDefault(b => b.Id == botId); if (botInstance == null || string.IsNullOrWhiteSpace(message)) { return; } var id = new SteamID(); id.SetFromSteam3String(steamId); botInstance.SteamFriends.SendChatMessage(id, EChatEntryType.ChatMsg, message); if (logMessage) { var friendName = botInstance.SteamFriends.GetFriendPersonaName(id); _logger.Info($"#{botInstance.SequenceNumber} [Chat TX] To {friendName} ({steamId}): {message}"); } }
private static bool TrySetSteamID(string input, out SteamID steamID) { steamID = new SteamID(); if (steamID.SetFromString(input, EUniverse.Public) || steamID.SetFromSteam3String(input)) { return(true); } if (ulong.TryParse(input, out var numericInput)) { steamID.SetFromUInt64(numericInput); return(true); } return(false); }
private async void Button_Click(object sender, RoutedEventArgs e) { var steam = new SteamID(); string url; if (!SteamID.CommunityURLRegex.IsMatch(TxtSteam.Text)) { if (!steam.SetFromString(TxtSteam.Text) && !steam.SetFromSteam3String(TxtSteam.Text)) { ToastManager.ShowToastAsync("Could not add cheater", $"Steam ID '{TxtSteam.Text}' is not valid.", Notifications.Wpf.Core.NotificationType.Warning); return; } url = $"https://steamcommunity.com/profiles/{steam.ConvertToUInt64()}/?xml=1"; } else { url = $"{SteamID.CommunityURLRegex.Match(TxtSteam.Text).Value}/?xml=1"; } var data = await Steam.GetProfileDataAsync(url); int.TryParse(TxtThreat.Text, out int threat); Cheater cheater = new() { AccountID = Convert.ToUInt64(data.steamID64), CheatList = TxtCheats.Text, LastKnownName = data.steamID, Submitter = TxtSubmitter.Text, ThreatLevel = threat, Notes = TxtNotes.Text }; Cheaters.Add(cheater); ToastManager.ShowToastAsync("Successfully added cheater", $"Hacker '{data.steamID}' has been added to the list.", Notifications.Wpf.Core.NotificationType.Success); }
internal SteamID GetLastLoggedSteamID() { var ActiveUser = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("SOFTWARE").OpenSubKey("Valve")?.OpenSubKey("Steam")?.OpenSubKey("ActiveProcess"); var userID = ActiveUser?.GetValue("ActiveUser").ToString(); int type = 0; switch (ActiveUser?.GetValue("Universe").ToString()) { case "Public": type = 1; break; case "Beta": type = 2; break; case "Internal": type = 3; break; case "Dev": type = 4; break; case "RC": type = 5; break; default: type = 0; break; } userID = "[U:" + type + ":" + userID + "]"; var steamid = new SteamID(); steamid.SetFromSteam3String(userID); return(steamid); }
public void SetFromSteam3StringHandlesInvalid() { SteamID sid = new SteamID(); bool setFromNullString = sid.SetFromSteam3String(null); Assert.False(setFromNullString); bool setFromEmptyString = sid.SetFromSteam3String(""); Assert.False(setFromEmptyString); bool setFromInvalidString = sid.SetFromSteam3String("NOT A STEAMID!"); Assert.False(setFromInvalidString); bool setFromInvalidAccountId = sid.SetFromSteam3String("STEAM_0:1:999999999999999999999999999999"); Assert.False(setFromInvalidAccountId); bool setFromSteam2String = sid.SetFromSteam3String("STEAM_0:1:4491990"); Assert.False(setFromSteam2String); bool mixingBracketsAndColons1 = sid.SetFromSteam3String("[A:1:2:345)]"); Assert.False(mixingBracketsAndColons1); bool mixingBracketsAndColons2 = sid.SetFromSteam3String("[A:1:2(345]"); Assert.False(mixingBracketsAndColons2); bool universeOutOfRange = sid.SetFromSteam3String("[U:5:123]"); Assert.False(universeOutOfRange); }
public void SetFromStringHandlesInvalid() { SteamID sid = new SteamID(); bool setFromNullString = sid.SetFromString(null, EUniverse.Public); Assert.False(setFromNullString); bool setFromEmptyString = sid.SetFromString("", EUniverse.Public); Assert.False(setFromEmptyString); bool setFromInvalidString = sid.SetFromString("NOT A STEAMID!", EUniverse.Public); Assert.False(setFromInvalidString); bool setFromInvalidAccountId = sid.SetFromString("STEAM_0:1:999999999999999999999999999999", EUniverse.Public); Assert.False(setFromInvalidAccountId); bool universeOutOfRange = sid.SetFromSteam3String("STEAM_5:0:123"); Assert.False(universeOutOfRange); }
private void OnDelayedActionReceived(object sender, BasicDeliverEventArgs basicDeliverEventArgs) { try { using (var streamReader = new StreamReader(new MemoryStream(basicDeliverEventArgs.Body))) { var serializer = new JsonSerializer(); var actionDto = serializer.Deserialize <SteamBotDelayedActionDto>(new JsonTextReader(streamReader)); switch (actionDto.Type) { case SteamBotDelayedActionType.SendChatMessage: { var steamId = new SteamID(); steamId.SetFromSteam3String((string)actionDto.Properties.SteamId); var message = (string)actionDto.Properties.Message; SteamFriends.SendChatMessage(steamId, EChatEntryType.ChatMsg, message); try { if ((bool)actionDto.Properties.LogMessage) { var friendName = SteamFriends.GetFriendPersonaName(steamId); _logger.Info($"#{SequenceNumber} [Chat TX] To {friendName} ({steamId}): {message}"); } } catch (RuntimeBinderException) { } break; } case SteamBotDelayedActionType.RemoveFriend: { var steamId = new SteamID(); steamId.SetFromSteam3String((string)actionDto.Properties.SteamId); var skip = SteamFriends.GetFriendRelationship(steamId) != EFriendRelationship.Friend; try { if (!skip && (bool)actionDto.Properties.OnlyIfNotKeylolUser) { var result = _coordinator.Consume( coordinator => coordinator.IsKeylolUser(steamId.Render(true), Id)); if (!result.HasNoException || result.Value) { skip = true; } } } catch (RuntimeBinderException) { } if (!skip) { try { SteamFriends.SendChatMessage(steamId, EChatEntryType.ChatMsg, (string)actionDto.Properties.Message); } catch (RuntimeBinderException) { } SteamFriends.RemoveFriend(steamId); } break; } default: _logger.Fatal($"#{SequenceNumber} Invalid delay action type: {actionDto.Type}."); break; } _mqChannel.BasicAck(basicDeliverEventArgs.DeliveryTag, false); } } catch (Exception e) { _mqChannel.BasicNack(basicDeliverEventArgs.DeliveryTag, false, false); _logger.Fatal($"#{SequenceNumber} Unhandled MQ consumer exception.", e); } }
public async Task <IHttpActionResult> UpdateListByCurrentUser(bool manual = false) { var userId = User.Identity.GetUserId(); var user = await _userManager.FindByIdAsync(userId); if (manual) { if (user.LastGameUpdateSucceed && DateTime.Now - user.LastGameUpdateTime < TimeSpan.FromMinutes(1)) { return(NotFound()); } } else { if (!user.AutoSubscribeEnabled || (DateTime.Now - user.LastGameUpdateTime < TimeSpan.FromDays(user.AutoSubscribeDaySpan) && user.LastGameUpdateSucceed)) { return(NotFound()); } } user.LastGameUpdateTime = DateTime.Now; user.LastGameUpdateSucceed = true; await _dbContext.SaveChangesAsync(KeylolDbContext.ConcurrencyStrategy.ClientWin); try { var steamId = new SteamID(); steamId.SetFromSteam3String(await _userManager.GetSteamIdAsync(user.Id)); string allGamesHtml; if (user.SteamBotId != null && user.SteamBot.IsOnline()) { var botCoordinator = SteamBotCoordinator.Sessions[user.SteamBot.SessionId]; allGamesHtml = await botCoordinator.Client.Curl(user.SteamBotId, $"http://steamcommunity.com/profiles/{steamId.ConvertToUInt64()}/games/?tab=all&l=english"); } else { var httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(10) }; allGamesHtml = await httpClient.GetStringAsync( $"http://steamcommunity.com/profiles/{steamId.ConvertToUInt64()}/games/?tab=all&l=english"); } if (!string.IsNullOrWhiteSpace(allGamesHtml)) { var match = Regex.Match(allGamesHtml, @"<script language=""javascript"">\s*var rgGames = (.*)"); if (match.Success) { var trimed = match.Groups[1].Value.Trim(); var games = JArray.Parse(trimed.Substring(0, trimed.Length - 1)); foreach (var game in games) { // game["hours"] 两周游戏时间 var appId = (int)game["appid"]; double totalPlayedTime = 0; if (game["hours_forever"] != null) { totalPlayedTime = (double)game["hours_forever"]; } if (Math.Abs(totalPlayedTime) <= 0.5) { continue; } var record = await _dbContext.UserGameRecords .Where(r => r.UserId == userId && r.SteamAppId == appId) .SingleOrDefaultAsync(); if (record == null) { record = _dbContext.UserGameRecords.Create(); record.UserId = userId; record.SteamAppId = appId; _dbContext.UserGameRecords.Add(record); } record.TotalPlayedTime = totalPlayedTime; if (game["last_played"] != null) { record.LastPlayTime = Helpers.DateTimeFromTimeStamp((int)game["last_played"]); } } await _dbContext.SaveChangesAsync(); var gameEntries = await _dbContext.UserGameRecords .Where(r => r.UserId == userId) .OrderByDescending(r => r.TotalPlayedTime) .Select(r => new { record = r, point = _dbContext.NormalPoints.FirstOrDefault( p => p.Type == NormalPointType.Game && p.SteamAppId == r.SteamAppId) }) .Where(e => e.point != null) .ToListAsync(); var mostPlayed = gameEntries.Where(g => !user.SubscribedPoints.OfType <Models.NormalPoint>().Contains(g.point)) .Select(g => g.point).Take(6).ToList(); var recentPlayed = gameEntries.Where(g => !user.SubscribedPoints.OfType <Models.NormalPoint>().Contains(g.point) && !mostPlayed.Contains(g.point)) .OrderByDescending(g => g.record.LastPlayTime) .Select(g => g.point).Take(3).ToList(); var genreStats = new Dictionary <Models.NormalPoint, int>(); var manufacturerStats = new Dictionary <Models.NormalPoint, int>(); foreach (var game in gameEntries) { foreach (var point in game.point.TagPoints .Concat(game.point.SeriesPoints) .Concat(game.point.GenrePoints) .Where(p => !user.SubscribedPoints.OfType <Models.NormalPoint>().Contains(p))) { if (genreStats.ContainsKey(point)) { genreStats[point]++; } else { genreStats[point] = 1; } } foreach (var point in game.point.DeveloperPoints .Concat(game.point.PublisherPoints) .Where(p => !user.SubscribedPoints.OfType <Models.NormalPoint>().Contains(p))) { if (manufacturerStats.ContainsKey(point)) { manufacturerStats[point]++; } else { manufacturerStats[point] = 1; } } } var genres = genreStats.OrderByDescending(pair => pair.Value) .Select(pair => pair.Key).Take(3).ToList(); var manufactures = manufacturerStats.OrderByDescending(pair => pair.Value) .Select(pair => pair.Key).Take(3).ToList(); _dbContext.AutoSubscriptions.RemoveRange( await _dbContext.AutoSubscriptions.Where(s => s.UserId == userId).ToListAsync()); var i = 0; _dbContext.AutoSubscriptions.AddRange( mostPlayed.Select(p => new { p, t = AutoSubscriptionType.MostPlayed }) .Concat(recentPlayed.Select(p => new { p, t = AutoSubscriptionType.RecentPlayed })) .Concat(genres.Select(p => new { p, t = AutoSubscriptionType.Genre })) .Concat(manufactures.Select(p => new { p, t = AutoSubscriptionType.Manufacture })) .Select(e => { var subscription = _dbContext.AutoSubscriptions.Create(); subscription.UserId = userId; subscription.NormalPointId = e.p.Id; subscription.Type = e.t; subscription.DisplayOrder = i; i++; return(subscription); })); await _dbContext.SaveChangesAsync(); return(Ok(new { MostPlayed = mostPlayed.Select(p => new NormalPointDto(p)), RecentPlayed = recentPlayed.Select(p => new NormalPointDto(p)), Genres = genres.Select(p => new NormalPointDto(p)), Manufacturers = manufactures.Select(p => new NormalPointDto(p)) })); } if (Regex.IsMatch(allGamesHtml, @"This profile is private\.")) { return(Unauthorized()); } throw new Exception(); } } catch (Exception) { user.LastGameUpdateSucceed = false; await _dbContext.SaveChangesAsync(KeylolDbContext.ConcurrencyStrategy.ClientWin); } return(NotFound()); }
/// <summary> /// 抓取指定用户的 Steam App 库 /// </summary> /// <param name="userId">用户 ID</param> /// <param name="dbContext"><see cref="KeylolDbContext"/></param> /// <param name="userManager"><see cref="KeylolUserManager"/></param> /// <param name="redis"><see cref="RedisProvider"/></param> /// <param name="cachedData"><see cref="CachedDataProvider.CachedDataProvider"/></param> /// <returns>如果抓取成功,返回 <c>true</c></returns> public static async Task <bool> UpdateUserSteamGameRecordsAsync([NotNull] string userId, KeylolDbContext dbContext, KeylolUserManager userManager, RedisProvider redis, CachedDataProvider.CachedDataProvider cachedData) { var cacheKey = UserSteamGameRecordsCrawlerStampCacheKey(userId); var redisDb = redis.GetDatabase(); var cacheResult = await redisDb.StringGetAsync(cacheKey); if (cacheResult.HasValue) { return(false); } await redisDb.StringSetAsync(cacheKey, DateTime.Now.ToTimestamp(), UserSteamGameRecordsUpdatePeriod); try { var user = await userManager.FindByIdAsync(userId); var steamId = new SteamID(); steamId.SetFromSteam3String(await userManager.GetSteamIdAsync(user.Id)); string allGamesHtml; if (user.SteamBotId != null && user.SteamBot.IsOnline()) { var botCoordinator = SteamBotCoordinator.Sessions[user.SteamBot.SessionId]; allGamesHtml = await botCoordinator.Client.Curl(user.SteamBotId, $"http://steamcommunity.com/profiles/{steamId.ConvertToUInt64()}/games/?tab=all&l=english"); } else { allGamesHtml = await HttpClient.GetStringAsync( $"http://steamcommunity.com/profiles/{steamId.ConvertToUInt64()}/games/?tab=all&l=english"); } if (string.IsNullOrWhiteSpace(allGamesHtml)) { throw new Exception(); } var match = Regex.Match(allGamesHtml, @"<script language=""javascript"">\s*var rgGames = (.*)"); if (!match.Success) { throw new Exception(); } var trimed = match.Groups[1].Value.Trim(); var games = JArray.Parse(trimed.Substring(0, trimed.Length - 1)); var oldRecords = (await dbContext.UserSteamGameRecords.Where(r => r.UserId == user.Id).ToListAsync()) .ToDictionary(r => r.SteamAppId, r => r); foreach (var game in games) { var appId = (int)game["appid"]; UserSteamGameRecord record; if (oldRecords.TryGetValue(appId, out record)) { oldRecords.Remove(appId); } else { record = new UserSteamGameRecord { UserId = user.Id, SteamAppId = appId }; dbContext.UserSteamGameRecords.Add(record); } record.TwoWeekPlayedTime = game["hours"] != null ? (double)game["hours"] : 0; record.TotalPlayedTime = game["hours_forever"] != null ? (double)game["hours_forever"] : 0; if (game["last_played"] != null) { record.LastPlayTime = Helpers.DateTimeFromTimeStamp((ulong)game["last_played"]); } } dbContext.UserSteamGameRecords.RemoveRange(oldRecords.Values); await dbContext.SaveChangesAsync(); await cachedData.Users.PurgeSteamAppLibraryCacheAsync(userId); return(true); } catch (Exception) { await redisDb.KeyExpireAsync(cacheKey, SilenceTime); return(false); } }