Search in sources :

Example 1 with Contest

use of top.hcode.hoj.pojo.entity.contest.Contest in project HOJ by HimitZH.

the class JudgeController method checkContestJudgeResult.

/**
 * @MethodName checkContestJudgeResult
 * @Params * @param submitIdListDto
 * @Description 需要检查是否为封榜,是否可以查询结果,避免有人恶意查询
 * @Return
 * @Since 2021/6/11
 */
@RequestMapping(value = "/check-contest-submissions-status", method = RequestMethod.POST)
@RequiresAuthentication
public CommonResult checkContestJudgeResult(@RequestBody SubmitIdListDto submitIdListDto, HttpServletRequest request) {
    if (submitIdListDto.getCid() == null) {
        return CommonResult.errorResponse("查询比赛ID不能为空");
    }
    if (CollectionUtils.isEmpty(submitIdListDto.getSubmitIds())) {
        return CommonResult.successResponse(new HashMap<>(), "查询的提交id列表为空!");
    }
    HttpSession session = request.getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    // 是否为超级管理员
    boolean isRoot = SecurityUtils.getSubject().hasRole("root");
    Contest contest = contestService.getById(submitIdListDto.getCid());
    boolean isContestAdmin = isRoot || userRolesVo.getUid().equals(contest.getUid());
    // 如果是封榜时间且不是比赛管理员和超级管理员
    boolean isSealRank = contestService.isSealRank(userRolesVo.getUid(), contest, true, isRoot);
    QueryWrapper<Judge> queryWrapper = new QueryWrapper<>();
    // lambada表达式过滤掉code
    queryWrapper.select(Judge.class, info -> !info.getColumn().equals("code")).in("submit_id", submitIdListDto.getSubmitIds()).eq("cid", submitIdListDto.getCid()).between(isSealRank, "submit_time", contest.getStartTime(), contest.getSealRankTime());
    List<Judge> judgeList = judgeService.list(queryWrapper);
    HashMap<Long, Object> result = new HashMap<>();
    for (Judge judge : judgeList) {
        judge.setCode(null);
        judge.setDisplayPid(null);
        judge.setErrorMessage(null);
        judge.setVjudgeUsername(null);
        judge.setVjudgeSubmitId(null);
        judge.setVjudgePassword(null);
        if (!judge.getUid().equals(userRolesVo.getUid()) && !isContestAdmin) {
            judge.setTime(null);
            judge.setMemory(null);
            judge.setLength(null);
        }
        result.put(judge.getSubmitId(), judge);
    }
    return CommonResult.successResponse(result, "获取最新判题数据成功!");
}
Also used : java.util(java.util) UpdateWrapper(com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper) Problem(top.hcode.hoj.pojo.entity.problem.Problem) TrainingRecordServiceImpl(top.hcode.hoj.service.training.impl.TrainingRecordServiceImpl) ContestRecord(top.hcode.hoj.pojo.entity.contest.ContestRecord) JudgeVo(top.hcode.hoj.pojo.vo.JudgeVo) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) RemoteJudgeDispatcher(top.hcode.hoj.judge.remote.RemoteJudgeDispatcher) Autowired(org.springframework.beans.factory.annotation.Autowired) RedisUtils(top.hcode.hoj.utils.RedisUtils) CommonResult(top.hcode.hoj.common.result.CommonResult) RefreshScope(org.springframework.cloud.context.config.annotation.RefreshScope) Value(org.springframework.beans.factory.annotation.Value) Judge(top.hcode.hoj.pojo.entity.judge.Judge) RequiresPermissions(org.apache.shiro.authz.annotation.RequiresPermissions) HttpServletRequest(javax.servlet.http.HttpServletRequest) ProblemService(top.hcode.hoj.service.problem.ProblemService) JudgeCaseServiceImpl(top.hcode.hoj.service.judge.impl.JudgeCaseServiceImpl) ContestRecordServiceImpl(top.hcode.hoj.service.contest.impl.ContestRecordServiceImpl) JudgeServiceImpl(top.hcode.hoj.service.judge.impl.JudgeServiceImpl) JudgeCase(top.hcode.hoj.pojo.entity.judge.JudgeCase) JudgeDispatcher(top.hcode.hoj.judge.self.JudgeDispatcher) HttpSession(javax.servlet.http.HttpSession) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) IpUtils(top.hcode.hoj.utils.IpUtils) Contest(top.hcode.hoj.pojo.entity.contest.Contest) SubmitIdListDto(top.hcode.hoj.pojo.dto.SubmitIdListDto) UserAcproblem(top.hcode.hoj.pojo.entity.user.UserAcproblem) CollectionUtils(org.springframework.util.CollectionUtils) org.springframework.web.bind.annotation(org.springframework.web.bind.annotation) ToJudgeDto(top.hcode.hoj.pojo.dto.ToJudgeDto) ContestServiceImpl(top.hcode.hoj.service.contest.impl.ContestServiceImpl) Constants(top.hcode.hoj.utils.Constants) UserAcproblemServiceImpl(top.hcode.hoj.service.user.impl.UserAcproblemServiceImpl) RequiresAuthentication(org.apache.shiro.authz.annotation.RequiresAuthentication) IPage(com.baomidou.mybatisplus.core.metadata.IPage) SecurityUtils(org.apache.shiro.SecurityUtils) Transactional(org.springframework.transaction.annotation.Transactional) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) HttpSession(javax.servlet.http.HttpSession) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) Contest(top.hcode.hoj.pojo.entity.contest.Contest) Judge(top.hcode.hoj.pojo.entity.judge.Judge) RequiresAuthentication(org.apache.shiro.authz.annotation.RequiresAuthentication)

