搭建与二次开发自己的OJ
oimaster
·
2020-12-30 19:48:40
·
个人记录
因为洛谷博客代码中吃 \$ ,所以 PHP 的变量前的 \$ 在这篇博客里全部被删除。
如果想要原版文章,请访问 https://oi-master.gitee.io/2020/12/30/%E6%90%AD%E5%BB%BA%E5%92%8C%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91%E6%82%A8%E7%9A%84OJ/
以下是加工后的内容。
欢迎阅读 OI-Master 的博客!本文将会介绍如何搭建您自己的 Online Judge。若您想要 Online Judge 功能更多或者前端更好看,我们也会初步介绍二次开发。
我希望大家的搭建过程不枯燥,并且二次开发、配置的过程尽可能十分舒服。所以,我们选用刚开始默认前端并不太好看的 HustOJ,稍后会更改前端。
如果您想搭建前段默认很好的 qduoj,推荐阅读 Steve George 的日报。
很好!让我们开始吧!
服务器准备
我们需要准备一台 Ubuntu18.04 服务器。OI-Master 推荐您使用 腾讯云 的服务器。这个平台的账号是可以用 QQ、微信账号的,并且对于新用户优惠较多,也有便宜的学生机。如果您真的没有钱来购买,您可以使用 Ubuntu 18.04 Server 虚拟机。
如果您需要使用虚拟机,您可以在 清华大学开源镜像站 进行下载 Ubuntu 18.04 系统。点击右侧 \color{white}\colorbox{lightblue}{获取下载链接} 按钮。左侧选择 \color{blue}\text{Ubuntu} ,然后下载 \color{blue}\text{18.04.5 (amd64, Server)} 。
打开您的虚拟机软件(如 VMware),安装这个系统。安装过程因软件而定。如果您没有虚拟机软件,推荐 VMware 的虚拟机,支持简易安装,对于新手是很好的事。
更换源
如果您是阿里云用户,可以跳过本段。其他用户需要更换您的 Ubuntu 源。
修改 Ubuntu 源的指令是有些复杂的,但是 HustOJ 官方给出一个更简单的脚本,只有 2 行代码。请在终端中输入:
wget http://dl.hustoj.com/update-sources-ubuntu.sh
sudo bash update-sources-ubuntu.sh
此处会需要输入密码。密码不会显示,请您不要认为没有输入进去。
出错可能
如果您看到这些文字:
E: Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)
E: Unable to lock directory /var/lib/apt/lists/
就说明您过于着急,您的系统还未准备好。请重新运行这行指令。
sudo bash update-sources-ubuntu.sh
完成
如果您看到这样(或类似)的文字:
Reading package lists... Done
Building dependency tree
Reading state information... Done
142 packages can be upgraded. Run 'apt list --upgradable' to see them.
那么恭喜!您已经成功更换源!
安装 HustOJ
HustOJ 的开发者们是十分良心的。他们又提供了一份智能化代码来一键安装 HustOJ。为了方便,我们使用这个代码。
首先您需要下载代码。为了节约您的生命,我们选择 Gitee 上的镜像。
wget https://gitee.com/zhblue/hustoj/raw/master/trunk/install/install-ubuntu18-gitee.sh
下载完成后,运行这份代码。
sudo bash install-ubuntu18-gitee.sh
等!注意可能中间会弹出几个 Warning,不用管。正常等待时间是 10 分钟左右。在这一段时间里,您可以先写一个 LCA 模板来玩玩。
p.s.: 其实 OI-Master 的服务器在这里出问题了,不过这不重要(bushi。
## 后台
### 警告!
接下来的内容因为稍微复杂,所以即将出现多张大图!
### 进入
打开您服务器的公网 IP 或用服务器访问 127.0.0.1,即可看到您的 HustOJ!
OI-Master 将会用自己的服务器给大家演示。
首先,让我们注册一个账号。
打开您的 OJ,然后点击注册。

注册一个学号为 `admin` 的用户。

p.s. OI-Master 其实现在真的是小学生(
完成了吗?现在,您的账号自动就有了管理权限!
接下来,我们进入后台看看。

后台左侧的样子应该是这样的。

## 删除广告
HustOJ 也有几处有些恶心的东西。例如——广告。

还有底部:

那么如何才能去掉这些呢?
### 顶部去除
进入后台,然后点击 $\color{white}\colorbox{lightblue}{新闻-设置公告}$,或进入左下链接。另外,鼠标真的不好写字……

直接对着框一顿 `Backspace` 就行了。

### 尾部广告
这个……稍后讲二次开发的时候再说吧。
## 高级后台功能
普通的后台功能就在这里了,十分清楚。接下来,我们来讲讲高级的后台功能。
### 修改帮助

你看,是不是格式十分难看?丑的要命?
后台呢?看起来没有这个功能?不!我们可以改!
进入后台,按下 $\color{white}\colorbox{lightblue}{新闻-添加}$ 按钮。

输入以下内容,然后保存。注意,标题一定要为 `faqs.cn`!

再看看前台?

Yes! 现在,您可以把 `test` 在后台改成任意内容,然后编写您自己的 FAQ!
### 克隆题目
想用用别的 OJ 的好题?不想重新输入题面?克隆题目功能可以帮助你!
注意,本功能只能复制题面,无法克隆数据!
因为这个功能并没有淦完,所以 HustOJ 把这个功能做得非常不起眼。看看它的后台入口!

看这个后台的左侧!看见了吗?看见了吗?非常浅的一行!
那么我们将会打开,出现几个链接。发现这个功能支持很多 OJ,包括洛谷 3.0(现在是 4.0 了,前端有变化,所以会出点问题),现在您只要有数据,就可以复制题面了!
## 二次开发
### 宝塔
这一段为了更好地使用,可以下载 [宝塔](https://www.bt.cn/)。
进入终端,然后输入安装指令:
```shell
wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh
```
然后输入密码,这时候出现了一个情况:
```shell
已有Web环境,安装宝塔可能影响现有站点
Web service is alreday installed,Can't install panel
----------------------------------------------------
输入yes强制安装/Enter yes to force installation (yes/n):
```
这里的现有站点应该是 HustOJ,不过没事,安装宝塔不会干扰这个。输入 `yes`。
然后等待约 $9$ 分钟,大佬可以写个 [侦探推理](https://www.luogu.com.cn/problem/P1039)。
接下来,千万不要关闭终端!看末尾的几串字符(为了安全在这里我们强制打了码):

我们访问这个链接,登录后接受这个协议。您一定要翻到底部!
### db_info.inc.php

我们不要管这个窗口,叉掉即可。然后点击 $\color{lightgray}\colorbox{black}{文件}$ 按钮。
在上方输入 `/home/judge/src/web/include`,然后您应该可以看到一些 `.php` 文件。
往下翻,找到 `db_info.inc.php`,鼠标右击编辑。
```php
<?php @session_start();
//ini_set("display_errors", "Off"); //set this to "On" for debugging ,especially when no reason blank shows up.
//header('X-Frame-Options:SAMEORIGIN');
//for people using hustoj out of China , be careful of the last two line of this file !
// connect db
static DB_HOST="localhost"; //数据库服务器ip或域名
static DB_NAME="jol"; //数据库名
static DB_USER="debian-sys-maint"; //数据库账户
static DB_PASS="tSIqUCnBNiuByEOp"; //数据库密码
static OJ_NAME="HUSTOJ"; //左上角显示的系统名称
static OJ_HOME="./"; //主页目录
static OJ_ADMIN="root@localhost"; //管理员email
static OJ_DATA="/home/judge/data"; //测试数据目录
static OJ_BBS=false; //设为"discuss3" 启用, "bbs" for phpBB3 bridge or "discuss" for mini-forum or false for close any
static OJ_ONLINE=false; //是否记录在线情况
static OJ_LANG="en"; //默认语言
static OJ_SIM=false; //显示相似度
static OJ_DICT=false; //显示在线翻译
static OJ_LANGMASK=1637684; //TIOBE index top 10, calculator : https://pigeon-developer.github.io/hustoj-langmask/
static OJ_EDITE_AREA=true; //true: syntax highlighting is active
static OJ_ACE_EDITOR=true;
static OJ_AUTO_SHARE=false; //true: One can view all AC submit if he/she has ACed it onece.
static OJ_CSS="white.css";
static OJ_SAE=false; //using sina application engine
static OJ_VCODE=false; //验证码
static OJ_APPENDCODE=false; // 代码预定模板
if (!OJ_APPENDCODE) ini_set("session.cookie_httponly", 1); // APPENDCODE模式需要允许javascript操作cookie保存当前语言。
static OJ_CE_PENALTY=false; // 编译错误是否罚时
static OJ_PRINTER=false; //启用打印服务
static OJ_MAIL=false; //内邮
static OJ_MARK="mark"; // "mark" for right "percent" for WA
static OJ_MEMCACHE=false; //使用内存缓存
static OJ_MEMSERVER="127.0.0.1";
static OJ_MEMPORT=11211;
static OJ_UDP=true; //使用UDP通知
static OJ_UDPSERVER="127.0.0.1";
static OJ_UDPPORT=1536;
static OJ_REDIS=false; //使用REDIS队列
static OJ_REDISSERVER="127.0.0.1";
static OJ_REDISPORT=6379;
static OJ_REDISQNAME="hustoj";
static SAE_STORAGE_ROOT="http://hustoj-web.stor.sinaapp.com/";
static OJ_CDN_URL=""; // http://cdn.hustoj.com/ https://raw.githubusercontent.com/zhblue/hustoj/master/trunk/web/
static OJ_TEMPLATE="bs3"; //使用的默认模板, [bs3 ie ace sweet sae mario] work with discuss3, [classic bs] work with discuss
//if(isset(_GET['tp'])) OJ_TEMPLATE=_GET['tp'];
if (OJ_TEMPLATE == "classic") OJ_CSS="hoj.css";
static OJ_LOGIN_MOD="hustoj";
static OJ_REGISTER=true; //允许注册新用户
static OJ_REG_NEED_CONFIRM=false; //新注册用户需要审核
static OJ_NEED_LOGIN=false; //需要登录才能访问
static OJ_LONG_LOGIN=false; //启用长时间登录信息保留
static OJ_KEEP_TIME="30"; //登录Cookie有效时间(单位:天(day),仅在上一行为true时生效)
static OJ_RANK_LOCK_PERCENT=0; //比赛封榜时间比例
static OJ_SHOW_DIFF=false; //是否显示WA的对比说明
static OJ_DOWNLOAD=false; //是否允许下载WA的测试数据
static OJ_TEST_RUN=false; //提交界面是否允许测试运行
static OJ_MATHJAX=false; // 激活mathjax
static OJ_BLOCKLY=false; //是否启用Blockly界面
static OJ_ENCODE_SUBMIT=false; //是否启用base64编码提交的功能,用来回避WAF防火墙误拦截。
static OJ_OI_1_SOLUTION_ONLY=false; //比赛是否采用noip中的仅保留最后一次提交的规则。true则在新提交发生时,将本场比赛该题老的提交删除。
static OJ_OI_MODE=false; //是否开启OI比赛模式,禁用排名、状态、统计、用户信息、内邮、论坛等。
static OJ_SHOW_METAL=true; //榜单上是否按比例显示奖牌
static OJ_RANK_LOCK_DELAY=3600; //赛后封榜持续时间,单位秒。根据实际情况调整,在闭幕式颁奖结束后设为0即可立即解封。
static OJ_BENCHMARK_MODE=false; //此选项将影响代码提交,不再有提交间隔限制,提交后会返回solution id
static OJ_CONTEST_RANK_FIX_HEADER=false; //比赛排名水平滚动时固定名单
static OJ_NOIP_KEYWORD="noip"; // 标题包含此关键词,激活noip模式,赛中不显示结果,仅保留最后一次提交。
static OJ_BEIAN=false; // 如果有备案号,填写备案号
//static OJ_EXAM_CONTEST_ID=1000; // 启用考试状态,填写考试比赛ID
//static OJ_ON_SITE_CONTEST_ID=1000; //启用现场赛状态,填写现场赛比赛ID
/* share code */
static OJ_SHARE_CODE=false; // 代码分享功能
/* recent contest */
static OJ_RECENT_CONTEST=true; // "http://algcontest.rainng.com/contests.json" ; // 名校联赛
//OJ_ON_SITE_TEAM_TOTAL用于根据比例的计算奖牌的队伍总数
//CCPC比赛的一种做法是比赛结束后导出终榜看AC至少1题的不打星的队伍数,现场修改此值即可正确计算奖牌
//0表示根据榜单上的出现的队伍总数计算(包含了AC0题的队伍和打星队伍)
static OJ_ON_SITE_TEAM_TOTAL=0;
static OJ_OPENID_PWD='8a367fe87b1e406ea8e94d7d508dcf01';
/* weibo config here */
static OJ_WEIBO_AUTH=false;
static OJ_WEIBO_AKEY='1124518951';
static OJ_WEIBO_ASEC='df709a1253ef8878548920718085e84b';
static OJ_WEIBO_CBURL='http://192.168.0.108/JudgeOnline/login_weibo.php';
/* renren config here */
static OJ_RR_AUTH=false;
static OJ_RR_AKEY='d066ad780742404d85d0955ac05654df';
static OJ_RR_ASEC='c4d2988cf5c149fabf8098f32f9b49ed';
static OJ_RR_CBURL='http://192.168.0.108/JudgeOnline/login_renren.php';
/* qq config here */
static OJ_QQ_AUTH=false;
static OJ_QQ_AKEY='1124518951';
static OJ_QQ_ASEC='df709a1253ef8878548920718085e84b';
static OJ_QQ_CBURL='192.168.0.108';
/* log */
OJ_LOG_FILE="/var/log/hustoj/{OJ_NAME}.log";
static OJ_LOG_ENABLED=false;
static OJ_LOG_DATETIME_FORMAT="Y-m-d H:i:s";
static OJ_LOG_PID_ENABLED=false;
static OJ_LOG_USER_ENABLED=false;
static OJ_LOG_URL_ENABLED=false;
static OJ_LOG_URL_HOST_ENABLED=false;
static OJ_LOG_URL_PARAM_ENABLED=false;
static OJ_LOG_TRACE_ENABLED=false;
//if(date('H')<5||date('H')>21||isset(_GET['dark'])) OJ_CSS="dark.css";
if (isset(_SESSION[OJ_NAME . '_' . 'OJ_LANG'])) {
OJ_LANG=_SESSION[OJ_NAME . '_' . 'OJ_LANG'];
} else if (isset(_COOKIE['lang']) && in_array(_COOKIE['lang'], array("cn", "ug", "en", 'fa', 'ko', 'th'))) {
OJ_LANG=_COOKIE['lang'];
} else if (isset(_GET['lang']) && in_array(_GET['lang'], array("cn", "ug", "en", 'fa', 'ko', 'th'))) {
OJ_LANG=_GET['lang'];
} else if (isset(_SERVER['HTTP_ACCEPT_LANGUAGE']) && strstr(_SERVER['HTTP_ACCEPT_LANGUAGE'], "zh-CN")) {
OJ_LANG="cn";
}
require_once(dirname(__FILE__) . "/pdo.php");
// use db
//pdo_query("set names utf8");
//sychronize php and mysql server with timezone settings, dafault setting for China
//if you are not from China, comment out these two lines or modify them.
//date_default_timezone_set("PRC");
//pdo_query("SET time_zone ='+8:00'");
require_once(dirname(__FILE__) . "/logger.php");
logger=new Logger(_SESSION[OJ_NAME . '_' . 'user_id'],
OJ_LOG_FILE,
OJ_LOG_DATETIME_FORMAT,
OJ_LOG_ENABLED,
OJ_LOG_PID_ENABLED,
OJ_LOG_USER_ENABLED,
OJ_LOG_URL_ENABLED,
OJ_LOG_URL_HOST_ENABLED,
OJ_LOG_URL_PARAM_ENABLED,
OJ_LOG_TRACE_ENABLED);
logger->info();
```
您会看到这样子的内容。上面的注释写得很清楚,您可以个性化修改。
如果出现问题,您可以来本博客复制上方内容恢复。
注意第 47 行。下面我们将会详细介绍主题问题。
### 主题
我们的主题默认是 `bs3` 主题。看看 HustOJ 还有哪些主题。
打开 `/home/judge/src/web/template`,看见这些文件夹。

看到了吗?这些是我们的主题。
+ bs3
+ bshark
+ mario
+ sweet
> p.s. OI-Master 写完本文后又突然更新了一个 syzoj 主题,大家可以试试qwq,这里太颓了不改了
我们来做个实验试试。我们把上面的 47 行改成 `static OJ_TEMPLATE="sweet";` 保存后,来到前台看看!哇!

是不是酷很多!这个界面目前是绝大多数用户认为 HustOJ 最好看的主题。目前,[JZOJ](http://www.jzoj.cn/index.php)、现在已经消失的小白菜OJ 等 OJ 都在使用此主题。
若果您觉得这些主题都太丑了,您也可以自己新建一个文件夹,用 `PHP` 等语言写一个主题。
### 广告去除(二次开发前端)
以 `bs3` 为例。之前我们讲过上方的广告如何去除,现在我们来看看下方。
我们查看 `bs3` 主题目录下的 `index.php` 文件,看看下方的页脚是怎么实现的。
```php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<title>
<?php echo OJ_NAME?>
</title>
<?php include("template/OJ_TEMPLATE/css.php");?>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="http://cdn.bootcss.com/html5shiv/3.7.0/html5shiv.js"></script>
<script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<?php include("template/OJ_TEMPLATE/nav.php");?>
<!-- Main component for a primary marketing message or call to action -->
<div class="jumbotron">
<p>
<center> Recent submission :
<?php echo speed?> .
<div id=submission style="width:80%;height:300px"></div>
</center>
</p>
<?php echo view_news?>
</div>
</div>
<!-- /container -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<?php include("template/OJ_TEMPLATE/js.php");?>
<script language="javascript" type="text/javascript" src="<?php echo OJ_CDN_URL?>include/jquery.flot.js"></script>
<script type="text/javascript">
( function () {
var d1 = <?php echo json_encode(chart_data_all)?>;
var d2 = <?php echo json_encode(chart_data_ac)?>;
.plot( ( "#submission" ), [ {
label: "<?php echo MSG_SUBMIT?>",
data: d1,
lines: {
show: true
}
}, {
label: "<?php echo MSG_SOVLED?>",
data: d2,
bars: {
show: true
}
} ], {
grid: {
backgroundColor: {
colors: [ "#fff", "#eee" ]
}
},
xaxis: {
mode: "time" //,
//max:(new Date()).getTime(),
//min:(new Date()).getTime()-100*24*3600*1000
}
} );
} );
//alert((new Date()).getTime());
</script>
</body>
</html>
```
注意 46 行,这里内嵌了一个 `PHP` 文件,这应该是我们需要的页脚等信息。我们打开 `js.php`。
```php
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="<?php echo OJ_CDN_URL.path_fix."template/OJ_TEMPLATE/"?>jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="<?php echo OJ_CDN_URL.path_fix."template/OJ_TEMPLATE/"?>bootstrap.min.js"></script>
<?php
if(file_exists("./admin/msg.txt"))
view_marquee_msg=file_get_contents(OJ_SAE?"saestor://web/msg.txt":"./admin/msg.txt");
if(file_exists("../admin/msg.txt"))
view_marquee_msg=file_get_contents(OJ_SAE?"saestor://web/msg.txt":"../admin/msg.txt");
/*
<!-- to enable mathjax in hustoj:
svn export http://github.com/mathjax/MathJax/trunk /home/judge/src/web/mathjax
<script type="text/javascript"
src="mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
or
<script type="text/javascript"
src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
-->
*/
?>
<script>
(document).ready(function(){
<?php if(view_marquee_msg!="") { ?>
var msg="<marquee style='margin-top:10px' direction='left' scrollamount=3 scrolldelay=50 onMouseOver='this.stop()'"+
" onMouseOut='this.start()' class=toprow>"+<?php echo json_encode(view_marquee_msg); ?>+"</marquee>";
(".jumbotron").prepend(msg);
<?php } ?>
("form").append("<div id='csrf' />");
("#csrf").load("<?php echo path_fix?>csrf.php");
("body").append("<div id=footer class=center >GPLv2 licensed by <a href='https://github.com/zhblue/hustoj' >HUSTOJ</a> "+(new Date()).getFullYear()+" </div>");
("body").append("<center><?php echo MSG_HELP_HUSTOJ?></center>");
("body").append("<div class=center > <img src='http://hustoj.com/wx.jpg' width='120px'><img src='http://hustoj.com/alipay.png' width='120px'><br> 欢迎关注微信公众号onlinejudge</div>");
<?php if(isset(OJ_BEIAN)&&OJ_BEIAN){ ?>
("body").append("<br><center><a href='http://beian.miit.gov.cn/' target='_blank'><?php echo OJ_BEIAN?></a></center>");
<?php } ?>
<?php
if(isset(_SESSION[OJ_NAME."_administrator"])) echo "admin_mod();";
?>
});
(".hint pre").each(function(){
var plus="<span class='glyphicon glyphicon-plus'>Click</span>";
var content=(this);
(this).before(plus);
(this).prev().click(function(){
content.toggle();
});
});
console.log("If you want to change the appearance of the web pages, make a copy of bs3 under template directory.\nRename it to whatever you like, and change the OJ_TEMPLATE value in db_info.inc.php\nAfter that modify files under your own directory .\n");
console.log("To enable mathjax in hustoj, check line 15 in /home/judge/src/web/template/bs3/js.php");
function admin_mod(){
("div[fd=source]").each(function(){
let pid=(this).attr('pid');
(this).append("<span><span class='label label-success' pid='"+pid+"' onclick='problem_add_source(this,"+pid+");'>+</span></span>");
});
("span[fd=time_limit]").each(function(){
let sp=(this);
let pid=(this).attr('pid');
(this).dblclick(function(){
let time=sp.text();
console.log("pid:"+pid+" time_limit:"+time);
sp.html("<form onsubmit='return false;'><input type=hidden name='m' value='problem_update_time'><input type='hidden' name='pid' value='"+pid+"'><input type='text' name='t' value='"+time+"' selected='true' class='input-mini' size=2 ></form>");
let ipt=sp.find("input[name=t]");
ipt.focus();
ipt[0].select();
sp.find("input").change(function(){
let newtime=sp.find("input[name=t]").val();
.post("admin/ajax.php",sp.find("form").serialize()).done(function(){
console.log("new time_limit:"+time);
sp.html(newtime);
});
});
});
});
}
function problem_add_source(sp,pid){
console.log("pid:"+pid);
let p=(sp).parent();
p.html("<form onsubmit='return false;'><input type='hidden' name='m' value='problem_add_source'><input type='hidden' name='pid' value='"+pid+"'><input type='text' class='input input-large' name='ns'></form>");
p.find("input").focus();
p.find("input").change(function(){
console.log(p.find("form").serialize());
let ns=p.find("input[name=ns]").val();
console.log("new source:"+ns);
.post("admin/ajax.php",p.find("form").serialize());
p.parent().append("<span class='label label-success'>"+ns+"</span>");
p.html("<span class='label label-success' pid='"+pid+"' onclick='problem_add_source(this,"+pid+");'>+</span>");
});
}
</script>
```
看到 42,43 行,就是我们的页脚最后的二维码和爱心代码!注释掉即可。保存刷新,看看前端。

消失了!现在我们已经成功修改前端了!
## 评测机
HustOJ 的评测系统也是十分完善的。
不过,有些时候,我们还是可以自定义评测集的设置。
我们使用宝塔进入 `/home/judge/etc`,然后修改 judge.conf。
```php
#Database Config
OJ_HOST_NAME=127.0.0.1
OJ_USER_NAME= #这里是数据库用户名
OJ_PASSWORD= #这里是数据库密码
#以上两行我已删除账号密码,防止被 Hack
OJ_DB_NAME=jol
OJ_PORT_NUMBER=3306
#CPU cores Config
OJ_RUNNING=1
#Query Interval/UDP timeout
OJ_SLEEP_TIME=1
#Multi-Judger Task Divider
OJ_TOTAL=1
OJ_MOD=0
#Java and Other VM language bonus
OJ_JAVA_TIME_BONUS=2
OJ_JAVA_MEMORY_BONUS=64
#JVM Compiler Settings
OJ_JAVA_XMS=-Xms64M
OJ_JAVA_XMX=-Xmx128M
#Similarity Tester from Dick Grune
OJ_SIM_ENABLE=0
#Using HTTP for distributed judgers
OJ_HTTP_JUDGE=0
OJ_HTTP_BASEURL=http://127.0.0.1/JudgeOnline
OJ_HTTP_USERNAME=admin
OJ_HTTP_PASSWORD=admin
OJ_HTTP_DOWNLOAD=1
#Using Redis for solutions queue
OJ_REDISENABLE=0
OJ_REDISSERVER=127.0.0.1
OJ_REDISPORT=6379
OJ_REDISAUTH=123456
OJ_REDISQNAME=hustoj
#Judge all test data even solution fails
OJ_OI_MODE=1
#Using /dev/shm as working directory
OJ_SHM_RUN=0
#Using the longest case of test as final time
OJ_USE_MAX_TIME=0
#Judge TLE by total time
OJ_TIME_LIMIT_TO_TOTAL=0
#Judge only listed languages
OJ_LANG_SET=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19
#Using Chroot to prevent compile time attack (#include</dev/random>)
OJ_COMPILE_CHROOT=0
#Jump some middle status update for faster judge
OJ_TURBO_MODE=0
#Bigger setting Slow down time on fast CPU, smaller setting Speed up time on slow CPU
OJ_CPU_COMPENSATION=1.04
#Using UDP for submission notification
OJ_UDP_ENABLE=1
OJ_UDP_SERVER=127.0.0.1
OJ_UDP_PORT=1536
#Let Python Free
OJ_PYTHON_FREE=0
#allow NOIP using data.in as input file
OJ_COPY_DATA=0
```
评测机的二次开发就可以看此文件了。
## FPS 题目
HustOJ 支持 `fps.xml` 存储的题目。您可以使用 [EasyFPSViewer](https://github.com/zhblue/freeproblemset/tree/master/EasyFPSViewer) 编辑 FPS 题目。同时,FPS 也支持 [Hydro](https://hydro.js.org/)、[OpenJudger](https://github.com/Azure99/OpenJudger)、[QDUOJ](https://github.com/QingdaoU/OnlineJudge)。这意味着,FPS 可以实现不同 OJ 系统的交换题目。
FPS 的仓库为 <https://github.com/zhblue/freeproblemset>,同时,HustOJ 又一次良心地为我们提供了 [TK 题库](http://tk.hustoj.com/)。这是一个支持下载数据、FPS 题目的网站,提供免费与付费题目。
近期 NOIP、CSP 等竞赛题目基本都在免费题库支持下载。大家想把这些题目导入时可以使用。
免费专区链接:<http://tk.hustoj.com/problemset.php?search=free>
## Vjudge
HustOJ 可以与 Vjudge 配合,自己的 VJ 抓自己的题目,也评测别的 OJ 的题目。
它的 GitHub 库为 <https://github.com/zhblue/vjudge>,暂时没有官方的 Gitee 镜像。
```shell
wget https://github.com/zhblue/vjudge/raw/master/install.sh
sudo bash install.sh
```
运行这些命令即可安装。这次会使用 tomcat8,所以要下载仓库中 vjudge.war。目前 OI-Master 尝试过搭建,不过出现了一点小问题(例如网络与无法解析),所以暂时不提供详细的安装教程。
## HustOJ+Vjudge 套餐
如果您是使用虚拟机或者手中的服务器、电脑,那么您可以下载 LiveCD。
您需要关注 HustOJ 官方 `onlinejudge` 公众号,发送 `livecd`,获取百度云下载链接。
详细的可以点击:<https://gitee.com/zhblue/hustoj#livecd%E4%B8%8B%E8%BD%BD%E5%AE%89%E8%A3%85>
## 结语
如果大家搭建时出现一些问题,欢迎用洛谷私信我或 QQ 202367038。
如果需要,我也会将视频传至哔哩哔哩。