refactor(contest): not rejudge submissions after contest

This commit is contained in:
Baoshuo Ren 2023-01-18 09:29:43 +08:00
parent e522538d98
commit 469fc99ca7
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
3 changed files with 117 additions and 66 deletions

View File

@ -54,10 +54,10 @@ if ($is_manager) {
isset($tabs_info[$cur_tab]) || UOJResponse::page404(); isset($tabs_info[$cur_tab]) || UOJResponse::page404();
if (UOJContest::cur()->userCanStartFinalTest(Auth::user())) { if (UOJContest::cur()->userCanStartFinalTest(Auth::user())) {
if (CONTEST_PENDING_FINAL_TEST <= $contest['cur_progress']) { if (CONTEST_PENDING_FINAL_TEST == $contest['cur_progress']) {
$start_test_form = new UOJBs4Form('start_test'); $start_test_form = new UOJBs4Form('start_test');
$start_test_form->handle = function () { $start_test_form->handle = function () {
UOJContest::finalTest(); UOJContest::cur()->finalTest();
}; };
$start_test_form->submit_button_config['class_str'] = 'btn btn-danger d-block w-100'; $start_test_form->submit_button_config['class_str'] = 'btn btn-danger d-block w-100';
$start_test_form->submit_button_config['smart_confirm'] = ''; $start_test_form->submit_button_config['smart_confirm'] = '';

View File

@ -596,11 +596,11 @@ EOD);
</tr> </tr>
EOD, EOD,
function ($row) { function ($row) {
$problem = UOJProblem::query($row['problem_id']); $problem = UOJContestProblem::query($row['problem_id'], UOJContest::cur());
echo '<tr>'; echo '<tr>';
echo '<td>', $row['problem_id'], '</td>'; echo '<td>', $row['problem_id'], '</td>';
echo '<td>', $problem->getLink(['with' => 'none']), '</td>'; echo '<td>', $problem->getLink(['with' => 'none']), '</td>';
echo '<td>', isset($contest['extra_config']["problem_{$problem->info['id']}"]) ? $contest['extra_config']["problem_{$problem->info['id']}"] : 'default', '</td>'; echo '<td>', $problem->getJudgeTypeInContest(), '</td>';
echo '<td>'; echo '<td>';
echo '<form class="d-inline-block" method="POST" target="_self" onsubmit=\'return confirm("你确定要将题目 #', $problem->info['id'], ' 从比赛中移除吗?")\'>'; echo '<form class="d-inline-block" method="POST" target="_self" onsubmit=\'return confirm("你确定要将题目 #', $problem->info['id'], ' 从比赛中移除吗?")\'>';
echo '<input type="hidden" name="_token" value="', crsf_token(), '">'; echo '<input type="hidden" name="_token" value="', crsf_token(), '">';

View File

@ -53,65 +53,6 @@ class UOJContest {
return isSuperUser($user) || UOJUser::checkPermission($user, 'contests.create'); return isSuperUser($user) || UOJUser::checkPermission($user, 'contests.create');
} }
public static function finalTest() {
$contest = self::info();
$res = DB::selectAll([
"select id, problem_id, content, submitter, hide_score_to_others from submissions",
"where", ["contest_id" => $contest['id']]
]);
foreach ($res as $submission) {
$content = json_decode($submission['content'], true);
if (isset($content['final_test_config'])) {
$content['config'] = $content['final_test_config'];
unset($content['final_test_config']);
}
if (isset($content['first_test_config'])) {
unset($content['first_test_config']);
}
UOJSubmission::rejudgeById($submission['id'], [
'reason_text' => HTML::stripTags($contest['name']) . ' 最终测试',
'reason_url' => HTML::url(UOJContest::cur()->getUri()),
'set_q' => [
"content" => json_encode($content)
]
]);
}
// warning: check if this command works well when the database is not MySQL
DB::update([
"update submissions",
"set", [
"score = hidden_score",
"hidden_score = NULL",
"hide_score_to_others = 0"
], "where", [
"contest_id" => $contest['id'],
"hide_score_to_others" => 1
]
]);
$updated = [];
foreach ($res as $submission) {
$submitter = $submission['submitter'];
$pid = $submission['problem_id'];
if (isset($updated[$submitter]) && isset($updated[$submitter][$pid])) {
continue;
}
updateBestACSubmissions($submitter, $pid);
if (!isset($updated[$submitter])) {
$updated[$submitter] = [];
}
$updated[$submitter][$pid] = true;
}
DB::update([
"update contests",
"set", ["status" => 'testing'],
"where", ["id" => $contest['id']]
]);
}
public static function announceOfficialResults() { public static function announceOfficialResults() {
// time config // time config
set_time_limit(0); set_time_limit(0);
@ -246,11 +187,121 @@ class UOJContest {
$label = '开始最终测试'; $label = '开始最终测试';
} }
if ($this->progress() >= CONTEST_TESTING) { return $label;
$label = '重新' . $label; }
public function finalTest() {
ignore_user_abort(true);
set_time_limit(0);
DB::update([
"update contests",
"set", ["status" => 'testing'],
"where", ["id" => $this->info['id']]
]);
if (DB::affected_rows() !== 1) {
// 已经有其他人开始评测了,不进行任何操作
return;
} }
return $label; $res = DB::selectAll([
"select id, problem_id, content, result, submitter, hide_score_to_others from submissions",
"where", ["contest_id" => $this->info['id']]
]);
foreach ($res as $submission) {
$content = json_decode($submission['content'], true);
if (isset($content['final_test_config'])) {
$content['config'] = $content['final_test_config'];
unset($content['final_test_config']);
}
if (isset($content['first_test_config'])) {
unset($content['first_test_config']);
}
$q = [
'content' => json_encode($content),
];
$problem_judge_type = $this->info['extra_config']["problem_{$submission['problem_id']}"] ?: $this->defaultProblemJudgeType();
$result = json_decode($submission['result'], true);
switch ($problem_judge_type) {
case 'sample':
if (isset($result['final_result']) && $result['final_result']['status'] == 'Judged') {
$q += [
'result' => json_encode($result['final_result']),
'score' => $result['final_result']['score'],
'used_time' => $result['final_result']['time'],
'used_memory' => $result['final_result']['memory'],
'judge_time' => $this->info['end_time_str'],
'status' => 'Judged',
];
if ($submission['hide_score_to_others']) {
$q['hidden_score'] = $q['score'];
$q['score'] = null;
}
}
break;
case 'no-details':
case 'full':
if ($result['status'] == 'Judged') {
$q += [
'result' => $submission['result'],
'score' => $result['score'],
'used_time' => $result['time'],
'used_memory' => $result['memory'],
'judge_time' => $this->info['end_time_str'],
'status' => 'Judged',
];
if ($submission['hide_score_to_others']) {
$q['hidden_score'] = $q['score'];
$q['score'] = null;
}
}
break;
}
UOJSubmission::rejudgeById($submission['id'], [
'reason_text' => HTML::stripTags($this->info['name']) . ' 最终测试',
'reason_url' => HTML::url(UOJContest::cur()->getUri()),
'set_q' => $q,
]);
}
// warning: check if this command works well when the database is not MySQL
DB::update([
"update submissions",
"set", [
"score = hidden_score",
"hidden_score = NULL",
"hide_score_to_others = 0"
], "where", [
"contest_id" => $this->info['id'],
"hide_score_to_others" => 1
]
]);
$updated = [];
foreach ($res as $submission) {
$submitter = $submission['submitter'];
$pid = $submission['problem_id'];
if (isset($updated[$submitter]) && isset($updated[$submitter][$pid])) {
continue;
}
updateBestACSubmissions($submitter, $pid);
if (!isset($updated[$submitter])) {
$updated[$submitter] = [];
}
$updated[$submitter][$pid] = true;
}
} }
public function queryJudgeProgress() { public function queryJudgeProgress() {