Example 2 with Contest

use of top.hcode.hoj.pojo.entity.contest.Contest in project HOJ by HimitZH.

the class JudgeController method getALLCaseResult.

/**
 * @MethodName getJudgeCase
 * @Params * @param null
 * @Description 获得指定提交id的测试样例结果,暂不支持查看测试数据,只可看测试点结果,时间,空间,或者IO得分
 * @Return
 * @Since 2020/10/29
 */
@GetMapping("/get-all-case-result")
public CommonResult getALLCaseResult(@RequestParam(value = "submitId", required = true) Long submitId, HttpServletRequest request) {
    Judge judge = judgeService.getById(submitId);
    if (judge == null) {
        return CommonResult.errorResponse("此提交数据不存在!");
    }
    Problem problem = problemService.getById(judge.getPid());
    // 如果该题不支持开放测试点结果查看
    if (!problem.getOpenCaseResult()) {
        return CommonResult.successResponse(null, "对不起,该题测试样例详情不支持开放!");
    }
    HttpSession session = request.getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    // 是否为超级管理员
    boolean isRoot = SecurityUtils.getSubject().hasRole("root");
    if (judge.getCid() != 0 && userRolesVo != null && !isRoot) {
        Contest contest = contestService.getById(judge.getCid());
        // 如果不是比赛管理员 比赛封榜不能看
        if (!contest.getUid().equals(userRolesVo.getUid())) {
            // 当前是比赛期间 同时处于封榜时间
            if (contest.getSealRank() && contest.getStatus().intValue() == Constants.Contest.STATUS_RUNNING.getCode() && contest.getSealRankTime().before(new Date())) {
                return CommonResult.successResponse(null, "对不起,该题测试样例详情不能查看!");
            }
            // 若是比赛题目,只支持OI查看测试点情况,ACM强制禁止查看,比赛管理员除外
            if (problem.getType().intValue() == Constants.Contest.TYPE_ACM.getCode()) {
                return CommonResult.successResponse(null, "对不起,该题测试样例详情不能查看!");
            }
        }
    }
    QueryWrapper<JudgeCase> wrapper = new QueryWrapper<>();
    if (userRolesVo == null || (!isRoot && !SecurityUtils.getSubject().hasRole("admin") && !SecurityUtils.getSubject().hasRole("problem_admin"))) {
        wrapper.select("time", "memory", "score", "status", "user_output");
    }
    wrapper.eq("submit_id", submitId).last("order by length(input_data) asc,input_data asc");
    // 当前所有测试点只支持 空间 时间 状态码 IO得分 输出文件名 输入文件名和错误信息提示查看而已
    List<JudgeCase> judgeCaseList = judgeCaseService.list(wrapper);
    if (judgeCaseList.isEmpty()) {
        // 未查询到一条数据
        return CommonResult.successResponse(null, "暂无数据");
    } else {
        return CommonResult.successResponse(judgeCaseList, "获取成功");
    }
}
Also used : JudgeCase(top.hcode.hoj.pojo.entity.judge.JudgeCase) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) HttpSession(javax.servlet.http.HttpSession) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) Problem(top.hcode.hoj.pojo.entity.problem.Problem) Contest(top.hcode.hoj.pojo.entity.contest.Contest) Judge(top.hcode.hoj.pojo.entity.judge.Judge)

