Search in sources :

Example 1 with ContestRecord

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

the class JudgeController method resubmit.

/**
 * @MethodName resubmit
 * @Params * @param null
 * @Description 调用判题服务器提交失败超过60s后,用户点击按钮重新提交判题进入的方法
 * @Return
 * @Since 2021/2/12
 */
@RequiresAuthentication
@GetMapping(value = "/resubmit")
@Transactional(rollbackFor = Exception.class)
public CommonResult resubmit(@RequestParam("submitId") Long submitId, HttpServletRequest request) {
    Judge judge = judgeService.getById(submitId);
    if (judge == null) {
        return CommonResult.errorResponse("此提交数据不存在!");
    }
    HttpSession session = request.getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    if (!judge.getUid().equals(userRolesVo.getUid())) {
        // 不是本人无法重新提交
        return CommonResult.errorResponse("对不起!您并非提交数据的本人,无法重新提交!");
    }
    Problem problem = problemService.getById(judge.getPid());
    // 如果是非比赛题目
    if (judge.getCid() == 0) {
        // 如果该题已经是AC通过状态,更新该题目的用户ac做题表 user_acproblem
        if (judge.getStatus().intValue() == Constants.Judge.STATUS_ACCEPTED.getStatus().intValue()) {
            QueryWrapper<UserAcproblem> userAcproblemQueryWrapper = new QueryWrapper<>();
            userAcproblemQueryWrapper.eq("submit_id", judge.getSubmitId());
            userAcproblemService.remove(userAcproblemQueryWrapper);
        }
    } else {
        if (problem.getIsRemote()) {
            // 将对应比赛记录设置成默认值
            UpdateWrapper<ContestRecord> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("submit_id", submitId).setSql("status=null,score=null");
            contestRecordService.update(updateWrapper);
        } else {
            return CommonResult.errorResponse("错误!非vJudge题目在比赛过程无权限重新提交");
        }
    }
    boolean isHasSubmitIdRemoteRejudge = false;
    if (Objects.nonNull(judge.getVjudgeSubmitId()) && (judge.getStatus().intValue() == Constants.Judge.STATUS_SUBMITTED_FAILED.getStatus() || judge.getStatus().intValue() == Constants.Judge.STATUS_PENDING.getStatus() || judge.getStatus().intValue() == Constants.Judge.STATUS_JUDGING.getStatus() || judge.getStatus().intValue() == Constants.Judge.STATUS_COMPILING.getStatus() || judge.getStatus().intValue() == Constants.Judge.STATUS_SYSTEM_ERROR.getStatus())) {
        isHasSubmitIdRemoteRejudge = true;
    }
    // 重新进入等待队列
    judge.setStatus(Constants.Judge.STATUS_PENDING.getStatus());
    judge.setVersion(judge.getVersion() + 1);
    judge.setErrorMessage(null).setOiRankScore(null).setScore(null).setTime(null).setJudger("").setMemory(null);
    judgeService.updateById(judge);
    // 将提交加入任务队列
    if (problem.getIsRemote()) {
        // 如果是远程oj判题
        remoteJudgeDispatcher.sendTask(judge, judgeToken, problem.getProblemId(), judge.getCid() != 0, isHasSubmitIdRemoteRejudge);
    } else {
        judgeDispatcher.sendTask(judge, judgeToken, judge.getCid() != 0);
    }
    return CommonResult.successResponse(judge, "重新提交成功!");
}
Also used : UpdateWrapper(com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) HttpSession(javax.servlet.http.HttpSession) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) ContestRecord(top.hcode.hoj.pojo.entity.contest.ContestRecord) Problem(top.hcode.hoj.pojo.entity.problem.Problem) UserAcproblem(top.hcode.hoj.pojo.entity.user.UserAcproblem) Judge(top.hcode.hoj.pojo.entity.judge.Judge) RequiresAuthentication(org.apache.shiro.authz.annotation.RequiresAuthentication) Transactional(org.springframework.transaction.annotation.Transactional)

Example 2 with ContestRecord

use of top.hcode.hoj.pojo.entity.contest.ContestRecord 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 3 with ContestRecord

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

the class ContestRecordServiceImpl method getACInfo.

