idz: Hoist userdb code
This commit is contained in:
committed by
da5669c09fdb0a288ba01e259a609d7779ac7fc9
parent
6dceb7c48a
commit
f959993197
@@ -0,0 +1,15 @@
|
||||
export function bitmap<T extends number>(buf: Buffer): Set<T> {
|
||||
const result = new Set<T>();
|
||||
|
||||
for (let byteNo = 0; byteNo < buf.length; byteNo++) {
|
||||
const byte = buf.readUInt8(byteNo);
|
||||
|
||||
for (let bitNo = 0; bitNo < 8; bitNo++) {
|
||||
if (byte & (1 << bitNo)) {
|
||||
result.add((8 * byteNo + bitNo) as T);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Car, CarSelector } from "../model/car";
|
||||
|
||||
export function car(buf: Buffer): Car {
|
||||
const field_04: number[] = [];
|
||||
|
||||
for (let i = 0; i < 32; i++) {
|
||||
field_04.push(buf.readUInt16LE(0x0004 + 2 * i));
|
||||
}
|
||||
|
||||
return {
|
||||
field_00: buf.readUInt16LE(0x0000),
|
||||
field_02: buf.readUInt16LE(0x0002),
|
||||
field_04,
|
||||
selector: buf.readUInt16LE(0x0044) as CarSelector,
|
||||
field_46: buf.readUInt16LE(0x0046),
|
||||
field_48: buf.readUInt16LE(0x0048),
|
||||
field_4a: buf.readUInt16LE(0x004a),
|
||||
field_4c: buf.readUInt32LE(0x004c),
|
||||
field_50_lo: buf.readUInt32LE(0x0050),
|
||||
field_50_hi: buf.readUInt32LE(0x0054),
|
||||
field_58: buf.readUInt16LE(0x0058),
|
||||
field_5a: buf.readUInt8(0x005a),
|
||||
field_5b: buf.readUInt8(0x005b),
|
||||
field_5c: buf.readUInt16LE(0x005c),
|
||||
field_5e: buf.readUInt16LE(0x005e),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { BackgroundCode, TitleCode } from "../model/base";
|
||||
import { Chara } from "../model/chara";
|
||||
|
||||
export function chara(buf: Buffer): Chara {
|
||||
return {
|
||||
gender: buf.readUInt16LE(0x00) === 0 ? "male" : "female",
|
||||
field_02: buf.readUInt16LE(0x02),
|
||||
field_04: buf.readUInt16LE(0x04),
|
||||
field_06: buf.readUInt16LE(0x06),
|
||||
field_08: buf.readUInt16LE(0x08),
|
||||
field_0a: buf.readUInt16LE(0x0a),
|
||||
field_0c: buf.readUInt16LE(0x0c),
|
||||
field_0e: buf.readUInt16LE(0x0e),
|
||||
title: buf.readUInt16LE(0x10) as TitleCode, // Swapped on load
|
||||
background: buf.readUInt16LE(0x12) as BackgroundCode, // Swapped on load
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { MissionGrid } from "../model/mission";
|
||||
|
||||
export function mission(buf: Buffer): MissionGrid[] {
|
||||
const grids = new Array();
|
||||
|
||||
for (let gridNo = 0; gridNo < 5; gridNo++) {
|
||||
const grid: MissionGrid = { cells: [] };
|
||||
|
||||
for (let cellNo = 0; cellNo < 9; cellNo++) {
|
||||
let cell = 0;
|
||||
let mask = 1 << cellNo;
|
||||
|
||||
for (let sliceNo = 0; sliceNo < 3; sliceNo++) {
|
||||
const slice = buf.readUInt16LE(0x0c * sliceNo + 0x02 * gridNo);
|
||||
|
||||
if (slice & mask) {
|
||||
cell |= 1 << sliceNo;
|
||||
}
|
||||
}
|
||||
|
||||
grid.cells.push(cell);
|
||||
}
|
||||
|
||||
grids.push(grid);
|
||||
}
|
||||
|
||||
return grids;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { CheckTeamNameRequest } from "../request/checkTeamName";
|
||||
|
||||
checkTeamName.msgCode = 0x00a2;
|
||||
checkTeamName.msgLen = 0x0040;
|
||||
|
||||
export function checkTeamName(buf: Buffer): CheckTeamNameRequest {
|
||||
return { type: "check_team_name_req" };
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { CreateAutoTeamRequest } from "../request/createAutoTeam";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
createAutoTeam.msgCode = 0x007b;
|
||||
createAutoTeam.msgLen = 0x0010;
|
||||
|
||||
export function createAutoTeam(buf: Buffer): CreateAutoTeamRequest {
|
||||
return {
|
||||
type: "create_auto_team_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
field_0008: buf.readUInt32LE(0x0008),
|
||||
field_000C: buf.readUInt8(0x000c),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import iconv from "iconv-lite";
|
||||
|
||||
import { car } from "./_car";
|
||||
import { chara } from "./_chara";
|
||||
import { CreateProfileRequest } from "../request/createProfile";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
createProfile.msgCode = 0x0066;
|
||||
createProfile.msgLen = 0x00c0;
|
||||
|
||||
export function createProfile(buf: Buffer): CreateProfileRequest {
|
||||
return {
|
||||
type: "create_profile_req",
|
||||
aimeId: buf.readInt32LE(0x0004) as AimeId,
|
||||
luid: buf.slice(0x0008, buf.indexOf("\0", 0x0008)).toString("ascii"),
|
||||
name: iconv.decode(
|
||||
buf.slice(0x001e, buf.indexOf("\0", 0x001e)),
|
||||
"shift_jis"
|
||||
),
|
||||
field_0034: buf.readUInt32LE(0x0034),
|
||||
car: car(buf.slice(0x0040, 0x00a0)),
|
||||
chara: chara(buf.slice(0x00a0, 0x00b4)),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import iconv from "iconv-lite";
|
||||
|
||||
import { CreateTeamRequest } from "../request/createTeam";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
createTeam.msgCode = 0x0071;
|
||||
createTeam.msgLen = 0x0050;
|
||||
|
||||
export function createTeam(buf: Buffer): CreateTeamRequest {
|
||||
return {
|
||||
type: "create_team_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
teamName: iconv.decode(
|
||||
buf.slice(0x0008, buf.indexOf("\0", 0x0008)),
|
||||
"shift_jis"
|
||||
),
|
||||
field_0028: buf.readUInt16LE(0x0028),
|
||||
field_002C: buf.readUInt32LE(0x002c),
|
||||
nameBg: buf.readUInt8(0x0030),
|
||||
field_0032: buf.readUInt16LE(0x0032),
|
||||
prevTeamId: buf.readUInt32LE(0x0034),
|
||||
pcbId: buf.slice(0x0038, buf.indexOf("\0", 0x0038)).toString("ascii"),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { DiscoverProfileRequest } from "../request/discoverProfile";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
discoverProfile.msgCode = 0x006b;
|
||||
discoverProfile.msgLen = 0x0010;
|
||||
|
||||
export function discoverProfile(buf: Buffer): DiscoverProfileRequest {
|
||||
return {
|
||||
type: "discover_profile_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
import logger from "debug";
|
||||
import { Transform } from "stream";
|
||||
|
||||
import { checkTeamName } from "./checkTeamName";
|
||||
import { createProfile } from "./createProfile";
|
||||
import { createTeam } from "./createTeam";
|
||||
import { createAutoTeam } from "./createAutoTeam";
|
||||
import { discoverProfile } from "./discoverProfile";
|
||||
import { load2on2_v1, load2on2_v2 } from "./load2on2";
|
||||
import { loadConfig } from "./loadConfig";
|
||||
import { loadConfig2 } from "./loadConfig2";
|
||||
import { loadEventInfo } from "./loadEventInfo";
|
||||
import { loadGacha } from "./loadGacha";
|
||||
import { loadGarage } from "./loadGarage";
|
||||
import { loadGeneralReward1, loadGeneralReward2 } from "./loadGeneralReward";
|
||||
import { loadGhost } from "./loadGhost";
|
||||
import { loadProfile2, loadProfile3 } from "./loadProfile";
|
||||
import { loadRewardTable } from "./loadRewardTable";
|
||||
import { loadServerList } from "./loadServerList";
|
||||
import { loadStocker } from "./loadStocker";
|
||||
import { loadTeam } from "./loadTeam";
|
||||
import { loadTeamRanking, loadTeamRanking2 } from "./loadTeamRanking";
|
||||
import { loadTopTen1 } from "./loadTopTen1";
|
||||
import { loadTopTen2 } from "./loadTopTen2";
|
||||
import { lockGarage } from "./lockGarage";
|
||||
import { lockProfile } from "./lockProfile";
|
||||
import { msg00AD } from "./msg00AD";
|
||||
import { saveExpedition1, saveExpedition2 } from "./saveExpedition";
|
||||
import { saveGarage } from "./saveGarage";
|
||||
import { saveNewCar } from "./saveNewCar";
|
||||
import { saveProfile2 } from "./saveProfile2";
|
||||
import { saveProfile3 } from "./saveProfile3";
|
||||
import { saveSettings } from "./saveSettings";
|
||||
import { saveStocker } from "./saveStocker";
|
||||
import { saveTeamBanner } from "./saveTeamBanner";
|
||||
import { saveTimeAttack1, saveTimeAttack2 } from "./saveTimeAttack";
|
||||
import { saveTopic } from "./saveTopic";
|
||||
import { unlockProfile } from "./unlockProfile";
|
||||
import { updateProvisionalStoreRank } from "./updateProvisionalStoreRank";
|
||||
import { updateTeamLeader } from "./updateTeamLeader";
|
||||
import { updateTeamMember } from "./updateTeamMember";
|
||||
import {
|
||||
updateStoryClearNum1,
|
||||
updateStoryClearNum2,
|
||||
} from "./updateStoryClearNum";
|
||||
import { Request } from "../request";
|
||||
import { updateResult } from "./updateResult";
|
||||
import { updateTeamPoints } from "./updateTeamPoints";
|
||||
import { updateUiReport } from "./updateUiReport";
|
||||
import { updateUserLog } from "./updateUserLog";
|
||||
import { lockProfileExtend } from "./lockProfileExtend";
|
||||
|
||||
const debug = logger("app:idz:userdb:decoder");
|
||||
|
||||
export type ReaderFn = ((buf: Buffer) => Request) & {
|
||||
msgCode: number;
|
||||
msgLen: number;
|
||||
};
|
||||
|
||||
const funcList: ReaderFn[] = [
|
||||
checkTeamName,
|
||||
createAutoTeam,
|
||||
createProfile,
|
||||
createTeam,
|
||||
discoverProfile,
|
||||
load2on2_v1,
|
||||
load2on2_v2,
|
||||
loadConfig,
|
||||
loadConfig2,
|
||||
loadEventInfo,
|
||||
loadGacha,
|
||||
loadGarage,
|
||||
loadGeneralReward1,
|
||||
loadGeneralReward2,
|
||||
loadGhost,
|
||||
loadProfile2,
|
||||
loadProfile3,
|
||||
loadRewardTable,
|
||||
loadServerList,
|
||||
loadStocker,
|
||||
loadTeam,
|
||||
loadTeamRanking,
|
||||
loadTeamRanking2,
|
||||
loadTopTen1,
|
||||
loadTopTen2,
|
||||
lockGarage,
|
||||
lockProfile,
|
||||
lockProfileExtend,
|
||||
msg00AD,
|
||||
saveExpedition1,
|
||||
saveExpedition2,
|
||||
saveGarage,
|
||||
saveNewCar,
|
||||
saveProfile2,
|
||||
saveProfile3,
|
||||
saveSettings,
|
||||
saveStocker,
|
||||
saveTeamBanner,
|
||||
saveTimeAttack1,
|
||||
saveTimeAttack2,
|
||||
saveTopic,
|
||||
unlockProfile,
|
||||
updateProvisionalStoreRank,
|
||||
updateResult,
|
||||
updateStoryClearNum1,
|
||||
updateStoryClearNum2,
|
||||
updateTeamLeader,
|
||||
updateTeamMember,
|
||||
updateTeamPoints,
|
||||
updateUiReport,
|
||||
updateUserLog,
|
||||
];
|
||||
|
||||
const readerFns = new Map<number, ReaderFn>();
|
||||
const msgLengths = new Map<number, number>();
|
||||
|
||||
for (const fn of funcList) {
|
||||
readerFns.set(fn.msgCode, fn);
|
||||
msgLengths.set(fn.msgCode, fn.msgLen);
|
||||
}
|
||||
|
||||
function readHeader(buf: Buffer) {
|
||||
return {
|
||||
blah: "blah",
|
||||
};
|
||||
}
|
||||
|
||||
export class Decoder extends Transform {
|
||||
state: Buffer;
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
readableObjectMode: true,
|
||||
writableObjectMode: true,
|
||||
});
|
||||
|
||||
this.state = Buffer.alloc(0);
|
||||
}
|
||||
|
||||
_transform(chunk: Buffer, encoding, callback) {
|
||||
this.state = Buffer.concat([this.state, chunk]);
|
||||
|
||||
// Read header
|
||||
|
||||
if (this.state.length < 0x04) {
|
||||
return callback(null);
|
||||
}
|
||||
|
||||
const magic = this.state.readUInt32LE(0);
|
||||
|
||||
if (magic !== 0x01020304) {
|
||||
return callback(
|
||||
new Error(
|
||||
"Invalid magic number, cryptographic processing probably incorrect."
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (this.state.length < 0x30) {
|
||||
return callback(null);
|
||||
}
|
||||
|
||||
const header = readHeader(this.state);
|
||||
|
||||
if (this.state.length < 0x32) {
|
||||
return callback(null);
|
||||
}
|
||||
|
||||
const msgCode = this.state.readUInt16LE(0x30);
|
||||
const msgLen = msgLengths.get(msgCode);
|
||||
|
||||
if (msgLen === undefined) {
|
||||
return callback(
|
||||
new Error(
|
||||
`Unknown command code ${msgCode.toString(16)}, cannot continue`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (this.state.length < 0x30 + msgLen) {
|
||||
return callback(null);
|
||||
}
|
||||
|
||||
const reqBuf = this.state.slice(0, 0x30 + msgLen);
|
||||
const payloadBuf = reqBuf.slice(0x30);
|
||||
|
||||
if (debug.enabled) {
|
||||
debug("Raw: %s", reqBuf.toString("hex"));
|
||||
debug("Header: %j", header);
|
||||
}
|
||||
|
||||
const reader = readerFns.get(msgCode);
|
||||
|
||||
if (reader === undefined) {
|
||||
return callback(
|
||||
new Error(`No reader for command code ${msgCode.toString(16)}`)
|
||||
);
|
||||
}
|
||||
|
||||
const payload = reader(payloadBuf);
|
||||
|
||||
debug("Payload: %j", payload);
|
||||
|
||||
return callback(null, payload);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { ExtId } from "../model/base";
|
||||
import { Team } from "../model/team";
|
||||
import { Load2on2Request1, Load2on2Request2 } from "../request/load2on2";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
load2on2_v1.msgCode = 0x00b0;
|
||||
load2on2_v1.msgLen = 0x0010;
|
||||
|
||||
export function load2on2_v1(buf: Buffer): Load2on2Request1 {
|
||||
return {
|
||||
type: "load_2on2_req",
|
||||
format: 1,
|
||||
field_0002: buf.readUInt16LE(0x0002),
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
teamId: buf.readUInt32LE(0x0008) as ExtId<Team>,
|
||||
};
|
||||
}
|
||||
|
||||
load2on2_v2.msgCode = 0x0132;
|
||||
load2on2_v2.msgLen = 0x0010;
|
||||
|
||||
export function load2on2_v2(buf: Buffer): Load2on2Request2 {
|
||||
return {
|
||||
type: "load_2on2_req",
|
||||
format: 2,
|
||||
field_0002: buf.readUInt16LE(0x0002),
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
teamId: buf.readUInt32LE(0x0008) as ExtId<Team>,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { LoadConfigRequest } from "../request/loadConfig";
|
||||
|
||||
loadConfig.msgCode = 0x0004;
|
||||
loadConfig.msgLen = 0x0050;
|
||||
|
||||
export function loadConfig(): LoadConfigRequest {
|
||||
return { type: "load_config_req" };
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { LoadConfigRequest2 } from "../request/loadConfig2";
|
||||
|
||||
loadConfig2.msgCode = 0x00ab;
|
||||
loadConfig2.msgLen = 0x0010;
|
||||
|
||||
export function loadConfig2(): LoadConfigRequest2 {
|
||||
return { type: "load_config_v2_req" };
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { LoadEventInfoRequest } from "../request/loadEventInfo";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
loadEventInfo.msgCode = 0x00be;
|
||||
loadEventInfo.msgLen = 0x0010;
|
||||
|
||||
export function loadEventInfo(buf: Buffer): LoadEventInfoRequest {
|
||||
return {
|
||||
type: "load_event_info_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { LoadGachaRequest } from "../request/loadGacha";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
loadGacha.msgCode = 0x00c1;
|
||||
loadGacha.msgLen = 0x0010;
|
||||
|
||||
export function loadGacha(buf: Buffer): LoadGachaRequest {
|
||||
return {
|
||||
type: "load_gacha_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { LoadGarageRequest } from "../request/loadGarage";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
loadGarage.msgCode = 0x0090;
|
||||
loadGarage.msgLen = 0x0010;
|
||||
|
||||
export function loadGarage(buf: Buffer): LoadGarageRequest {
|
||||
return {
|
||||
type: "load_garage_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
fetchOffset: buf.readUInt8(0x0008),
|
||||
field_000A: buf.readUInt16LE(0x000a),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import {
|
||||
LoadGeneralRewardRequest1,
|
||||
LoadGeneralRewardRequest2,
|
||||
} from "../request/loadGeneralReward";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
loadGeneralReward1.msgCode = 0x009c;
|
||||
loadGeneralReward1.msgLen = 0x0010;
|
||||
|
||||
export function loadGeneralReward1(buf: Buffer): LoadGeneralRewardRequest1 {
|
||||
return {
|
||||
type: "load_general_reward_req",
|
||||
format: 1,
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
};
|
||||
}
|
||||
|
||||
loadGeneralReward2.msgCode = 0x013b;
|
||||
loadGeneralReward2.msgLen = 0x0010;
|
||||
|
||||
export function loadGeneralReward2(buf: Buffer): LoadGeneralRewardRequest2 {
|
||||
return {
|
||||
type: "load_general_reward_req",
|
||||
format: 2,
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { LoadGhostRequest } from "../request/loadGhost";
|
||||
|
||||
loadGhost.msgCode = 0x00a0;
|
||||
loadGhost.msgLen = 0x0010;
|
||||
|
||||
export function loadGhost(buf: Buffer): LoadGhostRequest {
|
||||
return {
|
||||
type: "load_ghost_req",
|
||||
field_0002: buf.readUInt16LE(0x0002),
|
||||
field_0004: buf.readUInt16LE(0x0004),
|
||||
field_0008: buf.readUInt32LE(0x0008),
|
||||
field_000C: buf.readUInt16LE(0x000c),
|
||||
field_000E: buf.readUInt16LE(0x000e),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import {
|
||||
LoadProfileRequest2,
|
||||
LoadProfileRequest3,
|
||||
} from "../request/loadProfile";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
loadProfile2.msgCode = 0x0067;
|
||||
loadProfile2.msgLen = 0x0020;
|
||||
|
||||
export function loadProfile2(buf: Buffer): LoadProfileRequest2 {
|
||||
return {
|
||||
type: "load_profile_req",
|
||||
format: 2,
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
luid: buf.slice(0x0008, buf.indexOf("\0", 0x0008)).toString("ascii"),
|
||||
};
|
||||
}
|
||||
|
||||
loadProfile3.msgCode = 0x0012f;
|
||||
loadProfile3.msgLen = 0x0020;
|
||||
|
||||
export function loadProfile3(buf: Buffer): LoadProfileRequest3 {
|
||||
return {
|
||||
type: "load_profile_req",
|
||||
format: 3,
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
luid: buf.slice(0x0008, buf.indexOf("\0", 0x0008)).toString("ascii"),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { LoadRewardTableRequest } from "../request/loadRewardTable";
|
||||
|
||||
loadRewardTable.msgCode = 0x0086;
|
||||
loadRewardTable.msgLen = 0x0010;
|
||||
|
||||
export function loadRewardTable(): LoadRewardTableRequest {
|
||||
return {
|
||||
type: "load_reward_table_req",
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { LoadServerListRequest } from "../request/loadServerList";
|
||||
|
||||
loadServerList.msgCode = 0x0006;
|
||||
loadServerList.msgLen = 0x0020;
|
||||
|
||||
export function loadServerList(): LoadServerListRequest {
|
||||
return { type: "load_server_list_req" };
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { LoadStockerRequest } from "../request/loadStocker";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
loadStocker.msgCode = 0x00a7;
|
||||
loadStocker.msgLen = 0x0010;
|
||||
|
||||
export function loadStocker(buf: Buffer): LoadStockerRequest {
|
||||
return {
|
||||
type: "load_stocker_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { LoadTeamRequest } from "../request/loadTeam";
|
||||
import { ExtId } from "../model/base";
|
||||
import { Team } from "../model/team";
|
||||
|
||||
loadTeam.msgCode = 0x0077;
|
||||
loadTeam.msgLen = 0x0010;
|
||||
|
||||
export function loadTeam(buf: Buffer): LoadTeamRequest {
|
||||
const extId = buf.readUInt32LE(0x0008);
|
||||
|
||||
return {
|
||||
type: "load_team_req",
|
||||
aimeId: buf.readUInt32LE(0x0004),
|
||||
teamExtId: extId !== 0xffffffff ? (extId as ExtId<Team>) : undefined,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { LoadTeamRankingRequest } from "../request/loadTeamRanking";
|
||||
|
||||
loadTeamRanking.msgCode = 0x00b9;
|
||||
loadTeamRanking.msgLen = 0x0010;
|
||||
|
||||
export function loadTeamRanking(buf: Buffer): LoadTeamRankingRequest {
|
||||
return {
|
||||
type: "load_team_ranking_req",
|
||||
};
|
||||
}
|
||||
|
||||
// not sure what the difference is...
|
||||
|
||||
loadTeamRanking2.msgCode = 0x00bb;
|
||||
loadTeamRanking2.msgLen = 0x0010;
|
||||
|
||||
export function loadTeamRanking2(buf: Buffer): LoadTeamRankingRequest {
|
||||
return {
|
||||
type: "load_team_ranking_req",
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { ExtId, RouteNo } from "../model/base";
|
||||
import { Team } from "../model/team";
|
||||
import {
|
||||
LoadTopTenRequest,
|
||||
LoadTopTenRequestSelector,
|
||||
} from "../request/loadTopTen";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
loadTopTen1.msgCode = 0x00b5;
|
||||
loadTopTen1.msgLen = 0x00e0;
|
||||
|
||||
export function loadTopTen1(buf: Buffer): LoadTopTenRequest {
|
||||
const selectors = new Array<LoadTopTenRequestSelector>();
|
||||
|
||||
for (let i = 0; i < 32; i++) {
|
||||
selectors.push({
|
||||
routeNo: (buf.readUInt16LE(0x0004 + 2 * i) >> 1) as RouteNo,
|
||||
minTimestamp: new Date(buf.readUInt32LE(0x0044 + 4 * i) * 1000 + 1000),
|
||||
});
|
||||
}
|
||||
|
||||
const profileId = buf.readUInt32LE(0x00c8);
|
||||
const teamId = buf.readUInt32LE(0x00cc);
|
||||
|
||||
return {
|
||||
type: "load_top_ten_req",
|
||||
field_2: buf.readUInt16LE(0x0002), // Bitmask selector
|
||||
selectors,
|
||||
field_C4: buf.readUInt8(0x00c4), // Boolean, true if profile ID is set
|
||||
field_C5: buf.readUInt8(0x00c5), // Always zero
|
||||
field_C6: buf.readUInt16LE(0x00c6),
|
||||
aimeId: profileId !== 0 ? (profileId as AimeId) : undefined,
|
||||
teamId: teamId !== 0xffffffff ? (teamId as ExtId<Team>) : undefined,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { ExtId, RouteNo } from "../model/base";
|
||||
import { Team } from "../model/team";
|
||||
import {
|
||||
LoadTopTenRequest,
|
||||
LoadTopTenRequestSelector,
|
||||
} from "../request/loadTopTen";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
loadTopTen2.msgCode = 0x012c;
|
||||
loadTopTen2.msgLen = 0x0110;
|
||||
|
||||
export function loadTopTen2(buf: Buffer): LoadTopTenRequest {
|
||||
const selectors = new Array<LoadTopTenRequestSelector>();
|
||||
|
||||
for (let i = 0; i < 40; i++) {
|
||||
selectors.push({
|
||||
routeNo: (buf.readUInt16LE(0x0004 + 2 * i) >> 1) as RouteNo,
|
||||
minTimestamp: new Date(buf.readUInt32LE(0x0054 + 4 * i) * 1000 + 1000),
|
||||
});
|
||||
}
|
||||
|
||||
const profileId = buf.readUInt32LE(0x00f8);
|
||||
const teamId = buf.readUInt32LE(0x00fc);
|
||||
|
||||
return {
|
||||
type: "load_top_ten_req",
|
||||
field_2: buf.readUInt16LE(0x0002), // Bitmask selector
|
||||
selectors,
|
||||
field_C4: buf.readUInt8(0x00f4), // Boolean, true if profile ID is set
|
||||
field_C5: buf.readUInt8(0x00f5), // Always zero
|
||||
field_C6: buf.readUInt16LE(0x00f6),
|
||||
aimeId: profileId !== 0 ? (profileId as AimeId) : undefined,
|
||||
teamId: teamId !== 0xffffffff ? (teamId as ExtId<Team>) : undefined,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { LockGarageRequest } from "../request/lockGarage";
|
||||
|
||||
lockGarage.msgCode = 0x00a9;
|
||||
lockGarage.msgLen = 0x0010;
|
||||
|
||||
export function lockGarage(buf: Buffer): LockGarageRequest {
|
||||
return {
|
||||
type: "lock_garage_request",
|
||||
field_0004: buf.readUInt32LE(0x0004),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { LockProfileRequest } from "../request/lockProfile";
|
||||
|
||||
lockProfile.msgCode = 0x0069;
|
||||
lockProfile.msgLen = 0x0020;
|
||||
|
||||
export function lockProfile(buf: Buffer): LockProfileRequest {
|
||||
return {
|
||||
type: "lock_profile_req",
|
||||
aimeId: buf.readUInt32LE(0x0004),
|
||||
pcbId: buf.slice(0x0008, buf.indexOf("\0", 0x0008)).toString("ascii"),
|
||||
field_0018: buf.readUInt16LE(0x0018),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { LockProfileExtendRequest } from "../request/lockProfileExtend";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
lockProfileExtend.msgCode = 0x006d;
|
||||
lockProfileExtend.msgLen = 0x0020;
|
||||
|
||||
export function lockProfileExtend(buf: Buffer): LockProfileExtendRequest {
|
||||
return {
|
||||
type: "lock_profile_extend_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
luid: buf.slice(0x0008, buf.indexOf("\0")).toString("ascii"),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { Message00AD } from "../request/msg00AD";
|
||||
|
||||
msg00AD.msgCode = 0x00ad;
|
||||
msg00AD.msgLen = 0x061c;
|
||||
|
||||
export function msg00AD(buf: Buffer): Message00AD {
|
||||
return { type: "msg_00AD_req" };
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import {
|
||||
SaveExpeditionRequest1,
|
||||
SaveExpeditionRequest2,
|
||||
} from "../request/saveExpedition";
|
||||
|
||||
saveExpedition1.msgCode = 0x008c;
|
||||
saveExpedition1.msgLen = 0x0010;
|
||||
|
||||
export function saveExpedition1(buf: Buffer): SaveExpeditionRequest1 {
|
||||
return {
|
||||
type: "save_expedition_req",
|
||||
format: 1,
|
||||
field_0004: buf.readUInt32LE(0x0004),
|
||||
};
|
||||
}
|
||||
|
||||
saveExpedition2.msgCode = 0x013f;
|
||||
saveExpedition2.msgLen = 0x0010;
|
||||
|
||||
export function saveExpedition2(buf: Buffer): SaveExpeditionRequest2 {
|
||||
return {
|
||||
type: "save_expedition_req",
|
||||
format: 2,
|
||||
field_0004: buf.readUInt32LE(0x0004),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { car } from "./_car";
|
||||
import { SaveGarageRequest } from "../request/saveGarage";
|
||||
|
||||
saveGarage.msgCode = 0x008e;
|
||||
saveGarage.msgLen = 0x0090;
|
||||
|
||||
export function saveGarage(buf: Buffer): SaveGarageRequest {
|
||||
const field_0068: number[] = [];
|
||||
|
||||
for (let offset = 0x0068; offset < 0x007c; offset += 2) {
|
||||
field_0068.push(buf.readUInt16LE(offset));
|
||||
}
|
||||
|
||||
return {
|
||||
type: "save_garage_req",
|
||||
aimeId: buf.readUInt32LE(0x0004),
|
||||
payload: car(buf.slice(0x0008, 0x0068)),
|
||||
field_0068,
|
||||
field_0080: buf.readUInt8(0x0080),
|
||||
field_0081: buf.readUInt8(0x0081) !== 0,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { car } from "./_car";
|
||||
import { SaveNewCarRequest } from "../request/saveNewCar";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
saveNewCar.msgCode = 0x0079;
|
||||
saveNewCar.msgLen = 0x0090;
|
||||
|
||||
export function saveNewCar(buf: Buffer): SaveNewCarRequest {
|
||||
return {
|
||||
type: "save_new_car_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
luid: buf.slice(0x0008, buf.indexOf(0, 0x0008)).toString("ascii"),
|
||||
car: car(buf.slice(0x0020, 0x0080)),
|
||||
field_0080: buf.readUInt32LE(0x0080),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import { car } from "./_car";
|
||||
import { mission } from "./_mission";
|
||||
import { BackgroundCode, CourseNo, TitleCode } from "../model/base";
|
||||
import { SaveProfileRequest2 } from "../request/saveProfile";
|
||||
import { bitmap } from "./_bitmap";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
saveProfile2.msgCode = 0x0068;
|
||||
saveProfile2.msgLen = 0x0940;
|
||||
|
||||
export function saveProfile2(buf: Buffer): SaveProfileRequest2 {
|
||||
const storyRows = new Array();
|
||||
|
||||
for (let i = 0; i < 9; i++) {
|
||||
const cells = new Array();
|
||||
const rowOffset = 0x01a8 + i * 0x3c;
|
||||
|
||||
for (let j = 0; j < 9; j++) {
|
||||
const a = buf.readUInt32LE(rowOffset + 0x04 + j * 4);
|
||||
const b = buf.readUInt16LE(rowOffset + 0x28 + j * 2);
|
||||
const cell = { a, b };
|
||||
|
||||
cells.push(cell);
|
||||
}
|
||||
|
||||
const row = { cells };
|
||||
|
||||
storyRows.push(row);
|
||||
}
|
||||
|
||||
const coursePlays = new Map<CourseNo, number>();
|
||||
|
||||
for (let i = 0; i < 16; i++) {
|
||||
coursePlays.set(i as CourseNo, buf.readUInt16LE(0x04c0 + 2 * i));
|
||||
}
|
||||
|
||||
const freeCar = {
|
||||
validFrom: buf.readUInt32LE(0x0138),
|
||||
};
|
||||
|
||||
const freeContinue = {
|
||||
validFrom: buf.readUInt32LE(0x0038),
|
||||
validTo: buf.readUInt32LE(0x003c),
|
||||
};
|
||||
|
||||
return {
|
||||
type: "save_profile_req",
|
||||
format: 2,
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
lv: buf.readUInt16LE(0x0026),
|
||||
exp: buf.readUInt32LE(0x0028),
|
||||
fame: buf.readUInt32LE(0x0468),
|
||||
dpoint: buf.readUInt32LE(0x0464),
|
||||
mileage: buf.readUInt32LE(0x0008),
|
||||
title: buf.readUInt16LE(0x0040) as TitleCode,
|
||||
titles: bitmap(buf.slice(0x0042, 0x00f6)),
|
||||
background: buf.readUInt8(0x0750) as BackgroundCode,
|
||||
coursePlays,
|
||||
missions: {
|
||||
team: mission(buf.slice(0x03c4, 0x03e6)),
|
||||
solo: mission(buf.slice(0x0724, 0x0746)),
|
||||
},
|
||||
car: car(buf.slice(0x0834, 0x0894)),
|
||||
story: {
|
||||
x: buf.readUInt16LE(0x06fc),
|
||||
y: buf.readUInt8(0x06e0),
|
||||
rows: storyRows,
|
||||
},
|
||||
unlocks: {
|
||||
auras: buf.readUInt16LE(0x010c),
|
||||
cup: buf.readUInt8(0x0110),
|
||||
gauges: buf.readUInt16LE(0x0114),
|
||||
music: buf.readUInt16LE(0x0140),
|
||||
lastMileageReward: buf.readUInt32LE(0x013c),
|
||||
},
|
||||
tickets: {
|
||||
freeCar:
|
||||
freeCar.validFrom !== 0
|
||||
? {
|
||||
validFrom: new Date(freeCar.validFrom * 1000),
|
||||
}
|
||||
: undefined,
|
||||
freeContinue:
|
||||
freeContinue.validFrom !== 0 && freeContinue.validTo !== 0
|
||||
? {
|
||||
validFrom: new Date(freeContinue.validFrom * 1000),
|
||||
validTo: new Date(freeContinue.validTo * 1000),
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
settings: {
|
||||
music: buf.readUInt16LE(0x045a),
|
||||
pack: buf.readUInt32LE(0x0034),
|
||||
aura: buf.readUInt8(0x002c),
|
||||
paperCup: buf.readUInt8(0x00f6),
|
||||
gauges: buf.readUInt8(0x00f7),
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import { car } from "./_car";
|
||||
import { mission } from "./_mission";
|
||||
import { BackgroundCode, CourseNo, TitleCode } from "../model/base";
|
||||
import { SaveProfileRequest2 } from "../request/saveProfile";
|
||||
import { bitmap } from "./_bitmap";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
saveProfile3.msgCode = 0x0138;
|
||||
saveProfile3.msgLen = 0x0a70;
|
||||
|
||||
export function saveProfile3(buf: Buffer): SaveProfileRequest2 {
|
||||
const storyRows = new Array();
|
||||
|
||||
// Story layout has changed somewhat...
|
||||
|
||||
for (let i = 0; i < 27; i++) {
|
||||
const cells = new Array();
|
||||
const rowOffset = 0x01ac + i * 0x18;
|
||||
|
||||
for (let j = 0; j < 9; j++) {
|
||||
const a = buf.readUInt8(rowOffset + 0x00 + j);
|
||||
const b = buf.readUInt8(rowOffset + 0x09 + j);
|
||||
const cell = { a, b };
|
||||
|
||||
cells.push(cell);
|
||||
}
|
||||
|
||||
const row = { cells };
|
||||
|
||||
storyRows.push(row);
|
||||
}
|
||||
|
||||
const coursePlays = new Map<CourseNo, number>();
|
||||
|
||||
for (let i = 0; i < 20; i++) {
|
||||
coursePlays.set(i as CourseNo, buf.readUInt16LE(0x0554 + 2 * i));
|
||||
}
|
||||
|
||||
const freeCar = {
|
||||
validFrom: buf.readUInt32LE(0x0138),
|
||||
};
|
||||
|
||||
const freeContinue = {
|
||||
validFrom: buf.readUInt32LE(0x0038),
|
||||
validTo: buf.readUInt32LE(0x003c),
|
||||
};
|
||||
|
||||
return {
|
||||
type: "save_profile_req",
|
||||
format: 2,
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
lv: buf.readUInt16LE(0x0026),
|
||||
exp: buf.readUInt32LE(0x0028),
|
||||
fame: buf.readUInt32LE(0x04fc),
|
||||
dpoint: buf.readUInt32LE(0x04f8),
|
||||
mileage: buf.readUInt32LE(0x0008),
|
||||
title: buf.readUInt16LE(0x0040) as TitleCode,
|
||||
titles: bitmap(buf.slice(0x0042, 0x00f6)),
|
||||
background: buf.readUInt8(0x0874) as BackgroundCode,
|
||||
coursePlays,
|
||||
missions: {
|
||||
team: mission(buf.slice(0x0430, 0x0452)),
|
||||
solo: mission(buf.slice(0x0848, 0x086a)),
|
||||
},
|
||||
car: car(buf.slice(0x0958, 0x09b8)),
|
||||
story: {
|
||||
x: buf.readUInt16LE(0x0818),
|
||||
y: buf.readUInt8(0x07fc),
|
||||
rows: storyRows,
|
||||
},
|
||||
unlocks: {
|
||||
auras: buf.readUInt16LE(0x010c),
|
||||
cup: buf.readUInt8(0x0110),
|
||||
gauges: buf.readUInt16LE(0x0114),
|
||||
music: buf.readUInt16LE(0x0140),
|
||||
lastMileageReward: buf.readUInt32LE(0x013c),
|
||||
},
|
||||
tickets: {
|
||||
freeCar:
|
||||
freeCar.validFrom !== 0
|
||||
? {
|
||||
validFrom: new Date(freeCar.validFrom * 1000),
|
||||
}
|
||||
: undefined,
|
||||
freeContinue:
|
||||
freeContinue.validFrom !== 0 && freeContinue.validTo !== 0
|
||||
? {
|
||||
validFrom: new Date(freeContinue.validFrom * 1000),
|
||||
validTo: new Date(freeContinue.validTo * 1000),
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
settings: {
|
||||
music: buf.readUInt16LE(0x04ee),
|
||||
pack: buf.readUInt32LE(0x0034),
|
||||
aura: buf.readUInt8(0x002c),
|
||||
paperCup: buf.readUInt8(0x00f6),
|
||||
gauges: buf.readUInt8(0x00f7),
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { SaveSettingsRequest } from "../request/saveSettings";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
saveSettings.msgCode = 0x00a5;
|
||||
saveSettings.msgLen = 0x0020;
|
||||
|
||||
export function saveSettings(buf: Buffer): SaveSettingsRequest {
|
||||
const pack = buf.readUInt32LE(0x000c);
|
||||
|
||||
return {
|
||||
type: "save_settings_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
dpoint: buf.readUInt32LE(0x0008),
|
||||
settings: {
|
||||
music: buf.readUInt16LE(0x0002),
|
||||
pack: buf.readUInt32LE(0x000c),
|
||||
paperCup: buf.readUInt8(0x0011),
|
||||
gauges: buf.readUInt8(0x0012),
|
||||
aura: buf.readUInt8(0x0013),
|
||||
},
|
||||
field_0010: buf.readUInt8(0x0010),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { bitmap } from "./_bitmap";
|
||||
import { chara } from "./_chara";
|
||||
import { CarSelector } from "../model/car";
|
||||
import { SaveStockerRequest } from "../request/saveStocker";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
saveStocker.msgCode = 0x00a6;
|
||||
saveStocker.msgLen = 0x00c0;
|
||||
|
||||
export function saveStocker(buf: Buffer): SaveStockerRequest {
|
||||
return {
|
||||
type: "save_stocker_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
|
||||
backgrounds: bitmap(buf.slice(0x0008, 0x002c)),
|
||||
selectedCar: buf.readUInt16LE(0x009c) as CarSelector,
|
||||
chara: chara(buf.slice(0x009e, 0x00b2)),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { SaveTeamBannerRequest } from "../request/saveTeamBanner";
|
||||
import { ExtId } from "../model/base";
|
||||
import { Team } from "../model/team";
|
||||
|
||||
saveTeamBanner.msgCode = 0x0089;
|
||||
saveTeamBanner.msgLen = 0x0010;
|
||||
|
||||
export function saveTeamBanner(buf: Buffer): SaveTeamBannerRequest {
|
||||
return {
|
||||
type: "save_team_banner_req",
|
||||
teamExtId: buf.readUInt32LE(0x0004) as ExtId<Team>,
|
||||
nameBg: buf.readUInt32LE(0x0008),
|
||||
nameFx: buf.readUInt32LE(0x000c),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { RouteNo } from "../model/base";
|
||||
import { CarSelector } from "../model/car";
|
||||
import { SaveTimeAttackRequest } from "../request/saveTimeAttack";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
function saveTimeAttack(buf: Buffer): SaveTimeAttackRequest {
|
||||
return {
|
||||
type: "save_time_attack_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
dayNight: buf.readUInt8(0x0054) & 1,
|
||||
payload: {
|
||||
routeNo: (buf.readUInt8(0x0054) >> 1) as RouteNo,
|
||||
timestamp: new Date(buf.readUInt32LE(0x0058) * 1000),
|
||||
flags: buf.readUInt8(0x005c),
|
||||
totalTime: buf.readUInt32LE(0x0018) / 1000,
|
||||
sectionTimes: [
|
||||
buf.readUInt32LE(0x0024) / 1000,
|
||||
buf.readUInt32LE(0x0028) / 1000,
|
||||
buf.readUInt32LE(0x002c) / 1000,
|
||||
],
|
||||
grade: buf.readUInt8(0x0062),
|
||||
carSelector: buf.readUInt16LE(0x000c) as CarSelector,
|
||||
},
|
||||
field_0002: buf.readUInt16LE(0x0002),
|
||||
field_0008: buf.readUInt32LE(0x0008),
|
||||
field_0012: buf.readUInt8(0x0012),
|
||||
field_0015: buf.readUInt8(0x0015),
|
||||
field_005D: buf.readUInt8(0x005d),
|
||||
field_005E: buf.readUInt16LE(0x005e),
|
||||
field_0060: buf.readUInt16LE(0x0060),
|
||||
};
|
||||
}
|
||||
|
||||
// There is ... literally no difference between these messages other than their
|
||||
// request code..? Even the response uses the same response code, despite
|
||||
// the request codes differing.
|
||||
|
||||
saveTimeAttack1.msgCode = 0x00cd;
|
||||
saveTimeAttack1.msgLen = 0x0080;
|
||||
|
||||
export function saveTimeAttack1(buf: Buffer): SaveTimeAttackRequest {
|
||||
return saveTimeAttack(buf);
|
||||
}
|
||||
|
||||
saveTimeAttack2.msgCode = 0x0136;
|
||||
saveTimeAttack2.msgLen = 0x0080;
|
||||
|
||||
export function saveTimeAttack2(buf: Buffer): SaveTimeAttackRequest {
|
||||
return saveTimeAttack(buf);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { SaveTopicRequest } from "../request/saveTopic";
|
||||
|
||||
saveTopic.msgCode = 0x009a;
|
||||
saveTopic.msgLen = 0x0010;
|
||||
|
||||
export function saveTopic(buf: Buffer): SaveTopicRequest {
|
||||
const aimeId = buf.readUInt32LE(0x0004);
|
||||
|
||||
return {
|
||||
type: "save_topic_req",
|
||||
aimeId: aimeId !== 0xffffffff ? aimeId : undefined,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { UnlockProfileRequest } from "../request/unlockProfile";
|
||||
|
||||
unlockProfile.msgCode = 0x006f;
|
||||
unlockProfile.msgLen = 0x0020;
|
||||
|
||||
export function unlockProfile(buf: Buffer): UnlockProfileRequest {
|
||||
return {
|
||||
type: "unlock_profile_req",
|
||||
aimeId: buf.readUInt32LE(0x0004),
|
||||
pcbId: buf.slice(0x0008, buf.indexOf("\0", 0x0008)).toString("ascii"),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { UpdateProvisionalStoreRankRequest } from "../request/updateProvisionalStoreRank";
|
||||
|
||||
updateProvisionalStoreRank.msgCode = 0x0082;
|
||||
updateProvisionalStoreRank.msgLen = 0x0010;
|
||||
|
||||
export function updateProvisionalStoreRank(
|
||||
buf: Buffer
|
||||
): UpdateProvisionalStoreRankRequest {
|
||||
return {
|
||||
type: "update_provisional_store_rank_req",
|
||||
aimeId: buf.readUInt32LE(0x0004),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { UpdateResultRequest } from "../request/updateResult";
|
||||
|
||||
updateResult.msgCode = 0x00cc;
|
||||
updateResult.msgLen = 0x0030;
|
||||
|
||||
export function updateResult(buf: Buffer): UpdateResultRequest {
|
||||
return {
|
||||
type: "update_result_req",
|
||||
field_0002: buf.readUInt16LE(0x0002),
|
||||
field_0004: buf.readUInt32LE(0x0004),
|
||||
field_0008: buf.readUInt32LE(0x0008),
|
||||
field_000C: buf.readUInt32LE(0x000c),
|
||||
field_0010: buf.readUInt32LE(0x0010),
|
||||
field_0014: buf.readUInt16LE(0x0014),
|
||||
field_0016: buf.readUInt16LE(0x0016),
|
||||
field_0018: buf.readUInt8(0x0018),
|
||||
field_0019: buf.readUInt8(0x0019),
|
||||
field_001A: buf.readUInt8(0x001a),
|
||||
field_001C: buf.readUInt16LE(0x001c),
|
||||
field_0020: buf.readUInt32LE(0x0020),
|
||||
field_0024: buf.readUInt8(0x0024),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import {
|
||||
UpdateStoryClearNumRequest1,
|
||||
UpdateStoryClearNumRequest2,
|
||||
} from "../request/updateStoryClearNum";
|
||||
|
||||
updateStoryClearNum1.msgCode = 0x007f;
|
||||
updateStoryClearNum1.msgLen = 0x0010;
|
||||
|
||||
export function updateStoryClearNum1(
|
||||
buf: Buffer
|
||||
): UpdateStoryClearNumRequest1 {
|
||||
return {
|
||||
type: "update_story_clear_num_req",
|
||||
format: 1,
|
||||
};
|
||||
}
|
||||
|
||||
updateStoryClearNum2.msgCode = 0x013d;
|
||||
updateStoryClearNum2.msgLen = 0x0010;
|
||||
|
||||
export function updateStoryClearNum2(
|
||||
buf: Buffer
|
||||
): UpdateStoryClearNumRequest2 {
|
||||
return {
|
||||
type: "update_story_clear_num_req",
|
||||
format: 2,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { ExtId } from "../model/base";
|
||||
import { Team } from "../model/team";
|
||||
import { UpdateTeamLeaderRequest } from "../request/updateTeamLeader";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
updateTeamLeader.msgCode = 0x008a;
|
||||
updateTeamLeader.msgLen = 0x0020;
|
||||
|
||||
export function updateTeamLeader(buf: Buffer): UpdateTeamLeaderRequest {
|
||||
return {
|
||||
type: "update_team_leader_req",
|
||||
aimeId: buf.readUInt32LE(0x0004) as AimeId,
|
||||
teamExtId: buf.readUInt32LE(0x0008) as ExtId<Team>,
|
||||
field_000C: buf.slice(0x000c, buf.indexOf("\0", 0x000c)).toString("ascii"),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { ExtId } from "../model/base";
|
||||
import { Team } from "../model/team";
|
||||
import { UpdateTeamMemberRequest } from "../request/updateTeamMember";
|
||||
import { AimeId } from "../../../model";
|
||||
|
||||
updateTeamMember.msgCode = 0x0073;
|
||||
updateTeamMember.msgLen = 0x0010;
|
||||
|
||||
export function updateTeamMember(buf: Buffer): UpdateTeamMemberRequest {
|
||||
return {
|
||||
type: "update_team_member_req",
|
||||
action: buf.readUInt8(0x0004) === 0 ? "add" : "remove",
|
||||
aimeId: buf.readUInt32LE(0x0008) as AimeId,
|
||||
teamExtId: buf.readUInt32LE(0x000c) as ExtId<Team>,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { UpdateTeamPointsRequest } from "../request/updateTeamPoints";
|
||||
|
||||
updateTeamPoints.msgCode = 0x0081;
|
||||
updateTeamPoints.msgLen = 0x0010;
|
||||
|
||||
export function updateTeamPoints(buf: Buffer): UpdateTeamPointsRequest {
|
||||
return {
|
||||
type: "update_team_points_req",
|
||||
field_0004: buf.readUInt32LE(0x0004),
|
||||
field_0008: buf.readUInt32LE(0x0008),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { UpdateUiReportRequest } from "../request/updateUiReport";
|
||||
|
||||
updateUiReport.msgCode = 0x0084;
|
||||
updateUiReport.msgLen = 0x0410;
|
||||
|
||||
export function updateUiReport(buf: Buffer): UpdateUiReportRequest {
|
||||
return {
|
||||
type: "update_ui_report_req",
|
||||
field_02: buf.readUInt16LE(0x0002),
|
||||
field_04: buf.readUInt16LE(0x0004),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { UpdateUserLogRequest } from "../request/updateUserLog";
|
||||
|
||||
updateUserLog.msgCode = 0x00bd;
|
||||
updateUserLog.msgLen = 0x0050;
|
||||
|
||||
export function updateUserLog(buf: Buffer): UpdateUserLogRequest {
|
||||
return { type: "update_user_log_req" };
|
||||
}
|
||||
Reference in New Issue
Block a user