Example 3 with Contest

use of top.hcode.hoj.pojo.entity.contest.Contest in project HOJ by HimitZH.

the class ContestAdminController method getContestACInfo.

/**
 * @MethodName getContestACInfo
 * @Params * @param null
 * @Description 获取各个用户的ac情况,仅限于比赛管理者可查看
 * @Return
 * @Since 2021/1/17
 */
@GetMapping("/get-contest-ac-info")
@RequiresAuthentication
public CommonResult getContestACInfo(@RequestParam("cid") Long cid, @RequestParam(value = "currentPage", required = false) Integer currentPage, @RequestParam(value = "limit", required = false) Integer limit, HttpServletRequest request) {
    HttpSession session = request.getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    // 获取本场比赛的状态
    Contest contest = contestService.getById(cid);
    // 超级管理员或者该比赛的创建者,则为比赛管理者
    boolean isRoot = SecurityUtils.getSubject().hasRole("root");
    if (!isRoot && !contest.getUid().equals(userRolesVo.getUid())) {
        return CommonResult.errorResponse("对不起,你无权查看!", CommonResult.STATUS_FORBIDDEN);
    }
    if (currentPage == null || currentPage < 1)
        currentPage = 1;
    if (limit == null || limit < 1)
        limit = 30;
    // 获取当前比赛的,状态为ac,未被校验的排在签名
    IPage<ContestRecord> contestRecords = contestRecordService.getACInfo(currentPage, limit, Constants.Contest.RECORD_AC.getCode(), cid, contest.getUid());
    return CommonResult.successResponse(contestRecords, "查询成功");
}
Also used : HttpSession(javax.servlet.http.HttpSession) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) ContestRecord(top.hcode.hoj.pojo.entity.contest.ContestRecord) Contest(top.hcode.hoj.pojo.entity.contest.Contest) RequiresAuthentication(org.apache.shiro.authz.annotation.RequiresAuthentication)

Example 4 with Contest

use of top.hcode.hoj.pojo.entity.contest.Contest in project HOJ by HimitZH.

the class ProblemController method getUserProblemStatus.

/**
 * @MethodName getUserProblemStatus
 * @Params * @param UidAndPidListDto
 * @Description 获取用户对应该题目列表中各个题目的做题情况
 * @Return CommonResult
 * @Since 2020/12/29
 */
