add serviceKxml decorator

This commit is contained in:
GEEKiDoS
2024-03-08 15:11:38 +08:00
parent f4a9c7ced5
commit 08d6d5fa3d
17 changed files with 637 additions and 475 deletions
+1 -1
View File
@@ -22,7 +22,7 @@
// 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": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-explicit-any": "off"
}
+128 -1
View File
@@ -17,6 +17,7 @@
"fast-xml-parser": "^4.3.2",
"koa": "^2.15.0",
"lodash": "^4.17.21",
"mongodb": "^6.4.0",
"pug": "^3.0.2",
"reflect-metadata": "^0.2.1",
"tslib": "~2.6",
@@ -1741,6 +1742,14 @@
"resolved": "https://registry.npmmirror.com/@kamyu/kbinxml/-/kbinxml-2.0.2.tgz",
"integrity": "sha512-41ZiqAunpiwF0yu4LtWcYyF4BIhRGrOPMRVe4eAXWQ1KRL1cZI0+XGqnQIIxlhTcfBMDMLUnrmqpXRAh1sxhPQ=="
},
"node_modules/@mongodb-js/saslprep": {
"version": "1.1.5",
"resolved": "https://registry.npmmirror.com/@mongodb-js/saslprep/-/saslprep-1.1.5.tgz",
"integrity": "sha512-XLNOMH66KhJzUJNwT/qlMnS4WsNDWD5ASdyaSH3EtK+F4r/CFGa3jT4GNi4mfOitGvWXtdLgQJkQjxSVrio+jA==",
"dependencies": {
"sparse-bitfield": "^3.0.3"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -2117,6 +2126,19 @@
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
"dev": true
},
"node_modules/@types/webidl-conversions": {
"version": "7.0.3",
"resolved": "https://registry.npmmirror.com/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
"integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA=="
},
"node_modules/@types/whatwg-url": {
"version": "11.0.4",
"resolved": "https://registry.npmmirror.com/@types/whatwg-url/-/whatwg-url-11.0.4.tgz",
"integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==",
"dependencies": {
"@types/webidl-conversions": "*"
}
},
"node_modules/@types/yargs": {
"version": "17.0.32",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
@@ -2700,6 +2722,14 @@
"node-int64": "^0.4.0"
}
},
"node_modules/bson": {
"version": "6.4.0",
"resolved": "https://registry.npmmirror.com/bson/-/bson-6.4.0.tgz",
"integrity": "sha512-6/gSSEdbkuFlSb+ufj5jUSU4+wo8xQOwm2bDSqwmxiPE17JTpsP63eAwoN8iF8Oy4gJYj+PAL3zdRCTdaw5Y1g==",
"engines": {
"node": ">=16.20.1"
}
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -5187,6 +5217,11 @@
"node": ">= 0.6"
}
},
"node_modules/memory-pager": {
"version": "1.5.0",
"resolved": "https://registry.npmmirror.com/memory-pager/-/memory-pager-1.5.0.tgz",
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg=="
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -5264,6 +5299,60 @@
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/mongodb": {
"version": "6.4.0",
"resolved": "https://registry.npmmirror.com/mongodb/-/mongodb-6.4.0.tgz",
"integrity": "sha512-MdFHsyb1a/Ee0H3NmzWTSLqchacDV/APF0H6BNQvraWrOiIocys2EmTFZPgHxWhcfO94c1F34I9MACU7x0hHKA==",
"dependencies": {
"@mongodb-js/saslprep": "^1.1.0",
"bson": "^6.4.0",
"mongodb-connection-string-url": "^3.0.0"
},
"engines": {
"node": ">=16.20.1"
},
"peerDependencies": {
"@aws-sdk/credential-providers": "^3.188.0",
"@mongodb-js/zstd": "^1.1.0",
"gcp-metadata": "^5.2.0",
"kerberos": "^2.0.1",
"mongodb-client-encryption": ">=6.0.0 <7",
"snappy": "^7.2.2",
"socks": "^2.7.1"
},
"peerDependenciesMeta": {
"@aws-sdk/credential-providers": {
"optional": true
},
"@mongodb-js/zstd": {
"optional": true
},
"gcp-metadata": {
"optional": true
},
"kerberos": {
"optional": true
},
"mongodb-client-encryption": {
"optional": true
},
"snappy": {
"optional": true
},
"socks": {
"optional": true
}
}
},
"node_modules/mongodb-connection-string-url": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz",
"integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==",
"dependencies": {
"@types/whatwg-url": "^11.0.2",
"whatwg-url": "^13.0.0"
}
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -5807,7 +5896,6 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
"engines": {
"node": ">=6"
}
@@ -6165,6 +6253,14 @@
"source-map": "^0.6.0"
}
},
"node_modules/sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmmirror.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
"integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
"dependencies": {
"memory-pager": "^1.0.2"
}
},
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -6384,6 +6480,17 @@
"resolved": "https://registry.npmmirror.com/token-stream/-/token-stream-1.0.0.tgz",
"integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg=="
},
"node_modules/tr46": {
"version": "4.1.1",
"resolved": "https://registry.npmmirror.com/tr46/-/tr46-4.1.1.tgz",
"integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
"dependencies": {
"punycode": "^2.3.0"
},
"engines": {
"node": ">=14"
}
},
"node_modules/ts-api-utils": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz",
@@ -6703,6 +6810,26 @@
"makeerror": "1.0.12"
}
},
"node_modules/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
"engines": {
"node": ">=12"
}
},
"node_modules/whatwg-url": {
"version": "13.0.0",
"resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-13.0.0.tgz",
"integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==",
"dependencies": {
"tr46": "^4.1.1",
"webidl-conversions": "^7.0.0"
},
"engines": {
"node": ">=16"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+1
View File
@@ -50,6 +50,7 @@
"fast-xml-parser": "^4.3.2",
"koa": "^2.15.0",
"lodash": "^4.17.21",
"mongodb": "^6.4.0",
"pug": "^3.0.2",
"reflect-metadata": "^0.2.1",
"tslib": "~2.6",
+25
View File
@@ -0,0 +1,25 @@
import { Collection, Db } from "mongodb"
import { container } from "tsyringe"
export function col(
collectionName: string
): PropertyDecorator {
let col: Collection | undefined;
return (target: object, key: string | symbol) => {
Reflect.deleteProperty(target, key);
Reflect.defineProperty(target, key, {
get: () => {
if (!col) {
const db = container.resolve(Db);
col = db.collection(collectionName);
}
return col;
},
enumerable: true,
configurable: true,
});
}
}
+110 -95
View File
@@ -2,127 +2,142 @@ import _ from 'lodash';
import { to_bin } from '@kamyu/kbinxml';
function serializeValue(value: any, type: string): string {
if (
[
's8',
'u8',
's16',
'u16',
's32',
'u32',
's64',
'u64',
'float',
'double',
].includes(type)
) {
return value.toString();
if (
[
's8',
'u8',
's16',
'u16',
's32',
'u32',
's64',
'u64',
'float',
'double',
].includes(type)
) {
return value.toString();
}
if (['b', 'bool'].includes('type')) {
return value ? '1' : '0';
}
if (['bin', 'binary'].includes(type)) {
if (!(value instanceof Buffer)) {
throw new Error('binary with non-buffer value');
}
if (['b', 'bool'].includes('type')) {
return value ? '1' : '0';
return value.toString('hex');
}
if (['ip4', 'str', 'string'].includes(type)) {
return value;
}
if (type == 'time') {
if (value instanceof Date) {
return Math.floor(value.valueOf() / 1000).toString();
}
if (['bin', 'binary'].includes(type)) {
if (!(value instanceof Buffer)) {
throw new Error('binary with non-buffer value');
}
return value.toString('hex');
if (typeof value === 'number') {
return value.toString();
}
if (['ip4', 'str', 'string'].includes(type)) {
return value;
}
throw new Error('time with not date or number');
}
if (type == 'time') {
if (value instanceof Date) {
return Math.floor(value.valueOf() / 1000).toString();
}
if (typeof value === 'number') {
return value.toString();
}
throw new Error('time with not date or number');
}
throw new Error(`unsupported type ${type}`);
throw new Error(`unsupported type ${type}`);
}
function serializeObject(obj: Object, name: string, linePrefix: string = '') {
let output = `${linePrefix}<${name}`;
let output = `${linePrefix}<${name}`;
const entries = Object.entries(obj);
const attrs = entries
.filter(v => v[0].startsWith('$'))
.map(v => [v[0].substring(1), v[1]]);
const entries = Object.entries(obj);
const attrs = entries
.filter(v => v[0].startsWith('$'))
.map(v => [v[0].substring(1), v[1]]);
for (const attr of attrs) {
output += ` ${attr[0]}="${_.escape(attr[1])}"`;
for (const attr of attrs) {
output += ` ${attr[0]}="${_.escape(attr[1])}"`;
}
// handle kxml value shit
const value = entries.find(v => v[0] == '__value');
if (value && value[1] instanceof Array) {
output += ` __count="${value[1].length}"`;
}
if (value && value[1] instanceof Buffer) {
output += ` __size="${value[1].length}"`;
}
output += '>';
if (value) {
const type = attrs.find(v => v[0] == '__type');
if (!type) {
// or normal xml innerXml?
throw new Error(`value with no type in ${name}`);
}
// handle kxml value shit
const value = entries.find(v => v[0] == '__value');
output += (value[1] instanceof Array ? value[1] : [value[1]])
.map(v => serializeValue(v, type[1]))
.join(' ');
} else {
const elements = entries
.filter(v => !v[0].startsWith('$'));
if (value && value[1] instanceof Array) {
output += ` __count="${value[1].length}"`;
}
if (elements.length) {
output += '\n';
if (value && value[1] instanceof Buffer) {
output += ` __size="${value[1].length}"`;
}
for (const element of elements) {
if (element[1] instanceof Array) {
for (const item of element[1])
output += serializeObject(item, element[0], linePrefix + ' ');
output += '>';
if (value) {
const type = attrs.find(v => v[0] == '__type');
if (!type) {
// or normal xml innerXml?
throw new Error(`value with no type in ${name}`);
continue;
}
output += (value[1] instanceof Array ? value[1] : [value[1]])
.map(v => serializeValue(v, type[1]))
.join(' ');
} else {
const elements = entries
.filter(v => !v[0].startsWith('$'));
output += serializeObject(element[1], element[0], linePrefix + ' ');
}
if (elements.length) {
output += '\n';
for (const element of elements) {
if (element[1] instanceof Array) {
for (const item of element[1])
output += serializeObject(item, element[0], linePrefix + ' ');
continue;
}
output += serializeObject(element[1], element[0], linePrefix + ' ');
}
output += linePrefix;
}
output += linePrefix;
}
}
return output + `</${name}>\n`;
return output + `</${name}>\n`;
}
export function kxml(topName: string = 'response', encoding: 'UTF-8' | 'SHIFT_JIS' = 'UTF-8'): MethodDecorator {
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}"?>` + serializeObject(obj, topName);
const kxml = to_bin(xml);
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}"?>` + serializeObject(obj, topName);
const kxml = to_bin(xml);
return Buffer.from(kxml.data);
} as unknown as any;
};
return Buffer.from(kxml.data);
} as unknown as any;
}
}
export function serviceKxml(service: string, topName: string = 'response', encoding: 'UTF-8' | 'SHIFT_JIS' = 'UTF-8'): (method: string) => MethodDecorator {
return function (method: string) {
const toKxml = kxml(topName, encoding);
return function (_target, _propertyKey, descriptor) {
const orig = descriptor.value as Function;
descriptor.value = async function (...args: any[]) {
const obj = await orig.apply(this, args);
return { [service]: { method, ...obj } };
} as unknown as any;
toKxml(_target, _propertyKey, descriptor);
}
}
}
// console.log(serializeObject({
+4 -2
View File
@@ -58,6 +58,7 @@ async function main(): Promise<void> {
throw new Error('invaild model');
}
// eslint-disable-next-line prefer-const
let [serviceName, method] = ctx.query.f.split('.');
ctx.model = ctx.query.model;
@@ -65,7 +66,7 @@ async function main(): Promise<void> {
name: serviceName,
method,
};
ctx.body = ctx.body[ctx.service.name];
ctx.logger = ctx.service
? register(`logger:${ctx.service.name}`, {
@@ -90,9 +91,10 @@ async function main(): Promise<void> {
`./services/${ctx.service.name}.js`
);
}
service = register(ctx.service.name, {
useClass: module.default,
});
} catch (e) {
logger.error(
+17 -17
View File
@@ -1,19 +1,19 @@
import { kxml } from "../../decorators/to-kxml.js";
import { serviceKxml } from "../../decorators/to-kxml.js";
const resp = serviceKxml('IIDX31music');
export default class {
@kxml()
async crate() {
return {
IIDX31music: {
$expire: 1800,
c: [
// {
// $__type: 's32',
// $mid: 11451,
// __value: new Array(20).fill(-1),
// }
],
}
};
}
}
@resp('crate')
async crate() {
return {
$expire: 1800,
c: [
// {
// $__type: 's32',
// $mid: 11451,
// __value: new Array(20).fill(-1),
// }
],
};
}
}
+249 -247
View File
@@ -1,257 +1,259 @@
import { kxml } from "../../decorators/to-kxml.js";
import { serviceKxml } from "../../decorators/to-kxml.js";
import { Context } from "../../types.js";
interface GetPCDataCall {
ccode: string,
cid: string,
ctype: string,
did: string,
lid: string,
pid: string,
rid: string,
ccode: string,
cid: string,
ctype: string,
did: string,
lid: string,
pid: string,
rid: string,
}
const resp = serviceKxml('IIDX31pc');
export default class {
@kxml()
async common() {
return {
IIDX31pc: {
system_voice_phase: {
$phase: 0,
},
ir: {
$beat: 0,
},
vip_pass_black: {},
common_evnet: {
$flg: -1,
},
play_video: {},
music_retry: {},
display_asio_logo: {},
lane_gacha: {},
tourism_booster: {},
cm_movie_info: {
$type: 3,
},
monthly_mranking: {
$__type: 'u16',
__value: [],
},
total_mranking: {
$__type: 'u16',
__value: [],
},
hitchart: [{
$kind: 0,
$period: 0,
ranking: [{
$music_id: 31021,
$rank: 1
}]
}],
$expire: 180,
}
};
}
@resp('common')
async common() {
return {
system_voice_phase: {
$phase: 0,
},
ir: {
$beat: 0,
},
vip_pass_black: {},
common_evnet: {
$flg: -1,
},
play_video: {},
music_retry: {},
display_asio_logo: {},
lane_gacha: {},
tourism_booster: {},
cm_movie_info: {
$type: 3,
},
monthly_mranking: {
$__type: 'u16',
__value: [],
},
total_mranking: {
$__type: 'u16',
__value: [],
},
hitchart: [{
$kind: 0,
$period: 0,
ranking: [{
$music_id: 31021,
$rank: 1
}]
}],
$expire: 180,
};
}
getPlayerPcData(_: string) {
const data = {
d_auto_adjust: 0,
d_auto_scrach: 0,
d_camera_layout: 0,
d_classic_hispeed: 0,
d_disp_judge: 0,
d_gauge_disp: 0,
d_ghost_score: 0,
d_gno: 0,
d_graph_score: 0,
d_gtype: 0,
d_hispeed: 0.000000,
d_judge: 0,
d_judgeAdj: 0,
d_lane_brignt: 0,
d_liflen: 0,
d_notes: 0.000000,
d_opstyle: 0,
d_pace: 0,
d_sdlen: 0,
d_sdtype: 0,
d_sorttype: 0,
d_sub_gno: 0,
d_timing: 0,
d_timing_split: 0,
d_tsujigiri_disp: 0,
d_visualization: 0,
dach: 0,
dp_opt: 1048577,
dp_opt2: 1048577,
dpnum: 0,
gpos: 0,
id: 0,
idstr: '00000000',
mode: 3,
name: 'MK_',
ngrade: 0,
pid: 48,
player_kind: 0,
pmode: 0,
rtype: 0,
s_auto_adjust: 1,
s_auto_scrach: 0,
s_camera_layout: 0,
s_classic_hispeed: 0,
s_disp_judge: 1,
s_gauge_disp: 0,
s_ghost_score: 0,
s_gno: 0,
s_graph_score: 0,
s_gtype: 1,
s_hispeed: 7.888014,
s_judge: 0,
s_judgeAdj: -22,
s_lane_brignt: 0,
s_liflen: 90,
s_notes: 28.497925,
s_opstyle: 2,
s_pace: 0,
s_sdlen: 258,
s_sdtype: 1,
s_sorttype: 0,
s_sub_gno: 0,
s_timing: 1,
s_timing_split: 1,
s_tsujigiri_disp: 0,
s_visualization: 0,
sach: 49,
sp_opt: 17180950528,
spnum: 2,
};
return Object.fromEntries(
Object.entries(data).map(v => ['$' + v[0], v[1]])
);
}
@kxml()
get(ctx: Context) {
const { cid } = ctx.body as GetPCDataCall;
return {
pcdata: this.getPlayerPcData(cid),
bind_eaappli: {},
secret: {
flg1: {
$__type: 's64',
__value: [-1, -1, 1048575],
},
flg2: {
$__type: 's64',
__value: [-1, -1, 0],
},
flg3: {
$__type: 's64',
__value: [-1, -1, 0],
},
flg4: {
$__type: 's64',
__value: [-1, -1, 0],
},
},
favorite: {
sp_mlist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
sp_clist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
dp_mlist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
dp_clist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
},
extra_favorite: [{
$folder_id: 0,
sp_mlist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
sp_clist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
dp_mlist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
dp_clist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
}, {
$folder_id: 0,
sp_mlist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
sp_clist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
dp_mlist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
dp_clist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
}],
grade: {
$dgid: -1,
$sgid: -1,
g: {
$__type: 'u8',
__value: [0, 13, 3, 58],
}
},
skin: {
$__type: 's16',
__value: new Array(20).fill(0),
},
tdjskin: {
$__type: 's16',
__value: [0, 0, 0, 0],
},
qprodata: {
$__type: 'u32',
__value: [0, 0, 0, 0, 0],
},
spdp_rival: {
$flg: 1,
},
rlist: {},
ex: {},
secret_course_data: {},
weekly: {
$mid: 31048,
$wid: 2041,
},
weekly_score: [],
visitor: {
$anum: 1,
$pnum: 1,
$snum: 1,
$vs_flg: 0,
},
step: {
}
@resp('get')
get(ctx: Context) {
const { cid } = ctx.body as GetPCDataCall;
return {
pcdata: this.getPlayerPcData(cid),
bind_eaappli: {},
secret: {
flg1: {
$__type: 's64',
__value: [-1, -1, 1048575],
},
flg2: {
$__type: 's64',
__value: [-1, -1, 0],
},
flg3: {
$__type: 's64',
__value: [-1, -1, 0],
},
flg4: {
$__type: 's64',
__value: [-1, -1, 0],
},
},
favorite: {
sp_mlist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
sp_clist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
dp_mlist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
dp_clist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
},
extra_favorite: [{
$folder_id: 0,
sp_mlist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
sp_clist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
dp_mlist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
dp_clist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
}, {
$folder_id: 0,
sp_mlist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
sp_clist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
dp_mlist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
dp_clist: {
$__type: 'bin',
__value: Buffer.alloc(1, 0),
},
}],
grade: {
$dgid: -1,
$sgid: -1,
g: {
$__type: 'u8',
__value: [0, 13, 3, 58],
}
},
skin: {
$__type: 's16',
__value: new Array(20).fill(0),
},
tdjskin: {
$__type: 's16',
__value: [0, 0, 0, 0],
},
qprodata: {
$__type: 'u32',
__value: [0, 0, 0, 0, 0],
},
spdp_rival: {
$flg: 1,
},
rlist: {},
ex: {},
secret_course_data: {},
weekly: {
$mid: 31048,
$wid: 2041,
},
weekly_score: [],
visitor: {
$anum: 1,
$pnum: 1,
$snum: 1,
$vs_flg: 0,
},
step: {
}
}
}
private getPlayerPcData(id: string) {
const data = {
d_auto_adjust: 0,
d_auto_scrach: 0,
d_camera_layout: 0,
d_classic_hispeed: 0,
d_disp_judge: 0,
d_gauge_disp: 0,
d_ghost_score: 0,
d_gno: 0,
d_graph_score: 0,
d_gtype: 0,
d_hispeed: 0.000000,
d_judge: 0,
d_judgeAdj: 0,
d_lane_brignt: 0,
d_liflen: 0,
d_notes: 0.000000,
d_opstyle: 0,
d_pace: 0,
d_sdlen: 0,
d_sdtype: 0,
d_sorttype: 0,
d_sub_gno: 0,
d_timing: 0,
d_timing_split: 0,
d_tsujigiri_disp: 0,
d_visualization: 0,
dach: 0,
dp_opt: 1048577,
dp_opt2: 1048577,
dpnum: 0,
gpos: 0,
id: 0,
idstr: '00000000',
mode: 3,
name: 'MK_',
ngrade: 0,
pid: 48,
player_kind: 0,
pmode: 0,
rtype: 0,
s_auto_adjust: 1,
s_auto_scrach: 0,
s_camera_layout: 0,
s_classic_hispeed: 0,
s_disp_judge: 1,
s_gauge_disp: 0,
s_ghost_score: 0,
s_gno: 0,
s_graph_score: 0,
s_gtype: 1,
s_hispeed: 7.888014,
s_judge: 0,
s_judgeAdj: -22,
s_lane_brignt: 0,
s_liflen: 90,
s_notes: 28.497925,
s_opstyle: 2,
s_pace: 0,
s_sdlen: 258,
s_sdtype: 1,
s_sorttype: 0,
s_sub_gno: 0,
s_timing: 1,
s_timing_split: 1,
s_tsujigiri_disp: 0,
s_visualization: 0,
sach: 49,
sp_opt: 17180950528,
spnum: 2,
cardid: id,
};
return Object.fromEntries(
Object.entries(data).map(v => ['$' + v[0], v[1]])
);
}
}
+18 -18
View File
@@ -1,22 +1,22 @@
import { kxml } from "../../decorators/to-kxml.js";
import { serviceKxml } from "../../decorators/to-kxml.js";
const resp = serviceKxml('IIDX31shop');
export default class {
@kxml()
async getname() {
return {
IIDX31shop: {
$cls_opt: 14400,
$expire: 0,
$opname: '原神, 启动',
$pid: 30,
}
};
}
@resp('getname')
async getname() {
return {
$cls_opt: 14400,
$expire: 0,
$opname: '原神, 启动',
$pid: 30,
};
}
@kxml()
async sentinfo() {
return {
IIDX31shop: {},
};
}
@resp('sentinfo')
async sentinfo() {
return {
$status: 0,
};
}
}
+10 -10
View File
@@ -1,13 +1,13 @@
import { kxml } from "../../decorators/to-kxml.js";
import { serviceKxml } from "../../decorators/to-kxml.js";
const resp = serviceKxml('IIDX31streaming');
export default class {
@kxml()
common() {
return {
IIDX31streaming: {
$expire: Math.floor(new Date().valueOf() / 1000) + 259200,
cm_info: {},
}
};
}
@resp('common')
common() {
return {
$expire: Math.floor(new Date().valueOf() / 1000) + 259200,
cm_info: {},
};
}
}
+36 -33
View File
@@ -1,46 +1,49 @@
import { kxml } from "../../decorators/to-kxml.js";
import { serviceKxml } from "../../decorators/to-kxml.js";
import { Context } from "../../types.js";
interface CardInquire {
cardid: string,
cardtype: string,
cardid: string,
cardtype: string,
}
interface CardAuth {
pass: string,
refid: string,
pass: string,
refid: string,
}
const resp = serviceKxml('cardmng');
export default class {
@kxml()
inquire(ctx: Context) {
const { cardid, cardtype } = ctx.body as CardInquire;
ctx.logger.info('card %s (type %d) inquire', cardid, cardtype);
@resp('authpass')
authpass(ctx: Context) {
const { refid, pass } = ctx.body as CardAuth;
ctx.logger.info('auth %s with pass %s', refid, pass);
return {
cardmng: {
$binded: 1,
$dataid: cardid,
$ecflag: 1,
$expired: 0,
$method: 'inquire',
$newflag: 0,
$refid: cardid,
$status: 0,
}
};
}
return {
$status: 0,
};
}
@resp('getrefid')
getrefid() {
return {
@kxml()
authpass(ctx: Context) {
const { refid, pass } = ctx.body as CardAuth;
ctx.logger.info('auth %s with pass %s', refid, pass);
return {
$cardmng: {
method: 'authpass',
status: 0,
}
};
}
}
@resp('inquire')
inquire(ctx: Context) {
const { cardid, cardtype } = ctx.body as CardInquire;
ctx.logger.info('card %s (type %d) inquire', cardid, cardtype);
return {
$binded: 1,
$newflag: 0,
$ecflag: 1,
$expired: 0,
$dataid: cardid,
$refid: cardid,
$status: 0,
};
}
}
-2
View File
@@ -1,8 +1,6 @@
import { singleton } from 'tsyringe';
import { Context } from '../types.js';
import { kxml } from '../decorators/to-kxml.js';
@singleton()
export class DefaultService {
@kxml()
async default(ctx: Context) {
+6 -9
View File
@@ -1,16 +1,13 @@
import { kxml } from '../../decorators/to-kxml.js';
import { singleton } from 'tsyringe';
import { serviceKxml } from '../../decorators/to-kxml.js';
const resp = serviceKxml('message');
@singleton()
export default class {
@kxml()
@resp('get')
async get(): Promise<object> {
return {
message: {
$status: 0,
$expire: 60,
$method: 'get',
}
$status: 0,
$expire: 60,
};
}
}
-2
View File
@@ -1,7 +1,5 @@
import { singleton } from 'tsyringe';
import { DefaultService } from '../default.js';
@singleton()
export default class extends DefaultService {
list = this.default;
}
-2
View File
@@ -1,7 +1,5 @@
import { singleton } from 'tsyringe';
import { DefaultService } from '../default.js';
@singleton()
export default class extends DefaultService {
put = this.default;
}
+9 -12
View File
@@ -1,18 +1,15 @@
import { kxml } from '../../decorators/to-kxml.js';
import { singleton } from 'tsyringe';
import { serviceKxml } from '../../decorators/to-kxml.js';
const resp = serviceKxml('pcbtracker');
@singleton()
export default class {
@kxml()
async process(): Promise<object> {
@resp('alive')
async alive(): Promise<object> {
return {
pcbtracker: {
$ecenable: 1,
$expire: 3600,
$method: 'alive',
$status: 0,
$time: Math.floor(new Date().valueOf() / 1000),
}
$ecenable: 1,
$expire: 3600,
$status: 0,
$time: Math.floor(new Date().valueOf() / 1000),
};
}
}
+23 -24
View File
@@ -1,10 +1,12 @@
import { singleton } from 'tsyringe';
import config from '../../utils/config.js';
import { kxml } from '../../decorators/to-kxml.js';
import { serviceKxml } from '../../decorators/to-kxml.js';
const resp = serviceKxml('services');
@singleton()
export default class {
@kxml()
@resp('get')
async get() {
const selfServices = [
'services', 'dlstatus', 'cardmng',
@@ -14,27 +16,24 @@ export default class {
]
return {
services: {
$expire: 43200,
$method: 'get',
$mode: 'operation',
$product_domain: 1,
$statuc: 0,
item: [
{
$name: 'keepalive',
$url: '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',
},
{
$name: 'ntp',
$url: config.ntpUrl,
},
...selfServices.map(v => ({
$name: v,
$url: config.selfUrl,
}))
]
}
}
$expire: 43200,
$mode: 'operation',
$product_domain: 1,
$statuc: 0,
item: [
{
$name: 'keepalive',
$url: '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',
},
{
$name: 'ntp',
$url: config.ntpUrl,
},
...selfServices.map(v => ({
$name: v,
$url: config.selfUrl,
}))
]
};
}
}