@Override
public IPage<ContestRecord> getACInfo(Integer currentPage, Integer limit, Integer status, Long cid, String contestCreatorId) {
    List<ContestRecord> acInfo = contestRecordMapper.getACInfo(status, cid);
    HashMap<Long, String> pidMapUidAndPid = new HashMap<>(12);
    HashMap<String, Long> UidAndPidMapTime = new HashMap<>(12);
    List<UserInfo> superAdminList = getSuperAdminList();
    List<String> superAdminUidList = superAdminList.stream().map(UserInfo::getUuid).collect(Collectors.toList());
    List<ContestRecord> userACInfo = new LinkedList<>();
    for (ContestRecord contestRecord : acInfo) {
        if (contestRecord.getUid().equals(contestCreatorId) || superAdminUidList.contains(contestRecord.getUid())) {
            // 超级管理员和比赛创建者的提交跳过
            continue;
        }
        contestRecord.setFirstBlood(false);
        String uidAndPid = pidMapUidAndPid.get(contestRecord.getPid());
        if (uidAndPid == null) {
            pidMapUidAndPid.put(contestRecord.getPid(), contestRecord.getUid() + contestRecord.getPid());
            UidAndPidMapTime.put(contestRecord.getUid() + contestRecord.getPid(), contestRecord.getTime());
        } else {
            Long firstTime = UidAndPidMapTime.get(uidAndPid);
            Long tmpTime = contestRecord.getTime();
            if (tmpTime < firstTime) {
                pidMapUidAndPid.put(contestRecord.getPid(), contestRecord.getUid() + contestRecord.getPid());
                UidAndPidMapTime.put(contestRecord.getUid() + contestRecord.getPid(), tmpTime);
            }
        }
        userACInfo.add(contestRecord);
    }
    List<ContestRecord> pageList = new ArrayList<>();
    int count = userACInfo.size();
    // 计算当前页第一条数据的下标
    int currId = currentPage > 1 ? (currentPage - 1) * limit : 0;
    for (int i = 0; i < limit && i < count - currId; i++) {
        ContestRecord contestRecord = userACInfo.get(currId + i);
        if (pidMapUidAndPid.get(contestRecord.getPid()).equals(contestRecord.getUid() + contestRecord.getPid())) {
            contestRecord.setFirstBlood(true);
        }
        pageList.add(contestRecord);
    }
    Page<ContestRecord> page = new Page<>(currentPage, limit);
    page.setSize(limit);
    page.setCurrent(currentPage);
    page.setTotal(count);
    page.setRecords(pageList);
    return page;
}
Also used : ContestRecord(top.hcode.hoj.pojo.entity.contest.ContestRecord) UserInfo(top.hcode.hoj.pojo.entity.user.UserInfo) Page(com.baomidou.mybatisplus.extension.plugins.pagination.Page) IPage(com.baomidou.mybatisplus.core.metadata.IPage)

Example 4 with ContestRecord

use of top.hcode.hoj.pojo.entity.contest.ContestRecord 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)

Example 5 with ContestRecord

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

the class ContestAdminManager method checkContestACInfo.

public void checkContestACInfo(CheckACDto checkACDto) throws StatusFailException, StatusForbiddenException {
    Session session = SecurityUtils.getSubject().getSession();
    UserRolesVo userRolesVo = (UserRolesVo) session.getAttribute("userInfo");
    // 获取本场比赛的状态
    Contest contest = contestEntityService.getById(checkACDto.getCid());
    // 超级管理员或者该比赛的创建者,则为比赛管理者
    boolean isRoot = SecurityUtils.getSubject().hasRole("root");
    if (!isRoot && !contest.getUid().equals(userRolesVo.getUid()) && !(contest.getIsGroup() && groupValidator.isGroupRoot(userRolesVo.getUid(), contest.getGid()))) {
        throw new StatusForbiddenException("对不起,您无权限操作!");
    }
    boolean isOk = contestRecordEntityService.updateById(new ContestRecord().setChecked(checkACDto.getChecked()).setId(checkACDto.getId()));
    if (!isOk) {
        throw new StatusFailException("修改失败!");
    }
}
Also used : StatusForbiddenException(top.hcode.hoj.common.exception.StatusForbiddenException) UserRolesVo(top.hcode.hoj.pojo.vo.UserRolesVo) ContestRecord(top.hcode.hoj.pojo.entity.contest.ContestRecord) StatusFailException(top.hcode.hoj.common.exception.StatusFailException) Contest(top.hcode.hoj.pojo.entity.contest.Contest) Session(org.apache.shiro.session.Session)

Aggregations

ContestRecord (top.hcode.hoj.pojo.entity.contest.ContestRecord)13 QueryWrapper (com.baomidou.mybatisplus.core.conditions.query.QueryWrapper)8 Transactional (org.springframework.transaction.annotation.Transactional)8 Problem (top.hcode.hoj.pojo.entity.problem.Problem)8 UpdateWrapper (com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper)6 Judge (top.hcode.hoj.pojo.entity.judge.Judge)6 Contest (top.hcode.hoj.pojo.entity.contest.Contest)5 JudgeCase (top.hcode.hoj.pojo.entity.judge.JudgeCase)4 UserAcproblem (top.hcode.hoj.pojo.entity.user.UserAcproblem)4 UserRolesVo (top.hcode.hoj.pojo.vo.UserRolesVo)4 HttpSession (javax.servlet.http.HttpSession)3 RequiresAuthentication (org.apache.shiro.authz.annotation.RequiresAuthentication)3 StatusFailException (top.hcode.hoj.common.exception.StatusFailException)3 IPage (com.baomidou.mybatisplus.core.metadata.IPage)2 Page (com.baomidou.mybatisplus.extension.plugins.pagination.Page)2 HashMap (java.util.HashMap)2 LinkedList (java.util.LinkedList)2 StatusForbiddenException (top.hcode.hoj.common.exception.StatusForbiddenException)2 ContestProblem (top.hcode.hoj.pojo.entity.contest.ContestProblem)2 Session (org.apache.shiro.session.Session)1