Skip to content

Commit be8591e

Browse files
committed
add timesync
1 parent 924c995 commit be8591e

File tree

11 files changed

+138
-103
lines changed

11 files changed

+138
-103
lines changed

packages/server/client/printer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { PDFDocument } from 'pdf-lib';
66
import superagent from 'superagent';
77
import { config, saveConfig } from '../config';
88
import {
9-
fs, getPrinters, initWinPrinter, Logger, print, sleep,
9+
fs, getPrinters, initWinPrinter, Logger, print, randomstring, sleep,
1010
} from '../utils';
1111
import { createTypstCompiler, generateTypst } from './typst';
1212

@@ -46,7 +46,7 @@ function toUtf8(code: Buffer) {
4646

4747
export async function ConvertCodeToPDF(code: Buffer, lang, filename, team, location, codeColor = false) {
4848
compiler ||= await createTypstCompiler();
49-
const fakeFilename = String.random(8); // cubercsl: do not trust filename from user
49+
const fakeFilename = randomstring(8); // cubercsl: do not trust filename from user
5050
const typst = generateTypst(team, location, fakeFilename, filename, lang, codeColor);
5151
compiler.addSource('/main.typst', typst);
5252
compiler.addSource(`/${fakeFilename}`, toUtf8(code));

packages/server/config.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Schema from 'schemastery';
33
import { version as packageVersion } from './package.json';
44
import {
55
checkReceiptPrinter,
6-
fs, getPrinters, Logger, yaml,
6+
fs, getPrinters, Logger, randomstring, yaml,
77
} from './utils';
88

99
const logger = new Logger('init');
@@ -21,15 +21,17 @@ if (!fs.existsSync(configPath)) {
2121
exit = new Promise((resolve) => (async () => {
2222
const serverConfigDefault = `\
2323
type: server # server | domjudge | hydro
24-
viewPass: ${String.random(8)} # use admin / viewPass to login
25-
secretRoute: ${String.random(12)}
24+
viewPass: ${randomstring(8)} # use admin / viewPass to login
25+
secretRoute: ${randomstring(12)}
2626
seatFile: /home/icpc/Desktop/seats.txt
2727
customKeyfile:
2828
# if type is server, the following is not needed
2929
server:
3030
token:
3131
username:
3232
password:
33+
monitor:
34+
timeSync: false
3335
`;
3436
let printers = [];
3537
if (isClient) {
@@ -62,10 +64,13 @@ const serverSchema = Schema.intersect([
6264
] as const).description('server type').required(),
6365
port: Schema.number().default(5283),
6466
xhost: Schema.string().default('x-forwarded-host'),
65-
viewPass: Schema.string().default(String.random(8)),
66-
secretRoute: Schema.string().default(String.random(12)),
67+
viewPass: Schema.string().default(randomstring(8)),
68+
secretRoute: Schema.string().default(randomstring(12)),
6769
seatFile: Schema.string().default('/home/icpc/Desktop/seat.txt'),
6870
customKeyfile: Schema.string().default(''),
71+
monitor: Schema.object({
72+
timeSync: Schema.boolean().default(false),
73+
}).default({ timeSync: false }),
6974
}).description('Basic Config'),
7075
Schema.union([
7176
Schema.object({

packages/server/handler/client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Context } from 'cordis';
33
import {
44
BadRequestError, ForbiddenError, Handler, ValidationError,
55
} from '@hydrooj/framework';
6-
import { fs, Logger } from '../utils';
6+
import { fs, Logger, randomstring } from '../utils';
77
import { AuthHandler } from './misc';
88

99
const logger = new Logger('handler/client');
@@ -18,7 +18,7 @@ class ClientControlHandler extends AuthHandler {
1818
const { name, type } = params;
1919
const client = await this.ctx.db.client.findOne({ name });
2020
if (client) throw new ValidationError('Client', null, 'Client already exists');
21-
const id = String.random(6);
21+
const id = randomstring(6);
2222
await this.ctx.db.client.insert({
2323
id,
2424
name,

packages/server/handler/misc.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import { Registry } from 'prom-client';
44
import { Handler } from '@hydrooj/framework';
55
import { config, version } from '../config';
66
import StaticFrontend from '../data/static.frontend';
7-
import { createMetricsRegistry, decodeBinary, StaticHTML } from '../utils';
7+
import {
8+
createMetricsRegistry, decodeBinary, randomstring, StaticHTML,
9+
} from '../utils';
810

9-
const randomHash = String.random(8).toLowerCase();
11+
const randomHash = randomstring(8).toLowerCase();
1012
const buf = decodeBinary(StaticFrontend);
1113
let registry: Registry;
1214

packages/server/handler/monitor.ts

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
/* eslint-disable no-await-in-loop */
2-
import { Context } from 'cordis';
1+
import { Context, Schema } from 'cordis';
32
import { BadRequestError, Handler } from '@hydrooj/framework';
4-
import { Logger } from '../utils';
53
import { AuthHandler } from './misc';
64

7-
const logger = new Logger('handler/monitor');
8-
95
class MonitorAdminHandler extends AuthHandler {
106
async get(params) {
117
const { nogroup } = params;
@@ -101,7 +97,7 @@ async function saveMonitorInfo(ctx: Context, monitor: any) {
10197
} = monitor;
10298
const monitors = await ctx.db.monitor.find({ mac });
10399
const warn = monitors.length > 1 || (monitors.length && monitors[0].ip !== ip);
104-
if (warn) logger.warn(`Duplicate monitor ${mac} from (${ip}, ${monitors.length ? monitors[0].ip : 'null'})`);
100+
if (warn) ctx.logger('monitor').warn(`Duplicate monitor ${mac} from (${ip}, ${monitors.length ? monitors[0].ip : 'null'})`);
105101
await ctx.db.monitor.updateOne({ mac }, {
106102
$set: {
107103
mac,
@@ -122,21 +118,24 @@ async function saveMonitorInfo(ctx: Context, monitor: any) {
122118
}, { upsert: true });
123119
}
124120

125-
class MonitorReportHandler extends Handler {
126-
async get() {
127-
this.response.body = 'Monitor server is running';
128-
}
121+
export const Config = Schema.object({
122+
timeSync: Schema.boolean().default(false),
123+
});
129124

130-
async post(params) {
131-
if (!params.mac) throw new BadRequestError();
132-
params.ip = this.request.ip.replace('::ffff:', '');
133-
if (params.mac === '00:00:00:00:00:00') throw new BadRequestError('Invalid MAC address');
134-
await saveMonitorInfo(this.ctx, params);
135-
this.response.body = 'Monitor server is running';
136-
}
137-
}
125+
export async function apply(ctx: Context, config: ReturnType<typeof Config>) {
126+
class MonitorReportHandler extends Handler {
127+
async get() {
128+
this.response.body = 'Monitor server is running';
129+
}
138130

139-
export async function apply(ctx: Context) {
131+
async post(params) {
132+
if (!params.mac) throw new BadRequestError();
133+
params.ip = this.request.ip.replace('::ffff:', '');
134+
if (params.mac === '00:00:00:00:00:00') throw new BadRequestError('Invalid MAC address');
135+
await saveMonitorInfo(this.ctx, params);
136+
this.response.body = `#!/bin/bash\n${config.timeSync ? `date "${new Date().toISOString()}"` : 'echo Success'}`;
137+
}
138+
}
140139
ctx.Route('monitor_report', '/report', MonitorReportHandler);
141140
ctx.Route('monitor_admin', '/monitor', MonitorAdminHandler);
142141
}

packages/server/index.ts

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import os from 'os';
22
import path from 'path';
3+
import LoggerService from '@cordisjs/plugin-logger';
4+
import { TimerService } from '@cordisjs/plugin-timer';
35
import { Context } from 'cordis';
6+
import DBService from './service/db';
47
import { fs, Logger } from './utils';
58

6-
Logger.levels.base = 3;
7-
89
const logger = new Logger('tools');
910

1011
process.on('unhandledRejection', (e) => { logger.error(e); });
@@ -22,36 +23,54 @@ try {
2223
}
2324

2425
async function applyServer(ctx: Context) {
25-
ctx.plugin(require('./service/server'));
26-
ctx.plugin(require('./service/db'));
27-
ctx.plugin(require('./service/fetcher'));
28-
ctx.inject(['server', 'dbservice', 'fetcher'], (c) => {
29-
c.plugin(require('./handler/misc'));
30-
c.plugin(require('./handler/printer'));
31-
c.plugin(require('./handler/monitor'));
32-
c.plugin(require('./handler/client'));
33-
c.plugin(require('./handler/balloon'));
34-
c.plugin(require('./handler/commands'));
26+
await Promise.all([
27+
ctx.plugin(require('./service/server')),
28+
ctx.plugin(require('./service/fetcher')),
29+
]);
30+
await ctx.inject(['server', 'dbservice', 'fetcher'], async (c) => {
31+
await Promise.all([
32+
c.plugin(require('./handler/misc')),
33+
c.plugin(require('./handler/printer')),
34+
c.plugin(require('./handler/monitor'), config.monitor),
35+
c.plugin(require('./handler/client')),
36+
c.plugin(require('./handler/balloon')),
37+
c.plugin(require('./handler/commands')),
38+
]);
3539
c.server.listen();
3640
});
3741
}
3842

39-
async function applyClient(ctx: Context) {
43+
function applyClient(ctx: Context) {
4044
if (config.printers?.length) ctx.plugin(require('./client/printer'));
4145
if (config.balloon) ctx.plugin(require('./client/balloon'));
4246
}
4347

4448
async function apply(ctx) {
4549
if (process.argv.includes('--client')) {
46-
await applyClient(ctx);
50+
applyClient(ctx);
4751
} else {
48-
await applyServer(ctx);
52+
ctx.plugin(DBService);
53+
ctx.inject(['dbservice'], (c) => {
54+
applyServer(c);
55+
});
4956
}
50-
await ctx.lifecycle.flush();
51-
await ctx.parallel('app/listen');
5257
logger.success('Tools started');
5358
process.send?.('ready');
5459
await ctx.parallel('app/ready');
5560
}
5661

57-
if (config) apply(app);
62+
app.plugin(TimerService);
63+
app.plugin(LoggerService, {
64+
console: {
65+
showDiff: false,
66+
showTime: 'dd hh:mm:ss',
67+
label: {
68+
align: 'right',
69+
width: 9,
70+
margin: 1,
71+
},
72+
levels: { default: process.env.DEV ? 3 : 2 },
73+
},
74+
});
75+
76+
if (config) app.inject(['logger', 'timer'], (ctx) => apply(ctx));

packages/server/service/db.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ declare module 'cordis' {
2121
}
2222
}
2323

24-
export class DBService extends Service {
24+
export default class DBService extends Service {
2525
constructor(ctx: Context) {
2626
fs.ensureDirSync(path.resolve(process.cwd(), 'data/.db'));
27-
super(ctx, 'dbservice', true);
27+
super(ctx, 'dbservice');
2828
ctx.mixin('dbservice', ['db']);
29-
this.start();
3029
}
3130

3231
db: { [T in keyof Collections]: Datastore<Collections[T]> } = {} as any;
@@ -39,16 +38,11 @@ export class DBService extends Service {
3938
this.ctx.logger('db').info(`${key} Database loaded`);
4039
}
4140

42-
async start() {
41+
async [Service.init]() {
4342
await this.initDatabase('code', ['_id', 'createAt', 'done', 'printer', 'deleted']);
4443
await this.initDatabase('monitor', ['_id', 'mac', 'name', 'group']);
4544
await this.initDatabase('client', ['id', 'name', 'type', 'group']);
4645
await this.initDatabase('balloon', ['id', 'time', 'problem', 'teamid', 'awards', 'done', 'printDone']);
4746
await this.initDatabase('teams', []);
4847
}
4948
}
50-
51-
export function apply(ctx: Context) {
52-
ctx.provide('dbservice', undefined, true);
53-
ctx.dbservice = new DBService(ctx);
54-
}

0 commit comments

Comments
 (0)