atiro
Version:
Useless OI Tools
98 lines (85 loc) • 3.91 kB
JavaScript
const { spawn, spawnSync } = require('child_process');
const fs = require('fs');
const chalk = require('chalk');
const moment = require('moment');
const { exit } = require('./utils.js');
function writeJudgInfo(content, color) { // add '「' at the very beginning and '」' at the very ending
const lines = content.split('\n');
let maxl = 0;
for (let i = 0; i < lines.length; i++) {
maxl = maxl > lines[i].length ? maxl : lines[i].length;
if (!i) console.log(chalk.hex(color)('「' + lines[i]));
else if (i == lines.length - 1) {
let res = '';
for (let j = 0; j < maxl - lines[i].length; j++) res = res + ' ';
console.log(chalk.hex(color)(' ' + lines[i] + res + '」'));
}
else console.log(chalk.hex(color)(' ' + lines[i]));
}
return 0;
}
module.exports = async (file, inf, ouf, interactor, timeLimit) => {
try {
if (!interactor) { // traditional runner
const input = fs.readFileSync(inf).toString();
const startTime = process.hrtime.bigint();
const result = spawnSync(file, { input: input, stdio: ['pipe', 'pipe', 'inherit'], timeout: timeLimit, maxBuffer: 64 * 1024 * 1024 });
const endTime = process.hrtime.bigint();
const runTime = Number(endTime - startTime) / 1e6;
const currentTime = moment();
const kdl = (currentTime.hour() == 9 && currentTime.minute() == 22) || (currentTime.hour() == 22 && currentTime.minute() == 9);
writeJudgInfo(`Return Value: ${result.status == 0 && kdl ? 'kdl' : result.status}\nRunning Time: ${runTime.toFixed(0)}ms`, '#708090');
fs.writeFileSync(ouf, result.stdout);
if (runTime > timeLimit) {
console.log(chalk.blue('[Time Limit Exceeded]'));
return 1;
} else if (result.status != 0) {
console.log(chalk.magenta('[Runtime Error]'));
return 1;
} else {
return 0;
}
} else { // interaction
const startTime = process.hrtime.bigint();
const answer = spawn(file, { stdio: ['pipe', 'pipe', 'inherit'], timeout: timeLimit, maxBuffer: 64 * 1024 * 1024 });
const grader = spawn(interactor, [inf, ouf], { stdio: ['pipe', 'pipe', 'inherit'], maxBuffer: 64 * 1024 * 1024 });
answer.stdout.pipe(grader.stdin); // connect input and output
grader.stdout.pipe(answer.stdin);
grader.stdin.write('\n');
const res = await Promise.all([ // wait for program running
new Promise((resolve, reject) => {
answer.on('close', (code, signal) => {
resolve({
value: code,
signal: signal,
time: Number(process.hrtime.bigint() - startTime) / 1e6
});
});
}),
new Promise((resolve, reject) => {
grader.on('close', (code, signal) => {
resolve({
value: code,
signal: signal,
time: Number(process.hrtime.bigint() - startTime) / 1e6
});
});
})]);
const currentTime = moment();
const kdl = (currentTime.hour() == 9 && currentTime.minute() == 22) || (currentTime.hour() == 22 && currentTime.minute() == 9);
writeJudgInfo(`Return Value: ${res[0].value == 0 && kdl ? 'kdl' : res[0].value}\nRunning Time: ${res[0].time.toFixed(0)}ms`, '#708090');
if (res[0].time > timeLimit) {
console.log(chalk.blue('[Time Limit Exceeded]'));
return 1;
} else if (res[0].value != 0) {
console.log(chalk.magenta('[Runtime Error]'));
return 1;
} else {
return res[1].value != 0;
}
}
} catch (error) {
console.log(chalk.gray('[Mysterious Error]'), 'Failed on running.');
exit();
}
}