Dependencies:

  • gcc
  • make
  • postgresql14
  • libpq5
  • davidmoreno/onion
  • isolate
  • To be continued..

主要特性:

评测机可部署在多台不共享文件系统的机器上

对异构多核可以将评测机分组并限制在对应核心

数据库中的数据对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#define Administrator 0x7  // all
#define UserManager 0x1
#define ContestManager 0x2 // 管理 Contests 和 Problems
#define SubmissionManager 0x4 // rejudge, 提交作废,手动评测,之类的
struct User {
char Id[32]; // uuid
char Email[32]; // smail.nju, null terminated
char ContestantId[32]; // 学号, like 2312xxxxx; 或者老师、助教的自定义名称。用作登录名
// null terminated,仅限数字、字母、下划线
char ContestantName[32]; // null terminated,用作排行榜显示。任意 <= 31 字节的 utf-8 字符串
char Password[32]; // null terminated, libcrypt 加密后存储
int ClassId; // 班级号
uint32_t Roles; // 用户组 flags
};

struct Class {
int Id;
char Name[16]; // e.g. 2021SE1, 2022SZ6, GUEST, NOCLASS.
// null terminated.
};

struct Bulletin {
int Id;
int Weight;
char *Content;
struct tm PublishAt;
struct tm ExpireAt;
};

struct Problem {
int Id;
int ContestId;
enum { Ordinary, TestKitLab } Type;
char Title[128]; // null terminated
char *Description;
char *InputFormat;
char *OutputFormat;
char *FootNote;
double TimeLimit; // s
int MemoryLimit; // KiB
bool HasSpecialJudge;
bool SkipSample;
int SampleCasesCnt;
char **SampleCasesInput; // Base64
char **SampleCasesOutput; // Base64
int TestCasesCnt;
char **TestCasesInputPath; // $DATA_ROOT/tests/problemId/{ path }
char **TestCasesOutputPath;
struct tm SpjEdited; // 用于 spj 更新,worker 重新编译
struct tm TestEdited; // 用于测试点更新,worker 重新请求
bool IsGroupLimited; // Worker Group 限制
char *WorkerGroup; // 仅可由对应组 Worker 评测
};

struct Contest {
int Id;
char title[128];
char *description;
enum { Public, Private, Protected } Visibility;
// protected,考试中模式,做对了也不能看别人代码
// Private,仅管理员与存在提交记录者可见。不再有 Contestant 的设定
// Public,Contest 开始时间后就公开,做对可查看所有源码
enum { Practice, CodeForces, ACM, OI } ContestMode;
struct tm BeginTime;
struct tm SoftDDL;
struct tm HardDDL;
bool HasDecay;
bool IsDecayLinear;
int Decay[3]; // percent
struct tm DecayTime[3]; // before DecayTime[i], has Decay[i]
// After DecayTime[2], Score *= Decay[2] %
// After HardDDL, Score = 0
};

struct Submission {
int Id;
char UserId[32];
enum { C, Cpp, Rust } Language; //
int ProblemId;
struct tm SubmittedAt;
struct tm JudgedAt;
enum { FAILED, REJECTED, TESTOK, PENDING, JUDGING, ACCEPTED, WRONGANSWER,
TIMELIMITEXCEEDED, COMPILEERROR, MEMORYLIMITEXCEEDED,
PARTIALLYACCEPTED, RUNTIMEERROR, NGLANGUAGE, DRPRECATED } Verdict;
char *SourceCode; // Base64
int Time; // ms
int Memory; // KiB
int Score; // 0 - 100
bool HasInput; // T
char *UserInput; // 自定测试, Base64
char *Message; // Base64, Manual or CompilerOutput, or RuntimeStdErr
char *JudgedBy; // groupId-groupSeqNo or Manual
char *FailedOn; // Base64, given by Worker
};

所有请求和返回值都用 json

分为 Controller 和 Service 模块。其中 Controller 模块根据对应功能调用 Service 中的函数,并依此来判断 http 返回状态与内容。

Service 模块执行鉴权、实际的业务逻辑。