From fe0cd78db7982cb04a6d3583d14a09aad0717495 Mon Sep 17 00:00:00 2001 From: panda Date: Mon, 5 Sep 2022 19:51:43 +0800 Subject: [PATCH] fix hack rejudge & rejudge all --- packages/hydrojudge/src/flow.ts | 15 +++++++++------ packages/hydrooj/src/handler/judge.ts | 2 +- packages/hydrooj/src/handler/problem.ts | 6 +++++- packages/hydrooj/src/handler/record.ts | 5 ++++- packages/ui-default/templates/record_main_tr.html | 2 +- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/hydrojudge/src/flow.ts b/packages/hydrojudge/src/flow.ts index 7c93bc4cd..c6771cb50 100644 --- a/packages/hydrojudge/src/flow.ts +++ b/packages/hydrojudge/src/flow.ts @@ -80,22 +80,25 @@ export const runFlow = async (ctx: Context, task: Task) => { ctx.queue = new Queue({ concurrency: getConfig('singleTaskParallelism') }); ctx.failed = {}; if (ctx.meta.hackRejudge) { - const subtask = ctx.config.subtasks.find((i) => i.cases.find((j) => j.input === ctx.meta.hackRejudge)); + const subtask = ctx.config.subtasks.find((i) => i.cases.find((j) => j.input.endsWith(ctx.meta.hackRejudge))); const ctxSubtask = { subtask, status: STATUS.STATUS_ACCEPTED, score: subtask.type === 'min' ? subtask.score : 0, }; - const runner = task.judgeCase(subtask.cases.find((i) => i.input === ctx.meta.hackRejudge)); + const runner = task.judgeCase(subtask.cases.find((i) => i.input.endsWith(ctx.meta.hackRejudge))); const res = await runner(ctx, ctxSubtask, runner); - if (res) ctx.next({ case: res }); - const totalScore = Math.sum(ctx.config.subtasks.map((i) => i.score)); - if (ctxSubtask.status !== STATUS.STATUS_ACCEPTED) { + if (res) ctx.next(res); + if (res.status !== STATUS.STATUS_ACCEPTED) { + const totalScore = Math.sum(ctx.config.subtasks.map((i) => i.score)); ctx.end({ status: STATUS.STATUS_HACKED, score: totalScore - subtask.score, }); - } else ctx.end({ nop: true }); + } else { + ctx.next({ status: STATUS.STATUS_ACCEPTED }); + ctx.end({ nop: true }); + } } else { const tasks = []; for (const sid in ctx.config.subtasks) tasks.push(judgeSubtask(ctx.config.subtasks[sid], sid, task.judgeCase)(ctx)); diff --git a/packages/hydrooj/src/handler/judge.ts b/packages/hydrooj/src/handler/judge.ts index 472b70583..ffabe20dc 100644 --- a/packages/hydrooj/src/handler/judge.ts +++ b/packages/hydrooj/src/handler/judge.ts @@ -103,7 +103,7 @@ export async function postJudge(rdoc: RecordDoc) { }).project({ _id: 1, contest: 1 }).toArray(); const priority = await record.submissionPriority(this.user._id, -rdocs.length * 5 - 50); await Promise.all(rdocs.map( - (r) => record.judge(r.domainId, r._id, priority, r.contest ? { detail: false } : {}, { hackRejudge: input }), + (r) => record.judge(rdoc.domainId, r._id, priority, r.contest ? { detail: false } : {}, { hackRejudge: input }), )); } catch (e) { next({ diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index 5dc6882ff..0aa7cd9c1 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -431,7 +431,11 @@ export class ProblemDetailHandler extends ContestDetailBaseHandler { async postRejudge(domainId: string, pid: number) { this.checkPerm(PERM.PERM_REJUDGE_PROBLEM); // TODO maybe async? - const rdocs = await record.getMulti(domainId, { pid, contest: { $ne: new ObjectID('0'.repeat(24)) } }) + const rdocs = await record.getMulti(domainId, { + pid, + contest: { $ne: new ObjectID('0'.repeat(24)) }, + status: { $ne: [STATUS.STATUS_HACK_SUCCESSFUL, STATUS.STATUS_HACK_UNSUCCESSFUL] }, + }) .project({ _id: 1, contest: 1 }).toArray(); const priority = await record.submissionPriority(this.user._id, -rdocs.length * 5 - 50); await Promise.all(rdocs.map( diff --git a/packages/hydrooj/src/handler/record.ts b/packages/hydrooj/src/handler/record.ts index 6f1cd07e5..ce0d33e3f 100644 --- a/packages/hydrooj/src/handler/record.ts +++ b/packages/hydrooj/src/handler/record.ts @@ -1,7 +1,7 @@ import { debounce, omit } from 'lodash'; import { FilterQuery, ObjectID } from 'mongodb'; import { - ContestNotAttendedError, ContestNotFoundError, PermissionError, + ContestNotAttendedError, ContestNotFoundError, ForbiddenError, PermissionError, ProblemNotFoundError, RecordNotFoundError, UserNotFoundError, } from '../error'; import { RecordDoc, Tdoc } from '../interface'; @@ -173,6 +173,9 @@ class RecordDetailHandler extends Handler { @param('rid', Types.ObjectID) async postRejudge(domainId: string, rid: ObjectID) { this.checkPerm(PERM.PERM_REJUDGE); + if ([STATUS.STATUS_HACK_SUCCESSFUL, STATUS.STATUS_HACK_UNSUCCESSFUL].find((i) => i === this.rdoc.status)) { + throw new ForbiddenError('Cannot rejudge hack record.'); + } const priority = await record.submissionPriority(this.user._id, -20); const isContest = this.rdoc.contest && this.rdoc.contest.toString() !== '000000000000000000000000'; await record.reset(domainId, rid, true); diff --git a/packages/ui-default/templates/record_main_tr.html b/packages/ui-default/templates/record_main_tr.html index f699de6f1..08be4847c 100644 --- a/packages/ui-default/templates/record_main_tr.html +++ b/packages/ui-default/templates/record_main_tr.html @@ -3,7 +3,7 @@ {{ record.render_status_td(rdoc, allDomain = all) }} - {% if handler.user.hasPerm(perm.PERM_REJUDGE) %} + {% if handler.user.hasPerm(perm.PERM_REJUDGE) and rdoc['status'] == STATUS.STATUS_HACK_SUCCESSFUL and rdoc['status'] == STATUS.STATUS_HACK_UNSUCCESSFUL %}