fix lint error

This commit is contained in:
GEEKiDoS
2024-01-08 20:57:56 +08:00
parent e14f16c4d9
commit a9c444b1d1
18 changed files with 154 additions and 112 deletions
+3 -1
View File
@@ -22,6 +22,8 @@
// examples, and because it is not a recommended rule, you should either
// disable it, or understand what it enforces.
// https://typescript-eslint.io/rules/explicit-function-return-type/
"@typescript-eslint/explicit-function-return-type": "warn"
"@typescript-eslint/explicit-function-return-type": "warn",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-explicit-any": "off"
}
}
+1
View File
@@ -33,6 +33,7 @@
"build:watch": "tsc -w -p tsconfig.json",
"build:release": "npm run clean && tsc -p tsconfig.release.json",
"lint": "eslint . --ext .ts --ext .mts",
"lint:fix": "eslint . --ext .ts --ext .mts --fix",
"test": "jest --coverage",
"prettier": "prettier --config .prettierrc --write .",
"test:watch": "jest --watch"
+8 -4
View File
@@ -1,17 +1,21 @@
import pug from 'pug';
import { to_bin } from "@kamyu/kbinxml";
import { to_bin } from '@kamyu/kbinxml';
export function kxml(templatePath: string, encoding: 'UTF-8' | 'SHIFT_JIS' = 'UTF-8'): MethodDecorator {
export function kxml(
templatePath: string,
encoding: 'UTF-8' | 'SHIFT_JIS' = 'UTF-8',
): MethodDecorator {
const template = pug.compileFile('templates/' + templatePath + '.pug');
return function (_target, _propertyKey, descriptor) {
const orig = descriptor.value as Function;
descriptor.value = async function (...args: any[]) {
const obj = await orig.apply(this, args);
const xml = `<?xml version="1.0" encoding="${encoding}"?>` + template(obj);
const xml =
`<?xml version="1.0" encoding="${encoding}"?>` + template(obj);
const kxml = to_bin(xml);
return Buffer.from(kxml.data);
} as unknown as any;
}
};
}
+5 -5
View File
@@ -1,11 +1,11 @@
import { singleton } from "tsyringe";
import { Context, ILaochanService } from "../types.js";
import dedent from 'dedent-js'
import { to_bin } from "@kamyu/kbinxml";
import { singleton } from 'tsyringe';
import { Context, ILaochanService } from '../types.js';
import dedent from 'dedent-js';
import { to_bin } from '@kamyu/kbinxml';
@singleton()
export class DefaultService implements ILaochanService {
async process(ctx: Context) {
async process(ctx: Context): Promise<Buffer> {
const tmp = ctx.service.split('.');
const module = tmp[0];
const method = tmp[1];
+11 -7
View File
@@ -1,11 +1,11 @@
import { kxml } from "../../decorators/render-kxml.js";
import { ILaochanService } from "../../types.js";
import { singleton } from "tsyringe";
import { kxml } from '../../decorators/render-kxml.js';
import { ILaochanService } from '../../types.js';
import { singleton } from 'tsyringe';
@singleton()
export default class implements ILaochanService {
@kxml('facility/get')
async process() {
async process(): Promise<object> {
return {
status: 0,
location: {
@@ -48,12 +48,16 @@ export default class implements ILaochanService {
notchAmount: 0,
notchCount: 0,
supplyLimit: 100000,
}
},
},
calendar: {
year: 2024,
holiday: [0, 1, 8, 41, 53, 79, 118, 122, 123, 124, 197, 222, 260, 265, 281, 306, 326, 365, 372, 406, 407, 418, 444, 484, 488, 489, 490, 491, 561, 588, 589, 624, 630, 631, 652, 672, 673, 692],
}
holiday: [
0, 1, 8, 41, 53, 79, 118, 122, 123, 124, 197, 222, 260, 265, 281, 306,
326, 365, 372, 406, 407, 418, 444, 484, 488, 489, 490, 491, 561, 588,
589, 624, 630, 631, 652, 672, 673, 692,
],
},
};
}
}
+4 -4
View File
@@ -1,11 +1,11 @@
import { kxml } from "../../decorators/render-kxml.js";
import { ILaochanService } from "../../types.js";
import { singleton } from "tsyringe";
import { kxml } from '../../decorators/render-kxml.js';
import { ILaochanService } from '../../types.js';
import { singleton } from 'tsyringe';
@singleton()
export default class implements ILaochanService {
@kxml('message/get')
async process() {
async process(): Promise<object> {
return {
status: 0,
expire: 60,
+2 -2
View File
@@ -1,5 +1,5 @@
import { singleton } from "tsyringe";
import { DefaultService } from "../default.js";
import { singleton } from 'tsyringe';
import { DefaultService } from '../default.js';
@singleton()
export default class extends DefaultService {}
+2 -2
View File
@@ -1,5 +1,5 @@
import { singleton } from "tsyringe";
import { DefaultService } from "../default.js";
import { singleton } from 'tsyringe';
import { DefaultService } from '../default.js';
@singleton()
export default class extends DefaultService {}
+4 -4
View File
@@ -1,11 +1,11 @@
import { kxml } from "../../decorators/render-kxml.js";
import { ILaochanService } from "../../types.js";
import { singleton } from "tsyringe";
import { kxml } from '../../decorators/render-kxml.js';
import { ILaochanService } from '../../types.js';
import { singleton } from 'tsyringe';
@singleton()
export default class implements ILaochanService {
@kxml('pcbtracker/alive')
async process() {
async process(): Promise<object> {
return {
status: 0,
expire: 3600,
+6 -5
View File
@@ -1,13 +1,14 @@
import { kxml } from "../../decorators/render-kxml.js";
import { ILaochanService } from "../../types.js";
import { singleton } from "tsyringe";
import { kxml } from '../../decorators/render-kxml.js';
import { ILaochanService } from '../../types.js';
import { singleton } from 'tsyringe';
@singleton()
export default class implements ILaochanService {
@kxml('services/get')
async process() {
async process(): Promise<object> {
return {
keepaliveUrl: 'ping://127.0.0.1/?pa=127.0.0.1&ia=127.0.0.1&ga=127.0.0.1ma=127.0.0.1&t1=2&t2=15&rt=2',
keepaliveUrl:
'ping://127.0.0.1/?pa=127.0.0.1&ia=127.0.0.1&ga=127.0.0.1ma=127.0.0.1&t1=2&t2=15&rt=2',
ntpUrl: 'ntp://pool.ntp.org',
selfUrl: 'http://localhost:10573',
};
+44 -27
View File
@@ -1,34 +1,33 @@
import "reflect-metadata";
import 'reflect-metadata';
import Koa, { DefaultState } from 'koa';
import { InjectionToken, Provider, container } from "tsyringe";
import { InjectionToken, Provider, container } from 'tsyringe';
import { ILaochanContext, ILaochanService } from './types.js';
import { DefaultService } from "./functions/default.js";
import { Logger } from "@cordisjs/logger";
import { crypto } from "./middlewares/crypto.js";
import { binaryBody } from "./middlewares/binarybody.js";
import { parseKxml } from "./middlewares/parseKxml.js";
import { decompress } from "./middlewares/decompress.js";
import { DefaultService } from './functions/default.js';
import { Logger } from '@cordisjs/logger';
import { crypto } from './middlewares/crypto.js';
import { binaryBody } from './middlewares/binarybody.js';
import { parseKxml } from './middlewares/parseKxml.js';
import { decompress } from './middlewares/decompress.js';
function tryResolve<T>(token: InjectionToken<T>): T | undefined {
if (!container.isRegistered(token))
return undefined;
if (!container.isRegistered(token)) return undefined;
return container.resolve(token);
}
function register<T>(token: InjectionToken<T>, provider: Provider<T> | { new(...args: any[]): T }): T {
if (container.isRegistered(token))
return container.resolve(token);
function register<T>(
token: InjectionToken<T>,
provider: Provider<T> | { new (...args: any[]): T },
): T {
if (container.isRegistered(token)) return container.resolve(token);
// @ts-ignore
return container.register(token, provider)
.resolve(token);
// @ts-expect-error: noob tsc
return container.register(token, provider).resolve(token);
}
async function main() {
async function main(): Promise<void> {
const logger = new Logger('main');
const app = new Koa<DefaultState, ILaochanContext>()
@@ -47,20 +46,30 @@ async function main() {
ctx.model = ctx.query.model;
ctx.service = ctx.query.f;
ctx.logger = ctx.service ? register(`logger:${ctx.service}`, {
useValue: new Logger(ctx.service),
}) : logger;
ctx.logger = ctx.service
? register(`logger:${ctx.service}`, {
useValue: new Logger(ctx.service),
})
: logger;
let service: ILaochanService | undefined = ctx.service ?
tryResolve(ctx.service) : container.resolve(DefaultService);
let service: ILaochanService | undefined = ctx.service
? tryResolve(ctx.service)
: container.resolve(DefaultService);
if (service === undefined) {
try {
const module = await import(`./functions/${ctx.service.replace('.', '/')}.js`);
const module = await import(
`./functions/${ctx.service.replace('.', '/')}.js`
);
service = register(ctx.service, {
useClass: module.default,
});
} catch { }
} catch (e) {
logger.error(
`load service error %s`,
JSON.stringify(e, Object.getOwnPropertyNames(e), 2),
);
}
}
if (service === undefined) {
@@ -68,13 +77,21 @@ async function main() {
service = container.resolve(DefaultService);
}
logger.info('%s [%s]: request = %s', ctx.service, ctx.pcbid, JSON.stringify(ctx.request.body));
logger.info(
'%s [%s]: request = %s',
ctx.service,
ctx.pcbid,
JSON.stringify(ctx.request.body),
);
try {
ctx.body = await service.process(ctx);
ctx.status = 200;
} catch (e) {
logger.error('unexcepted error: %s', JSON.stringify(e, Object.getOwnPropertyNames(e), 2));
logger.error(
'unexcepted error: %s',
JSON.stringify(e, Object.getOwnPropertyNames(e), 2),
);
ctx.status = e.status ?? 500;
ctx.body = `${e.stack ?? 'Internal Error'}`;
+7 -7
View File
@@ -1,19 +1,19 @@
import { Next } from "koa";
import { Context } from "../types.js";
import { Next } from 'koa';
import { Context } from '../types.js';
export async function binaryBody(ctx: Context, next: Next) {
if (typeof ctx.headers["content-length"] !== 'string') {
export async function binaryBody(ctx: Context, next: Next): Promise<any> {
if (typeof ctx.headers['content-length'] !== 'string') {
return next();
}
const length = parseInt(ctx.headers["content-length"]);
const length = parseInt(ctx.headers['content-length']);
if (length === 0) {
return next();
}
ctx.request.body = await new Promise((resolve, reject) => {
const buffer = Buffer.allocUnsafe(length);
let len = 0
let len = 0;
ctx.req.on('data', (chunk: Buffer) => {
chunk.copy(buffer, len);
@@ -28,7 +28,7 @@ export async function binaryBody(ctx: Context, next: Next) {
if (len < length) {
reject(new Error('socket hanged up unexceptly.'));
}
})
});
});
return next();
+10 -6
View File
@@ -1,8 +1,8 @@
import { Next } from "koa";
import { Context } from "../types.js";
import { rc4Transfrom } from "../utils/rc4.js";
import { Next } from 'koa';
import { Context } from '../types.js';
import { rc4Transfrom } from '../utils/rc4.js';
export async function crypto(ctx: Context, next: Next) {
export async function crypto(ctx: Context, next: Next): Promise<any> {
if (typeof ctx.req.headers['x-eamuse-info'] !== 'string') {
return next();
}
@@ -31,8 +31,12 @@ export async function crypto(ctx: Context, next: Next) {
return;
}
const time = Math.floor(new Date().valueOf() / 1000).toString(16).padStart(8, '0');
const salt = Math.floor(Math.random() * 0xFFFF).toString(16).padStart(4, '0');
const time = Math.floor(new Date().valueOf() / 1000)
.toString(16)
.padStart(8, '0');
const salt = Math.floor(Math.random() * 0xffff)
.toString(16)
.padStart(4, '0');
const encrypted = rc4Transfrom(time + salt, ctx.body);
ctx.body = encrypted;
+4 -4
View File
@@ -1,8 +1,8 @@
import { Next } from "koa";
import { Context } from "../types.js";
import { lz77Decode } from "../utils/lz77.js";
import { Next } from 'koa';
import { Context } from '../types.js';
import { lz77Decode } from '../utils/lz77.js';
export async function decompress(ctx: Context, next: Next) {
export async function decompress(ctx: Context, next: Next): Promise<any> {
if (!(ctx.request.body instanceof Buffer)) {
return next();
}
+32 -19
View File
@@ -1,6 +1,6 @@
import { Next } from "koa";
import { Context } from "../types.js";
import { to_xml } from "@kamyu/kbinxml";
import { Next } from 'koa';
import { Context } from '../types.js';
import { to_xml } from '@kamyu/kbinxml';
import { XMLParser } from 'fast-xml-parser';
const parser = new XMLParser({
@@ -11,46 +11,59 @@ const parser = new XMLParser({
allowBooleanAttributes: true,
});
function parseValue(node: any) {
function parseValue(node: { $__type: string; $__count?: unknown }): any {
const isArray = '$__count' in node;
if (['s8', 'u8', 's16', 'u16', 's32', 'u32', 's64', 'u64', 'float', 'double'].includes(node.$__type)) {
if (isArray) {
return node['#text'].split(' ').map(v => new Number(v));
}
if (
[
's8',
'u8',
's16',
'u16',
's32',
'u32',
's64',
'u64',
'float',
'double',
].includes(node.$__type)
) {
if (isArray) {
return node['#text'].split(' ').map((v) => new Number(v));
}
return new Number(node['#text']);
return new Number(node['#text']);
}
if(['b', 'bool'].includes(node.$__type)) {
if (['b', 'bool'].includes(node.$__type)) {
return !!parseInt(node['#text']);
}
if (['bin', 'binary'].includes(node.$__type)) {
return Buffer.from(node['#text'], 'hex')
return Buffer.from(node['#text'], 'hex');
}
if(['ip4', 'str', 'string'].includes(node.$__type)) {
if (['ip4', 'str', 'string'].includes(node.$__type)) {
return node['#text'];
}
if(node.$__type == 'time') {
if (node.$__type == 'time') {
return new Date(parseInt(node['#text']) * 1000);
}
return {
type: node.$__type,
value: node['#text'],
}
};
}
function kxmlToObject(node: any) {
function kxmlToObject(node: Record<string, unknown>): any {
if (node instanceof Array) {
return node.map(v => kxmlToObject(v));
return node.map((v) => kxmlToObject(v));
}
if ('$__type' in node) {
return parseValue(node);
return parseValue(node as { $__type: string; $__count?: unknown });
}
const obj: object = {};
@@ -64,13 +77,13 @@ function kxmlToObject(node: any) {
continue;
}
obj[key] = kxmlToObject(node[key]);
obj[key] = kxmlToObject(node[key] as Record<string, unknown>);
}
return obj;
}
export async function parseKxml(ctx: Context, next: Next) {
export async function parseKxml(ctx: Context, next: Next): Promise<object> {
if (!(ctx.request.body instanceof Buffer)) {
return next();
}
+3 -3
View File
@@ -1,5 +1,5 @@
import { Logger } from "@cordisjs/logger";
import { DefaultState, ParameterizedContext } from "koa";
import { Logger } from '@cordisjs/logger';
import { DefaultState, ParameterizedContext } from 'koa';
export interface ILaochanContext {
model?: string;
@@ -9,7 +9,7 @@ export interface ILaochanContext {
request: {
body: Buffer | object | undefined;
}
};
}
export type Context = ParameterizedContext<DefaultState, ILaochanContext, any>;
+3 -6
View File
@@ -10,21 +10,18 @@ export function lz77Decode(data: Buffer): Buffer {
if (flag & (1 << bit)) {
output.push(data[offset]);
offset += 1;
} else {
if (offset >= data.length)
break;
if (offset >= data.length) break;
const lookbackFlag = data.readUInt16BE(offset);
const lookbackLength = (lookbackFlag & 0x000f) + 3;
const lookbackOffset = lookbackFlag >> 4;
offset += 2;
if (lookbackFlag == 0)
break;
if (lookbackFlag == 0) break;
for (let i = 0; i < lookbackLength; i++) {
let loffset = output.length - lookbackOffset;
const loffset = output.length - lookbackOffset;
if (loffset <= 0 || loffset >= output.length) {
output.push(0);
+5 -6
View File
@@ -1,13 +1,12 @@
import { createHash } from "crypto";
import { createHash } from 'crypto';
import rc4 from 'arc4';
const EAMUSE_RC4_KEY = '69D74627D985EE2187161570D08D93B12455035B6DF0D8205DF5';
export function rc4Transfrom(keyHex: string, data: Buffer) {
export function rc4Transfrom(keyHex: string, data: Buffer): Buffer {
const key = createHash('md5')
.update(keyHex + EAMUSE_RC4_KEY, 'hex')
.digest();
.update(keyHex + EAMUSE_RC4_KEY, 'hex')
.digest();
return rc4('arc4', key)
.encodeBuffer(data)
return rc4('arc4', key).encodeBuffer(data);
}