diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index adef8cb18..ba4860375 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.33.9", + "version": "2.33.10", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", diff --git a/packages/hydrooj/src/handler/homework.ts b/packages/hydrooj/src/handler/homework.ts index 79029be7d..f8cdf7a3c 100644 --- a/packages/hydrooj/src/handler/homework.ts +++ b/packages/hydrooj/src/handler/homework.ts @@ -17,7 +17,7 @@ import { } from '../service/server'; import * as bus from '../service/bus'; import domain from '../model/domain'; -import { PERM, PRIV } from '../model/builtin'; +import { PERM, PRIV, STATUS } from '../model/builtin'; import user from '../model/user'; import * as system from '../model/system'; import * as contest from '../model/contest'; @@ -265,7 +265,7 @@ class HomeworkDetailProblemSubmitHandler extends HomeworkDetailProblemHandler { && problem.inc(this.pdomainId, this.ppid, 'nSubmit', 1), domain.incUserInDomain(domainId, this.user._id, 'nSubmit'), contest.updateStatus(domainId, tid, this.user._id, - rid, pid, false, 0, document.TYPE_HOMEWORK), + rid, pid, STATUS.STATUS_WAITING, 0, document.TYPE_HOMEWORK), ]); } bus.broadcast('record/change', rdoc); diff --git a/packages/hydrooj/src/handler/judge.ts b/packages/hydrooj/src/handler/judge.ts index 56d1ac083..ada873303 100644 --- a/packages/hydrooj/src/handler/judge.ts +++ b/packages/hydrooj/src/handler/judge.ts @@ -28,7 +28,7 @@ export async function postJudge(rdoc: RecordDoc) { await contest.updateStatus( rdoc.domainId, rdoc.contest.tid, rdoc.uid, rdoc._id, rdoc.domainId === rdoc.pdomain ? rdoc.pid : `${rdoc.pdomain}:${rdoc.pid}`, - accept, rdoc.score, rdoc.contest.type, + rdoc.status, rdoc.score, rdoc.contest.type, ); } else if (accept && updated) await domain.incUserInDomain(rdoc.domainId, rdoc.uid, 'nAccept', 1); const pdoc = (accept && updated) diff --git a/packages/hydrooj/src/model/contest.ts b/packages/hydrooj/src/model/contest.ts index 777e31aaa..6f2ffc3f7 100644 --- a/packages/hydrooj/src/model/contest.ts +++ b/packages/hydrooj/src/model/contest.ts @@ -2,7 +2,7 @@ import { ObjectID, FilterQuery } from 'mongodb'; import user from './user'; import problem from './problem'; import * as document from './document'; -import { PERM } from './builtin'; +import { PERM, STATUS } from './builtin'; import { ValidationError, ContestNotFoundError, ContestAlreadyAttendedError, ContestNotAttendedError, ContestScoreboardHiddenError, @@ -18,6 +18,19 @@ import ranked from '../lib/rank'; type Type = 30 | 60; +interface AcmJournal { + rid: ObjectID; + pid: ProblemId; + score: number; + status: number; + time: number; +} +interface AcmDetail extends AcmJournal { + naccept?: number; + penalty: number; + real: number; +} + const acm: ContestRule = { TEXT: 'ACM/ICPC', check: () => { }, @@ -25,17 +38,19 @@ const acm: ContestRule = { showScoreboard: () => true, showSelfRecord: () => true, showRecord: (tdoc, now) => now > tdoc.endAt, - stat: (tdoc, journal) => { - const naccept = {}; - const effective = {}; - const detail = []; + stat: (tdoc, journal: AcmJournal[]) => { + const naccept: Record = {}; + const effective: Record = {}; + const detail: AcmDetail[] = []; let accept = 0; let time = 0; for (const j of journal) { if (tdoc.pids.includes(j.pid) && !(effective[j.pid] && effective[j.pid].accept)) { effective[j.pid] = j; - if (!j.accept) naccept[j.pid] = (naccept[j.pid] || 0) + 1; + if (![STATUS.STATUS_ACCEPTED, STATUS.STATUS_COMPILE_ERROR].includes(j.status)) { + naccept[j.pid] = (naccept[j.pid] || 0) + 1; + } } } for (const key in effective) { @@ -47,8 +62,8 @@ const acm: ContestRule = { }); } for (const d of detail) { - if (d.accept) { - accept += d.accept; + if (d.status === STATUS.STATUS_ACCEPTED) { + accept += 1; time += d.time; } } @@ -488,7 +503,7 @@ export function getStatus( export async function updateStatus( domainId: string, tid: ObjectID, uid: number, rid: ObjectID, pid: ProblemId, - accept = false, score = 0, type: 30 | 60 = document.TYPE_CONTEST, + status = STATUS.STATUS_WRONG_ANSWER, score = 0, type: 30 | 60 = document.TYPE_CONTEST, ) { const [tdoc, otsdoc] = await Promise.all([ get(domainId, tid, type), @@ -496,7 +511,7 @@ export async function updateStatus( ]); if (!otsdoc.attend) throw new ContestNotAttendedError(tid, uid); const tsdoc = await document.revPushStatus(domainId, type, tid, uid, 'journal', { - rid, pid, accept, score, + rid, pid, status, score, }, 'rid'); const journal = _getStatusJournal(tsdoc); const stats = RULES[tdoc.rule].stat(tdoc, journal); diff --git a/packages/hydrooj/src/upgrade.ts b/packages/hydrooj/src/upgrade.ts index 9040da754..324f0055e 100644 --- a/packages/hydrooj/src/upgrade.ts +++ b/packages/hydrooj/src/upgrade.ts @@ -20,11 +20,12 @@ import db from './service/db'; import difficultyAlgorithm from './lib/difficulty'; import problem from './model/problem'; import user from './model/user'; +import * as contest from './model/contest'; import * as discussion from './model/discussion'; import domain from './model/domain'; import * as document from './model/document'; import * as system from './model/system'; -import { PRIV } from './model/builtin'; +import { PRIV, STATUS } from './model/builtin'; import RecordModel from './model/record'; import StorageModel from './model/storage'; import { size } from './lib/misc'; @@ -470,6 +471,28 @@ const scripts: UpgradeScript[] = [ }); return true; }, + async function _42_43() { + const _FRESH_INSTALL_IGNORE = 1; + const processer = (i) => { + i.status = i.accept ? STATUS.STATUS_ACCEPTED : STATUS.STATUS_WRONG_ANSWER; + return i; + }; + await iterateAllDomain(async (ddoc) => { + const tdocs = await contest.getMulti(ddoc._id, { rule: 'acm' }).toArray(); + for (const tdoc of tdocs) { + const tsdocs = await contest.getMultiStatus(ddoc._id, { docId: tdoc.docId }).toArray(); + for (const tsdoc of tsdocs) { + const $set: any = {}; + if (tsdoc.journal?.length) $set.journal = tsdoc.journal.map(processer); + if (tsdoc.detail?.length) $set.detail = tsdoc.detail.map(processer); + if (Object.keys($set).length) { + await contest.setStatus(ddoc._id, tdoc.docId, tsdoc.uid, $set); + } + } + } + }); + return true; + }, ]; export default scripts; diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 07db897f7..a3eae3f63 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.18.6", + "version": "4.18.7", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/static/robots.txt b/packages/ui-default/static/robots.txt index 565fca24d..e093d7d8b 100644 --- a/packages/ui-default/static/robots.txt +++ b/packages/ui-default/static/robots.txt @@ -1,7 +1,18 @@ User-agent: * -Disallow: /p/*/submit -Disallow: /p/*/edit Disallow: /problem/ +Disallow: /record +Disallow: /d/*/record Disallow: /record/ -Disallow: /d/*/user/* +Disallow: /d/*/record/ Disallow: /manage/ +Disallow: /domain/ +Disallow: /d/*/domain/ +Disallow: /d/*/user/* +Disallow: /p/*/submit +Disallow: /d/*/p/*/submit +Disallow: /p/*/edit +Disallow: /d/*/p/*/edit +Disallow: /p/*/files +Disallow: /d/*/p/*/files +Disallow: /p/*/file/* +Disallow: /d/*/p/*/file/*