Пример #1
0
        public async Task <bool> CancelVoteContestAsync(string userId, int contestId)
        {
            var contest = await contestService.GetContestAsync(contestId);

            if (contest == null)
            {
                return(false);
            }
            var exists = await dbContext.VotesRecord.Where(i => i.UserId == userId && i.ProblemId == null && i.ContestId == contestId).FirstOrDefaultAsync();

            if (exists != null)
            {
                if (exists.VoteType == 1)
                {
                    contest.Upvote = Math.Max(0, contest.Upvote - 1);
                }
                else
                {
                    contest.Downvote = Math.Max(0, contest.Downvote - 1);
                }
                dbContext.Contest.Update(contest);
                dbContext.VotesRecord.Remove(exists);
            }
            await dbContext.SaveChangesAsync();

            return(true);
        }
Пример #2
0
        public async Task <IQueryable <Problem> > QueryProblemAsync(string?userId, int contestId)
        {
            var user = await userManager.FindByIdAsync(userId);

            var contest = await contestService.GetContestAsync(contestId);

            if (contest is null)
            {
                throw new NotFoundException("找不到该比赛");
            }

            if (!PrivilegeHelper.IsTeacher(user?.Privilege))
            {
                if (contest.Hidden)
                {
                    throw new ForbiddenException();
                }
            }

            IQueryable <Problem> problems = dbContext.ContestProblemConfig
                                            .Where(i => i.ContestId == contestId)
                                            .OrderBy(i => i.Id)
                                            .Select(i => i.Problem);

            return(problems);
        }
