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);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// 创建 <see cref="UserBasicInfo"/>
        /// </summary>
        /// <param name="currentUserId">当前登录用户 ID</param>
        /// <param name="user">用户对象</param>
        /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
        /// <param name="cachedData"><see cref="CachedDataProvider"/></param>
        /// <param name="userManager"><see cref="KeylolUserManager"/></param>
        /// <returns><see cref="UserBasicInfo"/></returns>
        public static async Task <UserBasicInfo> CreateAsync(string currentUserId, KeylolUser user,
                                                             KeylolDbContext dbContext, CachedDataProvider cachedData, KeylolUserManager userManager)
        {
            var basicInfo = new UserBasicInfo
            {
                Id           = user.Id,
                IdCode       = user.IdCode,
                HeaderImage  = user.HeaderImage,
                AvatarImage  = user.AvatarImage,
                UserName     = user.UserName,
                GamerTag     = user.GamerTag,
                RegisterTime = user.RegisterTime,
                IsFriend     = string.IsNullOrWhiteSpace(currentUserId)
                    ? (bool?)null
                    : await cachedData.Users.IsFriendAsync(currentUserId, user.Id),
                Subscribed = string.IsNullOrWhiteSpace(currentUserId)
                    ? (bool?)null
                    : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, user.Id,
                                                                       SubscriptionTargetType.User),
                FriendCount         = await cachedData.Subscriptions.GetFriendCountAsync(user.Id),
                SubscribedUserCount = await cachedData.Subscriptions.GetSubscribedUserCountAsync(user.Id),
                SubscriberCount     =
                    await cachedData.Subscriptions.GetSubscriberCountAsync(user.Id, SubscriptionTargetType.User),
                ThemeColor      = user.ThemeColor,
                LightThemeColor = user.LightThemeColor,
                SteamId         = await userManager.GetSteamIdAsync(user.Id)
            };

            if (!string.IsNullOrWhiteSpace(basicInfo.SteamId))
            {
                basicInfo.SteamProfileName = user.SteamProfileName;
            }
            int steamCnUid;

            if (int.TryParse(await userManager.GetSteamCnUidAsync(user.Id), out steamCnUid))
            {
                basicInfo.SteamCnUid      = steamCnUid;
                basicInfo.SteamCnUserName = user.SteamCnUserName;
            }
            return(basicInfo);
        }
        /// <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);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// 创建 <see cref="ActivityPage"/>
        /// </summary>
        /// <param name="authorIdCode">作者识别码</param>
        /// <param name="sidForAuthor">动态在作者名下的序号</param>
        /// <param name="currentUserId">当前登录用户 ID</param>
        /// <param name="isOperator">当前登录用户是否为运维职员</param>
        /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
        /// <param name="cachedData"><see cref="CachedDataProvider"/></param>
        /// <param name="userManager"><see cref="KeylolUserManager"/></param>
        /// <returns><see cref="ActivityPage"/></returns>
        public static async Task <ActivityPage> CreateAsync(string authorIdCode, int sidForAuthor, string currentUserId,
                                                            bool isOperator, KeylolDbContext dbContext, CachedDataProvider cachedData, KeylolUserManager userManager)
        {
            var activityPage = new ActivityPage();

            var activity = await dbContext.Activities
                           .Include(a => a.Author)
                           .Include(a => a.TargetPoint)
                           .Where(a => a.Author.IdCode == authorIdCode && a.SidForAuthor == sidForAuthor)
                           .SingleOrDefaultAsync();

            if (activity == null)
            {
                return(activityPage);
            }

            activityPage.Archived = activity.Archived != ArchivedState.None;
            if (activityPage.Archived.Value && currentUserId != activity.AuthorId && !isOperator)
            {
                return(activityPage);
            }

            activityPage.PointBasicInfo =
                await PointBasicInfo.CreateAsync(currentUserId, activity.TargetPoint, dbContext, cachedData);

            activityPage.AuthorBasicInfo = new UserBasicInfo
            {
                Id                  = activity.Author.Id,
                IdCode              = activity.Author.IdCode,
                AvatarImage         = activity.Author.AvatarImage,
                UserName            = activity.Author.UserName,
                FriendCount         = await cachedData.Subscriptions.GetFriendCountAsync(activity.AuthorId),
                SubscribedUserCount = await cachedData.Subscriptions
                                      .GetSubscribedUserCountAsync(activity.AuthorId),
                SubscriberCount = await cachedData.Subscriptions
                                  .GetSubscriberCountAsync(activity.AuthorId, SubscriptionTargetType.User),
                IsFriend = string.IsNullOrWhiteSpace(currentUserId)
                    ? (bool?)null
                    : await cachedData.Users.IsFriendAsync(currentUserId, activity.AuthorId),
                Subscribed = string.IsNullOrWhiteSpace(currentUserId)
                    ? (bool?)null
                    : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, activity.AuthorId,
                                                                       SubscriptionTargetType.User),
                SteamId = await userManager.GetSteamIdAsync(activity.AuthorId)
            };
            if (!string.IsNullOrWhiteSpace(activityPage.AuthorBasicInfo.SteamId))
            {
                activityPage.AuthorBasicInfo.SteamProfileName = activity.Author.SteamProfileName;
            }
            activityPage.AuthorPlayedTime = activity.TargetPoint.SteamAppId == null
                ? null
                : (await dbContext.UserSteamGameRecords
                   .Where(r => r.UserId == activity.AuthorId && r.SteamAppId == activity.TargetPoint.SteamAppId)
                   .SingleOrDefaultAsync())?.TotalPlayedTime;
            activityPage.Id          = activity.Id;
            activityPage.Rejected    = activity.Rejected;
            activityPage.Warned      = activity.Warned;
            activityPage.PublishTime = activity.PublishTime;
            activityPage.Rating      = activity.Rating;
            activityPage.Content     = activity.Content;
            activityPage.CoverImage  = activity.CoverImage;
            var attachedPointIds = Helpers.SafeDeserialize <List <string> >(activity.AttachedPoints) ?? new List <string>();

            activityPage.AttachedPoints = (from id in attachedPointIds
                                           join point in await(from point in dbContext.Points
                                                               where attachedPointIds.Contains(point.Id)
                                                               select new
            {
                point.Type,
                point.Id,
                point.IdCode,
                point.AvatarImage,
                point.ChineseName,
                point.EnglishName
            }).ToListAsync() on id equals point.Id
                                           select new PointBasicInfo
            {
                Type = point.Type,
                Id = point.Id,
                IdCode = point.IdCode,
                AvatarImage = point.AvatarImage,
                ChineseName = point.ChineseName,
                EnglishName = point.EnglishName
            }).ToList();
            var comments = await ActivityCommentList.CreateAsync(activity, 1, currentUserId, isOperator, true,
                                                                 dbContext, cachedData);

            activityPage.CommentCount     = comments.Item2;
            activityPage.CommentPageCount = comments.Item3;
            activityPage.Comments         = comments.Item1;
            activityPage.LikeCount        =
                await cachedData.Likes.GetTargetLikeCountAsync(activity.Id, LikeTargetType.Activity);

            activityPage.Liked = string.IsNullOrWhiteSpace(currentUserId)
                ? (bool?)null
                : await cachedData.Likes.IsLikedAsync(currentUserId, activity.Id, LikeTargetType.Activity);

            return(activityPage);
        }