mirror of
https://github.com/renbaoshuo/UOJ-Luogu-RemoteJudge.git
synced 2024-12-05 01:46:28 +00:00
227 lines
8.4 KiB
PHP
227 lines
8.4 KiB
PHP
<?php
|
|
requirePHPLib('judger');
|
|
requirePHPLib('data');
|
|
|
|
if (!authenticateJudger()) {
|
|
become404Page();
|
|
}
|
|
|
|
function submissionJudged() {
|
|
$submission = DB::selectFirst("select submitter, status, content, result, problem_id from submissions where id = {$_POST['id']}");
|
|
if ($submission == null) {
|
|
return;
|
|
}
|
|
if ($submission['status'] != 'Judging' && $submission['status'] != 'Judged, Judging') {
|
|
return;
|
|
}
|
|
$content = json_decode($submission['content'], true);
|
|
|
|
if (isset($content['first_test_config'])) {
|
|
$result = json_decode($submission['result'], true);
|
|
$result['final_result'] = json_decode($_POST['result'], true);
|
|
$result['final_result']['details'] = uojTextEncode($result['final_result']['details']);
|
|
$esc_result = DB::escape(json_encode($result, JSON_UNESCAPED_UNICODE));
|
|
|
|
$content['final_test_config'] = $content['config'];
|
|
$content['config'] = $content['first_test_config'];
|
|
unset($content['first_test_config']);
|
|
$esc_content = DB::escape(json_encode($content));
|
|
|
|
DB::update("update submissions set status = 'Judged', result = '$esc_result', content = '$esc_content' where id = {$_POST['id']}");
|
|
} else {
|
|
$result = json_decode($_POST['result'], true);
|
|
$result['details'] = uojTextEncode($result['details']);
|
|
$esc_result = DB::escape(json_encode($result, JSON_UNESCAPED_UNICODE));
|
|
if (isset($result["error"])) {
|
|
DB::update("update submissions set status = '{$result['status']}', result_error = '{$result['error']}', result = '$esc_result', score = null, used_time = null, used_memory = null where id = {$_POST['id']}");
|
|
} else {
|
|
DB::update("update submissions set status = '{$result['status']}', result_error = null, result = '$esc_result', score = {$result['score']}, used_time = {$result['time']}, used_memory = {$result['memory']} where id = {$_POST['id']}");
|
|
}
|
|
|
|
if (isset($content['final_test_config'])) {
|
|
$content['first_test_config'] = $content['config'];
|
|
$content['config'] = $content['final_test_config'];
|
|
unset($content['final_test_config']);
|
|
$esc_content = DB::escape(json_encode($content));
|
|
|
|
DB::update("update submissions set status = 'Judged, Waiting', content = '$esc_content' where id = ${_POST['id']}");
|
|
}
|
|
}
|
|
DB::update("update submissions set status_details = '' where id = {$_POST['id']}");
|
|
updateBestACSubmissions($submission['submitter'], $submission['problem_id']);
|
|
}
|
|
|
|
function customTestSubmissionJudged() {
|
|
$submission = DB::selectFirst("select submitter, status, content, result, problem_id from custom_test_submissions where id = {$_POST['id']}");
|
|
if ($submission == null) {
|
|
return;
|
|
}
|
|
if ($submission['status'] != 'Judging') {
|
|
return;
|
|
}
|
|
$content = json_decode($submission['content'], true);
|
|
$result = json_decode($_POST['result'], true);
|
|
$result['details'] = uojTextEncode($result['details']);
|
|
$esc_result = DB::escape(json_encode($result, JSON_UNESCAPED_UNICODE));
|
|
if (isset($result["error"])) {
|
|
DB::update("update custom_test_submissions set status = '{$result['status']}', result = '$esc_result' where id = {$_POST['id']}");
|
|
} else {
|
|
DB::update("update custom_test_submissions set status = '{$result['status']}', result = '$esc_result' where id = {$_POST['id']}");
|
|
}
|
|
DB::update("update custom_test_submissions set status_details = '' where id = {$_POST['id']}");
|
|
}
|
|
|
|
function hackJudged() {
|
|
$result = json_decode($_POST['result'], true);
|
|
$esc_details = DB::escape(uojTextEncode($result['details']));
|
|
$ok = DB::update("update hacks set success = {$result['score']}, details = '$esc_details' where id = {$_POST['id']}");
|
|
|
|
if ($ok) {
|
|
list($hack_input) = DB::fetch(DB::query("select input from hacks where id = {$_POST['id']}"), MYSQLI_NUM);
|
|
unlink(UOJContext::storagePath().$hack_input);
|
|
|
|
if ($result['score']) {
|
|
list($problem_id) = DB::selectFirst("select problem_id from hacks where id = ${_POST['id']}", MYSQLI_NUM);
|
|
if (validateUploadedFile('hack_input') && validateUploadedFile('std_output')) {
|
|
dataAddExtraTest(queryProblemBrief($problem_id), $_FILES["hack_input"]["tmp_name"], $_FILES["std_output"]["tmp_name"]);
|
|
} else {
|
|
error_log("hack successfully but received no data. id: {$_POST['id']}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isset($_POST['submit'])) {
|
|
if (!validateUInt($_POST['id'])) {
|
|
die("Wow! hacker! T_T....");
|
|
}
|
|
if (isset($_POST['is_hack'])) {
|
|
hackJudged();
|
|
} elseif (isset($_POST['is_custom_test'])) {
|
|
customTestSubmissionJudged();
|
|
} else {
|
|
submissionJudged();
|
|
}
|
|
}
|
|
if (isset($_POST['update-status'])) {
|
|
if (!validateUInt($_POST['id'])) {
|
|
die("Wow! hacker! T_T....");
|
|
}
|
|
$esc_status_details = DB::escape($_POST['status']);
|
|
if (isset($_POST['is_custom_test'])) {
|
|
DB::update("update custom_test_submissions set status_details = '$esc_status_details' where id = {$_POST['id']}");
|
|
} else {
|
|
DB::update("update submissions set status_details = '$esc_status_details' where id = {$_POST['id']}");
|
|
}
|
|
die();
|
|
}
|
|
|
|
$problem_ban_list = array();
|
|
|
|
if ($_POST['judger_name'] == "luogu_remote_judger") {
|
|
$problem_ban_list = array_map(function ($x) { return $x['id']; }, DB::selectAll("select id from problems where type != 'luogu'"));
|
|
} else {
|
|
$problem_ban_list = array_map(function ($x) { return $x['id']; }, DB::selectAll("select id from problems where type != 'local'"));
|
|
}
|
|
|
|
$conds = " (true) ";
|
|
|
|
if (!empty($problem_ban_list)) {
|
|
$conds .= " and problem_id not in (" . implode(",", $problem_ban_list) . ") ";
|
|
}
|
|
|
|
$submission = null;
|
|
$hack = null;
|
|
function querySubmissionToJudge($status, $set_q) {
|
|
global $submission, $conds;
|
|
$submission = DB::selectFirst("select id, problem_id, content from submissions where status = '$status' and $conds order by id limit 1");
|
|
if ($submission) {
|
|
DB::update("update submissions set $set_q where id = {$submission['id']} and status = '$status'");
|
|
if (DB::affected_rows() != 1) {
|
|
$submission = null;
|
|
}
|
|
}
|
|
}
|
|
function queryCustomTestSubmissionToJudge() {
|
|
global $submission, $conds;
|
|
$submission = DB::selectFirst("select id, problem_id, content from custom_test_submissions where judge_time is null and $conds order by id limit 1");
|
|
if ($submission) {
|
|
DB::update("update custom_test_submissions set judge_time = now(), status = 'Judging' where id = {$submission['id']} and judge_time is null");
|
|
if (DB::affected_rows() != 1) {
|
|
$submission = null;
|
|
}
|
|
}
|
|
if ($submission) {
|
|
$submission['is_custom_test'] = '';
|
|
}
|
|
}
|
|
function queryHackToJudge() {
|
|
global $hack, $conds;
|
|
$hack = DB::selectFirst("select id, submission_id, input, input_type from hacks where judge_time is null and $conds order by id limit 1");
|
|
if ($hack) {
|
|
DB::update("update hacks set judge_time = now() where id = {$hack['id']} and judge_time is null");
|
|
if (DB::affected_rows() != 1) {
|
|
$hack = null;
|
|
}
|
|
}
|
|
}
|
|
function findSubmissionToJudge() {
|
|
global $submission, $hack;
|
|
querySubmissionToJudge('Waiting', "judge_time = now(), status = 'Judging'");
|
|
if ($submission) {
|
|
return true;
|
|
}
|
|
|
|
queryCustomTestSubmissionToJudge();
|
|
if ($submission) {
|
|
return true;
|
|
}
|
|
|
|
querySubmissionToJudge('Waiting Rejudge', "judge_time = now(), status = 'Judging'");
|
|
if ($submission) {
|
|
return true;
|
|
}
|
|
|
|
querySubmissionToJudge('Judged, Waiting', "status = 'Judged, Judging'");
|
|
if ($submission) {
|
|
return true;
|
|
}
|
|
|
|
queryHackToJudge();
|
|
if ($hack) {
|
|
$submission = DB::selectFirst("select id, problem_id, content from submissions where id = {$hack['submission_id']} and score = 100");
|
|
if (!$submission) {
|
|
$details = "<error>the score gained by the hacked submission is not 100.\n</error>";
|
|
$esc_details = DB::escape(uojTextEncode($details));
|
|
DB::update("update hacks set success = 0, details = '$esc_details' where id = {$hack['id']}");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
if (isset($_POST['fetch_new']) && !$_POST['fetch_new']) {
|
|
die("Nothing to judge");
|
|
}
|
|
if (!findSubmissionToJudge()) {
|
|
die("Nothing to judge");
|
|
}
|
|
|
|
$submission['id'] = (int)$submission['id'];
|
|
$submission['problem_id'] = (int)$submission['problem_id'];
|
|
$submission['problem_mtime'] = filemtime("/var/uoj_data/{$submission['problem_id']}");
|
|
$submission['content'] = json_decode($submission['content']);
|
|
|
|
if ($hack) {
|
|
$submission['is_hack'] = "";
|
|
$submission['hack']['id'] = (int)$hack['id'];
|
|
$submission['hack']['input'] = $hack['input'];
|
|
$submission['hack']['input_type'] = $hack['input_type'];
|
|
}
|
|
|
|
echo json_encode($submission);
|
|
?>
|