userCanManage(Auth::user()) || UOJResponse::page403(); UOJProblem::info('type') === 'local' || UOJResponse::page404(); $tabs_info = [ 'statement' => [ 'name' => '题面', 'url' => UOJProblem::cur()->getUri('/manage/statement'), ], 'permissions' => [ 'name' => '权限', 'url' => UOJProblem::cur()->getUri('/manage/permissions'), ], 'data' => [ 'name' => '数据', 'url' => UOJProblem::cur()->getUri('/manage/data'), ], ]; $problem = UOJProblem::info(); $problem_extra_config = UOJProblem::cur()->getExtraConfig(); $data_dir = "/var/uoj_data/{$problem['id']}"; function echoFileNotFound($file_name) { echo '
', htmlspecialchars($file_name), '
'; echo '
', '文件未找到', '
'; } function echoFilePre($file_name) { global $data_dir; $file_full_name = $data_dir . '/' . $file_name; $finfo = finfo_open(FILEINFO_MIME); $mimetype = finfo_file($finfo, $file_full_name); if ($mimetype === false) { echoFileNotFound($file_name); return; } finfo_close($finfo); echo '
', htmlspecialchars($file_name), '
'; echo '
', $mimetype, '
'; echo '
', "\n";

	$output_limit = 1000;
	if (strStartWith($mimetype, 'text/')) {
		echo htmlspecialchars(uojFilePreview($file_full_name, $output_limit));
	} else {
		echo htmlspecialchars(uojFilePreview($file_full_name, $output_limit, 'binary'));
	}
	echo "\n
"; } // 上传数据 if ($_POST['problem_data_file_submit'] == 'submit') { if ($_FILES["problem_data_file"]["error"] > 0) { $errmsg = "Error: " . $_FILES["problem_data_file"]["error"]; becomeMsgPage('
' . $errmsg . '
返回'); } else { $zip_mime_types = array('application/zip', 'application/x-zip', 'application/x-zip-compressed'); if (in_array($_FILES["problem_data_file"]["type"], $zip_mime_types) || $_FILES["problem_data_file"]["type"] == 'application/octet-stream' && substr($_FILES["problem_data_file"]["name"], -4) == '.zip') { $up_filename = "/tmp/" . rand(0, 100000000) . "data.zip"; move_uploaded_file($_FILES["problem_data_file"]["tmp_name"], $up_filename); $zip = new ZipArchive; if ($zip->open($up_filename) === TRUE) { $zip->extractTo("/var/uoj_data/upload/{$problem['id']}"); $zip->close(); exec("cd /var/uoj_data/upload/{$problem['id']}; if [ -z \"`find . -maxdepth 1 -type f`\" ]; then for sub_dir in `find -maxdepth 1 -type d ! -name .`; do mv -f \$sub_dir/* . && rm -rf \$sub_dir; done; fi"); echo ""; } else { $errmsg = "解压失败!"; becomeMsgPage('
' . $errmsg . '
返回'); } unlink($up_filename); } else { $errmsg = "请上传zip格式!"; becomeMsgPage('
' . $errmsg . '
返回'); } } } $info_form = new UOJForm('info'); $attachment_url = UOJProblem::cur()->getAttachmentUri(); $info_form->appendHTML(<<
EOD); $download_url = UOJProblem::cur()->getMainDataUri(); $info_form->appendHTML(<< EOD); $info_form->appendHTML(<< EOD); $esc_submission_requirement = HTML::escape(json_encode(json_decode($problem['submission_requirement']), JSON_PRETTY_PRINT)); $info_form->appendHTML(<<
$esc_submission_requirement
EOD); $esc_extra_config = HTML::escape(json_encode(json_decode($problem['extra_config']), JSON_PRETTY_PRINT)); $info_form->appendHTML(<<
$esc_extra_config
EOD); if (isSuperUser(Auth::user())) { $info_form->addTextArea('submission_requirement', [ 'label' => '提交文件配置', 'input_class' => 'form-control font-monospace', 'default_value' => $problem['submission_requirement'], 'validator_php' => function ($submission_requirement, &$vdata) { $submission_requirement = json_decode($submission_requirement, true); if ($submission_requirement === null) { return '不是合法的JSON'; } $vdata['submission_requirement'] = json_encode($submission_requirement); }, ]); $info_form->addTextArea('extra_config', [ 'label' => '其他配置', 'input_class' => 'form-control font-monospace', 'default_value' => $problem['extra_config'], 'validator_php' => function ($extra_config, &$vdata) { $extra_config = json_decode($extra_config, true); if ($extra_config === null) { return '不是合法的JSON'; } $vdata['extra_config'] = json_encode($extra_config, JSON_FORCE_OBJECT); }, ]); $info_form->handle = function (&$vdata) use ($problem) { DB::update([ "update problems", "set", [ "submission_requirement" => $vdata['submission_requirement'], "extra_config" => $vdata['extra_config'], ], "where", [ "id" => $problem['id'], ] ]); }; } else { $info_form->config['no_submit'] = true; } $info_form->runAtServer(); function displayProblemConf(UOJProblemDataDisplayer $self) { global $info_form; $info_form->printHTML(); echo '
'; $self->echoProblemConfTable(); $self->echoFilePre('problem.conf'); } function addTestsTab(UOJProblemDataDisplayer $disp, UOJProblemConf $problem_conf) { $n_tests = $problem_conf->getVal('n_tests', 10); if (!validateUInt($n_tests)) { $disp->setProblemConfRowStatus('n_tests', 'danger'); return false; } $inputs = []; $outputs = []; for ($num = 1; $num <= $n_tests; $num++) { $inputs[$num] = $problem_conf->getInputFileName($num); $outputs[$num] = $problem_conf->getOutputFileName($num); unset($disp->rest_data_files[$inputs[$num]]); unset($disp->rest_data_files[$outputs[$num]]); } $disp->addTab('tests', function ($self) use ($inputs, $outputs, $n_tests) { for ($num = 1; $num <= $n_tests; $num++) { echo '
'; echo '
'; $self->echoFilePre($inputs[$num]); echo '
'; echo '
'; $self->echoFilePre($outputs[$num]); echo '
'; echo '
'; } }); return true; } function addExTestsTab(UOJProblemDataDisplayer $disp, UOJProblemConf $problem_conf) { $has_extra_tests = $problem_conf->getNonTraditionalJudgeType() != 'submit_answer'; if (!$has_extra_tests) { return false; } $n_ex_tests = $problem_conf->getVal('n_ex_tests', 0); if (!validateUInt($n_ex_tests)) { $disp->setProblemConfRowStatus('n_ex_tests', 'danger'); return false; } if ($n_ex_tests == 0) { return false; } $inputs = []; $outputs = []; for ($num = 1; $num <= $n_ex_tests; $num++) { $inputs[$num] = $problem_conf->getExtraInputFileName($num); $outputs[$num] = $problem_conf->getExtraOutputFileName($num); unset($disp->rest_data_files[$inputs[$num]]); unset($disp->rest_data_files[$outputs[$num]]); } $disp->addTab('extra tests', function ($self) use ($inputs, $outputs, $n_ex_tests) { for ($num = 1; $num <= $n_ex_tests; $num++) { echo '
'; echo '
'; $self->echoFilePre($inputs[$num]); echo '
'; echo '
'; $self->echoFilePre($outputs[$num]); echo '
'; echo '
'; } }); return true; } function addSrcTab(UOJProblemDataDisplayer $disp, $tab_name, string $name) { $src = UOJLang::findSourceCode($name, '', [$disp, 'isFile']); if ($src !== false) { unset($disp->rest_data_files[$src['path']]); } unset($disp->rest_data_files[$name]); $disp->addTab($tab_name, function ($self) use ($name, $src) { if ($src !== false) { $self->echoFilePre($src['path']); } $self->echoFilePre($name); }); return true; } function getDataDisplayer() { $disp = new UOJProblemDataDisplayer(UOJProblem::cur()); $problem_conf = UOJProblem::cur()->getProblemConf(); if ($problem_conf === -1) { return $disp->addTab('problem.conf', function ($self) { global $info_form; $info_form->printHTML(); echo '
'; $self->echoFileNotFound('problem.conf'); }); } elseif ($problem_conf === -2) { return $disp->addTab('problem.conf', function ($self) { global $info_form; $info_form->printHTML(); echo '
'; echo '
problem.conf 文件格式有误
'; $self->echoFilePre('problem.conf'); }); } $disp->setProblemConf($problem_conf->conf); unset($disp->rest_data_files['problem.conf']); unset($disp->rest_data_files['download.zip']); $disp->addTab('problem.conf', 'displayProblemConf'); addTestsTab($disp, $problem_conf); addExTestsTab($disp, $problem_conf); $judger_name = $problem_conf->getVal('use_builtin_judger', null); if ($judger_name === null) { return $disp; } elseif ($judger_name === 'on') { if ($problem_conf->isOn('interaction_mode')) { if ($problem_conf->getVal('use_builtin_checker', null)) { $disp->addTab('checker', function ($self) { echo '

use builtin checker: ', $self->problem_conf['use_builtin_checker']['val'], '

'; }); } else { addSrcTab($disp, 'checker', 'chk'); } } if (UOJProblem::info('hackable')) { addSrcTab($disp, 'standard', 'std'); addSrcTab($disp, 'validator', 'val'); } if ($problem_conf->isOn('interaction_mode')) { addSrcTab($disp, 'interactor', 'interactor'); } return $disp; } else { return $disp->setProblemConfRowStatus('use_builtin_judger', 'danger'); } } $data_disp = getDataDisplayer(); if (isset($_GET['display_file'])) { if (!isset($_GET['file_name'])) { echoFileNotFound(''); } else { $data_disp->displayFile($_GET['file_name']); } die(); } $hackable_form = new UOJForm('hackable'); $hackable_form->handle = function () use ($problem) { $problem['hackable'] = !$problem['hackable']; $ret = dataSyncProblemData($problem); if ($ret) { becomeMsgPage('
' . $ret . '
返回'); } $hackable = $problem['hackable'] ? 1 : 0; DB::update([ "update problems", "set", ["hackable" => $hackable], "where", ["id" => $problem['id']] ]); }; $hackable_form->config['submit_container']['class'] = ''; $hackable_form->config['submit_button']['class'] = 'btn btn-warning d-block w-100'; $hackable_form->config['submit_button']['text'] = $problem['hackable'] ? '禁用 Hack 功能' : '启用 Hack 功能'; $hackable_form->config['confirm']['smart'] = true; $hackable_form->runAtServer(); $data_form = new UOJForm('data'); $data_form->handle = function () use ($problem) { set_time_limit(60 * 5); $ret = dataSyncProblemData($problem, Auth::user()); if ($ret) { becomeMsgPage('
' . $ret . '
返回'); } }; $data_form->config['submit_container']['class'] = ''; $data_form->config['submit_button']['class'] = 'btn btn-danger d-block w-100'; $data_form->config['submit_button']['text'] = '检验配置并同步数据'; $data_form->config['confirm']['smart'] = true; $data_form->runAtServer(); $clear_data_form = new UOJForm('clear_data'); $clear_data_form->handle = function () { dataClearProblemData(UOJProblem::cur()); }; $clear_data_form->config['submit_container']['class'] = ''; $clear_data_form->config['submit_button']['class'] = 'btn btn-danger d-block w-100'; $clear_data_form->config['submit_button']['text'] = '清空题目数据'; $clear_data_form->config['confirm']['smart'] = true; $clear_data_form->runAtServer(); $rejudge_form = new UOJForm('rejudge'); $rejudge_form->handle = function () { UOJSubmission::rejudgeProblem(UOJProblem::cur()); }; $rejudge_form->succ_href = "/submissions?problem_id={$problem['id']}"; $rejudge_form->config['submit_container']['class'] = ''; $rejudge_form->config['submit_button']['class'] = 'btn btn-danger d-block w-100'; $rejudge_form->config['submit_button']['text'] = '重测该题'; $rejudge_form->config['confirm']['smart'] = true; $rejudge_form->runAtServer(); $rejudgege97_form = new UOJForm('rejudgege97'); $rejudgege97_form->handle = function () { UOJSubmission::rejudgeProblemGe97(UOJProblem::cur()); }; $rejudgege97_form->succ_href = "/submissions?problem_id={$problem['id']}"; $rejudgege97_form->config['submit_container']['class'] = ''; $rejudgege97_form->config['submit_button']['class'] = 'btn btn-danger d-block w-100'; $rejudgege97_form->config['submit_button']['text'] = '重测 >=97 的程序'; $rejudgege97_form->config['confirm']['smart'] = true; $rejudgege97_form->runAtServer(); if ($problem['hackable']) { $test_std_form = new UOJForm('test_std'); $test_std_form->handle = function () use ($problem, $data_disp) { $user_std = UOJUser::query('std'); if (!$user_std) { UOJResponse::message('Please create an user named "std"'); } $requirement = json_decode($problem['submission_requirement'], true); $src_std = UOJLang::findSourceCode('std', '', [$data_disp, 'isFile']); if ($src_std === false) { UOJResponse::message('未找到 std!'); } $zip_file_name = FS::randomAvailableSubmissionFileName(); $zip_file = new ZipArchive(); if ($zip_file->open(UOJContext::storagePath() . $zip_file_name, ZipArchive::CREATE) !== true) { UOJResponse::message('提交失败'); } $content = []; $content['file_name'] = $zip_file_name; $content['config'] = []; $tot_size = 0; foreach ($requirement as $req) { if ($req['type'] == "source code") { $content['config'][] = ["{$req['name']}_language", $src_std['lang']]; if ($zip_file->addFromString($req['file_name'], $data_disp->getFile($src_std['path'])) === false) { $zip_file->close(); unlink(UOJContext::storagePath() . $zip_file_name); UOJResponse::message('提交失败'); } $tot_size += $zip_file->statName($req['file_name'])['size']; } } $zip_file->close(); $content['config'][] = ['validate_input_before_test', 'on']; $content['config'][] = ['problem_id', $problem['id']]; $esc_content = json_encode($content); $result = []; $result['status'] = "Waiting"; $result_json = json_encode($result); $is_hidden = $problem['is_hidden'] ? 1 : 0; DB::insert([ "insert into submissions", "(problem_id, submit_time, submitter, content, language, tot_size, status, result, is_hidden)", "values", DB::tuple([ $problem['id'], DB::now(), $user_std['username'], $esc_content, $src_std['lang'], $tot_size, $result['status'], $result_json, $is_hidden ]) ]); }; $test_std_form->succ_href = "/submissions?problem_id={$problem['id']}"; $test_std_form->config['submit_container']['class'] = ''; $test_std_form->config['submit_button']['class'] = 'btn btn-warning d-block w-100'; $test_std_form->config['submit_button']['text'] = '检验数据正确性'; $test_std_form->runAtServer(); } ?> getTitle(['with' => 'id'])) ?>

getTitle(['with' => 'id']) ?> 管理

displayFile('problem.conf'); ?>