From 469fc99ca70f0e06855061d72568a37ef819c73c Mon Sep 17 00:00:00 2001 From: Baoshuo Date: Wed, 18 Jan 2023 09:29:43 +0800 Subject: [PATCH] refactor(contest): not rejudge submissions after contest --- web/app/controllers/contest_inside.php | 4 +- web/app/controllers/contest_manage.php | 4 +- web/app/models/UOJContest.php | 175 ++++++++++++++++--------- 3 files changed, 117 insertions(+), 66 deletions(-) diff --git a/web/app/controllers/contest_inside.php b/web/app/controllers/contest_inside.php index 3b47fe4..210bd23 100644 --- a/web/app/controllers/contest_inside.php +++ b/web/app/controllers/contest_inside.php @@ -54,10 +54,10 @@ if ($is_manager) { isset($tabs_info[$cur_tab]) || UOJResponse::page404(); 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->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['smart_confirm'] = ''; diff --git a/web/app/controllers/contest_manage.php b/web/app/controllers/contest_manage.php index 5ef3f81..0ab7f2a 100644 --- a/web/app/controllers/contest_manage.php +++ b/web/app/controllers/contest_manage.php @@ -596,11 +596,11 @@ EOD); EOD, function ($row) { - $problem = UOJProblem::query($row['problem_id']); + $problem = UOJContestProblem::query($row['problem_id'], UOJContest::cur()); echo ''; echo '', $row['problem_id'], ''; echo '', $problem->getLink(['with' => 'none']), ''; - echo '', isset($contest['extra_config']["problem_{$problem->info['id']}"]) ? $contest['extra_config']["problem_{$problem->info['id']}"] : 'default', ''; + echo '', $problem->getJudgeTypeInContest(), ''; echo ''; echo '
info['id'], ' 从比赛中移除吗?")\'>'; echo ''; diff --git a/web/app/models/UOJContest.php b/web/app/models/UOJContest.php index e7496d9..c9c8d2c 100644 --- a/web/app/models/UOJContest.php +++ b/web/app/models/UOJContest.php @@ -53,65 +53,6 @@ class UOJContest { 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() { // time config set_time_limit(0); @@ -246,11 +187,121 @@ class UOJContest { $label = '开始最终测试'; } - if ($this->progress() >= CONTEST_TESTING) { - $label = '重新' . $label; + return $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() {