From cab8fc233fbe56a6af34f637e8edaa8249fcc986 Mon Sep 17 00:00:00 2001
From: Himit_ZH <372347736@qq.com>
Date: Thu, 17 Jun 2021 21:16:50 +0800
Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4vjudge=20=E4=BF=AE=E6=94=B9?=
=?UTF-8?q?=E9=83=A8=E5=88=86=E5=89=8D=E7=AB=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
hoj-springboot/.idea/compiler.xml | 2 +-
.../admin/AdminContestController.java | 16 ++++--
.../admin/AdminJudgeController.java | 14 ++++-
.../hoj/controller/oj/JudgeController.java | 34 +++++++++----
.../java/top/hcode/hoj/judge/Dispatcher.java | 2 +-
.../hoj/service/impl/ScheduleServiceImpl.java | 7 +++
.../hoj/remoteJudge/RemoteJudgeGetResult.java | 10 ++--
.../task/Impl/CodeForcesJudge.java | 48 +++++++++---------
.../hoj/remoteJudge/task/Impl/HduJudge.java | 11 +++-
.../impl/ContestRecordServiceImpl.java | 4 +-
.../hoj/service/impl/JudgeServiceImpl.java | 1 +
.../java/top/hcode/hoj/util/Constants.java | 9 ++--
hoj-vue/src/components/oj/common/Login.vue | 4 +-
.../src/views/admin/problem/ProblemList.vue | 2 +-
hoj-vue/src/views/oj/Home.vue | 2 +-
hoj-vue/src/views/oj/rank/ACMRank.vue | 19 ++++++-
hoj-vue/src/views/oj/rank/OIRank.vue | 17 ++++++-
.../src/views/oj/status/SubmissionList.vue | 4 +-
judger/{Judger-SandBox => SandBox} | Bin
19 files changed, 146 insertions(+), 60 deletions(-)
rename judger/{Judger-SandBox => SandBox} (100%)
diff --git a/hoj-springboot/.idea/compiler.xml b/hoj-springboot/.idea/compiler.xml
index f0216164..7b623431 100644
--- a/hoj-springboot/.idea/compiler.xml
+++ b/hoj-springboot/.idea/compiler.xml
@@ -8,8 +8,8 @@
-
+
diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/admin/AdminContestController.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/admin/AdminContestController.java
index 7a714678..bbe8bff5 100644
--- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/admin/AdminContestController.java
+++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/admin/AdminContestController.java
@@ -400,10 +400,13 @@ public class AdminContestController {
Long cid = Long.valueOf(cidStr);
QueryWrapper contestProblemQueryWrapper = new QueryWrapper<>();
- contestProblemQueryWrapper.eq("pid", pid).eq("cid", cid);
+ contestProblemQueryWrapper.eq("cid", cid)
+ .and(QueryWrapper -> QueryWrapper.eq("pid", pid)
+ .or()
+ .eq("display_id",displayId));
ContestProblem contestProblem = contestProblemService.getOne(contestProblemQueryWrapper, false);
if (contestProblem != null) {
- return CommonResult.errorResponse("添加失败,该题目已经加入到此次比赛当中了,请勿重复操作!", CommonResult.STATUS_FAIL);
+ return CommonResult.errorResponse("添加失败,该题目已添加或者题目的比赛展示ID已存在!", CommonResult.STATUS_FAIL);
}
// 比赛中题目显示默认为原标题
@@ -456,12 +459,17 @@ public class AdminContestController {
}
QueryWrapper contestProblemQueryWrapper = new QueryWrapper<>();
- contestProblemQueryWrapper.eq("pid", problem.getId()).eq("cid", cid);
+ Problem finalProblem = problem;
+ contestProblemQueryWrapper.eq("cid", cid)
+ .and(QueryWrapper -> queryWrapper.eq("pid", finalProblem.getId())
+ .or()
+ .eq("display_id",displayId));
ContestProblem contestProblem = contestProblemService.getOne(contestProblemQueryWrapper, false);
if (contestProblem != null) {
- return CommonResult.errorResponse("添加失败,该题目已经加入到此次比赛当中了,请勿重复操作!", CommonResult.STATUS_FAIL);
+ return CommonResult.errorResponse("添加失败,该题目已添加或者题目的比赛展示ID已存在!", CommonResult.STATUS_FAIL);
}
+
// 比赛中题目显示默认为原标题
String displayName = problem.getTitle();
diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/admin/AdminJudgeController.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/admin/AdminJudgeController.java
index b0d3fd9c..d6c38ef2 100644
--- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/admin/AdminJudgeController.java
+++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/admin/AdminJudgeController.java
@@ -86,7 +86,12 @@ public class AdminJudgeController {
// 设置默认值
judge.setStatus(Constants.Judge.STATUS_PENDING.getStatus()); // 开始进入判题队列
judge.setVersion(judge.getVersion() + 1);
- judge.setJudger(null).setTime(null).setMemory(null).setErrorMessage(null);
+ judge.setJudger(null)
+ .setTime(null)
+ .setMemory(null)
+ .setErrorMessage(null)
+ .setJudger(null)
+ .setScore(null);
boolean result = judgeService.updateById(judge);
if (result) {
// 调用判题服务
@@ -123,7 +128,12 @@ public class AdminJudgeController {
for (Judge judge : rejudgeList) {
judge.setStatus(Constants.Judge.STATUS_PENDING.getStatus()); // 开始进入判题队列
judge.setVersion(judge.getVersion() + 1);
- judge.setJudger(null).setTime(null).setMemory(null).setErrorMessage(null);
+ judge.setJudger(null)
+ .setTime(null)
+ .setMemory(null)
+ .setErrorMessage(null)
+ .setJudger(null)
+ .setScore(null);
submitIdList.add(judge.getSubmitId());
}
boolean resetJudgeResult = judgeService.updateBatchById(rejudgeList);
diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/oj/JudgeController.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/oj/JudgeController.java
index c0eaf330..8452d6b7 100644
--- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/oj/JudgeController.java
+++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/controller/oj/JudgeController.java
@@ -300,7 +300,6 @@ public class JudgeController {
boolean root = SecurityUtils.getSubject().hasRole("root"); // 是否为超级管理员
HashMap result = new HashMap<>();
- // 如果是比赛需要判断是否为封榜,比赛管理员和超级管理员可以有权限查看(ACM题目除外)
if (judge.getCid() != 0 && !root) {
Contest contest = contestService.getById(judge.getCid());
if (!userRolesVo.getUid().equals(contest.getUid()) && contest.getSealRank()
@@ -315,16 +314,33 @@ public class JudgeController {
// 超级管理员与管理员有权限查看代码
// 如果不是本人或者并未分享代码,则不可查看
// 当此次提交代码不共享
- boolean admin = SecurityUtils.getSubject().hasRole("admin")
- || SecurityUtils.getSubject().hasRole("problem_admin");// 是否为管理员
- if (!judge.getShare() && !root && !admin) {
- if (userRolesVo != null) { // 当前是登陆状态
- // 需要判断是否为当前登陆用户自己的提交代码
- if (!judge.getUid().equals(userRolesVo.getUid())) {
+ // 比赛提交只有比赛创建者和root账号可看代码
+ if (judge.getCid() != 0){
+
+ Contest contest = contestService.getById(judge.getCid());
+ if (!root&&!userRolesVo.getUid().equals(contest.getUid())) {
+ // 如果是比赛,那么还需要判断是否为封榜,比赛管理员和超级管理员可以有权限查看(ACM题目除外)
+ if(contest.getSealRank()
+ && contest.getType().intValue() == Constants.Contest.TYPE_OI.getCode()
+ && contest.getStatus().intValue() == Constants.Contest.STATUS_RUNNING.getCode()
+ && contest.getSealRankTime().before(new Date())) {
+ result.put("submission", new Judge().setStatus(Constants.Judge.STATUS_SUBMITTED_UNKNOWN_RESULT.getStatus()));
+ return CommonResult.successResponse(result, "获取提交数据成功!");
+ }
+ judge.setCode(null);
+ }
+ }else {
+ boolean admin = SecurityUtils.getSubject().hasRole("admin")
+ || SecurityUtils.getSubject().hasRole("problem_admin");// 是否为管理员
+ if (!judge.getShare() && !root && !admin) {
+ if (userRolesVo != null) { // 当前是登陆状态
+ // 需要判断是否为当前登陆用户自己的提交代码
+ if (!judge.getUid().equals(userRolesVo.getUid())) {
+ judge.setCode(null);
+ }
+ } else { // 不是登陆状态,就直接无权限查看代码
judge.setCode(null);
}
- } else { // 不是登陆状态,就直接无权限查看代码
- judge.setCode(null);
}
}
diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/Dispatcher.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/Dispatcher.java
index 1918d992..6fa9a68c 100644
--- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/Dispatcher.java
+++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/Dispatcher.java
@@ -85,7 +85,7 @@ public class Dispatcher {
}
}
- if (count.get() == 90) { // 90次失败则判为提交失败
+ if (count.get() == 300) { // 300次失败则判为提交失败
if (isRemote) { // 远程判题需要将账号归为可用
UpdateWrapper remoteJudgeAccountUpdateWrapper = new UpdateWrapper<>();
remoteJudgeAccountUpdateWrapper
diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/service/impl/ScheduleServiceImpl.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/service/impl/ScheduleServiceImpl.java
index 98583588..65d51d8c 100644
--- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/service/impl/ScheduleServiceImpl.java
+++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/service/impl/ScheduleServiceImpl.java
@@ -24,6 +24,7 @@ import top.hcode.hoj.utils.JsoupUtils;
import top.hcode.hoj.utils.RedisUtils;
import java.util.*;
+import java.util.concurrent.TimeUnit;
/**
@@ -196,6 +197,12 @@ public class ScheduleServiceImpl implements ScheduleService {
// 格式化api
String ratingAPI = String.format(codeforcesUserInfoAPI, cfUsername);
try {
+ // 防止cf的频率限制
+ try {
+ TimeUnit.SECONDS.sleep(5);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
// 连接api,获取json格式对象
JSONObject resultObject = JsoupUtils.getJsonFromConnection(JsoupUtils.getConnectionFromUrl(ratingAPI, null, null));
// 获取状态码
diff --git a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/RemoteJudgeGetResult.java b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/RemoteJudgeGetResult.java
index d1a63ba8..23b5eeca 100644
--- a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/RemoteJudgeGetResult.java
+++ b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/RemoteJudgeGetResult.java
@@ -51,11 +51,15 @@ public class RemoteJudgeGetResult {
Integer status = (Integer) result.getOrDefault("status", Constants.Judge.STATUS_SYSTEM_ERROR.getStatus());
if (status.intValue() != Constants.Judge.STATUS_PENDING.getStatus() &&
status.intValue() != Constants.Judge.STATUS_JUDGING.getStatus()) {
- Judge judge = judgeService.getById(submitId);
+
Integer time = (Integer) result.getOrDefault("time", null);
Integer memory = (Integer) result.getOrDefault("memory", null);
String CEInfo = (String) result.getOrDefault("CEInfo", null);
- judge.setStatus(status)
+
+ Judge judge = new Judge();
+
+ judge.setSubmitId(submitId)
+ .setStatus(status)
.setTime(time)
.setMemory(memory);
@@ -66,7 +70,7 @@ public class RemoteJudgeGetResult {
}
// 如果是比赛题目,需要特别适配OI比赛的得分 除AC给100 其它结果给0分
- if (judge.getCid() != 0) {
+ if (cid != 0) {
int score = 0;
if (judge.getStatus().intValue() == Constants.Judge.STATUS_ACCEPTED.getStatus()) {
diff --git a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/CodeForcesJudge.java b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/CodeForcesJudge.java
index bb4c42c2..0d1c6293 100644
--- a/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/CodeForcesJudge.java
+++ b/hoj-springboot/JudgeServer/src/main/java/top/hcode/hoj/remoteJudge/task/Impl/CodeForcesJudge.java
@@ -2,6 +2,8 @@ package top.hcode.hoj.remoteJudge.task.Impl;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ReUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
@@ -21,13 +23,14 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
+import java.util.concurrent.TimeUnit;
@Slf4j(topic = "hoj")
public class CodeForcesJudge implements RemoteJudgeStrategy {
public static final String HOST = "https://codeforces.com/";
public static final String LOGIN_URL = "enter";
public static final String SUBMIT_URL = "problemset/submit";
- public static final String SUBMISSION_RESULT_URL = "api/user.status?handle=%s&from=1&count=5";
+ public static final String SUBMISSION_RESULT_URL = "api/user.status?handle=%s&from=1&count=30";
public static final String CE_INFO_URL = "data/submitSource";
private static final Map statusMap = new HashMap() {{
@@ -64,16 +67,14 @@ public class CodeForcesJudge implements RemoteJudgeStrategy {
return null;
}
- WebClient webClient = (WebClient) loginUtils.getOrDefault("webClient", null);
-
- boolean isSubmitted = submitCode(webClient, problemId, getLanguage(language), userCode);
-
- if (!isSubmitted) {
- log.error("进行题目提交时发生错误:提交题目失败," + CodeForcesJudge.class.getName() + ",题号:" + problemId);
- return null;
+ try (WebClient webClient = (WebClient) loginUtils.getOrDefault("webClient", null)) {
+ submitCode(webClient, problemId, getLanguage(language), userCode);
}
+
// 获取提交的题目id
+
Long maxRunId = getMaxRunId(null, username, problemId);
+
return MapUtil.builder(new HashMap())
.put("runId", maxRunId)
.put("token", "")
@@ -81,15 +82,24 @@ public class CodeForcesJudge implements RemoteJudgeStrategy {
.map();
}
- private Long getMaxRunId(Connection connection, String username, String problemId) {
-
+ private Long getMaxRunId(Connection connection, String username, String problemId) throws InterruptedException {
+ int retryNum = 0;
String url = String.format(SUBMISSION_RESULT_URL, username);
- String resJson = HttpUtil.createGet(HOST + url).timeout(30000).execute().body();
+ HttpRequest httpRequest = HttpUtil.createGet(HOST + url);
+ httpRequest.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36 Edg/91.0.864.48");
+ httpRequest.disableCache();
+ HttpResponse httpResponse = httpRequest.execute();
+ // 防止cf的nginx限制访问频率,重试10次
+ while (httpResponse.getStatus() != 200 && retryNum != 10) {
+ TimeUnit.SECONDS.sleep(3);
+ httpResponse = httpRequest.execute();
+ retryNum++;
+ }
String contestNum = problemId.replaceAll("\\D.*", "");
String problemNum = problemId.replaceAll("^\\d*", "");
try {
- Map json = JSONUtil.parseObj(resJson);
+ Map json = JSONUtil.parseObj(httpResponse.body());
List