Domjudge 8.2.3

环境依赖

首先,默认已经把该换的源都换好了,就执行

sudo apt-get update
sudo apt-get upgrade

接下来配置 nginx+php-fpm 以及数据库相关依赖:

sudo apt install acl zip unzip mariadb-server nginx \
        php-fpm php-gd php-cli php-intl php-mbstring php-mysql \
        php-curl php-json php-xml php-zip composer ntp

sudo apt install make gcc g++ debootstrap libcgroup-dev lsof \
        procps libcurl4-gnutls-dev libjsoncpp-dev libmagic-dev

如果遇到安装过程中输入 Y 还是直接 Abort 的情况,在 install 后面加一个 -y 参数即可。

编译 DOMjudge 8.2.3

首先需要创建一个非 root 用户,并且拥有 sudo 权限,执行

useradd -m <username>
passwd <username>

然后输入新用户的密码,之后

vim /etc/sudoers

里面 root 这一行下面加上一行,格式同 root 一行,只是 root 改成用户名。
下面都用 <username> 表示上面新建的用户名。

在 /home/<username>/ 下面下载 DOMjudge

wget https://www.domjudge.org/releases/domjudge-8.2.3.tar.gz

然后解压并 cd 到解压后的目录:

tar -zxvf domjudge-8.2.3.tar.gz
cd /home/<username>/domjudge-8.2.3/

之后就开始编译,执行如下命令:

sudo ./configure --prefix=/home/<username>/domjudge --with-domjudge-user=root --with-baseurl=127.0.0.1
make domserver && sudo make install-domserver

如果要生成更多文档,执行如下命令:

make docs && sudo make install-docs

但至少我这步失败了 233 好像是因为 python 的问题?所以这一步(指生成文档)失败了也不用管。

至此也就编译成功啦

配置数据库

sudo /home/<username>/domjudge/domserver/bin/dj_setup_database -u root install

如果这一步发现 Access Denied,可以先切换到 root 用户,然后用当前的 socket 来设置数据库,命令如下:

sudo dj_setup_database -s install

配置 Web 服务器