@RequiresAuthentication
@PostMapping("/get-user-problem-status")
public CommonResult getUserProblemStatus(@Validated @RequestBody PidListDto pidListDto, HttpServletRequest request) {
    // 需要获取一下该token对应用户的数据
    HttpSession session = request.getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    HashMap<Long, Object> result = new HashMap<>();
    // 先查询判断该用户对于这些题是否已经通过,若已通过,则无论后续再提交结果如何,该题都标记为通过
    QueryWrapper<Judge> queryWrapper = new QueryWrapper<>();
    queryWrapper.select("distinct pid,status,submit_time,score").in("pid", pidListDto.getPidList()).eq("uid", userRolesVo.getUid()).orderByDesc("submit_time");
    if (pidListDto.getIsContestProblemList()) {
        // 如果是比赛的提交记录需要判断cid
        queryWrapper.eq("cid", pidListDto.getCid());
    } else {
        queryWrapper.eq("cid", 0);
    }
    List<Judge> judges = judgeService.list(queryWrapper);
    boolean isACMContest = true;
    Contest contest = null;
    if (pidListDto.getIsContestProblemList()) {
        contest = contestService.getById(pidListDto.getCid());
        if (contest == null) {
            return CommonResult.errorResponse("比赛参数错误!");
        }
        isACMContest = contest.getType().intValue() == Constants.Contest.TYPE_ACM.getCode();
    }
    for (Judge judge : judges) {
        // 如果是比赛的题目列表状态
        HashMap<String, Object> temp = new HashMap<>();
        if (pidListDto.getIsContestProblemList()) {
            if (!isACMContest) {
                if (!result.containsKey(judge.getPid())) {
                    // 只有比赛结束可以看到,比赛管理员与超级管理员的提交除外
                    if (contestService.isSealRank(userRolesVo.getUid(), contest, true, SecurityUtils.getSubject().hasRole("root"))) {
                        temp.put("status", Constants.Judge.STATUS_SUBMITTED_UNKNOWN_RESULT.getStatus());
                        temp.put("score", null);
                    } else {
                        temp.put("status", judge.getStatus());
                        temp.put("score", judge.getScore());
                    }
                    result.put(judge.getPid(), temp);
                }
            } else {
                // 如果该题目已通过,且同时是为不封榜前提交的,则强制写为通过(0)
                if (judge.getStatus().intValue() == Constants.Judge.STATUS_ACCEPTED.getStatus()) {
                    temp.put("status", Constants.Judge.STATUS_ACCEPTED.getStatus());
                    temp.put("score", null);
                    result.put(judge.getPid(), temp);
                } else if (!result.containsKey(judge.getPid())) {
                    // 还未写入,则使用最新一次提交的结果
                    temp.put("status", judge.getStatus());
                    temp.put("score", null);
                    result.put(judge.getPid(), temp);
                }
            }
        } else {
            // 不是比赛题目
            if (judge.getStatus().intValue() == Constants.Judge.STATUS_ACCEPTED.getStatus()) {
                // 如果该题目已通过,则强制写为通过(0)
                temp.put("status", Constants.Judge.STATUS_ACCEPTED.getStatus());
                result.put(judge.getPid(), temp);
            } else if (!result.containsKey(judge.getPid())) {
                // 还未写入,则使用最新一次提交的结果
                temp.put("status", judge.getStatus());
                result.put(judge.getPid(), temp);
            }
        }
    }
    // 再次检查,应该可能从未提交过该题,则状态写为-10
    for (Long pid : pidListDto.getPidList()) {
        // 如果是比赛的题目列表状态
        if (pidListDto.getIsContestProblemList()) {
            if (!result.containsKey(pid)) {
                HashMap<String, Object> temp = new HashMap<>();
                temp.put("score", null);
                temp.put("status", Constants.Judge.STATUS_NOT_SUBMITTED.getStatus());
                result.put(pid, temp);
            }
        } else {
            if (!result.containsKey(pid)) {
                HashMap<String, Object> temp = new HashMap<>();
                temp.put("status", Constants.Judge.STATUS_NOT_SUBMITTED.getStatus());
                result.put(pid, temp);
            }
        }
    }
    return CommonResult.successResponse(result, "查询成功");
}
Also used : QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) HttpSession(javax.servlet.http.HttpSession) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) Contest(top.hcode.hoj.pojo.entity.contest.Contest) Judge(top.hcode.hoj.pojo.entity.judge.Judge) RequiresAuthentication(org.apache.shiro.authz.annotation.RequiresAuthentication)

Example 5 with Contest

use of top.hcode.hoj.pojo.entity.contest.Contest in project HOJ by HimitZH.

the class ContestRecordServiceImpl method submitContestProblem.