Пример #3
0
        public async Task <IActionResult> GetContestAsync(int id)
        {
            var roleType = _authService.GetRoleTypeFromRequest(Request.HttpContext.User.Claims);
            var userId   = _authService.GetUserIdFromRequest(Request.HttpContext.User.Claims);
            var token    = _authService.GetIpAddressFromRequest(Request.HttpContext.User.Claims);
            var result   = await _contestService.GetContestAsync(id, roleType, userId, token);

            switch (result.Error)
            {
            case GetContestResultType.ContestNotFound:
                return(NotFound(result));

            case GetContestResultType.InvaildToken:
                return(BadRequest(result));

            case GetContestResultType.Error:
                return(BadRequest(result));

            case GetContestResultType.Ok:
                return(Ok(result));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #4
0
        public async Task <IActionResult> GetUser([FromRoute] Guid id)
        {
            var contest = await _contestService.GetContestAsync(id);

            if (contest != null)
            {
                return(Ok(_mapper.Map <ContestResponse>(contest)));
            }
            return(NotFound());
        }
Пример #5
0
        public async Task UpvoteContestTest()
        {
            var adminId = (await UserUtils.GetAdmin()).Id;
            var stuId   = (await UserUtils.GetStudent()).Id;

            var pubId = await contestService.CreateContestAsync(new Data.Contest
            {
                Name   = Guid.NewGuid().ToString(),
                UserId = adminId
            });

            Assert.AreNotEqual(0, pubId);

            Assert.IsTrue(await voteService.UpvoteContestAsync(stuId, pubId));
            var result = await contestService.GetContestAsync(pubId);

            Assert.AreEqual(1, result?.Upvote);

            Assert.IsFalse(await voteService.UpvoteContestAsync(stuId, pubId));
            Assert.IsFalse(await voteService.DownvoteContestAsync(stuId, pubId));
        }
Пример #6
0
        public async Task <ActionResult> GetContests([FromQuery] int contestId)
        {
            try
            {
                var result = await _contestService.GetContestAsync(contestId);

                return(Result.Ok(result));
            }
            catch (Exception ex)
            {
                return(Result.Error(ex));
            }
        }
Пример #7
0
        public async Task <RankContestStatisticsModel> GetRankForContest(int contestId, int groupId)
        {
            var user = await userManager.GetUserAsync(User);

            var contest = await contestService.GetContestAsync(contestId);

            if (contest == null)
            {
                throw new NotFoundException("该比赛不存在");
            }
            if (groupId != 0)
            {
                var groups = await groupService.QueryGroupAsync(user?.Id);

                groups = groups.Where(i => i.GroupContestConfig.Any(j => j.ContestId == contestId && j.GroupId == groupId)) /*.Cacheable()*/;
                if (!await groups.AnyAsync())
                {
                    throw new NotFoundException("该比赛不存在或未加入对应小组");
                }
            }

            var config = contest.Config.DeserializeJson <ContestConfig>(false);

            if (!config.ShowRank && !Utils.PrivilegeHelper.IsTeacher(user?.Privilege))
            {
                throw new ForbiddenException("不允许查看排名");
            }

            var judges = await judgeService.QueryJudgesAsync(null,
                                                             groupId == 0?null : (int?)groupId,
                                                             contestId,
                                                             0);

            if (config.AutoStopRank && !Utils.PrivilegeHelper.IsTeacher(user?.Privilege) && DateTime.Now < contest.EndTime)
            {
                var time = contest.EndTime.AddHours(-1);
                judges = judges.Where(i => i.JudgeTime < time);
            }

            var ret = new RankContestStatisticsModel
            {
                ContestId = contestId,
                GroupId   = groupId
            };

            var results = judges.OrderBy(i => i.Id).Select(i => new
            {
                Id          = i.Id,
                ProblemId   = i.ProblemId,
                ProblemName = i.Problem.Name,
                UserId      = i.UserId,
                UserName    = i.UserInfo.UserName,
                Name        = i.UserInfo.Name,
                ResultType  = i.ResultType,
                Time        = i.JudgeTime,
                Score       = i.FullScore
            }) /*.Cacheable()*/;

            var isAccepted = new Dictionary <(string UserId, int ProblemId), bool>();

            foreach (var i in results)
            {
                if (!ret.UserInfos.ContainsKey(i.UserId))
                {
                    ret.UserInfos[i.UserId] = new RankUserInfoModel
                    {
                        UserName = i.UserName,
                        Name     = Utils.PrivilegeHelper.IsTeacher(user?.Privilege) ? i.Name : string.Empty
                    }
                }
                ;
                if (!ret.ProblemInfos.ContainsKey(i.ProblemId))
                {
                    ret.ProblemInfos[i.ProblemId] = new RankProblemInfoModel
                    {
                        ProblemName = i.ProblemName
                    }
                }
                ;
                if (!ret.RankInfos.ContainsKey(i.UserId))
                {
                    ret.RankInfos[i.UserId] = new Dictionary <int, RankContestItemModel>();
                }
                if (!ret.RankInfos[i.UserId].ContainsKey(i.ProblemId))
                {
                    ret.RankInfos[i.UserId][i.ProblemId] = new RankContestItemModel();
                }

                if (config.Type != ContestType.LastSubmit)
                {
                    ret.RankInfos[i.UserId][i.ProblemId].Accepted = ret.RankInfos[i.UserId][i.ProblemId].Accepted || (i.ResultType == (int)ResultCode.Accepted);
                }
                else
                {
                    ret.RankInfos[i.UserId][i.ProblemId].Accepted = ret.RankInfos[i.UserId][i.ProblemId].Accepted && (i.ResultType == (int)ResultCode.Accepted);
                }

                if (!isAccepted.ContainsKey((i.UserId, i.ProblemId)))
                {
                    isAccepted[(i.UserId, i.ProblemId)] = false;
Пример #8
0
        public async Task <SubmitSuccessModel> SubmitSolution([FromBody] SubmitModel model)
        {
            var user = await userManager.GetUserAsync(User);

            var now = DateTime.Now;
            var allowJumpToResult = true;

            if (user.Privilege == 5)
            {
                throw new ForbiddenException("不允许提交,请与管理员联系");
            }

            if (model.GroupId != 0)
            {
                var inGroup = await groupService.IsInGroupAsync(user.Id, model.GroupId);

                if (!inGroup)
                {
                    throw new ForbiddenException("未参加该小组");
                }
            }

            var problem = await problemService.GetProblemAsync(model.ProblemId);

            if (problem == null)
            {
                throw new NotFoundException("该题目不存在");
            }
            var problemConfig = problem.Config.DeserializeJson <ProblemConfig>(false);

            // For older version compatibility
            if (problemConfig.SourceFiles.Count == 0)
            {
                problemConfig.SourceFiles.Add(string.IsNullOrEmpty(problemConfig.SubmitFileName) ? "${random}${extension}" : $"{problemConfig.SubmitFileName}${{extension}}");
            }

            var sources = new List <Source>();

            foreach (var i in model.Content)
            {
                if (problemConfig.CodeSizeLimit != 0 && problemConfig.CodeSizeLimit < Encoding.UTF8.GetByteCount(i.Content))
                {
                    throw new BadRequestException("提交内容长度超出限制");
                }
                if (problemConfig.SourceFiles.Contains(i.FileName))
                {
                    sources.Add(new Source
                    {
                        FileName = i.FileName,
                        Content  = i.Content
                    });
                }
            }

            var useDefaultDisabledConfig = false;

            var langConfig = (await languageService.GetLanguageConfigAsync()).ToList();
            var langs      = problemConfig.Languages?.Split(';', StringSplitOptions.RemoveEmptyEntries) ?? new string[0];

            if (langs.Length == 0)
            {
                langs = langConfig.Select(i => i.Name).ToArray();
            }
            else
            {
                useDefaultDisabledConfig = true;
            }

            if (model.ContestId != 0)
            {
                var contest = await contestService.GetContestAsync(model.ContestId);

                if (contest != null)
                {
                    if (contest.StartTime > now || now > contest.EndTime)
                    {
                        throw new ForbiddenException("当前不允许提交");
                    }
                    if (contest.Hidden && !PrivilegeHelper.IsTeacher(user.Privilege))
                    {
                        throw new NotFoundException("该比赛不存在");
                    }

                    var contestConfig = contest.Config.DeserializeJson <ContestConfig>(false);
                    if (contestConfig.SubmissionLimit != 0)
                    {
                        var judges = await judgeService.QueryJudgesAsync(user.Id,
                                                                         model.GroupId == 0?null : (int?)model.GroupId,
                                                                         model.ContestId,
                                                                         model.ProblemId);

                        if (contestConfig.SubmissionLimit <= await judges.CountAsync())
                        {
                            throw new ForbiddenException("超出提交次数限制");
                        }
                    }
                    if (contestConfig.ResultMode != ResultDisplayMode.Intime)
                    {
                        allowJumpToResult = false;
                    }
                    var contestLangs = contestConfig.Languages?.Split(';', StringSplitOptions.RemoveEmptyEntries) ?? new string[0];
                    if (contestLangs.Length != 0)
                    {
                        langs = langs.Intersect(contestLangs).ToArray();
                        useDefaultDisabledConfig = true;
                    }
                }
            }
            else if (problem.Hidden && !PrivilegeHelper.IsTeacher(user.Privilege))
            {
                throw new NotFoundException("该题目不存在");
            }

            if (!useDefaultDisabledConfig)
            {
                langs = langs.Where(i => langConfig.Any(j => j.Name == i && !j.DisabledByDefault)).ToArray();
            }

            if (!langs.Contains(model.Language))
            {
                throw new ForbiddenException("不允许使用该语言提交");
            }

            user.SubmissionCount++;
            await userManager.UpdateAsync(user);

            var id = await judgeService.QueueJudgeAsync(new Judge
            {
                Content        = sources.SerializeJsonAsString(),
                Language       = model.Language,
                ProblemId      = model.ProblemId,
                ContestId      = model.ContestId == 0 ? null : (int?)model.ContestId,
                GroupId        = model.GroupId == 0 ? null : (int?)model.GroupId,
                UserId         = user.Id,
                Description    = "Online Judge",
                AdditionalInfo = "v2"
            });

            return(new SubmitSuccessModel
            {
                Jump = allowJumpToResult,
                ResultId = id
            });
        }