修复HOJ、POJ更新后的bug
This commit is contained in:
parent
8329f0d420
commit
3606ae9fe6
|
@ -11,7 +11,7 @@ module.exports = {
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
sidebarDepth: 5,
|
sidebarDepth: 5,
|
||||||
nav: [
|
nav: [
|
||||||
{ text: 'Demo', link: 'https://www.hcode.top' },
|
{ text: 'Demo', link: 'https://hdoi.cn/' },
|
||||||
{ text: 'Gitee', link: 'https://gitee.com/himitzh0730/hoj' },
|
{ text: 'Gitee', link: 'https://gitee.com/himitzh0730/hoj' },
|
||||||
{ text: 'Github', link: 'https://github.com/HimitZH/HOJ' },
|
{ text: 'Github', link: 'https://github.com/HimitZH/HOJ' },
|
||||||
{ text: '作者首页', link: 'https://blog.csdn.net/weixin_43853097' },
|
{ text: '作者首页', link: 'https://blog.csdn.net/weixin_43853097' },
|
||||||
|
|
|
@ -16,5 +16,5 @@ features:
|
||||||
details: 判题使用 cgroup 隔离用户程序,网站权限控制完善
|
details: 判题使用 cgroup 隔离用户程序,网站权限控制完善
|
||||||
- title: 多样化
|
- title: 多样化
|
||||||
details: 独有自身判题服务,同时支持其它知名OJ题目的提交判题
|
details: 独有自身判题服务,同时支持其它知名OJ题目的提交判题
|
||||||
footer: MIT Licensed | Copyright © 2021.06.14 @Author Himit_ZH QQ Group:598587305
|
footer: MIT Licensed | Copyright © 2021.06.25 @Author Himit_ZH QQ Group:598587305
|
||||||
---
|
---
|
|
@ -63,6 +63,8 @@
|
||||||
HDU_ACCOUNT_PASSWORD_LIST=
|
HDU_ACCOUNT_PASSWORD_LIST=
|
||||||
CF_ACCOUNT_USERNAME_LIST=
|
CF_ACCOUNT_USERNAME_LIST=
|
||||||
CF_ACCOUNT_PASSWORD_LIST=
|
CF_ACCOUNT_PASSWORD_LIST=
|
||||||
|
POJ_ACCOUNT_USERNAME_LIST=
|
||||||
|
POJ_ACCOUNT_PASSWORD_LIST=
|
||||||
|
|
||||||
# judgeserver的配置
|
# judgeserver的配置
|
||||||
JUDGE_SERVER_IP=172.20.0.7
|
JUDGE_SERVER_IP=172.20.0.7
|
||||||
|
@ -70,36 +72,36 @@
|
||||||
JUDGE_SERVER_NAME=judger-alone
|
JUDGE_SERVER_NAME=judger-alone
|
||||||
|
|
||||||
# docker network的配置
|
# docker network的配置
|
||||||
SUBNET=172.20.0.0/16
|
SUBNET=172.20.0.0/16
|
||||||
```
|
```
|
||||||
|
|
||||||
如果不改动,则以默认参数启动
|
如果不改动,则以默认参数启动
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
**根据网速情况,大约十到二十分钟拉取镜像,全程无需人工干预,拉取完毕后,自动启动容器服务,大概需要一至两分钟的初始化。**
|
**根据网速情况,大约十到二十分钟拉取镜像,全程无需人工干预,拉取完毕后,自动启动容器服务,大概需要一至两分钟的初始化。**
|
||||||
|
|
||||||
等待命令执行完毕后,查看容器状态
|
等待命令执行完毕后,查看容器状态
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker ps -a
|
docker ps -a
|
||||||
```
|
```
|
||||||
|
|
||||||
当看到所有的容器的状态status都为`UP`或`healthy`就代表 OJ 已经启动成功。
|
当看到所有的容器的状态status都为`UP`或`healthy`就代表 OJ 已经启动成功。
|
||||||
|
|
||||||
> 以下默认参数说明
|
> 以下默认参数说明
|
||||||
|
|
||||||
- 默认超级管理员账号与密码:root / hoj123456
|
- 默认超级管理员账号与密码:root / hoj123456
|
||||||
- 默认redis密码:hoj123456
|
- 默认redis密码:hoj123456
|
||||||
- 默认mysql账号与密码:root / hoj123456
|
- 默认mysql账号与密码:root / hoj123456
|
||||||
- 默认nacos管理员账号与密码:root / hoj123456
|
- 默认nacos管理员账号与密码:root / hoj123456
|
||||||
- 默认不开启https,开启需修改文件同时提供证书文件
|
- 默认不开启https,开启需修改文件同时提供证书文件
|
||||||
- 判题并发数默认:cpu核心数*2
|
- 判题并发数默认:cpu核心数*2
|
||||||
- 默认开启vj判题,需要手动修改添加账号与密码,如果不添加不能vj判题!
|
- 默认开启vj判题,需要手动修改添加账号与密码,如果不添加不能vj判题!
|
||||||
- vj判题并发数默认:cpu核心数*4
|
- vj判题并发数默认:cpu核心数*4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**登录root账号到后台查看服务状态以及到`http://ip/admin/conf`修改服务配置!**
|
**登录root账号到后台查看服务状态以及到`http://ip/admin/conf`修改服务配置!**
|
||||||
|
@ -199,6 +201,8 @@ Password: 开启SMTP服务后生成的随机授权码
|
||||||
HDU_ACCOUNT_PASSWORD_LIST=password1,password2
|
HDU_ACCOUNT_PASSWORD_LIST=password1,password2
|
||||||
CF_ACCOUNT_USERNAME_LIST=
|
CF_ACCOUNT_USERNAME_LIST=
|
||||||
CF_ACCOUNT_PASSWORD_LIST=
|
CF_ACCOUNT_PASSWORD_LIST=
|
||||||
|
POJ_ACCOUNT_USERNAME_LIST=
|
||||||
|
POJ_ACCOUNT_PASSWORD_LIST=
|
||||||
|
|
||||||
# 评测数据同步的配置
|
# 评测数据同步的配置
|
||||||
RSYNC_PASSWORD=hoj123456 # 请修改数据同步密码
|
RSYNC_PASSWORD=hoj123456 # 请修改数据同步密码
|
||||||
|
|
|
@ -25,7 +25,7 @@ HOJ,全称 Hcode Online Judge,是基于前后端分离,分布式架构的
|
||||||
- 扩展:支持分布式判题
|
- 扩展:支持分布式判题
|
||||||
- 简单:高度集中网站配置
|
- 简单:高度集中网站配置
|
||||||
- 功能:支持ACM、OI题目及比赛
|
- 功能:支持ACM、OI题目及比赛
|
||||||
- 多样:支持自身题目数据评测,也支持其它知名OJ(HDU、Codeforces)题目的爬取与提交
|
- 多样:支持自身题目数据评测,也支持其它知名OJ(HDU、Codeforces、POJ)题目的爬取与提交
|
||||||
|
|
||||||
## 截图
|
## 截图
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,6 @@ public class RemoteJudgeGetResult {
|
||||||
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||||
|
|
||||||
AtomicInteger count = new AtomicInteger(0);
|
AtomicInteger count = new AtomicInteger(0);
|
||||||
|
|
||||||
Runnable getResultTask = new Runnable() {
|
Runnable getResultTask = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
|
@ -54,7 +53,6 @@ public class RemoteJudgeGetResult {
|
||||||
Integer time = (Integer) result.getOrDefault("time", null);
|
Integer time = (Integer) result.getOrDefault("time", null);
|
||||||
Integer memory = (Integer) result.getOrDefault("memory", null);
|
Integer memory = (Integer) result.getOrDefault("memory", null);
|
||||||
String CEInfo = (String) result.getOrDefault("CEInfo", null);
|
String CEInfo = (String) result.getOrDefault("CEInfo", null);
|
||||||
|
|
||||||
Judge judge = new Judge();
|
Judge judge = new Judge();
|
||||||
|
|
||||||
judge.setSubmitId(submitId)
|
judge.setSubmitId(submitId)
|
||||||
|
|
|
@ -60,6 +60,7 @@ public class RemoteJudgeToSubmit {
|
||||||
|
|
||||||
UpdateWrapper<RemoteJudgeAccount> remoteJudgeAccountUpdateWrapper = new UpdateWrapper<>();
|
UpdateWrapper<RemoteJudgeAccount> remoteJudgeAccountUpdateWrapper = new UpdateWrapper<>();
|
||||||
remoteJudgeAccountUpdateWrapper.set("status", true)
|
remoteJudgeAccountUpdateWrapper.set("status", true)
|
||||||
|
.eq("oj", remoteJudge)
|
||||||
.eq("username", username)
|
.eq("username", username)
|
||||||
.eq("password", password);
|
.eq("password", password);
|
||||||
boolean isOk = remoteJudgeAccountService.update(remoteJudgeAccountUpdateWrapper);
|
boolean isOk = remoteJudgeAccountService.update(remoteJudgeAccountUpdateWrapper);
|
||||||
|
@ -87,10 +88,10 @@ public class RemoteJudgeToSubmit {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交成功顺便更新状态为-->STATUS_PENDING 等待中...
|
// 提交成功顺便更新状态为-->STATUS_JUDGING 判题中...
|
||||||
judgeService.updateById(new Judge()
|
judgeService.updateById(new Judge()
|
||||||
.setSubmitId(submitId)
|
.setSubmitId(submitId)
|
||||||
.setStatus(Constants.Judge.STATUS_PENDING.getStatus())
|
.setStatus(Constants.Judge.STATUS_JUDGING.getStatus())
|
||||||
.setJudger(name)
|
.setJudger(name)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class HduJudge implements RemoteJudgeStrategy {
|
||||||
.put("usercode", userCode)
|
.put("usercode", userCode)
|
||||||
.map())
|
.map())
|
||||||
.execute();
|
.execute();
|
||||||
if (response.getStatus() != 200) {
|
if (response.getStatus() != 200 && response.getStatus() != 302) {
|
||||||
log.error("进行题目提交时发生错误:提交题目失败," + HduJudge.class.getName() + ",题号:" + problemId);
|
log.error("进行题目提交时发生错误:提交题目失败," + HduJudge.class.getName() + ",题号:" + problemId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,6 @@ public class HduJudge implements RemoteJudgeStrategy {
|
||||||
request.setMethod(Method.GET);
|
request.setMethod(Method.GET);
|
||||||
// 获取提交的题目id
|
// 获取提交的题目id
|
||||||
Long maxRunId = getMaxRunId(request, username, problemId);
|
Long maxRunId = getMaxRunId(request, username, problemId);
|
||||||
|
|
||||||
if (maxRunId == -1L) { // 等待2s再次查询,如果还是失败,则表明提交失败了
|
if (maxRunId == -1L) { // 等待2s再次查询,如果还是失败,则表明提交失败了
|
||||||
TimeUnit.SECONDS.sleep(2);
|
TimeUnit.SECONDS.sleep(2);
|
||||||
maxRunId = getMaxRunId(request, username, problemId);
|
maxRunId = getMaxRunId(request, username, problemId);
|
||||||
|
@ -116,7 +115,7 @@ public class HduJudge implements RemoteJudgeStrategy {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> getLoginUtils(String username, String password){
|
public Map<String, Object> getLoginUtils(String username, String password) {
|
||||||
|
|
||||||
HttpRequest request = HttpUtil.createPost(HOST + LOGIN_URL).addHeaders(headers);
|
HttpRequest request = HttpUtil.createPost(HOST + LOGIN_URL).addHeaders(headers);
|
||||||
HttpResponse response = request.form(MapUtil
|
HttpResponse response = request.form(MapUtil
|
||||||
|
@ -152,11 +151,11 @@ public class HduJudge implements RemoteJudgeStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Long getMaxRunId(HttpRequest request, String userName, String problemId){
|
public Long getMaxRunId(HttpRequest request, String userName, String problemId) {
|
||||||
String url = String.format(STATUS_URL, userName, problemId);
|
String url = HOST + String.format(STATUS_URL, userName, problemId);
|
||||||
HttpResponse response = request.setUrl(url).execute();
|
HttpResponse response = HttpUtil.createGet(url).addHeaders(headers).execute();
|
||||||
Matcher matcher = Pattern.compile("<td height=22px>(\\d+)").matcher(response.body());
|
String maxRunId = ReUtil.get("<td height=22px>(\\d+)", response.body(), 1);
|
||||||
return matcher.find() ? Long.parseLong(matcher.group(1)) : -1L;
|
return maxRunId != null ? Long.parseLong(maxRunId) : -1L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class POJJudge implements RemoteJudgeStrategy {
|
||||||
.put("source", Base64.encode(userCode))
|
.put("source", Base64.encode(userCode))
|
||||||
.put("encoded", 1).map())
|
.put("encoded", 1).map())
|
||||||
.execute();
|
.execute();
|
||||||
if (response.getStatus() != 302) {
|
if (response.getStatus() != 302 && response.getStatus() != 200) {
|
||||||
log.error("进行题目提交时发生错误:提交题目失败," + POJJudge.class.getName() + ",题号:" + problemId);
|
log.error("进行题目提交时发生错误:提交题目失败," + POJJudge.class.getName() + ",题号:" + problemId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -89,11 +89,10 @@ public class POJJudge implements RemoteJudgeStrategy {
|
||||||
.replaceAll("<.*?>", "")
|
.replaceAll("<.*?>", "")
|
||||||
.trim();
|
.trim();
|
||||||
|
|
||||||
Constants.Judge statusType = statusTypeMap.getOrDefault(statusStr, null);
|
Constants.Judge statusType = statusMap.get(statusStr);
|
||||||
|
|
||||||
if (statusType == null) {
|
if (statusType == null) {
|
||||||
return MapUtil.builder(new HashMap<String, Object>())
|
return MapUtil.builder(new HashMap<String, Object>())
|
||||||
.put("status", Constants.Judge.STATUS_PENDING).build();
|
.put("status", Constants.Judge.STATUS_JUDGING).build();
|
||||||
}
|
}
|
||||||
// 返回的结果map
|
// 返回的结果map
|
||||||
Map<String, Object> result = MapUtil.builder(new HashMap<String, Object>())
|
Map<String, Object> result = MapUtil.builder(new HashMap<String, Object>())
|
||||||
|
@ -107,9 +106,9 @@ public class POJJudge implements RemoteJudgeStrategy {
|
||||||
} else {
|
} else {
|
||||||
// 如果不是CE,获取其他信息
|
// 如果不是CE,获取其他信息
|
||||||
String executionTime = ReUtil.get("<b>Memory:</b> ([-\\d]+)", response.body(), 1);
|
String executionTime = ReUtil.get("<b>Memory:</b> ([-\\d]+)", response.body(), 1);
|
||||||
result.put("time", Integer.parseInt(executionTime));
|
result.put("time", executionTime == null ? null : Integer.parseInt(executionTime));
|
||||||
String executionMemory = ReUtil.get("<b>Time:</b> ([-\\d]+)", response.body(), 1);
|
String executionMemory = ReUtil.get("<b>Time:</b> ([-\\d]+)", response.body(), 1);
|
||||||
result.put("memory", Integer.parseInt(executionMemory));
|
result.put("memory", executionMemory == null ? null : Integer.parseInt(executionMemory));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +161,7 @@ public class POJJudge implements RemoteJudgeStrategy {
|
||||||
|
|
||||||
|
|
||||||
// TODO 添加结果对应的状态
|
// TODO 添加结果对应的状态
|
||||||
private static final Map<String, Constants.Judge> statusTypeMap = new HashMap<String, Constants.Judge>() {
|
private static final Map<String, Constants.Judge> statusMap = new HashMap<String, Constants.Judge>() {
|
||||||
{
|
{
|
||||||
put("Compiling", Constants.Judge.STATUS_COMPILING);
|
put("Compiling", Constants.Judge.STATUS_COMPILING);
|
||||||
put("Accepted", Constants.Judge.STATUS_ACCEPTED);
|
put("Accepted", Constants.Judge.STATUS_ACCEPTED);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import top.hcode.hoj.remoteJudge.task.Impl.CodeForcesJudge;
|
import top.hcode.hoj.remoteJudge.task.Impl.CodeForcesJudge;
|
||||||
import top.hcode.hoj.remoteJudge.task.Impl.HduJudge;
|
import top.hcode.hoj.remoteJudge.task.Impl.HduJudge;
|
||||||
|
import top.hcode.hoj.remoteJudge.task.Impl.POJJudge;
|
||||||
import top.hcode.hoj.util.JsoupUtils;
|
import top.hcode.hoj.util.JsoupUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -90,4 +91,33 @@ public class JudgeServerApplicationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test03() throws Exception {
|
||||||
|
HduJudge hduJudge = new HduJudge();
|
||||||
|
Map<String, Object> submit = hduJudge.submit("账号", "密码", "1000", "GCC", "#include<stdio.h> \\n\" +\n" +
|
||||||
|
" \"int main()\\n\" +\n" +
|
||||||
|
" \"{\\n\" +\n" +
|
||||||
|
" \"\\tint a,b,sum;\\n\" +\n" +
|
||||||
|
" \"\\twhile(scanf(\\\"%d%d\\\",&a,&b)!=EOF)\\n\" +\n" +
|
||||||
|
" \"\\t{\\n\" +\n" +
|
||||||
|
" \"\\t\\tsum=a+b;\\n\" +\n" +
|
||||||
|
" \"\\t\\tprintf(\\\"%d\\\\n\\\",sum);\\n\" +\n" +
|
||||||
|
" \"\\n\" +\n" +
|
||||||
|
" \"\\t}\\n\" +\n" +
|
||||||
|
" \"\\treturn 0;\\n\" +\n" +
|
||||||
|
" \"}");
|
||||||
|
System.out.println(submit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void test04(){
|
||||||
|
POJJudge pojJudge = new POJJudge();
|
||||||
|
Map<String, Object> loginUtils = pojJudge.getLoginUtils("账号", "密码");
|
||||||
|
|
||||||
|
Map<String, Object> result = pojJudge.result(22716128L, "账号", (String) loginUtils.get("cookies"));
|
||||||
|
System.out.println(result);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -368,7 +368,7 @@ export const m = {
|
||||||
Security:'Security',
|
Security:'Security',
|
||||||
Security_Desc:'The Sandbox is isolated by CGroup, and the website authority control is perfect',
|
Security_Desc:'The Sandbox is isolated by CGroup, and the website authority control is perfect',
|
||||||
Diversity:'Diversity',
|
Diversity:'Diversity',
|
||||||
Diversity_Desc:'Support codefoces, HDU remote judge',
|
Diversity_Desc:'Support codefoces, HDU, POJ remote judge',
|
||||||
Available:'Available',
|
Available:'Available',
|
||||||
Faulty:'Faulty',
|
Faulty:'Faulty',
|
||||||
|
|
||||||
|
|
|
@ -370,7 +370,7 @@ export const m = {
|
||||||
Security:'安全性',
|
Security:'安全性',
|
||||||
Security_Desc:'判题沙盒使用cgroup隔离,网站权限控制完善',
|
Security_Desc:'判题沙盒使用cgroup隔离,网站权限控制完善',
|
||||||
Diversity:'多样性',
|
Diversity:'多样性',
|
||||||
Diversity_Desc:'支持Codefoces,HDU的远程判题',
|
Diversity_Desc:'支持Codefoces,HDU,POJ的远程判题',
|
||||||
Available:'有效',
|
Available:'有效',
|
||||||
Faulty:'不完善',
|
Faulty:'不完善',
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue