mirror of
https://github.com/laochan-eacnet/backend.git
synced 2026-09-22 22:28:11 +03:00
working sdvx trial mode
This commit is contained in:
+38
-12
@@ -1,22 +1,48 @@
|
||||
import { Context } from '../types.js';
|
||||
import { eacnet } from '../decorators/eacnet.js';
|
||||
import { p2d, sdvx } from '../decorators/eacnet.js';
|
||||
import { v } from '../utils/kxml-value.js';
|
||||
import { singleton } from 'tsyringe';
|
||||
|
||||
@singleton()
|
||||
export class DefaultService {
|
||||
async default(ctx: Context) {
|
||||
const descriptor = {
|
||||
value: () => ({
|
||||
status: v.s32(0),
|
||||
error: v.s32(0),
|
||||
result: {
|
||||
dummy: v.u8(0),
|
||||
}
|
||||
})
|
||||
};
|
||||
if (ctx.service.name === 'p2d') {
|
||||
const descriptor = {
|
||||
value: () => ({
|
||||
status: v.s32(0),
|
||||
error: v.s32(0),
|
||||
result: {},
|
||||
})
|
||||
};
|
||||
|
||||
eacnet(ctx.service.name)(undefined, undefined, descriptor);
|
||||
return descriptor.value();
|
||||
p2d()(undefined, undefined, descriptor);
|
||||
return descriptor.value();
|
||||
} else if (ctx.service.name === 'sdvx') {
|
||||
const result = {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {},
|
||||
};
|
||||
|
||||
// handle ac relay
|
||||
if (ctx.eacnetRequest) {
|
||||
result['xrpc_status_code'] = v.s32(0);
|
||||
result['xrpc_fault_code'] = v.s32(0);
|
||||
result['response'] = {
|
||||
[ctx.eacnetRequest.module]: {
|
||||
$status: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const descriptor = {
|
||||
value: () => result,
|
||||
};
|
||||
|
||||
sdvx()(undefined, undefined, descriptor);
|
||||
return descriptor.value();
|
||||
}
|
||||
|
||||
throw new Error(`unsupported game ${ctx.service.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
import { eacnet } from "../../decorators/eacnet.js";
|
||||
import { p2d } from "../../decorators/eacnet.js";
|
||||
import { Context } from "../../types.js";
|
||||
import { v } from "../../utils/kxml-value.js";
|
||||
|
||||
export class Game {
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getChampionshipInfo() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -23,7 +23,7 @@ export class Game {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getServerValues() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -41,7 +41,7 @@ export class Game {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async checkGameVersion() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -52,7 +52,7 @@ export class Game {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getClearRate(ctx: Context) {
|
||||
const { play_style } = ctx.body as { play_style: number };
|
||||
return {
|
||||
@@ -63,7 +63,7 @@ export class Game {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getGoodsList() {
|
||||
const goods = [{
|
||||
goods_id: v.str('G1000000'),
|
||||
|
||||
@@ -2,32 +2,11 @@ import { v } from "../../utils/kxml-value.js";
|
||||
import { Game } from "./game.js";
|
||||
import { Service } from "./service.js";
|
||||
import { User } from "./user.js";
|
||||
import data from './data.json' with { type: "json" };
|
||||
import { inject, singleton } from "tsyringe";
|
||||
import { UserService } from "../../services/p2d/user.js";
|
||||
import { Music } from "./music.js";
|
||||
|
||||
function Combine(...modules: ({ new(): any })[]) {
|
||||
class Modules {
|
||||
constructor() {
|
||||
modules.forEach(v => Object.assign(this, new v()));
|
||||
}
|
||||
}
|
||||
|
||||
modules.forEach(v => {
|
||||
const descriptors = Object.getOwnPropertyDescriptors(v.prototype);
|
||||
|
||||
for (const name in descriptors) {
|
||||
if (name === 'constructor')
|
||||
continue;
|
||||
|
||||
const descriptor = descriptors[name];
|
||||
Object.defineProperty(Modules.prototype, name, descriptor);
|
||||
}
|
||||
});
|
||||
|
||||
return Modules;
|
||||
}
|
||||
import { Combine } from "../../utils/combine.js";
|
||||
import * as data from '../../datas/p2d.js'
|
||||
|
||||
@singleton()
|
||||
export default class extends Combine(Service, User, Game, Music) {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { PlayerPlayLog } from "../../types/index.js";
|
||||
import { eacnet } from "../../decorators/eacnet.js";
|
||||
import { p2d } from "../../decorators/eacnet.js";
|
||||
import { UserService } from "../../services/p2d/user.js";
|
||||
import { Context } from "../../types.js";
|
||||
import { v } from "../../utils/kxml-value.js";
|
||||
import { MUSIC_LIST } from "./index.js";
|
||||
import { Binary } from "mongodb";
|
||||
import data from './data.json' with { type: "json" };
|
||||
import * as data from '../../datas/p2d.js'
|
||||
|
||||
// user only needs to unlock omni music, which is temporary
|
||||
const userUnlockMusic = new Map<string, number>();
|
||||
@@ -13,7 +13,7 @@ const userUnlockMusic = new Map<string, number>();
|
||||
export class Music {
|
||||
userService: UserService;
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getMusicGhost(ctx: Context) {
|
||||
// playstyle is actually chart diff, game is sending wrong request
|
||||
// TODO: check game code and maybe patch it later
|
||||
@@ -85,7 +85,7 @@ export class Music {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async reportMusicResult(ctx: Context) {
|
||||
const result = ctx.body as PlayerPlayLog;
|
||||
result.player = ctx.token;
|
||||
@@ -131,7 +131,7 @@ export class Music {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async unlockMusic(ctx: Context) {
|
||||
const { music: { music_id } } = ctx.body as { music: { music_id: number } };
|
||||
userUnlockMusic.set(ctx.token, music_id);
|
||||
@@ -144,7 +144,7 @@ export class Music {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getMusicList(ctx: Context) {
|
||||
let music = [...MUSIC_LIST];
|
||||
|
||||
@@ -177,7 +177,7 @@ export class Music {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getMusicData(ctx: Context) {
|
||||
const { play_style } = ctx.body as { play_style: number };
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { eacnet } from '../../decorators/eacnet.js';
|
||||
import { p2d } from '../../decorators/eacnet.js';
|
||||
import { Context } from '../../types.js';
|
||||
import config from '../../utils/config.js';
|
||||
import { v } from '../../utils/kxml-value.js';
|
||||
|
||||
export class Service {
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async sendLog() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -12,7 +12,7 @@ export class Service {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getServerState() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -25,7 +25,7 @@ export class Service {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getServerClock() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -36,7 +36,7 @@ export class Service {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async heartbeat(ctx: Context) {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -51,7 +51,7 @@ export class Service {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async checkSendLogAvailable() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -63,7 +63,7 @@ export class Service {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getServices() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
|
||||
+18
-18
@@ -1,4 +1,4 @@
|
||||
import { eacnet } from "../../decorators/eacnet.js";
|
||||
import { p2d } from "../../decorators/eacnet.js";
|
||||
import { Context } from "../../types.js";
|
||||
import { v } from "../../utils/kxml-value.js";
|
||||
import { fromToken } from "../../utils/laochan-id.js";
|
||||
@@ -10,7 +10,7 @@ import { ITEM_LIST } from "./index.js";
|
||||
export class User {
|
||||
userService: UserService;
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async addPoint() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -18,7 +18,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async reserveChangePoint() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -26,7 +26,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async sendGradeCertificationLog(ctx: Context) {
|
||||
await this.userService.addCourseLog({
|
||||
player: ctx.token,
|
||||
@@ -39,7 +39,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async consumeItem(ctx: Context) {
|
||||
const { item_id } = ctx.body;
|
||||
const { items_count } = await this.userService.getCustomizeSetting(ctx.token);
|
||||
@@ -75,7 +75,7 @@ export class User {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async reserveConsumeItem() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -83,7 +83,7 @@ export class User {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getCustomizeSetting(ctx: Context) {
|
||||
const { customize, other_customize } = await this.userService.getCustomizeSetting(ctx.token);
|
||||
|
||||
@@ -103,7 +103,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async gameEnd() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -111,7 +111,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getPointList(ctx: Context) {
|
||||
const customize = await this.userService.getCustomizeSetting(ctx.token);
|
||||
|
||||
@@ -128,7 +128,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getPrivilegeClient() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -139,7 +139,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getPrivilegeServer() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -150,7 +150,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async savePlayData(ctx: Context) {
|
||||
const { pdata, check_sum } = ctx.body as { pdata: Buffer, check_sum: string };
|
||||
const localChecksum = sha256(pdata);
|
||||
@@ -167,7 +167,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getPlayData(ctx: Context) {
|
||||
const result = await this.userService.getPDataBinary(ctx.token);
|
||||
|
||||
@@ -190,7 +190,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async registPlayer(ctx: Context) {
|
||||
const { pdata, check_sum } = ctx.body as { pdata: Buffer, check_sum: string };
|
||||
const localChecksum = sha256(pdata);
|
||||
@@ -207,7 +207,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async checkPlayData(ctx: Context) {
|
||||
const { check_sum } = ctx.body as { check_sum: string };
|
||||
|
||||
@@ -249,7 +249,7 @@ export class User {
|
||||
};
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getRivalInfo(ctx: Context) {
|
||||
const rivalData = await this.userService.getPlayerRivalData(ctx.token);
|
||||
if (!rivalData.enabled) {
|
||||
@@ -320,7 +320,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getCompeScoreData() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
@@ -329,7 +329,7 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
@eacnet('p2d')
|
||||
@p2d()
|
||||
async getItemList(ctx: Context) {
|
||||
const { items_count } = await this.userService.getCustomizeSetting(ctx.token);
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { sdvx } from "../../decorators/eacnet.js";
|
||||
import { Context } from "../../types.js";
|
||||
import { v } from "../../utils/kxml-value.js";
|
||||
import * as data from '../../datas/sdvx.js';
|
||||
|
||||
export class AcRelay {
|
||||
@sdvx()
|
||||
async sv6_music_url(ctx: Context) {
|
||||
let { music_id } = ctx.body as { music_id: number | number[] };
|
||||
if (typeof music_id === 'number') {
|
||||
music_id = [music_id];
|
||||
}
|
||||
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
xrpc_status_code: v.s32(0),
|
||||
xrpc_fault_code: v.s32(0),
|
||||
response: {
|
||||
game: {
|
||||
$status: 0,
|
||||
music: music_id.map(id => {
|
||||
const music = data.musicDownloadLinks[id];
|
||||
|
||||
if (!music) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
music_id: v.s32(id),
|
||||
url: v.str(music.url),
|
||||
hash: v.str(music.hash),
|
||||
size: v.s32(music.size),
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
import { sdvx } from "../../decorators/eacnet.js";
|
||||
import { Combine } from "../../utils/combine.js";
|
||||
import config from "../../utils/config.js";
|
||||
import { v } from "../../utils/kxml-value.js";
|
||||
import { AcRelay } from "./ac-relay.js";
|
||||
|
||||
export default class extends Combine(AcRelay) {
|
||||
@sdvx()
|
||||
async getItemList() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
item_num: v.s32(0),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async getGoodsList() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
goods_num: v.s32(0),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async getUserIDs() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
card_num: v.str('0123456789ABCDEF'),
|
||||
ref_id: v.str('0123456789ABCDEF'),
|
||||
data_id: v.str('0123456789ABCDEF'),
|
||||
sns_id: v.str('012345678'),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async getSubscriptionStatus() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
subscription: {
|
||||
name: v.str('test'),
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async heartbeat() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
state: v.s32(1),
|
||||
next_clock: v.u64(new Date().valueOf() + 36e5),
|
||||
server_state: v.s32(1),
|
||||
mainte_start_clock: v.u64(0),
|
||||
mainte_end_clock: v.u64(0),
|
||||
usta_boot_status: v.s32(1),
|
||||
usta_time_remain: v.s32(0),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async checkVersion() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
permission: v.s32(1),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async getServerClock() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
server_clock: v.u64(new Date().valueOf()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@sdvx()
|
||||
async getServerState() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
server_state: v.s32(1),
|
||||
mainte_start_clock: v.u64(0),
|
||||
mainte_end_clock: v.u64(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@sdvx('SHIFT_JIS')
|
||||
async getServices() {
|
||||
return {
|
||||
status: v.s32(0),
|
||||
error_code: v.s32(0),
|
||||
response: {
|
||||
service_num: v.s32(18),
|
||||
service: [
|
||||
{
|
||||
service_name: v.str('acRelay'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/AcRelay`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('cancelReserveConsumeItem'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/CancelReserveConsumeItem`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('checkGameStart'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/CheckGameStart`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('checkVersion'),
|
||||
url: v.str(`${config.selfUrl}/needless_auth/CheckVersion`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('consumeItem'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/ConsumeItem`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getGoodsList'),
|
||||
url: v.str(`${config.selfUrl}/needless_auth/GetGoodsList`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getHash'),
|
||||
url: v.str(`${config.selfUrl}/needless_auth/GetHash`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getItemList'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/GetItemList`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getLauncherData'),
|
||||
url: v.str(`${config.selfUrl}/needless_auth/GetLauncherData`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getResourceInfo'),
|
||||
url: v.str(`${config.selfUrl}/needless_auth/GetResourceInfo`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getServerClock'),
|
||||
url: v.str(`${config.selfUrl}/pre_process/GetServerClock`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getServerState'),
|
||||
url: v.str(`${config.selfUrl}/pre_process/GetServerStatus`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getServices'),
|
||||
url: v.str(`${config.selfUrl}/pre_process/GetServices`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getSubscriptionStatus'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/GetSubscriptionStatus`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('getUserIDs'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/GetUserId`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('heartbeat'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/Heartbeat`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('reserveConsumeItem'),
|
||||
url: v.str(`${config.selfUrl}/need_auth/ReserveConsumeItem`),
|
||||
},
|
||||
{
|
||||
service_name: v.str('uploadFile'),
|
||||
url: v.str(`${config.selfUrl}/needless_auth/UploadFile`),
|
||||
},
|
||||
|
||||
],
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,30 @@ export async function initMongoDb() {
|
||||
meta.version = 1;
|
||||
}
|
||||
|
||||
if (meta.version < 2) {
|
||||
const collections = await db.listCollections().toArray();
|
||||
const tryRenameCollection = async (src: string, dest: string) => {
|
||||
if (!collections.some(v => v.name === src)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const col = db.collection(src);
|
||||
await col.rename(dest);
|
||||
};
|
||||
|
||||
await Promise.all([
|
||||
tryRenameCollection('player_play_data', 'p2d_play_data'),
|
||||
tryRenameCollection('player_music_data', 'p2d_music_data'),
|
||||
tryRenameCollection('player_play_log', 'p2d_play_log'),
|
||||
tryRenameCollection('player_course_log', 'p2d_course_log'),
|
||||
tryRenameCollection('player_customize_setting', 'p2d_customize_setting'),
|
||||
tryRenameCollection('player_rival_data', 'p2d_rival_data'),
|
||||
])
|
||||
|
||||
logger.info('upgraded database to ver 2, renamed prefix player to p2d.');
|
||||
meta.version = 2;
|
||||
}
|
||||
|
||||
await metaCol.updateOne({}, { $set: meta }, { upsert: true });
|
||||
return db;
|
||||
}
|
||||
|
||||
+7712
File diff suppressed because it is too large
Load Diff
+8287
File diff suppressed because it is too large
Load Diff
+17
-12
@@ -1,19 +1,24 @@
|
||||
import { LZ77 } from '../utils/lz77.js';
|
||||
import { toKBinXml } from '../utils/kbinxml.js';
|
||||
|
||||
export function eacnet(topName: string, 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 kxml = toKBinXml(topName, obj, encoding);
|
||||
const compressed = LZ77.compress(kxml.data);
|
||||
const result = Buffer.allocUnsafe(compressed.length + 0x2E);
|
||||
export function eacnet(protocol_name: string, topName: string, dataOffset: number) {
|
||||
return (encoding: 'UTF-8' | 'SHIFT_JIS' = 'UTF-8') => {
|
||||
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 kxml = toKBinXml(topName, obj, encoding);
|
||||
const compressed = LZ77.compress(kxml.data);
|
||||
const result = Buffer.allocUnsafe(compressed.length + dataOffset);
|
||||
|
||||
result.write('P2D:2015091800', 0, 'ascii');
|
||||
result.set(compressed, 0x2E);
|
||||
result.write(protocol_name, 0, 'ascii');
|
||||
result.set(compressed, dataOffset);
|
||||
|
||||
return result;
|
||||
} as unknown as any;
|
||||
return result;
|
||||
} as unknown as any;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const p2d = eacnet('P2D:2015091800', 'p2d', 0x2E);
|
||||
export const sdvx = eacnet('2020090800', 'eacnet', 0x2A);
|
||||
|
||||
@@ -6,16 +6,16 @@ import { fromKBinXml } from '../utils/kbinxml.js';
|
||||
export async function eacnet(ctx: Context, next: Next): Promise<any> {
|
||||
const body = ctx.request.body as {
|
||||
request: string;
|
||||
p2d_token: string;
|
||||
p2d_token?: string;
|
||||
} | undefined;
|
||||
|
||||
if (!body || !body.request) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const { request, p2d_token: token } = body;
|
||||
const { request } = body;
|
||||
|
||||
if (!request || !token) {
|
||||
if (!request) {
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -29,12 +29,28 @@ export async function eacnet(ctx: Context, next: Next): Promise<any> {
|
||||
const decoded = LZ77.decompress(buffer);
|
||||
const result = fromKBinXml(decoded);
|
||||
|
||||
const game = Object.keys(result)[0];
|
||||
if (result['eacnet']) {
|
||||
const info = result['eacnet'].info;
|
||||
ctx.token = info.token;
|
||||
|
||||
if (!(game in result)) {
|
||||
const request = result['eacnet'].request;
|
||||
if (!request) {
|
||||
return next();
|
||||
}
|
||||
|
||||
ctx.service = {
|
||||
name: info.game_id,
|
||||
method: request.method,
|
||||
};
|
||||
|
||||
ctx.body = request.data ?? {};
|
||||
ctx.eacnetRequest = request;
|
||||
return next();
|
||||
}
|
||||
|
||||
// for p2d
|
||||
const game = Object.keys(result)[0];
|
||||
|
||||
if (result[game].params) {
|
||||
ctx.body = result.p2d.params;
|
||||
} else {
|
||||
@@ -46,6 +62,6 @@ export async function eacnet(ctx: Context, next: Next): Promise<any> {
|
||||
method: result[game].method,
|
||||
}
|
||||
|
||||
ctx.token = token;
|
||||
ctx.token = body.p2d_token;
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -15,27 +15,27 @@ export class UserService {
|
||||
) { }
|
||||
|
||||
get playDataCol() {
|
||||
return this.db.collection<PlayerPlayData>('player_play_data');
|
||||
return this.db.collection<PlayerPlayData>('p2d_play_data');
|
||||
}
|
||||
|
||||
get musicDataCol() {
|
||||
return this.db.collection<PlayerMusicData>('player_music_data');
|
||||
return this.db.collection<PlayerMusicData>('p2d_music_data');
|
||||
}
|
||||
|
||||
get playLogCol() {
|
||||
return this.db.collection<PlayerPlayLog>('player_play_log');
|
||||
return this.db.collection<PlayerPlayLog>('p2d_play_log');
|
||||
}
|
||||
|
||||
get courseLogCol() {
|
||||
return this.db.collection<PlayerCourseLog>('player_course_log');
|
||||
return this.db.collection<PlayerCourseLog>('p2d_course_log');
|
||||
}
|
||||
|
||||
get customizeSettingCol() {
|
||||
return this.db.collection<PlayerCustomizeSetting>('player_customize_setting');
|
||||
return this.db.collection<PlayerCustomizeSetting>('p2d_customize_setting');
|
||||
}
|
||||
|
||||
get rivalDataCol() {
|
||||
return this.db.collection<PlayerRivalData>('player_rival_data');
|
||||
return this.db.collection<PlayerRivalData>('p2d_rival_data');
|
||||
}
|
||||
|
||||
addCourseLog(coruseLog: PlayerCourseLog) {
|
||||
|
||||
@@ -10,6 +10,13 @@ export interface ILaochanContext {
|
||||
method: string,
|
||||
};
|
||||
|
||||
eacnetRequest?: {
|
||||
service: string;
|
||||
module: string;
|
||||
method: string;
|
||||
data: unknown;
|
||||
};
|
||||
|
||||
logger: Logger;
|
||||
body?: unknown;
|
||||
resolve: <T>(resolveToken: InjectionToken<T>) => T;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
export function Combine(...modules: ({ new(): any })[]) {
|
||||
class Modules {
|
||||
constructor() {
|
||||
modules.forEach(v => Object.assign(this, new v()));
|
||||
}
|
||||
}
|
||||
|
||||
modules.forEach(v => {
|
||||
const descriptors = Object.getOwnPropertyDescriptors(v.prototype);
|
||||
|
||||
for (const name in descriptors) {
|
||||
if (name === 'constructor')
|
||||
continue;
|
||||
|
||||
const descriptor = descriptors[name];
|
||||
Object.defineProperty(Modules.prototype, name, descriptor);
|
||||
}
|
||||
});
|
||||
|
||||
return Modules;
|
||||
}
|
||||
Reference in New Issue
Block a user