mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 17:38:19 +08:00
修复分数为0时不会自动更新成绩的问题,添加旧版测试数据格式兼容
This commit is contained in:
1 parent
e1cfe1cf4d
commit
441515297a
7 files changed
+70
-32
No files matched your search
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/hydrojudge",
|
||||
"version": "2.0.12",
|
||||
"version": "2.0.13",
|
||||
"main": "package.json",
|
||||
"author": "masnn",
|
||||
"os": [
|
||||
@@ -30,4 +30,4 @@
|
||||
"build": "tsc",
|
||||
"lint": "eslint . --ext ts --fix"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,17 @@ import { Dictionary } from 'lodash';
|
||||
import { FormatError, SystemError } from './error';
|
||||
import { parseTimeMS, parseMemoryMB, ensureFile } from './utils';
|
||||
|
||||
const RE0 = [
|
||||
interface Re0 {
|
||||
reg: RegExp,
|
||||
output: (a: RegExpExecArray) => string,
|
||||
id: (a: RegExpExecArray) => number,
|
||||
}
|
||||
|
||||
interface Re1 extends Re0 {
|
||||
subtask: (a: RegExpExecArray) => number,
|
||||
}
|
||||
|
||||
const RE0: Re0[] = [
|
||||
{
|
||||
reg: /^([a-z+_\-A-Z]*)([0-9]+).in$/,
|
||||
output: (a) => `${a[1] + a[2]}.out`,
|
||||
@@ -25,8 +35,28 @@ const RE0 = [
|
||||
output: (a) => `output${a[2]}.txt`,
|
||||
id: (a) => parseInt(a[2], 10),
|
||||
},
|
||||
{
|
||||
reg: /^input\/([a-z+_\-A-Z]*)([0-9]+).in$/,
|
||||
output: (a) => `output/${a[1] + a[2]}.out`,
|
||||
id: (a) => parseInt(a[2], 10),
|
||||
},
|
||||
{
|
||||
reg: /^input\/([a-z+_\-A-Z]*)([0-9]+).in$/,
|
||||
output: (a) => `output/${a[1] + a[2]}.ans`,
|
||||
id: (a) => parseInt(a[2], 10),
|
||||
},
|
||||
{
|
||||
reg: /^input\/([a-z+_\-A-Z0-9]*)\.in([0-9]+)$/,
|
||||
output: (a) => `output/${a[1]}.ou${a[2]}`,
|
||||
id: (a) => parseInt(a[2], 10),
|
||||
},
|
||||
{
|
||||
reg: /^input\/(input)([0-9]+).txt$/,
|
||||
output: (a) => `output/output${a[2]}.txt`,
|
||||
id: (a) => parseInt(a[2], 10),
|
||||
},
|
||||
];
|
||||
const RE1 = [
|
||||
const RE1: Re1[] = [
|
||||
{
|
||||
reg: /^([a-z+_\-A-Z]*)([0-9]+)-([0-9]+).in$/,
|
||||
output: (a) => `${a[1] + a[2]}-${a[3]}.out`,
|
||||
@@ -35,7 +65,7 @@ const RE1 = [
|
||||
},
|
||||
];
|
||||
|
||||
async function read0(folder, files, checkFile) {
|
||||
async function read0(folder: string, files: string[], checkFile) {
|
||||
const cases = [];
|
||||
for (const file of files) {
|
||||
for (const REG of RE0) {
|
||||
@@ -89,7 +119,7 @@ async function read0(folder, files, checkFile) {
|
||||
return config;
|
||||
}
|
||||
|
||||
async function read1(folder, files, checkFile) {
|
||||
async function read1(folder: string, files: string[], checkFile) {
|
||||
const subtask = {};
|
||||
const subtasks = [];
|
||||
for (const file of files) {
|
||||
@@ -144,6 +174,14 @@ async function readAutoCases(folder, { next }) {
|
||||
const checkFile = ensureFile(folder);
|
||||
try {
|
||||
const files = await fs.readdir(folder);
|
||||
if (await fs.pathExists(path.resolve(folder, 'input'))) {
|
||||
const inputs = await fs.readdir(path.resolve(folder, 'input'));
|
||||
files.push(...inputs.map((i) => `input/${i}`));
|
||||
}
|
||||
if (await fs.pathExists(path.resolve(folder, 'output'))) {
|
||||
const outputs = await fs.readdir(path.resolve(folder, 'output'));
|
||||
files.push(...outputs.map((i) => `output/${i}`));
|
||||
}
|
||||
let result = await read0(folder, files, checkFile);
|
||||
if (!result.count) result = await read1(folder, files, checkFile);
|
||||
Object.assign(config, result);
|
||||
|
||||
@@ -3,7 +3,7 @@ import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
import { argv } from 'yargs';
|
||||
import { STATUS } from 'hydrooj/dist/model/builtin';
|
||||
import { CompileError } from '../error';
|
||||
import { CompileError, SystemError } from '../error';
|
||||
import { copyInDir, parseFilename } from '../utils';
|
||||
import { run } from '../sandbox';
|
||||
import compile from '../compile';
|
||||
@@ -106,6 +106,7 @@ function judgeSubtask(subtask) {
|
||||
}
|
||||
|
||||
export const judge = async (ctx) => {
|
||||
if (!ctx.config.subtasks.length) throw new SystemError('没有找到测试数据');
|
||||
if (ctx.config.template) {
|
||||
if (ctx.config.template[ctx.lang]) {
|
||||
const tpl = ctx.config.template[ctx.lang];
|
||||
|
||||
@@ -28,6 +28,8 @@ async function postInit() {
|
||||
const { problem, file, task } = global.Hydro.model;
|
||||
const _judge = global.Hydro.handler.judge as any;
|
||||
const { monitor } = global.Hydro.service;
|
||||
const { Logger } = global.Hydro.Logger;
|
||||
const logger = new Logger('judge');
|
||||
|
||||
const info = await sysinfo.get();
|
||||
monitor.updateJudger(info);
|
||||
@@ -85,7 +87,7 @@ async function postInit() {
|
||||
|
||||
async function cacheOpen(domainId: string, pid: string, version: string) {
|
||||
const filePath = path.join(homedir(), '.cache', 'hydro', 'judge', domainId, pid);
|
||||
console.log(filePath);
|
||||
logger.debug('Cache found at %s', filePath);
|
||||
if (fs.existsSync(filePath)) {
|
||||
let ver: string;
|
||||
try {
|
||||
@@ -103,7 +105,8 @@ async function postInit() {
|
||||
function getNext(that) {
|
||||
that.nextId = 1;
|
||||
that.nextWaiting = [];
|
||||
return (data, id) => {
|
||||
return (data, id = 0) => {
|
||||
logger.debug('Next: %d %o', id, data);
|
||||
data.domainId = that.domainId;
|
||||
data.rid = new ObjectID(that.rid);
|
||||
data.time = data.time_ms || data.time;
|
||||
@@ -143,14 +146,9 @@ async function postInit() {
|
||||
data.key = 'end';
|
||||
data.rid = new ObjectID(rid);
|
||||
data.domainId = domainId;
|
||||
data.time = data.time_ms || data.time;
|
||||
data.memory = data.memory_kb || data.memory;
|
||||
console.log({
|
||||
status: data.status,
|
||||
score: data.score,
|
||||
time_ms: data.time_ms,
|
||||
memory_kb: data.memory_kb,
|
||||
});
|
||||
data.time = data.time_ms ?? data.time;
|
||||
data.memory = data.memory_kb ?? data.memory;
|
||||
logger.info('End: status=%d score=%d time=%dms memory=%dkb', data.status, data.score, data.time, data.memory);
|
||||
_judge.end(data);
|
||||
};
|
||||
}
|
||||
@@ -176,7 +174,7 @@ async function postInit() {
|
||||
|
||||
config: any;
|
||||
|
||||
next: (data: any, id?: any) => void;
|
||||
next: (data: any, id?: number) => void;
|
||||
|
||||
end: (data: any) => void;
|
||||
|
||||
@@ -208,7 +206,7 @@ async function postInit() {
|
||||
this.clean = [];
|
||||
fs.ensureDirSync(this.tmpdir);
|
||||
tmpfs.mount(this.tmpdir, '64m');
|
||||
console.log(`Submission: ${this.rid}`, { pid: this.pid });
|
||||
logger.info(`Submission: ${this.rid}`, { pid: this.pid });
|
||||
if (this.config.input) await this.run();
|
||||
else if (this.config.hack) await this.hack();
|
||||
else await this.submission();
|
||||
@@ -224,7 +222,7 @@ async function postInit() {
|
||||
status: STATUS_SYSTEM_ERROR, score: 0, time_ms: 0, memory_kb: 0,
|
||||
});
|
||||
} else {
|
||||
console.error(e);
|
||||
logger.error(e);
|
||||
this.next({ message: `${e.message}\n${e.stack}\n${JSON.stringify(e.params)}` });
|
||||
this.end({
|
||||
status: STATUS_SYSTEM_ERROR, score: 0, time_ms: 0, memory_kb: 0,
|
||||
@@ -269,7 +267,7 @@ async function postInit() {
|
||||
}
|
||||
}
|
||||
|
||||
task.consume({ type: 'judge' }, (t) => (new JudgeTask(t)).handle().catch(console.error));
|
||||
task.consume({ type: 'judge' }, (t) => (new JudgeTask(t)).handle().catch(logger.error));
|
||||
}
|
||||
|
||||
global.Hydro.service.bus.once('app/started', postInit);
|
||||
Reference in new issue
Block a user