diff --git a/web/app/controllers/problem.php b/web/app/controllers/problem.php index 8e289e3..29d2e00 100644 --- a/web/app/controllers/problem.php +++ b/web/app/controllers/problem.php @@ -104,6 +104,17 @@ $custom_test_enabled = $custom_test_requirement && $pre_submit_check_ret === tru function handleUpload($zip_file_name, $content, $tot_size) { global $is_participating; + + $remote_oj = UOJProblem::cur()->getExtraConfig('remote_online_judge'); + $remote_provider = UOJRemoteProblem::$providers[$remote_oj]; + + if (UOJProblem::info('type') == 'remote') { + $submit_type = in_array($_POST['answer_remote_submit_type'], $remote_provider['submit_type']) ? $_POST['answer_remote_submit_type'] : $remote_provider['submit_type'][0]; + $content['no_rejudge'] = true; + $content['config'][] = ['remote_submit_type', $submit_type]; + $content['config'][] = ['remote_account_data', $_POST['answer_remote_account_data']]; + } + UOJSubmission::onUpload($zip_file_name, $content, $tot_size, $is_participating); } function handleCustomTestUpload($zip_file_name, $content, $tot_size) { @@ -182,7 +193,7 @@ if ($pre_submit_check_ret === true && !$no_more_submission) { if (UOJProblem::cur()->userCanUploadSubmissionViaZip(Auth::user())) { $zip_answer_form = newZipSubmissionForm( - 'zip-answer', + 'zip_answer', $submission_requirement, 'FS::randomAvailableSubmissionFileName', 'handleUpload' @@ -198,6 +209,24 @@ if ($pre_submit_check_ret === true && !$no_more_submission) { 'FS::randomAvailableSubmissionFileName', 'handleUpload' ); + + if (UOJProblem::info('type') == 'remote') { + $remote_oj = UOJProblem::cur()->getExtraConfig('remote_online_judge'); + $remote_pid = UOJProblem::cur()->getExtraConfig('remote_problem_id'); + $remote_url = UOJRemoteProblem::getProblemRemoteUrl($remote_oj, $remote_pid); + $submit_type = json_encode(UOJRemoteProblem::$providers[$remote_oj]['submit_type']); + + $answer_form->addNoVal('answer_remote_submit_type', ''); + $answer_form->addNoVal('answer_remote_account_data', ''); + $answer_form->appendHTML(<<Remote Judge 配置 +
+ + EOD); + } + $answer_form->extra_validator = $submission_extra_validator; $answer_form->succ_href = $is_participating ? '/contest/' . UOJContest::info('id') . '/submissions' : '/submissions'; $answer_form->runAtServer(); diff --git a/web/app/libs/uoj-form-lib.php b/web/app/libs/uoj-form-lib.php index f2c4355..ddde655 100644 --- a/web/app/libs/uoj-form-lib.php +++ b/web/app/libs/uoj-form-lib.php @@ -58,101 +58,6 @@ function newSubmissionForm($form_name, $requirement, $zip_file_name_gen, $handle $form->addTextFileInput("{$form_name}_{$req['name']}", [ 'filename' => $req['file_name'], ]); - } else if ($req['type'] == "remote submission") { - if ($req['name'] == 'luogu') { - $form->appendHTML(HTML::tag_begin('div', ['class' => 'row'])); - $form->appendHTML(HTML::tag( - 'div', - [ - 'class' => 'col-sm-2', - ], - HTML::tag('label', [ - 'class' => 'form-col-label', - ], '_uid') - )); - $form->addInput("{$form_name}_{$req['name']}_uid", [ - 'div_class' => 'col-sm-4', - 'validator_php' => function ($x) { - if (!validateUInt($x)) { - return 'ID 不合法'; - } - - return ''; - }, - ]); - $form->appendHTML(HTML::tag( - 'div', - [ - 'class' => 'col-sm-6', - ], - HTML::tag('div', [ - 'class' => 'form-text', - ], '请在 Cookie 中找到 _uid,然后填入框中。') - )); - $form->appendHTML(HTML::tag_end('div')); - - $form->appendHTML(HTML::tag_begin('div', ['class' => 'row mt-3'])); - $form->appendHTML(HTML::tag( - 'div', - [ - 'class' => 'col-sm-2', - ], - HTML::tag('label', [ - 'class' => 'form-col-label', - ], '__clientid') - )); - $form->addInput("{$form_name}_{$req['name']}_clientid", [ - 'div_class' => 'col-sm-4', - 'validator_php' => function ($x) { - if (!validateString($x)) { - return 'ID 不合法'; - } - - return ''; - }, - ]); - $form->appendHTML(HTML::tag( - 'div', - [ - 'class' => 'col-sm-6', - ], - HTML::tag('div', [ - 'class' => 'form-text', - ], '请在 Cookie 中找到 __clientid,然后填入框中。') - )); - $form->appendHTML(HTML::tag_end('div')); - - $form->appendHTML(HTML::tag_begin('div', ['class' => 'row mt-3'])); - $form->appendHTML(HTML::tag( - 'div', - [ - 'class' => 'col-sm-2', - ], - HTML::tag('label', [ - 'class' => 'form-col-label', - ], '提交记录 ID') - )); - $form->addInput("{$form_name}_{$req['name']}_submission_id", [ - 'div_class' => 'col-sm-4', - 'validator_php' => function ($x) { - if (!validateUInt($x)) { - return 'ID 不合法'; - } - - return ''; - }, - ]); - $form->appendHTML(HTML::tag( - 'div', - [ - 'class' => 'col-sm-6', - ], - HTML::tag('div', [ - 'class' => 'form-text', - ], '请填入提交记录 ID(不带开头的字母 R)。') - )); - $form->appendHTML(HTML::tag_end('div')); - } } } @@ -174,45 +79,32 @@ function newSubmissionForm($form_name, $requirement, $zip_file_name_gen, $handle foreach ($requirement as $req) { if ($req['type'] == "source code") { $content['config'][] = ["{$req['name']}_language", $_POST["{$form_name}_{$req['name']}_language"]]; - } else if ($req['type'] == "remote submission") { - $content['no_rejudge'] = true; - $content['manual_submit'] = true; - - if ($req['name'] == "luogu") { - $content['config'][] = ["{$req['name']}_uid", $_POST["{$form_name}_{$req['name']}_uid"]]; - $content['config'][] = ["{$req['name']}_clientid", $_POST["{$form_name}_{$req['name']}_clientid"]]; - $content['config'][] = ["{$req['name']}_submission_id", $_POST["{$form_name}_{$req['name']}_submission_id"]]; - } } } foreach ($requirement as $req) { - if ($req['type'] == "remote submission") { - $zip_file->addFromString($req['name'], ''); + if ($_POST["{$form_name}_{$req['name']}_upload_type"] == 'editor') { + $zip_file->addFromString($req['file_name'], $_POST["{$form_name}_{$req['name']}_editor"]); } else { - if ($_POST["{$form_name}_{$req['name']}_upload_type"] == 'editor') { - $zip_file->addFromString($req['file_name'], $_POST["{$form_name}_{$req['name']}_editor"]); + $tmp_name = UOJForm::uploadedFileTmpName("{$form_name}_{$req['name']}_file"); + if ($tmp_name == null) { + $zip_file->addFromString($req['file_name'], ''); } else { - $tmp_name = UOJForm::uploadedFileTmpName("{$form_name}_{$req['name']}_file"); - if ($tmp_name == null) { - $zip_file->addFromString($req['file_name'], ''); - } else { - $zip_file->addFile($tmp_name, $req['file_name']); - } + $zip_file->addFile($tmp_name, $req['file_name']); } - $stat = $zip_file->statName($req['file_name']); - - if ($req['type'] == 'source code') { - $max_size = isset($req['size']) ? (int)$req['size'] : 100; - if ($stat['size'] > $max_size * 1024) { - $zip_file->close(); - unlink(UOJContext::storagePath() . $zip_file_name); - UOJResponse::message("源代码长度不能超过 {$max_size} kB。"); - } - } - - $tot_size += $stat['size']; } + $stat = $zip_file->statName($req['file_name']); + + if ($req['type'] == 'source code') { + $max_size = isset($req['size']) ? (int)$req['size'] : 100; + if ($stat['size'] > $max_size * 1024) { + $zip_file->close(); + unlink(UOJContext::storagePath() . $zip_file_name); + UOJResponse::message("源代码长度不能超过 {$max_size} kB。"); + } + } + + $tot_size += $stat['size']; } $zip_file->close(); diff --git a/web/app/libs/uoj-html-lib.php b/web/app/libs/uoj-html-lib.php index d6b5157..c874368 100644 --- a/web/app/libs/uoj-html-lib.php +++ b/web/app/libs/uoj-html-lib.php @@ -417,22 +417,6 @@ function echoSubmissionContent($submission, $requirement) { echo ''; echo ''; echo ''; - } else if ($req['type'] == "remote submission") { - $remote_provider = UOJRemoteProblem::$providers[$req['name']]; - $content = ''; - - if ($req['name'] == 'luogu') { - $content .= '

远端评测 ID:' . - HTML::tag( - 'a', - [ - 'href' => $remote_provider['url'] . '/record/' . $config['luogu_submission_id'] - ], - 'R' . $config['luogu_submission_id'] - ) . '

'; - } - - HTML::echoPanel('', '远端评测记录', $content); } } diff --git a/web/app/models/UOJProblem.php b/web/app/models/UOJProblem.php index 2db8eb6..ee0da7d 100644 --- a/web/app/models/UOJProblem.php +++ b/web/app/models/UOJProblem.php @@ -562,8 +562,6 @@ class UOJProblem { foreach ($submission_requirement as $req) { if ($req['type'] == 'source code') { return false; - } else if ($req['type'] == 'remote submission') { - return false; } } diff --git a/web/app/models/UOJRemoteProblem.php b/web/app/models/UOJRemoteProblem.php index caeb50a..636984a 100644 --- a/web/app/models/UOJRemoteProblem.php +++ b/web/app/models/UOJRemoteProblem.php @@ -14,6 +14,7 @@ class UOJRemoteProblem { 'ограничение по времени на тест', ], 'languages' => ['C', 'C++', 'C++17', 'C++20', 'Java17', 'Pascal', 'Python2', 'Python3'], + 'submit_type' => ['bot'], ], 'atcoder' => [ 'name' => 'AtCoder', @@ -24,6 +25,7 @@ class UOJRemoteProblem { '指定されたタスクが見つかりません', ], 'languages' => ['C', 'C++', 'Java11', 'Python3', 'Pascal'], + 'submit_type' => ['bot'], ], 'uoj' => [ 'name' => 'UniversalOJ', @@ -33,18 +35,21 @@ class UOJRemoteProblem { '未找到该页面', ], 'languages' => ['C', 'C++03', 'C++11', 'C++', 'C++17', 'C++20', 'Python3', 'Python2.7', 'Java8', 'Java11', 'Java17', 'Pascal'], + 'submit_type' => ['bot'], ], 'loj' => [ 'name' => 'LibreOJ', 'short_name' => 'LOJ', 'url' => 'https://loj.ac', 'languages' => ['C', 'C++03', 'C++11', 'C++', 'C++17', 'C++20', 'Python3', 'Python2.7', 'Java17', 'Pascal'], + 'submit_type' => ['bot'], ], 'luogu' => [ 'name' => '洛谷', 'short_name' => '洛谷', 'url' => 'https://www.luogu.com.cn', - 'languages' => [], + 'languages' => ['C', 'C++98', 'C++11', 'C++', 'C++17', 'C++20', 'Python3', 'Java8', 'Pascal'], + 'submit_type' => ['my'], ], ]; @@ -460,15 +465,6 @@ class UOJRemoteProblem { public static function getSubmissionRequirements($oj) { $remote_provider = UOJRemoteProblem::$providers[$oj]; - if ($oj == 'luogu') { - return [ - [ - "name" => "luogu", - "type" => "remote submission", - ] - ]; - } - return [ [ "name" => "answer", diff --git a/web/app/models/UOJSubmission.php b/web/app/models/UOJSubmission.php index ad9f20f..6ae9327 100644 --- a/web/app/models/UOJSubmission.php +++ b/web/app/models/UOJSubmission.php @@ -89,8 +89,7 @@ class UOJSubmission { $content['config'][] = ['problem_id', UOJProblem::info('id')]; if (UOJProblem::info('type') == 'remote') { - $remote_online_judge = UOJProblem::cur()->getExtraConfig('remote_online_judge'); - $content['config'][] = ['remote_online_judge', $remote_online_judge]; + $content['config'][] = ['remote_online_judge', UOJProblem::cur()->getExtraConfig('remote_online_judge')]; $content['config'][] = ['remote_problem_id', UOJProblem::cur()->getExtraConfig('remote_problem_id')]; } diff --git a/web/app/models/UOJSubmissionLikeTrait.php b/web/app/models/UOJSubmissionLikeTrait.php index c4126eb..5166ff6 100644 --- a/web/app/models/UOJSubmissionLikeTrait.php +++ b/web/app/models/UOJSubmissionLikeTrait.php @@ -210,24 +210,6 @@ trait UOJSubmissionLikeTrait { EOD; - } else if ($req['type'] == "remote submission") { - $remote_provider = UOJRemoteProblem::$providers[$req['name']]; - $content = ''; - - if ($req['name'] == 'luogu') { - $content .= HTML::tag('div', [], [ - '远端评测 ID:', - HTML::tag( - 'a', - [ - 'href' => "{$remote_provider['url']}/record/{$config['luogu_submission_id']}" - ], - 'R' . $config['luogu_submission_id'] - ), - ]); - } - - HTML::echoPanel('mb-3', '远端评测记录', $content); } } $zip_file->close(); diff --git a/web/js/uoj.js b/web/js/uoj.js index 41bf66a..652b357 100644 --- a/web/js/uoj.js +++ b/web/js/uoj.js @@ -947,6 +947,108 @@ $.fn.text_file_form_group = function(name, text) { }); } +// remote judge submit type group +$.fn.remote_submit_type_group = function(oj, pid, url, submit_type) { + return this.each(function() { + var input_submit_type_bot_id = 'input-submit_type_bot'; + var input_submit_type_my_id = 'input-submit_type_my'; + var div_submit_type_bot_id = 'div-submit_type_bot'; + var div_submit_type_my_id = 'div-submit_type_my'; + + var input_submit_type_bot = $(''); + var input_submit_type_my = $(''); + var input_my_account_data = $(''); + + var div_submit_type_bot = $('
') + .append('
将使用公用账号提交本题。
'); + var div_submit_type_my = $('
') + .append('
将使用您的账号提交本题。
'); + + input_submit_type_bot.click(function() { + div_submit_type_my.hide('fast'); + div_submit_type_bot.show('fast'); + }); + input_submit_type_my.click(function() { + div_submit_type_bot.hide('fast'); + div_submit_type_my.show('fast'); + }); + + if (submit_type[0] == 'bot') { + div_submit_type_my.hide(); + input_submit_type_bot[0].checked = true; + } else if (submit_type[0] == 'my') { + div_submit_type_bot.hide(); + input_submit_type_my[0].checked = true; + } + + if (submit_type.indexOf('bot') == -1) { + input_submit_type_bot.attr('disabled', 'disabled'); + } + if (submit_type.indexOf('my') == -1) { + input_submit_type_my.attr('disabled', 'disabled'); + } + + if (oj == 'luogu') { + var luogu_account_data = {"_uid": "", "__clientid": ""}; + var input_luogu_uid = $(''); + var input_luogu_clientid = $(''); + + if ('localStorage' in window) { + try { + var luogu_account_data_str = localStorage.getItem('uoj_remote_judge_luogu_account_data'); + if (luogu_account_data_str) { + luogu_account_data = JSON.parse(luogu_account_data_str); + } + } catch (e) {} + + var save_luogu_account_data = function() { + localStorage.setItem('uoj_remote_judge_luogu_account_data', JSON.stringify(luogu_account_data)); + } + } else { + var save_luogu_account_data = function() {}; + } + + input_luogu_uid.change(function() { + luogu_account_data._uid = $(this).val(); + input_my_account_data.val(JSON.stringify(luogu_account_data)); + save_luogu_account_data(); + }); + + input_luogu_clientid.change(function() { + luogu_account_data.__clientid = $(this).val(); + input_my_account_data.val(JSON.stringify(luogu_account_data)); + save_luogu_account_data(); + }); + + input_my_account_data.val(JSON.stringify(luogu_account_data)); + + div_submit_type_my.append( + $('
') + .append($('
').append('')) + .append($('
').append(input_luogu_uid)) + .append($('
').append($('
').append('请填入 Cookie 中的 _uid。'))) + ).append( + $('
') + .append($('
').append('')) + .append($('
').append(input_luogu_clientid)) + .append($('
').append($('
').append('请填入 Cookie 中的 __clientid。'))) + ).append(input_my_account_data); + } + + $(this).append( + $('
').append( + $('
') + .append(input_submit_type_bot) + .append($('