diff --git a/remote_judger/package-lock.json b/remote_judger/package-lock.json index 0e1e96d..d66645f 100644 --- a/remote_judger/package-lock.json +++ b/remote_judger/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "license": "AGPL-3.0", "dependencies": { + "crlf-normalize": "^1.0.18", "fs-extra": "^11.1.0", "jsdom": "^21.0.0", "math-sum": "^2.0.0", @@ -80,8 +81,7 @@ "node_modules/@types/node": { "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", - "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", - "dev": true + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==" }, "node_modules/@types/superagent": { "version": "4.1.16", @@ -230,6 +230,14 @@ "resolved": "https://registry.npmjs.org/cosmokit/-/cosmokit-1.4.0.tgz", "integrity": "sha512-9Y5epwkPxnWDSjweuWoFATY8GKg9N1/r/3wL32Cjs7FIvo0S9syyY39xmNKq7+SZjbw+9bZUSbeQSbJaqufV3Q==" }, + "node_modules/crlf-normalize": { + "version": "1.0.18", + "resolved": "https://registry.npmjs.org/crlf-normalize/-/crlf-normalize-1.0.18.tgz", + "integrity": "sha512-bBPJTekqhw/yUgHvHrOT2QBb6gJt/gNDx++GKkSYaBIepeEiLIezouV8xgDFTL3yRMpK7wOYC9a8xvY7bFQCLg==", + "dependencies": { + "ts-type": ">=2" + } + }, "node_modules/cssom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", @@ -1298,6 +1306,25 @@ "node": ">=12" } }, + "node_modules/ts-toolbelt": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", + "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", + "peer": true + }, + "node_modules/ts-type": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ts-type/-/ts-type-3.0.1.tgz", + "integrity": "sha512-cleRydCkBGBFQ4KAvLH0ARIkciduS745prkGVVxPGvcRGhMMoSJUB7gNR1ByKhFTEYrYRg2CsMRGYnqp+6op+g==", + "dependencies": { + "@types/node": "*", + "tslib": ">=2", + "typedarray-dts": "^1.0.0" + }, + "peerDependencies": { + "ts-toolbelt": "^9.6.0" + } + }, "node_modules/tslib": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", @@ -1314,6 +1341,11 @@ "node": ">= 0.8.0" } }, + "node_modules/typedarray-dts": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typedarray-dts/-/typedarray-dts-1.0.0.tgz", + "integrity": "sha512-Ka0DBegjuV9IPYFT1h0Qqk5U4pccebNIJCGl8C5uU7xtOs+jpJvKGAY4fHGK25hTmXZOEUl9Cnsg5cS6K/b5DA==" + }, "node_modules/typescript": { "version": "4.9.4", "dev": true, @@ -1538,8 +1570,7 @@ "@types/node": { "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", - "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", - "dev": true + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==" }, "@types/superagent": { "version": "4.1.16", @@ -1664,6 +1695,14 @@ "resolved": "https://registry.npmjs.org/cosmokit/-/cosmokit-1.4.0.tgz", "integrity": "sha512-9Y5epwkPxnWDSjweuWoFATY8GKg9N1/r/3wL32Cjs7FIvo0S9syyY39xmNKq7+SZjbw+9bZUSbeQSbJaqufV3Q==" }, + "crlf-normalize": { + "version": "1.0.18", + "resolved": "https://registry.npmjs.org/crlf-normalize/-/crlf-normalize-1.0.18.tgz", + "integrity": "sha512-bBPJTekqhw/yUgHvHrOT2QBb6gJt/gNDx++GKkSYaBIepeEiLIezouV8xgDFTL3yRMpK7wOYC9a8xvY7bFQCLg==", + "requires": { + "ts-type": ">=2" + } + }, "cssom": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", @@ -2470,6 +2509,22 @@ "punycode": "^2.1.1" } }, + "ts-toolbelt": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", + "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", + "peer": true + }, + "ts-type": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ts-type/-/ts-type-3.0.1.tgz", + "integrity": "sha512-cleRydCkBGBFQ4KAvLH0ARIkciduS745prkGVVxPGvcRGhMMoSJUB7gNR1ByKhFTEYrYRg2CsMRGYnqp+6op+g==", + "requires": { + "@types/node": "*", + "tslib": ">=2", + "typedarray-dts": "^1.0.0" + } + }, "tslib": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", @@ -2483,6 +2538,11 @@ "prelude-ls": "~1.1.2" } }, + "typedarray-dts": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typedarray-dts/-/typedarray-dts-1.0.0.tgz", + "integrity": "sha512-Ka0DBegjuV9IPYFT1h0Qqk5U4pccebNIJCGl8C5uU7xtOs+jpJvKGAY4fHGK25hTmXZOEUl9Cnsg5cS6K/b5DA==" + }, "typescript": { "version": "4.9.4", "dev": true diff --git a/remote_judger/package.json b/remote_judger/package.json index efde41f..86ff0e9 100644 --- a/remote_judger/package.json +++ b/remote_judger/package.json @@ -12,6 +12,7 @@ "license": "AGPL-3.0", "private": true, "dependencies": { + "crlf-normalize": "^1.0.18", "fs-extra": "^11.1.0", "jsdom": "^21.0.0", "math-sum": "^2.0.0", diff --git a/remote_judger/src/providers/codeforces.ts b/remote_judger/src/providers/codeforces.ts index c50b4a6..669621a 100644 --- a/remote_judger/src/providers/codeforces.ts +++ b/remote_judger/src/providers/codeforces.ts @@ -1,6 +1,7 @@ import { JSDOM } from 'jsdom'; import superagent from 'superagent'; import proxy from 'superagent-proxy'; +import { crlf, LF } from 'crlf-normalize'; import sleep from '../utils/sleep'; import mathSum from 'math-sum'; import { IBasicProvider, RemoteAccount, USER_AGENT } from '../interface'; @@ -313,9 +314,9 @@ export default class CodeforcesProvider implements IBasicProvider { if (body.compilationError === 'true') { return await end({ id, - error: 1, + error: true, status: 'Compile Error', - message: body['checkerStdoutAndStderr#1'], + message: crlf(body['checkerStdoutAndStderr#1'], LF), }); } const time = mathSum( @@ -331,16 +332,52 @@ export default class CodeforcesProvider implements IBasicProvider { ) / 1024; await next({ test_id: body.testCount }); if (body.waiting === 'true') continue; + + const testCount = +body.testCount; const status = VERDICT[ Object.keys(VERDICT).find(k => normalize(body.verdict).includes(k)) ]; + let tests: string[] = []; + + for (let i = 1; i <= testCount; i++) { + let test_info = ''; + let info_text = + VERDICT[ + Object.keys(VERDICT).find(k => + normalize(body[`verdict#${i}`]).includes(k) + ) + ]; + + test_info += ``; + + const parse = (id: string) => crlf(body[id], LF); + + test_info += `${parse(`input#${i}`)}\n`; + test_info += `${parse(`output#${i}`)}\n`; + test_info += `${parse(`answer#${i}`)}\n`; + test_info += `${parse(`checkerStdoutAndStderr#${i}`)}\n`; + + test_info += ''; + + tests.push(test_info); + } + + const details = + '
' + + `REMOTE_SUBMISSION_ID = ${id}\nVERDICT = ${status}` + + `${tests.join('\n')}` + + '
'; + return await end({ id, status, score: status === 'Accepted' ? 100 : 0, time, memory, + details, }); } } diff --git a/remote_judger/src/vjudge.ts b/remote_judger/src/vjudge.ts index 387053c..ce0035a 100644 --- a/remote_judger/src/vjudge.ts +++ b/remote_judger/src/vjudge.ts @@ -67,10 +67,11 @@ class AccountService { time: payload.time, memory: payload.memory, details: + payload.details || '
' + - `ID = ${payload.id || 'None'}` + - `VERDICT = ${payload.status}` + - '
', + `ID = ${payload.id || 'None'}` + + `VERDICT = ${payload.status}` + + '', }), judge_time, }); diff --git a/web/app/libs/uoj-html-lib.php b/web/app/libs/uoj-html-lib.php index 3de8d1e..66bb094 100644 --- a/web/app/libs/uoj-html-lib.php +++ b/web/app/libs/uoj-html-lib.php @@ -664,6 +664,11 @@ class JudgmentDetailsPrinter { echo '
', "\n";
 			$this->_print_c($node);
 			echo "\n
"; + } elseif ($node->nodeName == 'ans') { + echo '

answer:

'; + echo '
', "\n";
+			$this->_print_c($node);
+			echo "\n
"; } elseif ($node->nodeName == 'res') { echo '

result:

'; echo '
', "\n";