mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-26 07:48:41 +00:00
Merge branch 'master' into uoj_form_v2
This commit is contained in:
commit
7e08faa920
@ -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 UOJForm('start_test');
|
$start_test_form = new UOJForm('start_test');
|
||||||
$start_test_form->handle = function () {
|
$start_test_form->handle = function () {
|
||||||
UOJContest::finalTest();
|
UOJContest::cur()->finalTest();
|
||||||
};
|
};
|
||||||
$start_test_form->config['submit_container']['class'] = 'mt-2';
|
$start_test_form->config['submit_container']['class'] = 'mt-2';
|
||||||
$start_test_form->config['submit_button']['class'] = 'btn btn-danger d-block w-100';
|
$start_test_form->config['submit_button']['class'] = 'btn btn-danger d-block w-100';
|
||||||
@ -65,7 +65,7 @@ if (UOJContest::cur()->userCanStartFinalTest(Auth::user())) {
|
|||||||
$start_test_form->config['confirm']['smart'] = true;
|
$start_test_form->config['confirm']['smart'] = true;
|
||||||
$start_test_form->runAtServer();
|
$start_test_form->runAtServer();
|
||||||
}
|
}
|
||||||
if ($contest['cur_progress'] >= CONTEST_TESTING) {
|
if ($contest['cur_progress'] >= CONTEST_TESTING && UOJContest::cur()->queryJudgeProgress()['fully_judged']) {
|
||||||
$publish_result_form = new UOJForm('publish_result');
|
$publish_result_form = new UOJForm('publish_result');
|
||||||
$publish_result_form->handle = function () {
|
$publish_result_form->handle = function () {
|
||||||
UOJContest::announceOfficialResults();
|
UOJContest::announceOfficialResults();
|
||||||
|
@ -101,7 +101,7 @@ if (UOJContest::cur()) {
|
|||||||
|
|
||||||
$submission_requirement = UOJProblem::cur()->getSubmissionRequirement();
|
$submission_requirement = UOJProblem::cur()->getSubmissionRequirement();
|
||||||
$custom_test_requirement = UOJProblem::cur()->getCustomTestRequirement();
|
$custom_test_requirement = UOJProblem::cur()->getCustomTestRequirement();
|
||||||
$custom_test_enabled = $custom_test_requirement && $pre_submit_check_ret === true;
|
$custom_test_enabled = $custom_test_requirement && $pre_submit_check_ret === true && UOJProblem::info('type') != 'remote';
|
||||||
|
|
||||||
function handleUpload($zip_file_name, $content, $tot_size) {
|
function handleUpload($zip_file_name, $content, $tot_size) {
|
||||||
global $is_participating;
|
global $is_participating;
|
||||||
@ -168,11 +168,8 @@ if ($custom_test_enabled) {
|
|||||||
$custom_test_form->runAtServer();
|
$custom_test_form->runAtServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
$can_use_zip_upload = true;
|
if (empty($submission_requirement)) {
|
||||||
foreach ($submission_requirement as $req) {
|
$no_more_submission = '当前题目未配置提交文件,请联系管理员!';
|
||||||
if ($req['type'] == 'source code') {
|
|
||||||
$can_use_zip_upload = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($pre_submit_check_ret === true && !$no_more_submission) {
|
if ($pre_submit_check_ret === true && !$no_more_submission) {
|
||||||
@ -271,12 +268,12 @@ if (UOJContest::cur()) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="tab-pane" id="submit">
|
<div class="tab-pane" id="submit">
|
||||||
<?php if ($pre_submit_check_ret !== true) : ?>
|
<?php if ($pre_submit_check_ret !== true) : ?>
|
||||||
<h3 class="text-warning"><?= $pre_submit_check_ret ?></h3>
|
<p class="text-warning h4"><?= $pre_submit_check_ret ?></p>
|
||||||
<?php elseif ($no_more_submission) : ?>
|
<?php elseif ($no_more_submission) : ?>
|
||||||
<h3 class="text-warning"><?= $no_more_submission ?></h3>
|
<p class="text-warning h4"><?= $no_more_submission ?></p>
|
||||||
<?php else : ?>
|
<?php else : ?>
|
||||||
<?php if ($submission_warning) : ?>
|
<?php if ($submission_warning) : ?>
|
||||||
<h3 class="text-warning"><?= $submission_warning ?></h3>
|
<p class="text-warning h4"><?= $submission_warning ?></p>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<?php if (isset($zip_answer_form)) : ?>
|
<?php if (isset($zip_answer_form)) : ?>
|
||||||
<?php $zip_answer_form->printHTML(); ?>
|
<?php $zip_answer_form->printHTML(); ?>
|
||||||
|
@ -88,7 +88,7 @@ $reply_form->addHidden(
|
|||||||
return '您要回复的对象不存在';
|
return '您要回复的对象不存在';
|
||||||
}
|
}
|
||||||
$comment = UOJBlogComment::query($reply_id);
|
$comment = UOJBlogComment::query($reply_id);
|
||||||
if (!$comment || $comment['blog_id'] != $blog['id']) {
|
if (!$comment || $comment->info['blog_id'] != $blog['id']) {
|
||||||
return '您要回复的对象不存在';
|
return '您要回复的对象不存在';
|
||||||
}
|
}
|
||||||
$vdata['parent'] = $comment;
|
$vdata['parent'] = $comment;
|
||||||
|
@ -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,17 +187,128 @@ 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() {
|
||||||
if ($this->basicRule() == 'OI' && $this->progress() < CONTEST_TESTING) {
|
if ($this->basicRule() == 'OI' && $this->progress() < CONTEST_TESTING) {
|
||||||
$rop = 0;
|
$rop = 0;
|
||||||
$title = UOJLocale::get('contests::contest pending final test');
|
$title = UOJLocale::get('contests::contest pending final test');
|
||||||
|
$fully_judged = false;
|
||||||
} else {
|
} else {
|
||||||
$total = DB::selectCount([
|
$total = DB::selectCount([
|
||||||
"select count(*) from submissions",
|
"select count(*) from submissions",
|
||||||
@ -272,13 +324,15 @@ class UOJContest {
|
|||||||
$rop = $total == 0 ? 100 : (int)($n_judged / $total * 100);
|
$rop = $total == 0 ? 100 : (int)($n_judged / $total * 100);
|
||||||
|
|
||||||
$title = UOJLocale::get('contests::contest final testing');
|
$title = UOJLocale::get('contests::contest final testing');
|
||||||
if ($this->basicRule() != 'OI' && $n_judged == $total) {
|
$fully_judged = $n_judged == $total;
|
||||||
|
if ($this->basicRule() != 'OI' && $fully_judged) {
|
||||||
$title = UOJLocale::get('contests::contest official results to be announced');
|
$title = UOJLocale::get('contests::contest official results to be announced');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'rop' => $rop,
|
'rop' => $rop,
|
||||||
'title' => $title
|
'title' => $title,
|
||||||
|
'fully_judged' => $fully_judged,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,10 +460,6 @@ class UOJProblem {
|
|||||||
return $key === null ? $extra_config : $extra_config[$key];
|
return $key === null ? $extra_config : $extra_config[$key];
|
||||||
}
|
}
|
||||||
public function getCustomTestRequirement() {
|
public function getCustomTestRequirement() {
|
||||||
if ($this->info['type'] == 'remote') {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$extra_config = json_decode($this->info['extra_config'], true);
|
$extra_config = json_decode($this->info['extra_config'], true);
|
||||||
|
|
||||||
if (isset($extra_config['custom_test_requirement'])) {
|
if (isset($extra_config['custom_test_requirement'])) {
|
||||||
@ -559,11 +555,16 @@ class UOJProblem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function userCanUploadSubmissionViaZip(array $user = null) {
|
public function userCanUploadSubmissionViaZip(array $user = null) {
|
||||||
foreach ($this->getSubmissionRequirement() as $req) {
|
$submission_requirement = $this->getSubmissionRequirement();
|
||||||
|
|
||||||
|
if (empty($submission_requirement)) return false;
|
||||||
|
|
||||||
|
foreach ($submission_requirement as $req) {
|
||||||
if ($req['type'] == 'source code') {
|
if ($req['type'] == 'source code') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,50 @@ if (!isset($ShowPageHeader)) {
|
|||||||
skipHtmlTags: {
|
skipHtmlTags: {
|
||||||
'[-]': ['pre']
|
'[-]': ['pre']
|
||||||
},
|
},
|
||||||
}
|
renderActions: {
|
||||||
|
addCopyText: [
|
||||||
|
155,
|
||||||
|
(doc) => {
|
||||||
|
for (const math of doc.math) {
|
||||||
|
MathJax.config.addCopyText(math, doc);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function(math, doc) {
|
||||||
|
MathJax.config.addCopyText(math, doc);
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
addCopyText(math, doc) {
|
||||||
|
doc.adaptor.append(
|
||||||
|
math.typesetRoot,
|
||||||
|
doc.adaptor.node(
|
||||||
|
'mjx-copytext', {
|
||||||
|
'aria-hidden': true,
|
||||||
|
},
|
||||||
|
[
|
||||||
|
doc.adaptor.text(
|
||||||
|
math.start.delim +
|
||||||
|
math.math +
|
||||||
|
math.end.delim)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
startup: {
|
||||||
|
ready() {
|
||||||
|
MathJax._.output.chtml_ts.CHTML.commonStyles['mjx-copytext'] = {
|
||||||
|
display: 'inline-block',
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
opacity: 0,
|
||||||
|
};
|
||||||
|
MathJax.startup.defaultReady();
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<script id="MathJax-script" src="<?= HTML::url('/js/mathjax3/tex-mml-chtml.js') ?>"></script>
|
<script id="MathJax-script" src="<?= HTML::url('/js/mathjax3/tex-mml-chtml.js') ?>"></script>
|
||||||
|
Loading…
Reference in New Issue
Block a user