@Override
@Transactional(rollbackFor = Exception.class)
public CommonResult submitContestProblem(ToJudgeDto judgeDto, UserRolesVo userRolesVo, Judge judge) {
    // 首先判断一下比赛的状态是否是正在进行,结束状态都不能提交,比赛前比赛管理员可以提交
    Contest contest = contestService.getById(judgeDto.getCid());
    if (contest == null) {
        return CommonResult.errorResponse("对不起,该比赛不存在!");
    }
    if (contest.getStatus().intValue() == Constants.Contest.STATUS_ENDED.getCode()) {
        return CommonResult.errorResponse("比赛已结束,不可再提交!");
    }
    // 是否为超级管理员或者该比赛的创建者,则为比赛管理者
    boolean root = SecurityUtils.getSubject().hasRole("root");
    if (!root && !contest.getUid().equals(userRolesVo.getUid())) {
        if (contest.getStatus().intValue() == Constants.Contest.STATUS_SCHEDULED.getCode()) {
            return CommonResult.errorResponse("比赛未开始,不可提交!");
        }
        // 需要检查是否有权限在当前比赛进行提交
        CommonResult checkResult = contestService.checkJudgeAuth(contest, userRolesVo.getUid());
        if (checkResult != null) {
            return checkResult;
        }
        if (contest.getAuth().equals(Constants.Contest.AUTH_PROTECT.getCode()) && contest.getOpenAccountLimit() && !contestService.checkAccountRule(contest.getAccountLimitRule(), userRolesVo.getUsername())) {
            return CommonResult.errorResponse("对不起!本次比赛只允许特定账号规则的用户参赛!", CommonResult.STATUS_ACCESS_DENIED);
        }
    }
    // 查询获取对应的pid和cpid
    QueryWrapper<ContestProblem> contestProblemQueryWrapper = new QueryWrapper<>();
    contestProblemQueryWrapper.eq("cid", judgeDto.getCid()).eq("display_id", judgeDto.getPid());
    ContestProblem contestProblem = contestProblemMapper.selectOne(contestProblemQueryWrapper);
    judge.setCpid(contestProblem.getId()).setPid(contestProblem.getPid());
    Problem problem = problemService.getById(contestProblem.getPid());
    if (problem.getAuth() == 2) {
        return CommonResult.errorResponse("错误!当前题目不可提交!", CommonResult.STATUS_FORBIDDEN);
    }
    judge.setDisplayPid(problem.getProblemId());
    // 将新提交数据插入数据库
    judgeMapper.insert(judge);
    // 同时初始化写入contest_record表
    ContestRecord contestRecord = new ContestRecord();
    contestRecord.setDisplayId(judgeDto.getPid()).setCpid(contestProblem.getId()).setSubmitId(judge.getSubmitId()).setPid(judge.getPid()).setUsername(userRolesVo.getUsername()).setRealname(userRolesVo.getRealname()).setUid(userRolesVo.getUid()).setCid(judge.getCid()).setSubmitTime(judge.getSubmitTime());
    if (contest.getStatus().intValue() == Constants.Contest.STATUS_SCHEDULED.getCode()) {
        contestRecord.setTime(0L);
    } else {
        // 设置比赛开始时间到提交时间之间的秒数
        contestRecord.setTime(DateUtil.between(contest.getStartTime(), judge.getSubmitTime(), DateUnit.SECOND));
    }
    contestRecordMapper.insert(contestRecord);
    return null;
}
Also used : QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) ContestRecord(top.hcode.hoj.pojo.entity.contest.ContestRecord) CommonResult(top.hcode.hoj.common.result.CommonResult) Problem(top.hcode.hoj.pojo.entity.problem.Problem) ContestProblem(top.hcode.hoj.pojo.entity.contest.ContestProblem) Contest(top.hcode.hoj.pojo.entity.contest.Contest) ContestProblem(top.hcode.hoj.pojo.entity.contest.ContestProblem) Transactional(org.springframework.transaction.annotation.Transactional)

Aggregations

Contest (top.hcode.hoj.pojo.entity.contest.Contest)59 UserRolesVo (top.hcode.hoj.pojo.vo.UserRolesVo)39 Session (org.apache.shiro.session.Session)35 StatusForbiddenException (top.hcode.hoj.common.exception.StatusForbiddenException)33 StatusFailException (top.hcode.hoj.common.exception.StatusFailException)26 QueryWrapper (com.baomidou.mybatisplus.core.conditions.query.QueryWrapper)25 StatusNotFoundException (top.hcode.hoj.common.exception.StatusNotFoundException)17 Group (top.hcode.hoj.pojo.entity.group.Group)15 HttpSession (javax.servlet.http.HttpSession)13 RequiresAuthentication (org.apache.shiro.authz.annotation.RequiresAuthentication)12 Judge (top.hcode.hoj.pojo.entity.judge.Judge)12 UpdateWrapper (com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper)11 ContestProblem (top.hcode.hoj.pojo.entity.contest.ContestProblem)11 Problem (top.hcode.hoj.pojo.entity.problem.Problem)11 Transactional (org.springframework.transaction.annotation.Transactional)10 JSONObject (cn.hutool.json.JSONObject)9 IPage (com.baomidou.mybatisplus.core.metadata.IPage)7 ContestPrint (top.hcode.hoj.pojo.entity.contest.ContestPrint)7 ContestRecord (top.hcode.hoj.pojo.entity.contest.ContestRecord)7 Discussion (top.hcode.hoj.pojo.entity.discussion.Discussion)7