Skip to content

Commit a113dbf

Browse files
committed
publish v1 version
1 parent bd5a7d5 commit a113dbf

File tree

5 files changed

+167
-9
lines changed

5 files changed

+167
-9
lines changed

README.md

Lines changed: 105 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,105 @@
1-
# xcpc-tools
2-
A tools for CN XCPC contests
3-
4-
## TODOs
5-
- [ ] balloons notification tools with webhook/receipts printer
6-
- [ ] remote printer
7-
- [ ] resolver
8-
- [ ] seat binder
1+
# Hydro/XCPC-TOOLS
2+
3+
A tool for CN XCPC contests
4+
5+
- 全平台远程代码打印
6+
- 支持封榜期间发放鼓励气球的小票机
7+
- 选手机赛时数据监控与屏幕监控
8+
9+
TODO Features:
10+
11+
- [ ] 更好的选手机座位绑定
12+
- [ ] 支持多平台参赛系统
13+
- [ ] Windows 小票机支持
14+
- [ ] 优化 UI 顺畅度
15+
- [ ] 使用 WebSocket 返回指令执行情况
16+
- [ ] 支持全考场监视
17+
- [ ] 企业微信/钉钉/TG Webhook 气球机
18+
- [ ] 滚榜
19+
20+
当前最新版本可直接在 [Releases](https://github.com/hydro-dev/xcpc-tools/releases/) 下载使用
21+
22+
### Server
23+
24+
Server 端分为 `Server Mode``Fetch Mode` ,在 `Fetch Mode` 下支持获取用户气球与连接小票机打印。各功能配置方法如下:
25+
26+
#### 安装
27+
28+
[Releases](https://github.com/hydro-dev/xcpc-tools/releases/) 下载已经封装好的 Windows、Linux、MacOS 二进制使用,如有未封装好的架构但 Node.js 支持的系统或系统内已有 Node.js 亦可下载 `xcpc-tools-bundle.js`使用。
29+
30+
下载后首次运行可见填写配置文件字样,打开 `config.server.yaml` ,如使用 `Fetch Mode` 请填写相关赛事系统配置,如使用 `Server Mode` 则无须填写配置可直接启动。
31+
32+
系统配置介绍如下:
33+
34+
```ts
35+
const serverSchema = Schema.intersect([
36+
Schema.object({
37+
type: Schema.union([
38+
Schema.const('server'),
39+
Schema.const('domjudge'),
40+
Schema.const('hydro'),
41+
] as const).description('server type').required(), // 服务类型
42+
port: Schema.number().default(5283), // 服务端口
43+
viewPass: Schema.string().default(String.random(8)), // UI登录密码,可通过 admin / {viewPass} 登录
44+
secretRoute: Schema.string().default(String.random(12)), // 打印路径,用于远程调用
45+
seatFile: Schema.string().default('/home/icpc/Desktop/seat.txt'), // 选手座位绑定文件
46+
}).description('Basic Config'),
47+
Schema.union([
48+
Schema.object({
49+
type: Schema.union([
50+
Schema.const('domjudge'),
51+
Schema.const('hydro'),
52+
] as const).required(), // 赛事系统类型
53+
server: Schema.string().role('url').required(), // 赛事系统地址
54+
contestId: Schema.string(), // 赛事ID,如无则自动获取(Domjudge),hydro 请使用 domainId/contestId 作为ID
55+
token: Schema.string(), // 赛事系统 Token 如无可使用用户名密码登录
56+
username: Schema.string(), // 赛事系统用户名
57+
password: Schema.string(), // 赛事系统密码
58+
}).description('Fetcher Config'), // token 与 username/password 二选一
59+
Schema.object({
60+
type: Schema.const('server').required(),
61+
}).description('Server Mode Config'),
62+
]),
63+
]);
64+
```
65+
66+
填写好配置重启后即可使用,程序默认监听 0.0.0.0 ,可通过 `http://服务IP:5283` 访问 UI 界面。服务用户名为 `admin` ,密码为填写的 `viewPass`
67+
68+
#### Print
69+
70+
支持各类比赛系统推送打印信息,系统将自动调用 `typst` 为选手代码进行高亮并转换为 PDF 文件,由打印/气球客户端进行打印。 建议使用命令进行打印,避免服务交互数据泄漏,如需使用请从`https://github.com/hydro-dev/xcpc-tools/blob/main/scripts/print`下载脚本并提前将脚本放置在 `PATH` 中。
71+
72+
`print [file] [original] [language] [username] [teamname] [teamid] [location]` 为打印命令,其中 `file` 为代码文件路径,`original` 为原文件名,`language` 为语言,`username` 为用户名,`teamname` 为队伍名,`teamid` 为队伍ID,`location` 为选手位置。
73+
74+
#### Balloon
75+
服务支持 `Fetch Mode` 下的气球推送,支持 `Domjudge``Hydro` 系统,支持 `Domjudge``Hydro` 系统的 `Balloon` 推送,同时若赛事在封榜后仍然推送气球,则支持自定义鼓励气球数,高于设定值则不推送,为所有队伍打造优质赛场体验。
76+
77+
#### Monitor
78+
服务支持监控选手机情况和监控服务器桌面,如您需要选手机监控,可通过设置 Systemd 定时执行任务等多种方式定时执行 `monitor` 命令,如需监控服务器桌面,请在选手机上提前运行 `vlc-camera``vlc-desktop` 服务, CAICPC 镜像已经内置了这三两个服务,您只需在选手机上运行即可,如您为自己的镜像,可从 `https://github.com/hydro-dev/xcpc-tools/blob/main/scripts/monitor` 下载 `monitor` 服务。
79+
80+
当您的选手机启动了 `monitor` 服务后,服务会定时向服务器发送选手机状态,您可以在 `http://服务IP:5283/monitor` 查看选手机状态,如选手机掉线/未启动,系统会有明显提示协助找到对应机型。
81+
82+
由于 VLC 自带的服务不支持 CORS , 因此产品内置了一个代理服务,代理服务会将请求转发到选手机上,您可以通过代理服务访问选手机上的 VLC 服务以实现监控。
83+
84+
请注意,默认上报的选手机是不支持查看屏幕的,需要在 UI 上配置选手机信息。点击选手机列表中的选手机的详情按钮,然后在弹出的对话框中即可修改选手机信息。字段含义如下:
85+
86+
- `Client Name` 选手机名称
87+
- `Client group` 选手机组别
88+
- `Camera Stream` 选手机摄像头地址(暂只支持 TS 流地址)
89+
- `Desktop Stream` 选手机桌面地址(暂只支持 TS 流地址)
90+
91+
流地址可使用 `proxy://xxxx` 代理服务,`proxy://` 取代的是 `http://{ip}`, 如 `proxy://:9090/`, 此时代理服务会将请求转发到选手机 `http://{ip}:9090/` 上。
92+
93+
如您有可直接访问的 TS 流地址,可直接填写,您可通过 CDS 等服务获得此类流地址,注意流地址需要支持跨域访问,否则无法在 UI 上正常显示,如您的流地址不支持跨域访问,您可以使用代理服务进行转发,同时 CDS 服务提供的流在封榜后将无法观看,请自行取舍。如修改成功, Info 选项卡后便会多出桌面和摄像头的预览标签页,同时在选手机列表中也会支持直接查看选手机的摄像头和桌面。
94+
95+
#### Batch / Quick Operation
96+
为了方便修改选手机信息,服务支持批量操作和根据选手机字段快速操作,如您需要批量修改选手机信息,可通过 `Batch Operation` 选项卡进行批量操作。
97+
98+
快速操作即你可以在对话框中填写 `[]` 指代已有的字段,如 `[hostname]`, `[ip]`, `[mac]` 等,系统会自动将对应字段填充到选手机信息中。
99+
100+
同时,组别名支持只取名字前缀,如 `[hostname:3]` 会取选手机名称的前三位,如您需要使用 hostname 为 AXX 的选手机 hostname 中的第一位作为组别名,您可以在快速操作中填写 `[hostname:1]`,系统会自动填充对应的选手机信息。
101+
102+
在字段中输入 `del` 可以删除对应字段的信息。
103+
104+
#### Commands
105+
服务支持通过 `ssh` 执行命令,如您需要执行命令,内置的命令分别为 重启、根据 `config.seatFile` 选手座位绑定文件更新选手机机器名称、显示选手机座位信息。如您需要执行其他命令,请直接在 UI 界面中输入指令,系统会自动向所有选手机发送指令,并返回结果。

packages/server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hydrooj/xcpc-tools",
3-
"version": "0.0.1",
3+
"version": "1.0.0",
44
"description": "A tools for XCPC contests",
55
"main": "index.ts",
66
"repository": "https://github.com/Hydro-dev/xcpc-tools",

scripts/ips-seats-json-gen.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import requests
2+
import base64
3+
import json
4+
5+
auth = 'admin:admin'
6+
7+
req = requests.get('http://SERVER:5283/monitor', headers={'Authorization': 'Basic ' + base64.b64encode(auth.encode()).decode()})
8+
reqjson = req.json()
9+
10+
ips = []
11+
12+
seats = {}
13+
14+
for i in reqjson['monitors']:
15+
if reqjson['monitors'][i]['ip'].startswith('192.'):
16+
ips.append(reqjson['monitors'][i]['ip'])
17+
seats[reqjson['monitors'][i]['hostname']] = reqjson['monitors'][i]['ip']
18+
19+
20+
with open("ips.json", "w") as f:
21+
f.write(json.dumps(ips, indent=2))
22+
23+
with open("seats.json", "w") as f:
24+
f.write(json.dumps(seats, indent=2))
File renamed without changes.

scripts/print

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash -e
2+
# SPDX-License-Identifier: MIT
3+
4+
if [ $# -lt 7 ]; then
5+
echo "Something went wrong. Please contact the contest staff."
6+
echo "Error: not enough arguments" >&2
7+
echo "Usage: $0 <filename> <origname> <language> <username> <teamname> <teamid> <location>" >&2
8+
echo "Set print command to: $0 [file] [original] [language] [username] [teamname] [teamid] [location]" >&2
9+
exit 1
10+
fi
11+
12+
PRINT_SERVER=https://print.icpc/
13+
14+
filename=$1; shift
15+
origname=$1; shift
16+
language=$1; shift
17+
username=$1; shift
18+
teamname=$1; shift
19+
teamid=$1; shift
20+
location=$1; shift
21+
22+
23+
echo "Filename: $origname"
24+
echo "Language: $language"
25+
echo "Username: $username"
26+
[ -n "$teamname" ] && echo "Team Name: $teamname" || teamname="$username"
27+
[ -n "$teamid" ] && echo "Team ID: $teamid"
28+
[ -n "$location" ] && echo "Location: $location"
29+
30+
exec curl -fsS \
31+
-F file=@"$filename" \
32+
-F filename="$origname" \
33+
-F lang="$language" \
34+
-F tname="$teamname" \
35+
-F team="$teamid" \
36+
-F location="$location" \
37+
$PRINT_SERVER 2>&1

0 commit comments

Comments
 (0)