idz: Add idz2 decoders

This commit is contained in:
b166fe48b91eb09f279b79a4ecf57b2f8f0d3705
2021-02-03 23:43:42 +00:00
committed by da5669c09fdb0a288ba01e259a609d7779ac7fc9
parent 4c36e0abf0
commit 2474879c89
36 changed files with 797 additions and 182 deletions
+10 -3
View File
@@ -1,8 +1,15 @@
import { CheckTeamNameRequest } from "../request/checkTeamName";
checkTeamName.msgCode = 0x00a2;
checkTeamName.msgLen = 0x0040;
checkTeamName1.msgCode = 0x00a2;
checkTeamName1.msgLen = 0x0040;
export function checkTeamName(buf: Buffer): CheckTeamNameRequest {
export function checkTeamName1(buf: Buffer): CheckTeamNameRequest {
return { type: "check_team_name_req" };
}
checkTeamName2.msgCode = 0x0097;
checkTeamName2.msgLen = 0x0040;
export function checkTeamName2(buf: Buffer): CheckTeamNameRequest {
return { type: "check_team_name_req" };
}
+16 -3
View File
@@ -1,10 +1,10 @@
import { CreateAutoTeamRequest } from "../request/createAutoTeam";
import { AimeId } from "../../../model";
createAutoTeam.msgCode = 0x007b;
createAutoTeam.msgLen = 0x0010;
createAutoTeam1.msgCode = 0x007b;
createAutoTeam1.msgLen = 0x0010;
export function createAutoTeam(buf: Buffer): CreateAutoTeamRequest {
export function createAutoTeam1(buf: Buffer): CreateAutoTeamRequest {
return {
type: "create_auto_team_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
@@ -13,3 +13,16 @@ export function createAutoTeam(buf: Buffer): CreateAutoTeamRequest {
field_000C: buf.readUInt8(0x000c),
};
}
createAutoTeam2.msgCode = 0x0077;
createAutoTeam2.msgLen = 0x0010;
export function createAutoTeam2(buf: Buffer): CreateAutoTeamRequest {
return {
type: "create_auto_team_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
version: 2,
field_0008: buf.readUInt32LE(0x0008),
field_000C: buf.readUInt8(0x000c),
};
}
+19 -3
View File
@@ -4,10 +4,10 @@ import { CreateProfileRequest } from "../request/createProfile";
import { AimeId } from "../../../model";
import { readAsciiStr, readSjisStr } from "../../util/bin";
createProfile.msgCode = 0x0066;
createProfile.msgLen = 0x00c0;
createProfile1.msgCode = 0x0066;
createProfile1.msgLen = 0x00c0;
export function createProfile(buf: Buffer): CreateProfileRequest {
export function createProfile1(buf: Buffer): CreateProfileRequest {
return {
type: "create_profile_req",
aimeId: buf.readInt32LE(0x0004) as AimeId,
@@ -19,3 +19,19 @@ export function createProfile(buf: Buffer): CreateProfileRequest {
chara: chara(buf.slice(0x00a0, 0x00b4)),
};
}
createProfile2.msgCode = 0x0064;
createProfile2.msgLen = 0x00c0;
export function createProfile2(buf: Buffer): CreateProfileRequest {
return {
type: "create_profile_req",
aimeId: buf.readInt32LE(0x0004) as AimeId,
version: 2,
luid: readAsciiStr(buf, 0x0008, 0x001e),
name: readSjisStr(buf, 0x001e, 0x0034),
field_0034: buf.readUInt32LE(0x0034),
car: car(buf.slice(0x0040, 0x00a0)),
chara: chara(buf.slice(0x00a8, 0x00bc)),
};
}
+21 -3
View File
@@ -2,10 +2,10 @@ import { CreateTeamRequest } from "../request/createTeam";
import { AimeId } from "../../../model";
import { readAsciiStr, readSjisStr } from "../../util/bin";
createTeam.msgCode = 0x0071;
createTeam.msgLen = 0x0050;
createTeam1.msgCode = 0x0071;
createTeam1.msgLen = 0x0050;
export function createTeam(buf: Buffer): CreateTeamRequest {
export function createTeam1(buf: Buffer): CreateTeamRequest {
return {
type: "create_team_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
@@ -19,3 +19,21 @@ export function createTeam(buf: Buffer): CreateTeamRequest {
pcbId: readAsciiStr(buf, 0x0038, 0x0050),
};
}
createTeam2.msgCode = 0x006d;
createTeam2.msgLen = 0x0050;
export function createTeam2(buf: Buffer): CreateTeamRequest {
return {
type: "create_team_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
version: 2,
teamName: readSjisStr(buf, 0x0008, 0x0028),
field_0028: buf.readUInt16LE(0x0028),
field_002C: buf.readUInt32LE(0x002c),
nameBg: buf.readUInt8(0x0030),
field_0032: buf.readUInt16LE(0x0032),
prevTeamId: buf.readUInt32LE(0x0034),
pcbId: readAsciiStr(buf, 0x0038, 0x0050),
};
}
+14 -3
View File
@@ -1,13 +1,24 @@
import { DiscoverProfileRequest } from "../request/discoverProfile";
import { AimeId } from "../../../model";
discoverProfile.msgCode = 0x006b;
discoverProfile.msgLen = 0x0010;
discoverProfile1.msgCode = 0x006b;
discoverProfile1.msgLen = 0x0010;
export function discoverProfile(buf: Buffer): DiscoverProfileRequest {
export function discoverProfile1(buf: Buffer): DiscoverProfileRequest {
return {
type: "discover_profile_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
version: 1,
};
}
discoverProfile2.msgCode = 0x0067;
discoverProfile2.msgLen = 0x0010;
export function discoverProfile2(buf: Buffer): DiscoverProfileRequest {
return {
type: "discover_profile_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
version: 2,
};
}
+151 -92
View File
@@ -1,54 +1,67 @@
import logger from "debug";
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 { checkTeamName1, checkTeamName2 } from "./checkTeamName";
import { createProfile1, createProfile2 } from "./createProfile";
import { createTeam1, createTeam2 } from "./createTeam";
import { createAutoTeam1, createAutoTeam2 } from "./createAutoTeam";
import { discoverProfile1, discoverProfile2 } from "./discoverProfile";
import { load2on2_v1, load2on2_v2, load2on2_v3 } from "./load2on2";
import { loadConfig1, loadConfig2 } from "./loadConfig";
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 { loadEventInfo1, loadEventInfo2 } from "./loadEventInfo";
import { loadGacha1, loadGacha2 } from "./loadGacha";
import { loadGarage1, loadGarage2 } from "./loadGarage";
import {
loadGeneralReward1,
loadGeneralReward2,
loadGeneralReward3,
} from "./loadGeneralReward";
import { loadGhost1, loadGhost2 } from "./loadGhost";
import { loadProfile2, loadProfile3, loadProfile4 } from "./loadProfile";
import { loadRewardTable1, loadRewardTable2 } from "./loadRewardTable";
import { loadServerList } from "./loadServerList";
import { loadStocker } from "./loadStocker";
import { loadTeam } from "./loadTeam";
import { loadTeamRanking1, loadTeamRanking2 } from "./loadTeamRanking";
import { loadStocker1, loadStocker2 } from "./loadStocker";
import { loadTeam1, loadTeam2 } from "./loadTeam";
import {
loadTeamRanking1,
loadTeamRanking3,
loadTeamRanking4,
} from "./loadTeamRanking";
import { loadTopTen1 } from "./loadTopTen1";
import { loadTopTen2 } from "./loadTopTen2";
import { lockGarage } from "./lockGarage";
import { lockProfile } from "./lockProfile";
import { lockGarage1, lockGarage2 } from "./lockGarage";
import { lockProfile1, lockProfile2 } from "./lockProfile";
import { saveExpedition1, saveExpedition2 } from "./saveExpedition";
import { saveGarage } from "./saveGarage";
import { saveNewCar } from "./saveNewCar";
import { saveGarage1, saveGarage2 } from "./saveGarage";
import { saveNewCar1, saveNewCar2 } from "./saveNewCar";
import { saveProfile2 } from "./saveProfile2";
import { saveProfile3 } from "./saveProfile3";
import { saveSettings } from "./saveSettings";
import { saveStocker } from "./saveStocker";
import { saveTeamBanner } from "./saveTeamBanner";
import { saveSettings1, saveSettings2 } from "./saveSettings";
import { saveStocker1, saveStocker2 } from "./saveStocker";
import { saveTeamBanner1, saveTeamBanner2 } from "./saveTeamBanner";
import { saveTimeAttack1, saveTimeAttack2 } from "./saveTimeAttack";
import { saveTopic } from "./saveTopic";
import { unknownA } from "./unknownA";
import { unlockProfile } from "./unlockProfile";
import { updateProvisionalStoreRank } from "./updateProvisionalStoreRank";
import { updateTeamLeader } from "./updateTeamLeader";
import { updateTeamMember } from "./updateTeamMember";
import { saveTopic1, saveTopic2 } from "./saveTopic";
import { unknownA_1, unknownA_2 } from "./unknownA";
import { unlockProfile1, unlockProfile2 } from "./unlockProfile";
import {
updateProvisionalStoreRank1,
updateProvisionalStoreRank2,
} from "./updateProvisionalStoreRank";
import { updateTeamLeader1, updateTeamLeader2 } from "./updateTeamLeader";
import { updateTeamMember1, updateTeamMember2 } from "./updateTeamMember";
import {
updateStoryClearNum1,
updateStoryClearNum2,
updateStoryClearNum3,
} 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";
import { updateTeamPoints1, updateTeamPoints2 } from "./updateTeamPoints";
import { updateUiReport1, updateUiReport2 } from "./updateUiReport";
import { updateUserLog1, updateUserLog2 } from "./updateUserLog";
import { lockProfileExtend1, lockProfileExtend2 } from "./lockProfileExtend";
import { BLOCK_SIZE, ClientHello } from "../../common";
import { ByteStream } from "../../../util/stream";
import { saveProfile4 } from "./saveProfile4";
const debug = logger("app:idz:userdb:decoder");
@@ -69,99 +82,145 @@ function makeReaderMap(funcList: ReaderFn[]): Map<number, ReaderFn> {
// TODO confirm v1.21.00 proto version
const funcList110: ReaderFn[] = [
checkTeamName,
createAutoTeam,
createProfile,
createTeam,
discoverProfile,
checkTeamName1,
createAutoTeam1,
createProfile1,
createTeam1,
discoverProfile1,
load2on2_v1,
loadConfig1,
loadConfig2,
loadEventInfo,
loadGacha,
loadGarage,
loadEventInfo1,
loadGacha1,
loadGarage1,
loadGeneralReward1,
loadGhost,
loadGhost1,
loadProfile2,
loadRewardTable,
loadRewardTable1,
loadServerList,
loadStocker,
loadTeam,
loadStocker1,
loadTeam1,
loadTeamRanking1,
lockGarage,
lockProfile,
lockProfileExtend,
lockGarage1,
lockProfile1,
lockProfileExtend1,
loadTopTen1,
saveExpedition1,
saveGarage,
saveNewCar,
saveGarage1,
saveNewCar1,
saveProfile2,
saveSettings,
saveStocker,
saveTeamBanner,
saveSettings1,
saveStocker1,
saveTeamBanner1,
saveTimeAttack1,
saveTopic,
unknownA,
unlockProfile,
updateProvisionalStoreRank,
saveTopic1,
unknownA_1,
unlockProfile1,
updateProvisionalStoreRank1,
updateResult,
updateStoryClearNum1,
updateTeamLeader,
updateTeamMember,
updateTeamPoints,
updateUiReport,
updateUserLog,
updateTeamLeader1,
updateTeamMember1,
updateTeamPoints1,
updateUiReport1,
updateUserLog1,
];
const funcList130: ReaderFn[] = [
checkTeamName,
createAutoTeam,
createProfile,
createTeam,
discoverProfile,
checkTeamName1,
createAutoTeam1,
createProfile1,
createTeam1,
discoverProfile1,
load2on2_v2,
updateStoryClearNum2,
loadConfig1,
loadConfig2,
loadEventInfo,
loadGacha,
loadGarage,
loadEventInfo1,
loadGacha1,
loadGarage1,
loadGeneralReward2,
loadGhost,
loadGhost1,
loadProfile3,
loadRewardTable,
loadRewardTable1,
loadServerList,
loadStocker,
loadTeam,
loadTeamRanking2,
loadStocker1,
loadTeam1,
loadTeamRanking3,
loadTopTen2,
lockGarage,
lockProfile,
lockProfileExtend,
lockGarage1,
lockProfile1,
lockProfileExtend1,
saveExpedition2,
saveGarage,
saveNewCar,
saveGarage1,
saveNewCar1,
saveProfile3,
saveSettings,
saveStocker,
saveTeamBanner,
saveSettings1,
saveStocker1,
saveTeamBanner1,
saveTimeAttack2,
saveTopic,
unknownA,
unlockProfile,
updateProvisionalStoreRank,
saveTopic1,
unknownA_1,
unlockProfile1,
updateProvisionalStoreRank1,
updateResult,
updateTeamLeader,
updateTeamMember,
updateTeamPoints,
updateUiReport,
updateUserLog,
updateTeamLeader1,
updateTeamMember1,
updateTeamPoints1,
updateUiReport1,
updateUserLog1,
];
const funcList210: ReaderFn[] = [
checkTeamName2,
createAutoTeam2,
createProfile2,
createTeam2,
discoverProfile2,
load2on2_v3,
updateStoryClearNum3,
loadConfig1,
loadConfig2,
loadEventInfo2,
loadGacha2,
loadGarage2,
loadGeneralReward3,
loadGhost2,
loadProfile4,
loadRewardTable2,
loadServerList,
loadStocker2,
loadTeam2,
loadTeamRanking4,
loadTopTen2,
lockGarage2,
lockProfile2,
lockProfileExtend2,
saveExpedition2,
saveGarage2,
saveNewCar2,
saveProfile4,
saveSettings2,
saveStocker2,
saveTeamBanner2,
saveTimeAttack2,
saveTopic2,
unknownA_2,
unlockProfile2,
updateProvisionalStoreRank2,
updateResult,
updateTeamLeader2,
updateTeamMember2,
updateTeamPoints2,
updateUiReport2,
updateUserLog2,
];
const protocols = new Map<string, Map<number, ReaderFn>>();
protocols.set("110", makeReaderMap(funcList110));
protocols.set("130", makeReaderMap(funcList130));
protocols.set("210", makeReaderMap(funcList210));
async function readRequest(
clientHello: ClientHello,
+12
View File
@@ -26,3 +26,15 @@ export function load2on2_v2(buf: Buffer): Load2on2Request {
teamId: buf.readUInt32LE(0x0008) as ExtId<Team>,
};
}
load2on2_v3.msgCode = 0x00a3;
load2on2_v3.msgLen = 0x0010;
export function load2on2_v3(buf: Buffer): Load2on2Request {
return {
type: "load_2on2_req",
field_0002: buf.readUInt16LE(0x0002),
aimeId: buf.readUInt32LE(0x0004) as AimeId,
teamId: buf.readUInt32LE(0x0008) as ExtId<Team>,
};
}
+13 -3
View File
@@ -1,10 +1,20 @@
import { LoadEventInfoRequest } from "../request/loadEventInfo";
import { AimeId } from "../../../model";
loadEventInfo.msgCode = 0x00be;
loadEventInfo.msgLen = 0x0010;
loadEventInfo1.msgCode = 0x00be;
loadEventInfo1.msgLen = 0x0010;
export function loadEventInfo(buf: Buffer): LoadEventInfoRequest {
export function loadEventInfo1(buf: Buffer): LoadEventInfoRequest {
return {
type: "load_event_info_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
};
}
loadEventInfo2.msgCode = 0x00ac;
loadEventInfo2.msgLen = 0x0010;
export function loadEventInfo2(buf: Buffer): LoadEventInfoRequest {
return {
type: "load_event_info_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
+13 -3
View File
@@ -1,10 +1,20 @@
import { LoadGachaRequest } from "../request/loadGacha";
import { AimeId } from "../../../model";
loadGacha.msgCode = 0x00c1;
loadGacha.msgLen = 0x0010;
loadGacha1.msgCode = 0x00c1;
loadGacha1.msgLen = 0x0010;
export function loadGacha(buf: Buffer): LoadGachaRequest {
export function loadGacha1(buf: Buffer): LoadGachaRequest {
return {
type: "load_gacha_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
};
}
loadGacha2.msgCode = 0x00af;
loadGacha2.msgLen = 0x0010;
export function loadGacha2(buf: Buffer): LoadGachaRequest {
return {
type: "load_gacha_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
+16 -3
View File
@@ -1,10 +1,10 @@
import { LoadGarageRequest } from "../request/loadGarage";
import { AimeId } from "../../../model";
loadGarage.msgCode = 0x0090;
loadGarage.msgLen = 0x0010;
loadGarage1.msgCode = 0x0090;
loadGarage1.msgLen = 0x0010;
export function loadGarage(buf: Buffer): LoadGarageRequest {
export function loadGarage1(buf: Buffer): LoadGarageRequest {
return {
type: "load_garage_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
@@ -13,3 +13,16 @@ export function loadGarage(buf: Buffer): LoadGarageRequest {
field_000A: buf.readUInt16LE(0x000a),
};
}
loadGarage2.msgCode = 0x0087;
loadGarage2.msgLen = 0x0010;
export function loadGarage2(buf: Buffer): LoadGarageRequest {
return {
type: "load_garage_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
version: 2,
fetchOffset: buf.readUInt8(0x0008),
field_000A: buf.readUInt16LE(0x000a),
};
}
@@ -20,3 +20,13 @@ export function loadGeneralReward2(buf: Buffer): LoadGeneralRewardRequest {
aimeId: buf.readUInt32LE(0x0004) as AimeId,
};
}
loadGeneralReward3.msgCode = 0x093b;
loadGeneralReward3.msgLen = 0x0010;
export function loadGeneralReward3(buf: Buffer): LoadGeneralRewardRequest {
return {
type: "load_general_reward_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
};
}
+17 -3
View File
@@ -1,9 +1,23 @@
import { LoadGhostRequest } from "../request/loadGhost";
loadGhost.msgCode = 0x00a0;
loadGhost.msgLen = 0x0010;
loadGhost1.msgCode = 0x00a0;
loadGhost1.msgLen = 0x0010;
export function loadGhost(buf: Buffer): LoadGhostRequest {
export function loadGhost1(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),
};
}
loadGhost2.msgCode = 0x0095;
loadGhost2.msgLen = 0x0010;
export function loadGhost2(buf: Buffer): LoadGhostRequest {
return {
type: "load_ghost_req",
field_0002: buf.readUInt16LE(0x0002),
+12
View File
@@ -25,3 +25,15 @@ export function loadProfile3(buf: Buffer): LoadProfileRequest {
luid: readAsciiStr(buf, 0x0008, 0x0020),
};
}
loadProfile4.msgCode = 0x0667;
loadProfile4.msgLen = 0x0020;
export function loadProfile4(buf: Buffer): LoadProfileRequest {
return {
type: "load_profile_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
version: 2,
luid: readAsciiStr(buf, 0x0008, 0x0020),
};
}
+12 -3
View File
@@ -1,9 +1,18 @@
import { LoadRewardTableRequest } from "../request/loadRewardTable";
loadRewardTable.msgCode = 0x0086;
loadRewardTable.msgLen = 0x0010;
loadRewardTable1.msgCode = 0x0086;
loadRewardTable1.msgLen = 0x0010;
export function loadRewardTable(): LoadRewardTableRequest {
export function loadRewardTable1(): LoadRewardTableRequest {
return {
type: "load_reward_table_req",
};
}
loadRewardTable2.msgCode = 0x007f;
loadRewardTable2.msgLen = 0x0010;
export function loadRewardTable2(): LoadRewardTableRequest {
return {
type: "load_reward_table_req",
};
+14 -3
View File
@@ -1,13 +1,24 @@
import { LoadStockerRequest } from "../request/loadStocker";
import { AimeId } from "../../../model";
loadStocker.msgCode = 0x00a7;
loadStocker.msgLen = 0x0010;
loadStocker1.msgCode = 0x00a7;
loadStocker1.msgLen = 0x0010;
export function loadStocker(buf: Buffer): LoadStockerRequest {
export function loadStocker1(buf: Buffer): LoadStockerRequest {
return {
type: "load_stocker_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
version: 1,
};
}
loadStocker2.msgCode = 0x009c;
loadStocker2.msgLen = 0x0010;
export function loadStocker2(buf: Buffer): LoadStockerRequest {
return {
type: "load_stocker_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
version: 2,
};
}
+17 -3
View File
@@ -2,10 +2,10 @@ import { LoadTeamRequest } from "../request/loadTeam";
import { ExtId } from "../model/base";
import { Team } from "../model/team";
loadTeam.msgCode = 0x0077;
loadTeam.msgLen = 0x0010;
loadTeam1.msgCode = 0x0077;
loadTeam1.msgLen = 0x0010;
export function loadTeam(buf: Buffer): LoadTeamRequest {
export function loadTeam1(buf: Buffer): LoadTeamRequest {
const extId = buf.readUInt32LE(0x0008);
return {
@@ -15,3 +15,17 @@ export function loadTeam(buf: Buffer): LoadTeamRequest {
teamExtId: extId !== 0xffffffff ? (extId as ExtId<Team>) : undefined,
};
}
loadTeam2.msgCode = 0x0073;
loadTeam2.msgLen = 0x0010;
export function loadTeam2(buf: Buffer): LoadTeamRequest {
const extId = buf.readUInt32LE(0x0008);
return {
type: "load_team_req",
aimeId: buf.readUInt32LE(0x0004),
version: 2,
teamExtId: extId !== 0xffffffff ? (extId as ExtId<Team>) : undefined,
};
}
+22 -3
View File
@@ -9,9 +9,8 @@ export function loadTeamRanking1(buf: Buffer): LoadTeamRankingRequest {
};
}
// not sure what the difference is...
loadTeamRanking2.msgCode = 0x00bb;
// unused? Not sure where this came from.
loadTeamRanking2.msgCode = 0x00a7;
loadTeamRanking2.msgLen = 0x0010;
export function loadTeamRanking2(buf: Buffer): LoadTeamRankingRequest {
@@ -19,3 +18,23 @@ export function loadTeamRanking2(buf: Buffer): LoadTeamRankingRequest {
type: "load_team_ranking_req",
};
}
// not sure what the difference is...
loadTeamRanking3.msgCode = 0x00bb;
loadTeamRanking3.msgLen = 0x0010;
export function loadTeamRanking3(buf: Buffer): LoadTeamRankingRequest {
return {
type: "load_team_ranking_req",
};
}
loadTeamRanking4.msgCode = 0x00a9;
loadTeamRanking4.msgLen = 0x0010;
export function loadTeamRanking4(buf: Buffer): LoadTeamRankingRequest {
return {
type: "load_team_ranking_req",
};
}
+13 -3
View File
@@ -1,9 +1,19 @@
import { LockGarageRequest } from "../request/lockGarage";
lockGarage.msgCode = 0x00a9;
lockGarage.msgLen = 0x0010;
lockGarage1.msgCode = 0x00a9;
lockGarage1.msgLen = 0x0010;
export function lockGarage(buf: Buffer): LockGarageRequest {
export function lockGarage1(buf: Buffer): LockGarageRequest {
return {
type: "lock_garage_request",
field_0004: buf.readUInt32LE(0x0004),
};
}
lockGarage2.msgCode = 0x009e;
lockGarage2.msgLen = 0x0010;
export function lockGarage2(buf: Buffer): LockGarageRequest {
return {
type: "lock_garage_request",
field_0004: buf.readUInt32LE(0x0004),
+15 -3
View File
@@ -1,10 +1,22 @@
import { readAsciiStr } from "../../util/bin";
import { LockProfileRequest } from "../request/lockProfile";
lockProfile.msgCode = 0x0069;
lockProfile.msgLen = 0x0020;
lockProfile1.msgCode = 0x0069;
lockProfile1.msgLen = 0x0020;
export function lockProfile(buf: Buffer): LockProfileRequest {
export function lockProfile1(buf: Buffer): LockProfileRequest {
return {
type: "lock_profile_req",
aimeId: buf.readUInt32LE(0x0004),
pcbId: readAsciiStr(buf, 0x0008, 0x0018),
field_0018: buf.readUInt16LE(0x0018),
};
}
lockProfile2.msgCode = 0x0065;
lockProfile2.msgLen = 0x0020;
export function lockProfile2(buf: Buffer): LockProfileRequest {
return {
type: "lock_profile_req",
aimeId: buf.readUInt32LE(0x0004),
+14 -3
View File
@@ -2,13 +2,24 @@ import { LockProfileExtendRequest } from "../request/lockProfileExtend";
import { AimeId } from "../../../model";
import { readAsciiStr } from "../../util/bin";
lockProfileExtend.msgCode = 0x006d;
lockProfileExtend.msgLen = 0x0020;
lockProfileExtend1.msgCode = 0x006d;
lockProfileExtend1.msgLen = 0x0020;
export function lockProfileExtend(buf: Buffer): LockProfileExtendRequest {
export function lockProfileExtend1(buf: Buffer): LockProfileExtendRequest {
return {
type: "lock_profile_extend_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
luid: readAsciiStr(buf, 0x0008, 0x0020),
};
}
lockProfileExtend2.msgCode = 0x0069;
lockProfileExtend2.msgLen = 0x0020;
export function lockProfileExtend2(buf: Buffer): LockProfileExtendRequest {
return {
type: "lock_profile_extend_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
luid: buf.slice(0x0008, buf.indexOf("\0")).toString("ascii"),
};
}
+23 -3
View File
@@ -1,10 +1,10 @@
import { car } from "./_car";
import { SaveGarageRequest } from "../request/saveGarage";
saveGarage.msgCode = 0x008e;
saveGarage.msgLen = 0x0090;
saveGarage1.msgCode = 0x008e;
saveGarage1.msgLen = 0x0090;
export function saveGarage(buf: Buffer): SaveGarageRequest {
export function saveGarage1(buf: Buffer): SaveGarageRequest {
const field_0068: number[] = [];
for (let offset = 0x0068; offset < 0x007c; offset += 2) {
@@ -20,3 +20,23 @@ export function saveGarage(buf: Buffer): SaveGarageRequest {
field_0081: buf.readUInt8(0x0081) !== 0,
};
}
saveGarage2.msgCode = 0x0085;
saveGarage2.msgLen = 0x0090;
export function saveGarage2(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(0x0088),
field_0081: buf.readUInt8(0x0089) !== 0,
};
}
+17 -3
View File
@@ -3,10 +3,10 @@ import { SaveNewCarRequest } from "../request/saveNewCar";
import { readAsciiStr } from "../../util/bin";
import { AimeId } from "../../../model";
saveNewCar.msgCode = 0x0079;
saveNewCar.msgLen = 0x0090;
saveNewCar1.msgCode = 0x0079;
saveNewCar1.msgLen = 0x0090;
export function saveNewCar(buf: Buffer): SaveNewCarRequest {
export function saveNewCar1(buf: Buffer): SaveNewCarRequest {
return {
type: "save_new_car_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
@@ -16,3 +16,17 @@ export function saveNewCar(buf: Buffer): SaveNewCarRequest {
field_0080: buf.readUInt32LE(0x0080),
};
}
saveNewCar2.msgCode = 0x0075;
saveNewCar2.msgLen = 0x0090;
export function saveNewCar2(buf: Buffer): SaveNewCarRequest {
return {
type: "save_new_car_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
version: 2,
luid: readAsciiStr(buf, 0x0008, 0x001e),
car: car(buf.slice(0x0020, 0x0080)),
field_0080: buf.readUInt32LE(0x0080),
};
}
+127
View File
@@ -0,0 +1,127 @@
import { car } from "./_car";
import { mission } from "./_mission";
import { BackgroundCode, CourseNo, StampCode, TitleCode } from "../model/base";
import { StoryCell, StoryRow } from "../model/story";
import { SaveProfileRequest } from "../request/saveProfile";
import { bitmap } from "./_bitmap";
import { AimeId } from "../../../model";
saveProfile4.msgCode = 0x0138;
saveProfile4.msgLen = 0x0eb0;
export function saveProfile4(buf: Buffer): SaveProfileRequest {
const storyRows = new Map<number, StoryRow>();
// Story layout got another rework in idz2
// First two bytes per row denote the chapter, however
// since this is in completely linear order (in 2.12) we can
// just skip saving/reading this for our convenience.
for (let i = 0; i < 6; i++) {
const cells = new Map<number, StoryCell>();
const rowOffset = 0x026c + 0x02 + i * 0x7a;
for (let j = 0; j < 28; j++) {
const a = buf.readUInt8(rowOffset + 0x00 + j * 4);
const b = buf.readUInt8(rowOffset + 0x01 + j * 4);
const c = buf.readUInt8(rowOffset + 0x02 + j * 4);
const cell = { a, b, c };
cells.set(j, cell);
}
const row = { cells };
storyRows.set(i, row);
}
const coursePlays = new Map<CourseNo, number>();
for (let i = 0; i < 20; i++) {
coursePlays.set(i as CourseNo, buf.readUInt16LE(0x07dc + 2 * i));
}
const freeCar = {
validFrom: buf.readUInt32LE(0x01fc),
};
const freeContinue = {
validFrom: buf.readUInt32LE(0x0038),
validTo: buf.readUInt32LE(0x003c),
};
const weeklyReset = {
endDate: buf.readUInt32LE(0x0c90),
};
return {
type: "save_profile_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
version: 2,
lv: buf.readUInt16LE(0x0026),
exp: buf.readUInt32LE(0x0028),
fame: buf.readUInt32LE(0x0784),
dpoint: buf.readUInt32LE(0x0780),
mileage: buf.readUInt32LE(0x0008),
title: buf.readUInt16LE(0x0040) as TitleCode,
titles: bitmap(buf.slice(0x0042, 0x01b9)),
background: buf.readUInt8(0x0afc) as BackgroundCode,
coursePlays,
missions: {
team: mission(buf.slice(0x06c0, 0x06e4)),
solo: mission(buf.slice(0x0ad0, 0x0af2)),
},
car: car(buf.slice(0x0b80, 0x0be0)),
story: {
x: buf.readUInt16LE(0x0aa0),
y: buf.readUInt8(0x0a84),
rows: storyRows,
},
unlocks: {
auras: buf.readUInt16LE(0x01d0),
cup: buf.readUInt8(0x01d4),
gauges: buf.readUInt32LE(0x01d8),
music: buf.readUInt16LE(0x0204),
lastMileageReward: buf.readUInt32LE(0x0200),
},
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,
},
selectedStamps: {
stamp01: buf.readUInt16LE(0x0d74) as StampCode,
stamp02: buf.readUInt16LE(0x0d76) as StampCode,
stamp03: buf.readUInt16LE(0x0d78) as StampCode,
stamp04: buf.readUInt16LE(0x0d7a) as StampCode,
},
stamps: bitmap(buf.slice(0x0d28, 0x0d4e)),
settings: {
music: buf.readUInt16LE(0x0776),
pack: buf.readUInt32LE(0x0034),
aura: buf.readUInt8(0x002c),
paperCup: buf.readUInt8(0x01b9),
gauges: buf.readUInt8(0x01ba),
drivingStyle: buf.readUInt8(0x0dae),
},
weeklyMissions: {
weeklyReset: new Date(weeklyReset.endDate * 1000),
weeklyMissionLeft: buf.readUInt16LE(0x0c84),
weeklyProgressLeft: buf.readUInt16LE(0x0c86),
weeklyParamsLeft: buf.readUInt16LE(0x0c88),
weeklyMissionRight: buf.readUInt16LE(0x0c8a),
weeklyProgressRight: buf.readUInt16LE(0x0c8c),
weeklyParamsRight: buf.readUInt16LE(0x0c8e),
},
};
}
+24 -3
View File
@@ -1,10 +1,10 @@
import { SaveSettingsRequest } from "../request/saveSettings";
import { AimeId } from "../../../model";
saveSettings.msgCode = 0x00a5;
saveSettings.msgLen = 0x0020;
saveSettings1.msgCode = 0x00a5;
saveSettings1.msgLen = 0x0020;
export function saveSettings(buf: Buffer): SaveSettingsRequest {
export function saveSettings1(buf: Buffer): SaveSettingsRequest {
return {
type: "save_settings_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
@@ -21,3 +21,24 @@ export function saveSettings(buf: Buffer): SaveSettingsRequest {
field_0010: buf.readUInt8(0x0010),
};
}
saveSettings2.msgCode = 0x009a;
saveSettings2.msgLen = 0x0020;
export function saveSettings2(buf: Buffer): SaveSettingsRequest {
return {
type: "save_settings_req",
aimeId: buf.readUInt32LE(0x0008) as AimeId,
version: 2,
dpoint: buf.readUInt32LE(0x000c),
settings: {
music: buf.readUInt16LE(0x0004),
pack: buf.readUInt32LE(0x0010),
paperCup: buf.readUInt8(0x0015),
gauges: buf.readUInt8(0x0016),
aura: buf.readUInt8(0x0017),
drivingStyle: buf.readUInt8(0x0018),
},
field_0010: buf.readUInt32LE(0x0014),
};
}
+26 -3
View File
@@ -1,13 +1,14 @@
import { bitmap } from "./_bitmap";
import { chara } from "./_chara";
import { StampCode } from "../model/base";
import { CarSelector } from "../model/car";
import { SaveStockerRequest } from "../request/saveStocker";
import { AimeId } from "../../../model";
saveStocker.msgCode = 0x00a6;
saveStocker.msgLen = 0x00c0;
saveStocker1.msgCode = 0x00a6;
saveStocker1.msgLen = 0x00c0;
export function saveStocker(buf: Buffer): SaveStockerRequest {
export function saveStocker1(buf: Buffer): SaveStockerRequest {
return {
type: "save_stocker_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
@@ -17,3 +18,25 @@ export function saveStocker(buf: Buffer): SaveStockerRequest {
chara: chara(buf.slice(0x009e, 0x00b2)),
};
}
saveStocker2.msgCode = 0x009b;
saveStocker2.msgLen = 0x0110;
export function saveStocker2(buf: Buffer): SaveStockerRequest {
return {
type: "save_stocker_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
version: 2,
backgrounds: bitmap(buf.slice(0x0008, 0x0034)),
selectedCar: buf.readUInt16LE(0x009c) as CarSelector,
chara: chara(buf.slice(0x009e, 0x00b2)),
myChara: bitmap(buf.slice(0x0034, 0x098)),
selectedStamps: {
stamp01: buf.readUInt16LE(0x00da) as StampCode,
stamp02: buf.readUInt16LE(0x00dc) as StampCode,
stamp03: buf.readUInt16LE(0x00de) as StampCode,
stamp04: buf.readUInt16LE(0x00e0) as StampCode,
},
stamps: bitmap(buf.slice(0x00b3, 0x00d9)),
};
}
+16 -3
View File
@@ -2,10 +2,10 @@ import { SaveTeamBannerRequest } from "../request/saveTeamBanner";
import { ExtId } from "../model/base";
import { Team } from "../model/team";
saveTeamBanner.msgCode = 0x0089;
saveTeamBanner.msgLen = 0x0010;
saveTeamBanner1.msgCode = 0x0089;
saveTeamBanner1.msgLen = 0x0010;
export function saveTeamBanner(buf: Buffer): SaveTeamBannerRequest {
export function saveTeamBanner1(buf: Buffer): SaveTeamBannerRequest {
return {
type: "save_team_banner_req",
teamExtId: buf.readUInt32LE(0x0004) as ExtId<Team>,
@@ -14,3 +14,16 @@ export function saveTeamBanner(buf: Buffer): SaveTeamBannerRequest {
nameFx: buf.readUInt32LE(0x000c),
};
}
saveTeamBanner2.msgCode = 0x0082;
saveTeamBanner2.msgLen = 0x0010;
export function saveTeamBanner2(buf: Buffer): SaveTeamBannerRequest {
return {
type: "save_team_banner_req",
teamExtId: buf.readUInt32LE(0x0004) as ExtId<Team>,
version: 2,
nameBg: buf.readUInt32LE(0x0008),
nameFx: buf.readUInt32LE(0x000c),
};
}
+15 -3
View File
@@ -1,9 +1,21 @@
import { SaveTopicRequest } from "../request/saveTopic";
saveTopic.msgCode = 0x009a;
saveTopic.msgLen = 0x0010;
saveTopic1.msgCode = 0x009a;
saveTopic1.msgLen = 0x0010;
export function saveTopic(buf: Buffer): SaveTopicRequest {
export function saveTopic1(buf: Buffer): SaveTopicRequest {
const aimeId = buf.readUInt32LE(0x0004);
return {
type: "save_topic_req",
aimeId: aimeId !== 0xffffffff ? aimeId : undefined,
};
}
saveTopic2.msgCode = 0x0091;
saveTopic2.msgLen = 0x0010;
export function saveTopic2(buf: Buffer): SaveTopicRequest {
const aimeId = buf.readUInt32LE(0x0004);
return {
+10 -3
View File
@@ -1,8 +1,15 @@
import { UnknownRequestA } from "../request/unknownA";
unknownA.msgCode = 0x00ad;
unknownA.msgLen = 0x0620;
unknownA_1.msgCode = 0x00ad;
unknownA_1.msgLen = 0x0620;
export function unknownA(buf: Buffer): UnknownRequestA {
export function unknownA_1(buf: Buffer): UnknownRequestA {
return { type: "unknown_A_req" };
}
unknownA_2.msgCode = 0x00a2;
unknownA_2.msgLen = 0x061c;
export function unknownA_2(buf: Buffer): UnknownRequestA {
return { type: "unknown_A_req" };
}
+14 -3
View File
@@ -1,9 +1,20 @@
import { UnlockProfileRequest } from "../request/unlockProfile";
unlockProfile.msgCode = 0x006f;
unlockProfile.msgLen = 0x0020;
unlockProfile1.msgCode = 0x006f;
unlockProfile1.msgLen = 0x0020;
export function unlockProfile(buf: Buffer): UnlockProfileRequest {
export function unlockProfile1(buf: Buffer): UnlockProfileRequest {
return {
type: "unlock_profile_req",
aimeId: buf.readUInt32LE(0x0004),
pcbId: buf.slice(0x0008, buf.indexOf("\0", 0x0008)).toString("ascii"),
};
}
unlockProfile2.msgCode = 0x006b;
unlockProfile2.msgLen = 0x0020;
export function unlockProfile2(buf: Buffer): UnlockProfileRequest {
return {
type: "unlock_profile_req",
aimeId: buf.readUInt32LE(0x0004),
@@ -1,9 +1,21 @@
import { UpdateProvisionalStoreRankRequest } from "../request/updateProvisionalStoreRank";
updateProvisionalStoreRank.msgCode = 0x0082;
updateProvisionalStoreRank.msgLen = 0x0010;
updateProvisionalStoreRank1.msgCode = 0x0082;
updateProvisionalStoreRank1.msgLen = 0x0010;
export function updateProvisionalStoreRank(
export function updateProvisionalStoreRank1(
buf: Buffer
): UpdateProvisionalStoreRankRequest {
return {
type: "update_provisional_store_rank_req",
aimeId: buf.readUInt32LE(0x0004),
};
}
updateProvisionalStoreRank2.msgCode = 0x007c;
updateProvisionalStoreRank2.msgLen = 0x0010;
export function updateProvisionalStoreRank2(
buf: Buffer
): UpdateProvisionalStoreRankRequest {
return {
@@ -17,3 +17,12 @@ export function updateStoryClearNum2(buf: Buffer): UpdateStoryClearNumRequest {
type: "update_story_clear_num_req",
};
}
updateStoryClearNum3.msgCode = 0x097f;
updateStoryClearNum3.msgLen = 0x0010;
export function updateStoryClearNum3(buf: Buffer): UpdateStoryClearNumRequest {
return {
type: "update_story_clear_num_req",
};
}
+16 -3
View File
@@ -4,10 +4,10 @@ import { UpdateTeamLeaderRequest } from "../request/updateTeamLeader";
import { AimeId } from "../../../model";
import { readAsciiStr } from "../../util/bin";
updateTeamLeader.msgCode = 0x008a;
updateTeamLeader.msgLen = 0x0020;
updateTeamLeader1.msgCode = 0x008a;
updateTeamLeader1.msgLen = 0x0020;
export function updateTeamLeader(buf: Buffer): UpdateTeamLeaderRequest {
export function updateTeamLeader1(buf: Buffer): UpdateTeamLeaderRequest {
return {
type: "update_team_leader_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
@@ -16,3 +16,16 @@ export function updateTeamLeader(buf: Buffer): UpdateTeamLeaderRequest {
field_000C: readAsciiStr(buf, 0x000c, 0x0020),
};
}
updateTeamLeader2.msgCode = 0x0083;
updateTeamLeader2.msgLen = 0x0020;
export function updateTeamLeader2(buf: Buffer): UpdateTeamLeaderRequest {
return {
type: "update_team_leader_req",
aimeId: buf.readUInt32LE(0x0004) as AimeId,
version: 2,
teamExtId: buf.readUInt32LE(0x0008) as ExtId<Team>,
field_000C: readAsciiStr(buf, 0x000c, 0x0020),
};
}
+16 -3
View File
@@ -3,10 +3,10 @@ import { Team } from "../model/team";
import { UpdateTeamMemberRequest } from "../request/updateTeamMember";
import { AimeId } from "../../../model";
updateTeamMember.msgCode = 0x0073;
updateTeamMember.msgLen = 0x0010;
updateTeamMember1.msgCode = 0x0073;
updateTeamMember1.msgLen = 0x0010;
export function updateTeamMember(buf: Buffer): UpdateTeamMemberRequest {
export function updateTeamMember1(buf: Buffer): UpdateTeamMemberRequest {
return {
type: "update_team_member_req",
action: buf.readUInt8(0x0004) === 0 ? "add" : "remove",
@@ -15,3 +15,16 @@ export function updateTeamMember(buf: Buffer): UpdateTeamMemberRequest {
teamExtId: buf.readUInt32LE(0x000c) as ExtId<Team>,
};
}
updateTeamMember2.msgCode = 0x006f;
updateTeamMember2.msgLen = 0x0010;
export function updateTeamMember2(buf: Buffer): UpdateTeamMemberRequest {
return {
type: "update_team_member_req",
action: buf.readUInt8(0x0004) === 0 ? "add" : "remove",
aimeId: buf.readUInt32LE(0x0008) as AimeId,
version: 2,
teamExtId: buf.readUInt32LE(0x000c) as ExtId<Team>,
};
}
+14 -3
View File
@@ -1,9 +1,20 @@
import { UpdateTeamPointsRequest } from "../request/updateTeamPoints";
updateTeamPoints.msgCode = 0x0081;
updateTeamPoints.msgLen = 0x0010;
updateTeamPoints1.msgCode = 0x0081;
updateTeamPoints1.msgLen = 0x0010;
export function updateTeamPoints(buf: Buffer): UpdateTeamPointsRequest {
export function updateTeamPoints1(buf: Buffer): UpdateTeamPointsRequest {
return {
type: "update_team_points_req",
field_0004: buf.readUInt32LE(0x0004),
field_0008: buf.readUInt32LE(0x0008),
};
}
updateTeamPoints2.msgCode = 0x007b;
updateTeamPoints2.msgLen = 0x0010;
export function updateTeamPoints2(buf: Buffer): UpdateTeamPointsRequest {
return {
type: "update_team_points_req",
field_0004: buf.readUInt32LE(0x0004),
+14 -3
View File
@@ -1,9 +1,20 @@
import { UpdateUiReportRequest } from "../request/updateUiReport";
updateUiReport.msgCode = 0x0084;
updateUiReport.msgLen = 0x0410;
updateUiReport1.msgCode = 0x0084;
updateUiReport1.msgLen = 0x0410;
export function updateUiReport(buf: Buffer): UpdateUiReportRequest {
export function updateUiReport1(buf: Buffer): UpdateUiReportRequest {
return {
type: "update_ui_report_req",
field_02: buf.readUInt16LE(0x0002),
field_04: buf.readUInt16LE(0x0004),
};
}
updateUiReport2.msgCode = 0x007e;
updateUiReport2.msgLen = 0x0410;
export function updateUiReport2(buf: Buffer): UpdateUiReportRequest {
return {
type: "update_ui_report_req",
field_02: buf.readUInt16LE(0x0002),
+10 -3
View File
@@ -1,8 +1,15 @@
import { UpdateUserLogRequest } from "../request/updateUserLog";
updateUserLog.msgCode = 0x00bd;
updateUserLog.msgLen = 0x0050;
updateUserLog1.msgCode = 0x00bd;
updateUserLog1.msgLen = 0x0050;
export function updateUserLog(buf: Buffer): UpdateUserLogRequest {
export function updateUserLog1(buf: Buffer): UpdateUserLogRequest {
return { type: "update_user_log_req" };
}
updateUserLog2.msgCode = 0x00ab;
updateUserLog2.msgLen = 0x0050;
export function updateUserLog2(buf: Buffer): UpdateUserLogRequest {
return { type: "update_user_log_req" };
}