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, "重新提交成功!");
}
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, "查询成功");
}
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;
}
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;
}
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("修改失败!");
}
}
Aggregations