cd /home/<username>/domjudge/domserver
sudo ln -s /home/<username>/domjudge/domserver/etc/nginx-conf /etc/nginx/sites-enabled/domjudge
sudo ln -s /opt/domjudge/domserver/etc/domjudge-fpm.conf /etc/php/7.4/fpm/pool.d/domjudge.conf
sudo service php7.4-fpm reload
sudo service nginx reload
sudo chown www-data:www-data -R webapp/var/*

上面配置 php-fpm 时注意一下版本号。最后一行是用于配置该文件夹下的用于上传校徽、队伍照片等文件时的权限设置。

现在,内网的话就可以访问 http://127.0.0.1/domjudge 然后就看到如下类似界面

(上面的图是 domjudge 7.3.4 版本的界面,新版界面有些许变化)

此时可以用用户名 admin 和

/home/<username>/domjudge/domserver/etc/initial_admin_password.secret

内的密码来登录管理后台了。

如果是第三方服务器,比如阿里云啥的,要用公网 ip 访问的话检查一下有没有开放 80 端口。

配置 MySQL

执行:

vim /etc/mysql/conf.d/mysql.cnf

然后里面覆盖为下面内容

[mysqld]
max_connections = 1000
max_allowed_packet = 16MB
innodb_log_file_size = 48MB

其中 max_allowed_packet 数值改成两倍于题目测试数据文件的大小,innodb_log_file_size 数值改成十倍于题目测试数据文件的大小。

若使用的是 mariadb,则 /etc/mysql/mariadb.conf.d/50-server.cnf 中 max_allowed_packet 一项也需要修改。

之后重启数据库

sudo systemctl restart mysql

配置 Nginx


```/etc/php/php版本号/cli/php.ini``` 里,需要修改的东西都在 DOMjudge 后台管理里面有个 Config checker 的东西,位置如下

根据里面的东西来改即可。


至此,DOMserver 的配置全部完毕!更多内容可以参考 https://github.com/cn-xcpc-tools/cn-xcpc-docs/blob/master/domserver.md

Judgehost (docker)

表示实在受不了不用 docker 直接嗯搭的折磨了......所以 Judgehost 就直接用 docker 搭算了(

由于国内的 docker 镜像都挂了,所以需要事先在服务器上挂好梯子,才能比较顺畅地拉取镜像。如果不想配置 docker 的话,可以参照 https://github.com/cn-xcpc-tools/cn-xcpc-docs/blob/master/judgehost.md

下载 docker

curl -sSL https://get.docker.com | sh

设置 cgroups

然后需要设置本机 cgroups,编辑 /etc/default/grub 文件,将下面这行

GRUB_CMDLINE_LINUX_DEFAULT=""

修改为

GRUB_CMDLINE_LINUX_DEFAULT="quiet cgroup_enable=memory swapaccount=1"

之后执行

update-grub

然后再重启机子即可,之后检查下 /proc/cmdline 里面有无对应 log,有的话就好耶~
如果没有的话,有些机子可能会被 /etc/default/grub.d/ 里面的东西覆盖,在 update-grub 可以看到 Sourcing 了哪些文件,都检查一下,凡是有 GRUB_CMDLINE_LINUX_DEFAULT 的地方都改一下即可。

注意上面更改的 grub 内容在不同机器上可能不同,到时候拉取镜像时启动会报错。报错信息包含了 grub 需要追加的内容,根据这上面的提示修改然后重启机器即可。

运行 Judgehost

接下来就是直接在 docker 里面运行 Judgehost。命令如下:

docker run -d -it --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro --name judgehost-0 --hostname judgedaemon-0 -e DAEMON_ID=0 -e CONTAINER_TIMEZONE=Asia/Shanghai -e JUDGEDAEMON_PASSWORD=<domserver password> -e DOMSERVER_BASEURL=<domjudge url> domjudge/judgehost:8.1.3

其中 domserver password 是在

/home/<username>/domjudge/domserver/etc/restapi.secret

里面,domjudge url 就是 domserver 对应的地址,最后要加个 / 符号。

如果要配置多台 Judgehost,就把上面 DAEMON_ID=0 judgehost-0, judgedaemon-0, 对应编号一起改了,依次递增即可。如果一台机子 CPU 是多核(物理核)的话,核心编号就是 DAEMON_ID,从 0 开始编号。

这里建议一个物理核只开一个 judgehost。数量的话不要太多也不要太少,用四川省赛作参考:一共 254 个队伍,开了六个 judgehost,全程评测没有压力,结束前几分钟的压力也很顺畅。

然后在 domjudge 后台管理界面就应该看得到几个 Judgehost 了,像这样

好,终于把这杀千刀的 Judgehost 配置好了(

配置打印机

不同的打印机配置不一样,也有即插即用的,而惠普的打印机大多数要自己手动配置一些东西,下面就介绍一下惠普打印机的配置。

通过 USB 连接上打印机之后,执行

sudo apt install hplip

除了与 root 用户有关的那个选项注意一下其他一路默认即可。

之后再安装

sudo apt install hplip-gui

之后在打印机连接的情况下再安装

sudo hp-plugins

之后执行

sudo hp-setup

如果没有图形的界面的话,执行

sudo hp-setup -i

然后选择 USB,之后会自动寻找到该打印机,一路安装好即可。

之后去 DOMjudge 后台,找到 print_command(在 Configuration 啥的地方),里面加上一句

enscript -b [username] -a 0-10 -f Courier9 [file] 2>&1

其中 username 就是用户名,0~10 就是每次请求只打印前 10 页。

为了方便志愿者根据座位号送代码,打印的代码可以附带更多信息。四川省赛使用的打印命令如下:

enscript -b 'team: [username] | file: [original] | location: [location]' -a 0-7 -f Courier9 [file] 2>&1

之后,找个用户来登录,就可以看到上面有个 Print,如图

就可以愉快打印啦~

之后再连接惠普系列的打印机时,就不需要配置上面这些了,即插即用。

配置气球小票机

气球小票用以志愿者领取小票之后送气球方便使用。这里使用了 https://github.com/hydro-dev/xcpc-tools 这一工具,十分好用,不过官方文档暂时写得不太明确)

这一步我是在 windows 上配置的,因为当时的气球小票机没有 Linux 对应的驱动程序。首先,去 https://github.com/hydro-dev/xcpc-tools/releases 下载
```xcpc-tools-bundle.js```,然后电脑需要安装 Node.js。

由于该工具需要将打印内容转换成 pdf,而其识别 pdf 是识别同一目录下是否有 SumatraPDF,所以你需要将该脚本放在与 SumatraPDF 主程序 exe 对应的同一目录下(Linux 据说没有这个神奇问题)。

首先大致介绍一下该工具的运行方式。首先需要用其启动一个 Server 作为管理后台,然后需要另外启动多个 Client 作为从 Server 端接收数据的服务。

对于小票机,连上电脑之后需要先将其设置为共享打印机,这样 Server 端才能识别上。

那么我们首先来启动 Server 服务。执行:

node ./xcpc-tools-bundle.js

第一次运行时,该工具会检查你的所有已连接的打印机(其中包括输出 pdf,不过我们不需要)。然后在目录下会生成一个
```config.server.yaml``` 的配置文件。在里面将 type 更改为 domjudge,然后需要设置 server、contestId、username、password 以及 balloon,其中 username 和 password 可以直接使用 domjudge 的 admin 账号,balloon 的配置在第一次运行 Server 时可以看到。这些配置的具体说明可以参考 https://github.com/hydro-dev/xcpc-tools 的 README 文件。

然后再次执行上述命令启动 Server。之后 Server 会在本地 5283 端口(默认)启动 Web 端,包括 Print、Balloon 等。我们只使用了气球服务,故仅需要看 Balloon 相关。

在 Balloon 界面右边有一个 Add Client 的选项,之后在里面添加一个 Client(名称无所谓),并记下其对应的较短的 Token。这个 Token 用于之后启动 Client 服务。

接下来启动 Client。执行:

node ./xcpc-tools-bundle.js --client

第一次运行时,本地会生成一个
```config.client.yaml``` 的配置文件。在里面配置 Server 端对应的 ip 地址,以及上面的 Client Token。

注意到本地另外还生成了一个 data 文件夹。如果想要更换比赛,首先将 data 文件夹以及上述两个 config 删除之后,再次执行上述的命令即可。

配置 ICPC Tools

这是个甚么东西?主要就是用来显示一些东西用的,包括 judge queue、scoreboard、大屏倒计时等等,总的来说配好了的话还挺有比赛氛围的(

这一部分主要参照 官方文档,但这上面也有一点小错误,这里就整理下吧。

配置 CDS

CDS 又叫 Contest Data Server,主要用以比赛后台的一些管理服务,得先配置好这个才能用其他 Tools(Resolver 除外)。

首先,在 DOMjudge 后台创建一个账号,并且分配其角色为 API reader、API writer、Source code reader,记录下用户名和密码(下面用户名和密码分别称为 usercds 和 usercdspwd)。

不过其实这一部分建议直接用 admin 账号,防止出现奇奇怪怪的权限问题。

之后,在需要运行 CDS 的机子上下载并安装 CDS(这个东西占用资源较大,建议把 DOMserver 和 CDS 放一起),链接在这里(CDS v2.5.940)
下载好了之后解压,把 wlp 目录重命名为 cds,方便好认些。

接下来,修改 cds/usr/servers/cds/config/cdsConfig.xml,里面所有的内容替换成如下:

<cds>
    <!-- Set location= to a directory that the user running the CDS can write to -->
    <contest location="/home/cds/contest-data" recordReactions="false">
        <!-- Set the url to the URL of your DOMjudge installation, followed by /api/contests/<cid>, where <cid> is your CID or external ID -->
        <!-- Set the user and password to the user you created in the previous step -->
        <ccs
            url="https://www.domjudge.org/demoweb/api/contests/nwerc18"
            user="cds"
            password="somepassword" />
    </contest>
</cds>

其中 location 替换成一个不需要 root 就能访问或者修改的目录(比如

/home/<username>/cds/contest-data

),url 就是

<domjudge url>/api/contests/<contest cid>
例如:http://127.0.0.1/domjudge/api/contests/5

,其中 contest cid 就是下面这个

另外还有 user 和 password,分别就对应 usercds 和 usercdspwd(也可以直接用 admin 的账号密码)。

注意:如果你 domjudge 设置的是使用 external data source,那么这一步需要使用 external ID。

接下来修改 cds/usr/servers/cds/config/users.xml,里面的所有用户名不能修改,否则会很麻烦,把所有密码修改一下,为了安全(不修改也可以,但不推荐)。

接下来就可以运行(需要装 java jdk 11 或以上)

cds/bin/server run cds

来启动 CDS 了,关闭的话直接 Ctrl+C 停止服务即可。

之后,访问

https://<server ip>:8443/

,这里需要保证 8443 端口开放,直接就 ip:8443 即可。忽略 SSL 警告,就会看到如下界面:

点右上角 login,用 users.xml 里面 admin 的信息来登录。

至此,CDS 算是弄好啦

配置 Presentation Admin

这又是个甚么东西?可以看 这份文档。总之就是个屏幕显示后台管理工具,可以管理多个 Client 的屏幕显示。

这个东西可以装在任意一台电脑上,点这里下载Presentation Admin v2.5.940,并且据说在 macOS 和 Windows 下更不容易挂?

我是在 Windows 下弄的,下载解压之后,在 bash 环境下在该目录内运行(没有 bash 可以装个 git)

ICPC_FONT="DengXian" ./presAdmin.bat https://<server ip>:8443 presAdmin <presAdmin password>

其中 presAdmin 还有其密码见 users.xml,server ip 就是上面说的那个 ip:8443。cid 则是上面所说的 contest cid。(还是要注意 domjudge 是否使用的 external id)

要记得一定要加个
```ICPC_FONT="DengXian"``` ,否则可能中文支持有问题。后面 ICPC Tools 所有东西都要加个这个。

之后,会出现这个界面

如果一直显示 Disconnected 就重新试一下。

配置 Presentation Client

上面这张图左边一个 Client 都没有,接下来来配置。

同样,这一步我还是选择了一台 Windows 来配置的(实测 Linux 下有点问题)。下载地址Presentation Client v2.5.940,官方文档见 这里

之后解压,还是在 bash 环境下在该目录下运行

ICPC_FONT="Microsoft Yahei" ./client.bat https://<server ip>:8443/api/contests/<cid> presentation <presentation password> --name <client name>

其中 presentation 及密码见 users.xml,最后的 name 是指这台 client 的名称,可以不加。cid 同上面 contest cid。(当然还得注意 domjudge 是否使用的 external id)

这样执行完之后,会看到整个屏幕都是下面这个

以及 Presentation Admin 这边也多了一台 Client

然后就可以愉快体验辣(

其他的一个比较有用的参数:
```--display id```,即如果连了多台显示器,用这个来指定显示的显示器编号。通常用于向大屏扩展投放时使用。

配置 Resolver(滚榜)

resolver 可以支持 CDP 格式的文件夹,2.5 版本之后支持的 CDP 文件夹格式如下:

.
├── config              // 非必需
│   ├── contest.yaml    // 从domjudge Import/export页面导出即可
│   ├── groups.tsv      // 从domjudge Import/export页面导出即可
│   ├── problemset.yaml
│   └── teams.tsv       // 从domjudge Import/export页面导出即可
├── contest
│   ├── banner.png      // resolver无用,但在cds放置于此就可显示banner
│   └── logo.png        // resolver主页面的图片&无照片队伍的默认照片
├── event-feed.ndjson   // 滚榜数据
├── groups              // Categories照片,但在resolver似乎没起到作用
│   └── 3               // Categories的id
│       └── logo.png
├── organizations       // Affiliations照片,只要某Affiliations的队伍有logo,其他同Affiliations的队伍就都是该logo
│   ├── 3000            // 该Affiliations所对应的任一队伍的icpc id
│   │   └── logo.png
│   ├── 3001
│   │   └── logo.png
│   ├── 3012
│   │   └── logo.png
│   ├── 3017
│   │   ├── country_flag.png    // 照源码里是这样放置的,但在resolver似乎没起到作用
│   │   └── logo.png
│   └── 3187
│       └── logo.png
└── teams               // 队伍照片
    ├── 3000            // 队伍的icpc id
    │   └── photo.png   // 照片名字固定是photo
    ├── 3001
    │   └── photo.png
    ├── 3009
    │   └── photo.png
    └── 3010
        └── photo.png

所以队伍照片等等直接按照上面的格式来就行...... 就只有一个 teams 文件夹带上 event-feed.ndjson 就是最简单的结构了。

最主要的就是这个 event-feed.ndjson 怎么生成。比赛结束后,首先在 DOMjudge 上 Finalize 这场比赛,之后浏览器访问以下网址:

http://<domjudge url>/api/v4/contests/<cid>/event-feed?stream=false

然后输入 domjudge 的 admin 账号密码,之后会下载下来一个 event-feed 的文件。手动加上 .json 的后缀名,然后打开 awards.json 来读取这个 event-feed.json。读取之后,可以在界面手动设置奖项,然后点右上角的 Save event Feed,如图:

之后会保存一个
```event-feed.ndjson``` 的文件,将其放在 cdp 文件夹的根目录下即可。

之后在 Git Bash 下运行 resolver.bat,并用如下格式来指定对应的 cdp 文件夹:

ICPC_FONT="DengXian" ./resolver.bat ./cdp/ --fast 0.3

其中
```--fast``` 用来指示滚榜速度,后面的小数表示所有时间缩短的倍数,例如 0.5 表示二倍速。如果这场比赛没有 Finalize 的话,上述命令需要在最后加一句 ```--test```。

如果遇到 java 报 OutOfMemory 则直接修改 resolver.bat 内最后一句命令,将 -Xmx=1024m 调大,比如 -Xmx=4g 再试试。

然后就可以愉快滚榜啦,具体操作见官方文档

References

CN-XCPC-DOCS
计算机 · DOMjudge Docker 配置
Connecting the ICPC Tools with DOMjudge
ICPC Tools
docker hub - domjudge
DOMjudge Manual 8.2
ICPCToy - DOMjudge
Hydro/XCPC-TOOLS
Lanly - 滚榜程序Resolver源码阅读