diff --git a/packages/hydrojudge/src/judge/run.ts b/packages/hydrojudge/src/judge/run.ts index 12d1da7ba..05ecf9b4e 100644 --- a/packages/hydrojudge/src/judge/run.ts +++ b/packages/hydrojudge/src/judge/run.ts @@ -5,27 +5,72 @@ import * as STATUS from '../status'; import { run } from '../sandbox'; import compile from '../compile'; import signals from '../signals'; +import { compilerText, parseMemoryMB, parseTimeMS } from '../utils'; +import { CompileError } from '../error'; export const judge = async (ctx) => { ctx.stat.judge = new Date(); ctx.next({ status: STATUS.STATUS_COMPILING }); - ctx.execute = await compile(ctx.lang, ctx.code, 'code', {}, ctx.next); + try { + ctx.execute = await compile(ctx.lang, ctx.code, 'code', {}, ctx.next); + } catch (e) { + if (e instanceof CompileError) { + ctx.next({ + status: STATUS.STATUS_COMPILE_ERROR, + case: { + status: STATUS.STATUS_COMPILE_ERROR, + score: 0, + time_ms: 0, + memory_kb: 0, + message: compilerText(e.stdout, e.stderr), + }, + }); + ctx.end({ + status: STATUS.STATUS_COMPILE_ERROR, + score: 0, + time_ms: 0, + memory_kb: 0, + }); + } else { + ctx.next({ + status: STATUS.STATUS_SYSTEM_ERROR, + case: { + status: STATUS.STATUS_SYSTEM_ERROR, + score: 0, + time_ms: 0, + memory_kb: 0, + message: `${e.message}\n${JSON.stringify(e.params)}`, + }, + }); + ctx.end({ + status: STATUS.STATUS_COMPILE_ERROR, + score: 0, + time_ms: 0, + memory_kb: 0, + }); + } + return; + } ctx.clean.push(ctx.execute.clean); ctx.next({ status: STATUS.STATUS_JUDGING, progress: 0 }); const copyIn = { ...ctx.execute.copyIn }; - const stdin = path.resolve(ctx.tmpdir, 'stdin'); - const stdout = path.resolve(ctx.tmpdir, 'stdout'); - const stderr = path.resolve(ctx.tmpdir, 'stderr'); - fs.writeFileSync(stdin, ctx.config.input || ''); + const { filename } = ctx.config; + if (filename) copyIn[`${filename}.in`] = { content: ctx.config.input }; + const copyOut = filename ? [`${filename}.out`] : []; + const stdin = path.resolve(ctx.tmpdir, '0.in'); + await fs.writeFile(stdin, ctx.config.input); + const stdout = path.resolve(ctx.tmpdir, '0.out'); + const stderr = path.resolve(ctx.tmpdir, '0.err'); const res = await run( ctx.execute.execute.replace(/\$\{name\}/g, 'code'), { - stdin, - stdout, + stdin: filename ? null : stdin, + stdout: filename ? null : stdout, stderr, copyIn, - time_limit_ms: ctx.config.time, - memory_limit_mb: ctx.config.memory, + copyOut, + time_limit_ms: parseTimeMS(ctx.config.time), + memory_limit_mb: parseMemoryMB(ctx.config.memory), }, ); const { code, time_usage_ms, memory_usage_kb } = res; diff --git a/packages/hydrojudge/src/utils.ts b/packages/hydrojudge/src/utils.ts index 301a08bd5..7994b7831 100644 --- a/packages/hydrojudge/src/utils.ts +++ b/packages/hydrojudge/src/utils.ts @@ -12,18 +12,19 @@ const MEMORY_UNITS = { k: 0.1, m: 1, g: 1024 }; const EMPTY_STR = /^[ \r\n\t]*$/i; export const cmd = parse; - export function noop() { } -export function parseTimeMS(str: string) { - const match = TIME_RE.exec(str); - if (!match) throw new FormatError('Error parsing time: {0}', [str]); +export function parseTimeMS(val: string | number) { + if (typeof val === 'number') return val; + const match = TIME_RE.exec(val); + if (!match) throw new FormatError('Error parsing time: {0}', [val]); return Math.floor(parseFloat(match[1]) * TIME_UNITS[match[2]]); } -export function parseMemoryMB(str: string) { - const match = MEMORY_RE.exec(str); - if (!match) throw new FormatError('Error parsing memory: {0}', [str]); +export function parseMemoryMB(val: string | number) { + if (typeof val === 'number') return val; + const match = MEMORY_RE.exec(val); + if (!match) throw new FormatError('Error parsing memory: {0}', [val]); return Math.floor(parseFloat(match[1]) * MEMORY_UNITS[match[2]]); } diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 3dc876eb9..1f5274768 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.15.18", + "version": "2.15.19", "bin": "bin/hydrooj.js", "main": "dist/loader.js", "typings": "dist/loader.d.ts", diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index 0c009da38..a5afe144f 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -295,9 +295,7 @@ export class ProblemPretestHandler extends ProblemDetailHandler { export class ProblemPretestConnectionHandler extends ConnectionHandler { pid: string; - domainId: string; - dispose: bus.Disposable; @param('pid', Types.String) @@ -316,12 +314,6 @@ export class ProblemPretestConnectionHandler extends ConnectionHandler { || rdoc.pid.toString() !== this.pid || rdoc.domainId !== this.domainId ) return; - rdoc.compilerTexts = []; - rdoc.judgeTexts = []; - // @ts-ignore - rdoc.testCases = rdoc.testCases.map((c) => ({ - status: c.status, - })); // TODO handle update if (rdoc.contest) return; this.send({ rdoc }); diff --git a/packages/hydrooj/src/lib/i18n.ts b/packages/hydrooj/src/lib/i18n.ts index e0053137d..946522908 100644 --- a/packages/hydrooj/src/lib/i18n.ts +++ b/packages/hydrooj/src/lib/i18n.ts @@ -1,5 +1,3 @@ -import { Dictionary } from 'lodash'; - const locales = {}; declare global { @@ -43,7 +41,6 @@ String.prototype.rawformat = function rawFormat(object) { }; String.prototype.translate = function translate(...languages: string[]) { - languages.push(global.Hydro.model.system.get('server.language')); for (const language of languages) { if (!language) continue; const curr = (locales[language] || {})[this] || (locales[language.split('_')[0]] || {})[this]; @@ -52,9 +49,9 @@ String.prototype.translate = function translate(...languages: string[]) { return this; }; -function load(data: Dictionary) { +function load(data: Record>) { for (const i in data) { - if (!locales[i]) locales[i] = data[i]; + if (!locales[i]) locales[i] = { __id: i, ...data[i] }; else locales[i] = Object.assign(locales[i], data[i]); } } diff --git a/packages/hydrooj/src/utils.ts b/packages/hydrooj/src/utils.ts index 58d9e13a0..c8d38e805 100644 --- a/packages/hydrooj/src/utils.ts +++ b/packages/hydrooj/src/utils.ts @@ -232,15 +232,10 @@ export namespace Time { export const week = day * 7; export function formatTimeShort(ms: number) { const abs = Math.abs(ms); - if (abs >= day - hour / 2) { - return `${Math.round(ms / day)}d`; - } if (abs >= hour - minute / 2) { - return `${Math.round(ms / hour)}h`; - } if (abs >= minute - second / 2) { - return `${Math.round(ms / minute)}m`; - } if (abs >= second) { - return `${Math.round(ms / second)}s`; - } + if (abs >= day - hour / 2) return `${Math.round(ms / day)}d`; + if (abs >= hour - minute / 2) return `${Math.round(ms / hour)}h`; + if (abs >= minute - second / 2) return `${Math.round(ms / minute)}m`; + if (abs >= second) return `${Math.round(ms / second)}s`; return `${ms}ms`; }