diff --git a/src/idz/userdb/decoder/index.ts b/src/idz/userdb/decoder/index.ts index 2baea8b..98adc93 100644 --- a/src/idz/userdb/decoder/index.ts +++ b/src/idz/userdb/decoder/index.ts @@ -18,7 +18,7 @@ import { loadRewardTable } from "./loadRewardTable"; import { loadServerList } from "./loadServerList"; import { loadStocker } from "./loadStocker"; import { loadTeam } from "./loadTeam"; -import { loadTeamRanking, loadTeamRanking2 } from "./loadTeamRanking"; +import { loadTeamRanking1, loadTeamRanking2 } from "./loadTeamRanking"; import { loadTopTen1 } from "./loadTopTen1"; import { loadTopTen2 } from "./loadTopTen2"; import { lockGarage } from "./lockGarage"; @@ -48,7 +48,7 @@ import { updateTeamPoints } from "./updateTeamPoints"; import { updateUiReport } from "./updateUiReport"; import { updateUserLog } from "./updateUserLog"; import { lockProfileExtend } from "./lockProfileExtend"; -import { BLOCK_SIZE } from "../../common"; +import { BLOCK_SIZE, ClientHello } from "../../common"; import { ByteStream } from "../../../util/stream"; const debug = logger("app:idz:userdb:decoder"); @@ -58,53 +58,55 @@ export type ReaderFn = ((buf: Buffer) => Request) & { msgLen: number; }; -const funcList: ReaderFn[] = [ +function makeReaderMap(funcList: ReaderFn[]): Map { + const result = new Map(); + + for (const fn of funcList) { + result.set(fn.msgCode, fn); + } + + return result; +} + +// TODO confirm v1.21.00 proto version +const funcList110: 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, + loadTeamRanking1, lockGarage, lockProfile, lockProfileExtend, + loadTopTen1, msg00AD, saveExpedition1, - saveExpedition2, saveGarage, saveNewCar, saveProfile2, - saveProfile3, saveSettings, saveStocker, saveTeamBanner, saveTimeAttack1, - saveTimeAttack2, saveTopic, unlockProfile, updateProvisionalStoreRank, updateResult, updateStoryClearNum1, - updateStoryClearNum2, updateTeamLeader, updateTeamMember, updateTeamPoints, @@ -112,15 +114,66 @@ const funcList: ReaderFn[] = [ updateUserLog, ]; -const readerFns = new Map(); -const msgLengths = new Map(); +const funcList130: ReaderFn[] = [ + checkTeamName, + createAutoTeam, + createProfile, + createTeam, + discoverProfile, + load2on2_v2, + updateStoryClearNum2, + loadConfig, + loadConfig2, + loadEventInfo, + loadGacha, + loadGarage, + loadGeneralReward2, + loadGhost, + loadProfile3, + loadRewardTable, + loadServerList, + loadStocker, + loadTeam, + loadTeamRanking2, + loadTopTen2, + lockGarage, + lockProfile, + lockProfileExtend, + msg00AD, + saveExpedition2, + saveGarage, + saveNewCar, + saveProfile3, + saveSettings, + saveStocker, + saveTeamBanner, + saveTimeAttack2, + saveTopic, + unlockProfile, + updateProvisionalStoreRank, + updateResult, + updateTeamLeader, + updateTeamMember, + updateTeamPoints, + updateUiReport, + updateUserLog, +]; -for (const fn of funcList) { - readerFns.set(fn.msgCode, fn); - msgLengths.set(fn.msgCode, fn.msgLen); -} +const protocols = new Map>(); + +protocols.set("110", makeReaderMap(funcList110)); +protocols.set("130", makeReaderMap(funcList130)); + +async function readRequest( + clientHello: ClientHello, + stm: ByteStream +): Promise { + const protocol = protocols.get(clientHello.protocol); + + if (protocol === undefined) { + throw new Error(`Unsupported protocol version ${clientHello.protocol}`); + } -async function readRequest(stm: ByteStream): Promise { const head = await stm.read(BLOCK_SIZE); if (head.length === 0) { @@ -129,16 +182,16 @@ async function readRequest(stm: ByteStream): Promise { } const msgCode = head.readUInt16LE(0x0000); - const msgLen = msgLengths.get(msgCode); + const readerFn = protocol.get(msgCode); - if (msgLen === undefined) { + if (readerFn === undefined) { throw new Error(`Message ${msgCode.toString(16)}: Unknown command code`); } - const tail = await stm.read(msgLen - BLOCK_SIZE); + const tail = await stm.read(readerFn.msgLen - BLOCK_SIZE); const msg = Buffer.concat([head, tail]); - if (msg.length < msgLen) { + if (msg.length < readerFn.msgLen) { throw new Error(`Message ${msgCode.toString(16)}: Truncated read`); } @@ -146,22 +199,19 @@ async function readRequest(stm: ByteStream): Promise { debug("Raw: %s", msg.toString("hex")); } - const reader = readerFns.get(msgCode); - - if (reader === undefined) { - throw new Error(`Message ${msgCode.toString(16)}: No read handler`); - } - - const payload = reader(msg); + const payload = readerFn(msg); debug("Payload: %j", payload); return payload; } -export default async function* readRequestStream(stm: ByteStream) { +export default async function* readRequestStream( + clientHello: ClientHello, + stm: ByteStream +) { while (true) { - const req = await readRequest(stm); + const req = await readRequest(clientHello, stm); if (req === undefined) { return; diff --git a/src/idz/userdb/decoder/load2on2.ts b/src/idz/userdb/decoder/load2on2.ts index dbf8873..abe5f4b 100644 --- a/src/idz/userdb/decoder/load2on2.ts +++ b/src/idz/userdb/decoder/load2on2.ts @@ -1,15 +1,14 @@ import { ExtId } from "../model/base"; import { Team } from "../model/team"; -import { Load2on2Request1, Load2on2Request2 } from "../request/load2on2"; +import { Load2on2Request } from "../request/load2on2"; import { AimeId } from "../../../model"; load2on2_v1.msgCode = 0x00b0; load2on2_v1.msgLen = 0x0010; -export function load2on2_v1(buf: Buffer): Load2on2Request1 { +export function load2on2_v1(buf: Buffer): Load2on2Request { return { type: "load_2on2_req", - format: 1, field_0002: buf.readUInt16LE(0x0002), aimeId: buf.readUInt32LE(0x0004) as AimeId, teamId: buf.readUInt32LE(0x0008) as ExtId, @@ -19,10 +18,9 @@ export function load2on2_v1(buf: Buffer): Load2on2Request1 { load2on2_v2.msgCode = 0x0132; load2on2_v2.msgLen = 0x0010; -export function load2on2_v2(buf: Buffer): Load2on2Request2 { +export function load2on2_v2(buf: Buffer): Load2on2Request { return { type: "load_2on2_req", - format: 2, field_0002: buf.readUInt16LE(0x0002), aimeId: buf.readUInt32LE(0x0004) as AimeId, teamId: buf.readUInt32LE(0x0008) as ExtId, diff --git a/src/idz/userdb/decoder/loadGeneralReward.ts b/src/idz/userdb/decoder/loadGeneralReward.ts index ff761c1..bd990b6 100644 --- a/src/idz/userdb/decoder/loadGeneralReward.ts +++ b/src/idz/userdb/decoder/loadGeneralReward.ts @@ -1,16 +1,12 @@ -import { - LoadGeneralRewardRequest1, - LoadGeneralRewardRequest2, -} from "../request/loadGeneralReward"; +import { LoadGeneralRewardRequest } from "../request/loadGeneralReward"; import { AimeId } from "../../../model"; loadGeneralReward1.msgCode = 0x009c; loadGeneralReward1.msgLen = 0x0010; -export function loadGeneralReward1(buf: Buffer): LoadGeneralRewardRequest1 { +export function loadGeneralReward1(buf: Buffer): LoadGeneralRewardRequest { return { type: "load_general_reward_req", - format: 1, aimeId: buf.readUInt32LE(0x0004) as AimeId, }; } @@ -18,10 +14,9 @@ export function loadGeneralReward1(buf: Buffer): LoadGeneralRewardRequest1 { loadGeneralReward2.msgCode = 0x013b; loadGeneralReward2.msgLen = 0x0010; -export function loadGeneralReward2(buf: Buffer): LoadGeneralRewardRequest2 { +export function loadGeneralReward2(buf: Buffer): LoadGeneralRewardRequest { return { type: "load_general_reward_req", - format: 2, aimeId: buf.readUInt32LE(0x0004) as AimeId, }; } diff --git a/src/idz/userdb/decoder/loadProfile.ts b/src/idz/userdb/decoder/loadProfile.ts index 6a65ac5..70ac42f 100644 --- a/src/idz/userdb/decoder/loadProfile.ts +++ b/src/idz/userdb/decoder/loadProfile.ts @@ -1,17 +1,13 @@ -import { - LoadProfileRequest2, - LoadProfileRequest3, -} from "../request/loadProfile"; +import { LoadProfileRequest } from "../request/loadProfile"; import { AimeId } from "../../../model"; import { readAsciiStr } from "../../util/bin"; loadProfile2.msgCode = 0x0067; loadProfile2.msgLen = 0x0020; -export function loadProfile2(buf: Buffer): LoadProfileRequest2 { +export function loadProfile2(buf: Buffer): LoadProfileRequest { return { type: "load_profile_req", - format: 2, aimeId: buf.readUInt32LE(0x0004) as AimeId, version: 1, luid: readAsciiStr(buf, 0x0008, 0x0020), @@ -21,10 +17,9 @@ export function loadProfile2(buf: Buffer): LoadProfileRequest2 { loadProfile3.msgCode = 0x0012f; loadProfile3.msgLen = 0x0020; -export function loadProfile3(buf: Buffer): LoadProfileRequest3 { +export function loadProfile3(buf: Buffer): LoadProfileRequest { return { type: "load_profile_req", - format: 3, aimeId: buf.readUInt32LE(0x0004) as AimeId, version: 1, luid: readAsciiStr(buf, 0x0008, 0x0020), diff --git a/src/idz/userdb/decoder/loadTeamRanking.ts b/src/idz/userdb/decoder/loadTeamRanking.ts index 736f71b..35a8de2 100644 --- a/src/idz/userdb/decoder/loadTeamRanking.ts +++ b/src/idz/userdb/decoder/loadTeamRanking.ts @@ -1,9 +1,9 @@ import { LoadTeamRankingRequest } from "../request/loadTeamRanking"; -loadTeamRanking.msgCode = 0x00b9; -loadTeamRanking.msgLen = 0x0010; +loadTeamRanking1.msgCode = 0x00b9; +loadTeamRanking1.msgLen = 0x0010; -export function loadTeamRanking(buf: Buffer): LoadTeamRankingRequest { +export function loadTeamRanking1(buf: Buffer): LoadTeamRankingRequest { return { type: "load_team_ranking_req", }; diff --git a/src/idz/userdb/decoder/saveExpedition.ts b/src/idz/userdb/decoder/saveExpedition.ts index e977d8a..fa9e470 100644 --- a/src/idz/userdb/decoder/saveExpedition.ts +++ b/src/idz/userdb/decoder/saveExpedition.ts @@ -1,15 +1,11 @@ -import { - SaveExpeditionRequest1, - SaveExpeditionRequest2, -} from "../request/saveExpedition"; +import { SaveExpeditionRequest } from "../request/saveExpedition"; saveExpedition1.msgCode = 0x008c; saveExpedition1.msgLen = 0x0010; -export function saveExpedition1(buf: Buffer): SaveExpeditionRequest1 { +export function saveExpedition1(buf: Buffer): SaveExpeditionRequest { return { type: "save_expedition_req", - format: 1, field_0004: buf.readUInt32LE(0x0004), }; } @@ -17,10 +13,9 @@ export function saveExpedition1(buf: Buffer): SaveExpeditionRequest1 { saveExpedition2.msgCode = 0x013f; saveExpedition2.msgLen = 0x0010; -export function saveExpedition2(buf: Buffer): SaveExpeditionRequest2 { +export function saveExpedition2(buf: Buffer): SaveExpeditionRequest { return { type: "save_expedition_req", - format: 2, field_0004: buf.readUInt32LE(0x0004), }; } diff --git a/src/idz/userdb/decoder/saveProfile2.ts b/src/idz/userdb/decoder/saveProfile2.ts index 6161ad9..60dbbcf 100644 --- a/src/idz/userdb/decoder/saveProfile2.ts +++ b/src/idz/userdb/decoder/saveProfile2.ts @@ -1,14 +1,14 @@ import { car } from "./_car"; import { mission } from "./_mission"; import { BackgroundCode, CourseNo, TitleCode } from "../model/base"; -import { SaveProfileRequest2 } from "../request/saveProfile"; +import { SaveProfileRequest } from "../request/saveProfile"; import { bitmap } from "./_bitmap"; import { AimeId } from "../../../model"; saveProfile2.msgCode = 0x0068; saveProfile2.msgLen = 0x0940; -export function saveProfile2(buf: Buffer): SaveProfileRequest2 { +export function saveProfile2(buf: Buffer): SaveProfileRequest { const storyRows = new Array(); for (let i = 0; i < 9; i++) { @@ -45,7 +45,6 @@ export function saveProfile2(buf: Buffer): SaveProfileRequest2 { return { type: "save_profile_req", - format: 2, aimeId: buf.readUInt32LE(0x0004) as AimeId, version: 1, lv: buf.readUInt16LE(0x0026), diff --git a/src/idz/userdb/decoder/saveProfile3.ts b/src/idz/userdb/decoder/saveProfile3.ts index 08c6b73..0d8876f 100644 --- a/src/idz/userdb/decoder/saveProfile3.ts +++ b/src/idz/userdb/decoder/saveProfile3.ts @@ -1,14 +1,14 @@ import { car } from "./_car"; import { mission } from "./_mission"; import { BackgroundCode, CourseNo, TitleCode } from "../model/base"; -import { SaveProfileRequest2 } from "../request/saveProfile"; +import { SaveProfileRequest } from "../request/saveProfile"; import { bitmap } from "./_bitmap"; import { AimeId } from "../../../model"; saveProfile3.msgCode = 0x0138; saveProfile3.msgLen = 0x0a70; -export function saveProfile3(buf: Buffer): SaveProfileRequest2 { +export function saveProfile3(buf: Buffer): SaveProfileRequest { const storyRows = new Array(); // Story layout has changed somewhat... @@ -47,7 +47,6 @@ export function saveProfile3(buf: Buffer): SaveProfileRequest2 { return { type: "save_profile_req", - format: 2, aimeId: buf.readUInt32LE(0x0004) as AimeId, version: 1, lv: buf.readUInt16LE(0x0026), diff --git a/src/idz/userdb/decoder/updateStoryClearNum.ts b/src/idz/userdb/decoder/updateStoryClearNum.ts index 720205d..e77247b 100644 --- a/src/idz/userdb/decoder/updateStoryClearNum.ts +++ b/src/idz/userdb/decoder/updateStoryClearNum.ts @@ -1,28 +1,19 @@ -import { - UpdateStoryClearNumRequest1, - UpdateStoryClearNumRequest2, -} from "../request/updateStoryClearNum"; +import { UpdateStoryClearNumRequest } from "../request/updateStoryClearNum"; updateStoryClearNum1.msgCode = 0x007f; updateStoryClearNum1.msgLen = 0x0010; -export function updateStoryClearNum1( - buf: Buffer -): UpdateStoryClearNumRequest1 { +export function updateStoryClearNum1(buf: Buffer): UpdateStoryClearNumRequest { return { type: "update_story_clear_num_req", - format: 1, }; } updateStoryClearNum2.msgCode = 0x013d; updateStoryClearNum2.msgLen = 0x0010; -export function updateStoryClearNum2( - buf: Buffer -): UpdateStoryClearNumRequest2 { +export function updateStoryClearNum2(buf: Buffer): UpdateStoryClearNumRequest { return { type: "update_story_clear_num_req", - format: 2, }; } diff --git a/src/idz/userdb/encoder/index.ts b/src/idz/userdb/encoder/index.ts index d2a89fa..03a1b61 100644 --- a/src/idz/userdb/encoder/index.ts +++ b/src/idz/userdb/encoder/index.ts @@ -7,7 +7,7 @@ import { discoverProfile } from "./discoverProfile"; import { generic } from "./generic"; import { lockProfile } from "./lockProfile"; import { lockProfileExtend } from "./lockProfileExtend"; -import { load2on2 } from "./load2on2"; +import { load2on2_v1, load2on2_v2 } from "./load2on2"; import { loadConfig } from "./loadConfig"; import { loadConfig2 } from "./loadConfig2"; import { loadEventInfo } from "./loadEventInfo"; @@ -15,27 +15,32 @@ import { loadGacha } from "./loadGacha"; import { loadGarage } from "./loadGarage"; import { loadGeneralReward } from "./loadGeneralReward"; import { loadGhost } from "./loadGhost"; -import { loadProfile } from "./loadProfile"; +import { loadProfile2 } from "./loadProfile2"; +import { loadProfile3 } from "./loadProfile3"; import { loadRewardTable } from "./loadRewardTable"; import { loadServerList } from "./loadServerList"; import { loadStocker } from "./loadStocker"; import { loadTeamRanking } from "./loadTeamRanking"; import { loadTopTen } from "./loadTopTen"; -import { saveExpedition } from "./saveExpedition"; +import { saveExpedition1, saveExpedition2 } from "./saveExpedition"; import { saveGarage } from "./saveGarage"; import { saveNewCar } from "./saveNewCar"; import { saveTimeAttack } from "./saveTimeAttack"; import { saveTopic } from "./saveTopic"; import { unlockProfile } from "./unlockProfile"; import { updateProvisionalStoreRank } from "./updateProvisionalStoreRank"; -import { updateStoryClearNum } from "./updateStoryClearNum"; +import { + updateStoryClearNum1, + updateStoryClearNum2, +} from "./updateStoryClearNum"; import { updateTeamLeader } from "./updateTeamLeader"; import { updateTeamMember } from "./updateTeamMember"; import { Response } from "../response"; +import { ClientHello } from "../../common"; const debug = logger("app:idz:userdb:encoder"); -function encode(res: Response): Buffer { +function encode110(res: Response): Buffer { switch (res.type) { case "check_team_name_res": return checkTeamName(res); @@ -53,7 +58,7 @@ function encode(res: Response): Buffer { return generic(res); case "load_2on2_res": - return load2on2(res); + return load2on2_v1(res); case "load_config_res": return loadConfig(res); @@ -77,7 +82,7 @@ function encode(res: Response): Buffer { return loadGhost(res); case "load_profile_res": - return loadProfile(res); + return loadProfile2(res); case "load_reward_table_res": return loadRewardTable(res); @@ -104,7 +109,7 @@ function encode(res: Response): Buffer { return lockProfile(res); case "save_expedition_res": - return saveExpedition(res); + return saveExpedition1(res); case "save_garage_res": return saveGarage(res); @@ -122,7 +127,7 @@ function encode(res: Response): Buffer { return updateProvisionalStoreRank(res); case "update_story_clear_num_res": - return updateStoryClearNum(res); + return updateStoryClearNum1(res); case "update_team_leader_res": return updateTeamLeader(res); @@ -140,10 +145,131 @@ function encode(res: Response): Buffer { } } -export default function writeResponse(res: Response) { +function encode130(res: Response): Buffer { + switch (res.type) { + case "check_team_name_res": + return checkTeamName(res); + + case "create_auto_team_res": + return _team(res); + + case "create_team_res": + return createTeam(res); + + case "discover_profile_res": + return discoverProfile(res); + + case "generic_res": + return generic(res); + + case "load_2on2_res": + return load2on2_v2(res); + + case "load_config_res": + return loadConfig(res); + + case "load_config_v2_res": + return loadConfig2(res); + + case "load_event_info_res": + return loadEventInfo(res); + + case "load_gacha_res": + return loadGacha(res); + + case "load_garage_res": + return loadGarage(res); + + case "load_general_reward_res": + return loadGeneralReward(res); + + case "load_ghost_res": + return loadGhost(res); + + case "load_profile_res": + return loadProfile3(res); + + case "load_reward_table_res": + return loadRewardTable(res); + + case "load_server_list_res": + return loadServerList(res); + + case "load_stocker_res": + return loadStocker(res); + + case "load_team_res": + return _team(res); + + case "load_team_ranking_res": + return loadTeamRanking(res); + + case "load_top_ten_res": + return loadTopTen(res); + + case "lock_profile_extend_res": + return lockProfileExtend(res); + + case "lock_profile_res": + return lockProfile(res); + + case "save_expedition_res": + return saveExpedition2(res); + + case "save_garage_res": + return saveGarage(res); + + case "save_new_car_res": + return saveNewCar(res); + + case "save_time_attack_res": + return saveTimeAttack(res); + + case "unlock_profile_res": + return unlockProfile(res); + + case "update_provisional_store_rank_res": + return updateProvisionalStoreRank(res); + + case "update_story_clear_num_res": + return updateStoryClearNum2(res); + + case "update_team_leader_res": + return updateTeamLeader(res); + + case "update_team_member_res": + return updateTeamMember(res); + + case "save_topic_res": + return saveTopic(res); + + default: + const exhaustCheck: never = res; + + throw new Error(`No writer fn for ${res["type"]}`); + } +} + +function encode(res: Response, clientHello: ClientHello) { + switch (clientHello.protocol) { + case "110": + return encode110(res); + + case "130": + return encode130(res); + + default: + throw new Error(`Unsupported protocol version ${clientHello.protocol}`); + } +} + +export default function writeResponse( + res: Response, + clientHello: ClientHello +) { debug("Object: %j", res); - const buf = encode(res); + const buf = encode(res, clientHello); if (debug.enabled) { debug("Encoded: %s", buf.toString("hex")); diff --git a/src/idz/userdb/encoder/load2on2.ts b/src/idz/userdb/encoder/load2on2.ts index dc10861..8321a05 100644 --- a/src/idz/userdb/encoder/load2on2.ts +++ b/src/idz/userdb/encoder/load2on2.ts @@ -1,25 +1,6 @@ -import { - Load2on2Response, - Load2on2Response1, - Load2on2Response2, -} from "../response/load2on2"; +import { Load2on2Response } from "../response/load2on2"; -export function load2on2(res: Load2on2Response): Buffer { - switch (res.format) { - case 1: - return load2on2_v1(res); - - case 2: - return load2on2_v2(res); - - default: - const exhaust: never = res; - - throw new Error(`Unsupported 2on2 response format ${res["format"]}`); - } -} - -function load2on2_v1(res: Load2on2Response1): Buffer { +export function load2on2_v1(res: Load2on2Response): Buffer { const buf = Buffer.alloc(0x04c0); buf.writeInt16LE(0x00b1, 0x0000); @@ -28,7 +9,7 @@ function load2on2_v1(res: Load2on2Response1): Buffer { } // Same size but presumably incompatible somehow -function load2on2_v2(res: Load2on2Response2): Buffer { +export function load2on2_v2(res: Load2on2Response): Buffer { const buf = Buffer.alloc(0x04c0); buf.writeInt16LE(0x0133, 0x0000); diff --git a/src/idz/userdb/encoder/loadProfile.ts b/src/idz/userdb/encoder/loadProfile.ts deleted file mode 100644 index df29669..0000000 --- a/src/idz/userdb/encoder/loadProfile.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { loadProfile1 } from "./loadProfile1"; -import { loadProfile2 } from "./loadProfile2"; -import { loadProfile3 } from "./loadProfile3"; -import { LoadProfileResponse } from "../response/loadProfile"; - -export function loadProfile(res: LoadProfileResponse) { - switch (res.format) { - case 1: - return loadProfile1(res); - - case 2: - return loadProfile2(res); - - case 3: - return loadProfile3(res); - - default: - const exhaust: never = res; - - throw new Error(`Unsupported profile response format ${res["format"]}`); - } -} diff --git a/src/idz/userdb/encoder/loadProfile1.ts b/src/idz/userdb/encoder/loadProfile1.ts index 0dd9d73..1cc896a 100644 --- a/src/idz/userdb/encoder/loadProfile1.ts +++ b/src/idz/userdb/encoder/loadProfile1.ts @@ -1,9 +1,9 @@ -import { LoadProfileResponse1 } from "../response/loadProfile"; +import { LoadProfileResponse } from "../response/loadProfile"; // Sending this causes an error in v1.21, so it is currently unmapped and // unimplemented. -export function loadProfile1(res: LoadProfileResponse1) { +export function loadProfile1(res: LoadProfileResponse) { const buf = Buffer.alloc(0x0c60); buf.writeInt16LE(0x0064, 0x0000); diff --git a/src/idz/userdb/encoder/loadProfile2.ts b/src/idz/userdb/encoder/loadProfile2.ts index 7f70c5b..5450351 100644 --- a/src/idz/userdb/encoder/loadProfile2.ts +++ b/src/idz/userdb/encoder/loadProfile2.ts @@ -2,10 +2,10 @@ import { encodeBitmap } from "./_bitmap"; import { encodeCar } from "./_car"; import { encodeChara } from "./_chara"; import { encodeMission } from "./_mission"; -import { LoadProfileResponse2 } from "../response/loadProfile"; +import { LoadProfileResponse } from "../response/loadProfile"; import { writeSjisStr } from "../../util/bin"; -export function loadProfile2(res: LoadProfileResponse2) { +export function loadProfile2(res: LoadProfileResponse) { const buf = Buffer.alloc(0x0d30); // FLAMETHROWER ANALYSIS (watch out for C strings) diff --git a/src/idz/userdb/encoder/loadProfile3.ts b/src/idz/userdb/encoder/loadProfile3.ts index 53290b0..0841840 100644 --- a/src/idz/userdb/encoder/loadProfile3.ts +++ b/src/idz/userdb/encoder/loadProfile3.ts @@ -2,10 +2,10 @@ import { encodeBitmap } from "./_bitmap"; import { encodeCar } from "./_car"; import { encodeChara } from "./_chara"; import { encodeMission } from "./_mission"; -import { LoadProfileResponse3 } from "../response/loadProfile"; +import { LoadProfileResponse } from "../response/loadProfile"; import { writeSjisStr } from "../../util/bin"; -export function loadProfile3(res: LoadProfileResponse3) { +export function loadProfile3(res: LoadProfileResponse) { const buf = Buffer.alloc(0x0ea0); // Initialize all TA grades to uhh... fuck knows diff --git a/src/idz/userdb/encoder/saveExpedition.ts b/src/idz/userdb/encoder/saveExpedition.ts index 0c5b478..6f9820a 100644 --- a/src/idz/userdb/encoder/saveExpedition.ts +++ b/src/idz/userdb/encoder/saveExpedition.ts @@ -1,25 +1,6 @@ -import { - SaveExpeditionResponse, - SaveExpeditionResponse1, - SaveExpeditionResponse2, -} from "../response/saveExpedition"; +import { SaveExpeditionResponse } from "../response/saveExpedition"; -export function saveExpedition(res: SaveExpeditionResponse): Buffer { - switch (res.format) { - case 1: - return saveExpedition1(res); - - case 2: - return saveExpedition2(res); - - default: - const exhaust: never = res; - - throw new Error(`Unsupported data format ${res["format"]}`); - } -} - -function saveExpedition1(res: SaveExpeditionResponse1): Buffer { +export function saveExpedition1(res: SaveExpeditionResponse): Buffer { // in awe of the size of this lad const buf = Buffer.alloc(0x17c0); @@ -28,7 +9,7 @@ function saveExpedition1(res: SaveExpeditionResponse1): Buffer { return buf; } -function saveExpedition2(res: SaveExpeditionResponse2): Buffer { +export function saveExpedition2(res: SaveExpeditionResponse): Buffer { // absolute unit const buf = Buffer.alloc(0x18ac); diff --git a/src/idz/userdb/encoder/updateStoryClearNum.ts b/src/idz/userdb/encoder/updateStoryClearNum.ts index 63333e9..7b8992e 100644 --- a/src/idz/userdb/encoder/updateStoryClearNum.ts +++ b/src/idz/userdb/encoder/updateStoryClearNum.ts @@ -1,25 +1,8 @@ -import { - UpdateStoryClearNumResponse, - UpdateStoryClearNumResponse1, - UpdateStoryClearNumResponse2, -} from "../response/updateStoryClearNum"; +import { UpdateStoryClearNumResponse } from "../response/updateStoryClearNum"; -export function updateStoryClearNum(res: UpdateStoryClearNumResponse): Buffer { - switch (res.format) { - case 1: - return updateStoryClearNum1(res); - - case 2: - return updateStoryClearNum2(res); - - default: - const exhaust: never = res; - - throw new Error(`Unsupported data format ${res["format"]}`); - } -} - -function updateStoryClearNum1(res: UpdateStoryClearNumResponse1): Buffer { +export function updateStoryClearNum1( + res: UpdateStoryClearNumResponse +): Buffer { const buf = Buffer.alloc(0x0220); buf.writeInt16LE(0x0080, 0x0000); @@ -27,7 +10,9 @@ function updateStoryClearNum1(res: UpdateStoryClearNumResponse1): Buffer { return buf; } -function updateStoryClearNum2(res: UpdateStoryClearNumResponse2): Buffer { +export function updateStoryClearNum2( + res: UpdateStoryClearNumResponse +): Buffer { const buf = Buffer.alloc(0x04f0); buf.writeInt16LE(0x013e, 0x0000); diff --git a/src/idz/userdb/handler/load2on2.ts b/src/idz/userdb/handler/load2on2.ts index 3ec8422..3005afa 100644 --- a/src/idz/userdb/handler/load2on2.ts +++ b/src/idz/userdb/handler/load2on2.ts @@ -8,6 +8,5 @@ export function load2on2( ): Load2on2Response { return { type: "load_2on2_res", - format: req.format as any, }; } diff --git a/src/idz/userdb/handler/loadProfile.ts b/src/idz/userdb/handler/loadProfile.ts index de27c7a..17e89e9 100644 --- a/src/idz/userdb/handler/loadProfile.ts +++ b/src/idz/userdb/handler/loadProfile.ts @@ -31,7 +31,6 @@ export async function loadProfile( return { type: "load_profile_res", - format: req.format as any, // TS fart name: profile.name, aimeId, lv: profile.lv, diff --git a/src/idz/userdb/handler/saveExpedition.ts b/src/idz/userdb/handler/saveExpedition.ts index 2d18e3a..e136b34 100644 --- a/src/idz/userdb/handler/saveExpedition.ts +++ b/src/idz/userdb/handler/saveExpedition.ts @@ -15,7 +15,6 @@ export function saveExpedition( } else { return { type: "save_expedition_res", - format: req.format as any, }; } } diff --git a/src/idz/userdb/handler/updateStoryClearNum.ts b/src/idz/userdb/handler/updateStoryClearNum.ts index 29d88ea..2b4970e 100644 --- a/src/idz/userdb/handler/updateStoryClearNum.ts +++ b/src/idz/userdb/handler/updateStoryClearNum.ts @@ -8,6 +8,5 @@ export function updateStoryClearNum( ): UpdateStoryClearNumResponse { return { type: "update_story_clear_num_res", - format: req.format as any, }; } diff --git a/src/idz/userdb/index.ts b/src/idz/userdb/index.ts index 6a0d7cb..ea15517 100644 --- a/src/idz/userdb/index.ts +++ b/src/idz/userdb/index.ts @@ -19,12 +19,12 @@ export default function idz(db: DataSource) { debug("Handshake OK", clientHello); - for await (const req of readRequestStream(aesStream)) { + for await (const req of readRequestStream(clientHello, aesStream)) { const res = await db.transaction(txn => dispatch(new SqlRepositories(txn), req) ); - await aesStream.write(writeResponse(res)); + await aesStream.write(writeResponse(res, clientHello)); } } catch (error) { if (debug.enabled) { diff --git a/src/idz/userdb/request/load2on2.ts b/src/idz/userdb/request/load2on2.ts index 7490a7b..15f1a20 100644 --- a/src/idz/userdb/request/load2on2.ts +++ b/src/idz/userdb/request/load2on2.ts @@ -2,19 +2,9 @@ import { ExtId } from "../model/base"; import { Team } from "../model/team"; import { AimeId } from "../../../model"; -interface Load2on2RequestBase { +export interface Load2on2Request { type: "load_2on2_req"; field_0002: number; aimeId: AimeId; teamId: ExtId; } - -export interface Load2on2Request1 extends Load2on2RequestBase { - format: 1; -} - -export interface Load2on2Request2 extends Load2on2RequestBase { - format: 2; -} - -export type Load2on2Request = Load2on2Request1 | Load2on2Request2; diff --git a/src/idz/userdb/request/loadGeneralReward.ts b/src/idz/userdb/request/loadGeneralReward.ts index 91bcc02..c6d89b0 100644 --- a/src/idz/userdb/request/loadGeneralReward.ts +++ b/src/idz/userdb/request/loadGeneralReward.ts @@ -1,20 +1,6 @@ import { AimeId } from "../../../model"; -interface LoadGeneralRewardRequestBase { +export interface LoadGeneralRewardRequest { type: "load_general_reward_req"; aimeId: AimeId; } - -export interface LoadGeneralRewardRequest1 - extends LoadGeneralRewardRequestBase { - format: 1; -} - -export interface LoadGeneralRewardRequest2 - extends LoadGeneralRewardRequestBase { - format: 2; -} - -export type LoadGeneralRewardRequest = - | LoadGeneralRewardRequest1 - | LoadGeneralRewardRequest2; diff --git a/src/idz/userdb/request/loadProfile.ts b/src/idz/userdb/request/loadProfile.ts index 63119ee..ad6acc0 100644 --- a/src/idz/userdb/request/loadProfile.ts +++ b/src/idz/userdb/request/loadProfile.ts @@ -1,18 +1,8 @@ import { AimeId } from "../../../model"; -interface LoadProfileRequestBase { +export interface LoadProfileRequest { type: "load_profile_req"; aimeId: AimeId; version: number; luid: string; } - -export interface LoadProfileRequest2 extends LoadProfileRequestBase { - format: 2; -} - -export interface LoadProfileRequest3 extends LoadProfileRequestBase { - format: 3; -} - -export type LoadProfileRequest = LoadProfileRequest2 | LoadProfileRequest3; diff --git a/src/idz/userdb/request/saveExpedition.ts b/src/idz/userdb/request/saveExpedition.ts index 8483066..081eec3 100644 --- a/src/idz/userdb/request/saveExpedition.ts +++ b/src/idz/userdb/request/saveExpedition.ts @@ -1,16 +1,4 @@ -interface SaveExpeditionRequestBase { +export interface SaveExpeditionRequest { type: "save_expedition_req"; field_0004: number; } - -export interface SaveExpeditionRequest1 extends SaveExpeditionRequestBase { - format: 1; -} - -export interface SaveExpeditionRequest2 extends SaveExpeditionRequestBase { - format: 2; -} - -export type SaveExpeditionRequest = - | SaveExpeditionRequest1 - | SaveExpeditionRequest2; diff --git a/src/idz/userdb/request/saveProfile.ts b/src/idz/userdb/request/saveProfile.ts index 71aaf54..de12e47 100644 --- a/src/idz/userdb/request/saveProfile.ts +++ b/src/idz/userdb/request/saveProfile.ts @@ -7,7 +7,7 @@ import { Tickets } from "../model/tickets"; import { Unlocks } from "../model/unlocks"; import { AimeId } from "../../../model"; -interface SaveProfileRequestBase { +export interface SaveProfileRequest { type: "save_profile_req"; aimeId: AimeId; version: number; @@ -27,13 +27,3 @@ interface SaveProfileRequestBase { tickets: Tickets; settings: Settings; } - -export interface SaveProfileRequest2 extends SaveProfileRequestBase { - format: 2; -} - -export interface SaveProfileRequest3 extends SaveProfileRequestBase { - format: 3; -} - -export type SaveProfileRequest = SaveProfileRequest2 | SaveProfileRequest3; diff --git a/src/idz/userdb/request/updateStoryClearNum.ts b/src/idz/userdb/request/updateStoryClearNum.ts index b3349a1..ba28fd8 100644 --- a/src/idz/userdb/request/updateStoryClearNum.ts +++ b/src/idz/userdb/request/updateStoryClearNum.ts @@ -1,17 +1,3 @@ -interface UpdateStoryClearNumRequestBase { +export interface UpdateStoryClearNumRequest { type: "update_story_clear_num_req"; } - -export interface UpdateStoryClearNumRequest1 - extends UpdateStoryClearNumRequestBase { - format: 1; -} - -export interface UpdateStoryClearNumRequest2 - extends UpdateStoryClearNumRequestBase { - format: 2; -} - -export type UpdateStoryClearNumRequest = - | UpdateStoryClearNumRequest1 - | UpdateStoryClearNumRequest2; diff --git a/src/idz/userdb/response/load2on2.ts b/src/idz/userdb/response/load2on2.ts index b6bb6e1..c3626a6 100644 --- a/src/idz/userdb/response/load2on2.ts +++ b/src/idz/userdb/response/load2on2.ts @@ -1,14 +1,4 @@ -interface Load2on2ResponseBase { +export interface Load2on2Response { type: "load_2on2_res"; // TODO? } - -export interface Load2on2Response1 extends Load2on2ResponseBase { - format: 1; -} - -export interface Load2on2Response2 extends Load2on2ResponseBase { - format: 2; -} - -export type Load2on2Response = Load2on2Response1 | Load2on2Response2; diff --git a/src/idz/userdb/response/loadProfile.ts b/src/idz/userdb/response/loadProfile.ts index fcf5778..d214391 100644 --- a/src/idz/userdb/response/loadProfile.ts +++ b/src/idz/userdb/response/loadProfile.ts @@ -9,7 +9,7 @@ import { TimeAttackScore } from "../model/timeAttack"; import { Unlocks } from "../model/unlocks"; import { AimeId } from "../../../model"; -interface LoadProfileResponseBase { +export interface LoadProfileResponse { type: "load_profile_res"; name: string; aimeId: AimeId; @@ -33,20 +33,3 @@ interface LoadProfileResponseBase { tickets: Tickets; // giga TODO } - -export interface LoadProfileResponse1 extends LoadProfileResponseBase { - format: 1; -} - -export interface LoadProfileResponse2 extends LoadProfileResponseBase { - format: 2; -} - -export interface LoadProfileResponse3 extends LoadProfileResponseBase { - format: 3; -} - -export type LoadProfileResponse = - | LoadProfileResponse1 - | LoadProfileResponse2 - | LoadProfileResponse3; diff --git a/src/idz/userdb/response/saveExpedition.ts b/src/idz/userdb/response/saveExpedition.ts index 71cd7ee..1401ccf 100644 --- a/src/idz/userdb/response/saveExpedition.ts +++ b/src/idz/userdb/response/saveExpedition.ts @@ -1,16 +1,4 @@ -interface SaveExpeditionResponseBase { +export interface SaveExpeditionResponse { type: "save_expedition_res"; // tera TODO } - -export interface SaveExpeditionResponse1 extends SaveExpeditionResponseBase { - format: 1; -} - -export interface SaveExpeditionResponse2 extends SaveExpeditionResponseBase { - format: 2; -} - -export type SaveExpeditionResponse = - | SaveExpeditionResponse1 - | SaveExpeditionResponse2; diff --git a/src/idz/userdb/response/updateStoryClearNum.ts b/src/idz/userdb/response/updateStoryClearNum.ts index ecf3096..190fbfc 100644 --- a/src/idz/userdb/response/updateStoryClearNum.ts +++ b/src/idz/userdb/response/updateStoryClearNum.ts @@ -1,18 +1,4 @@ -interface UpdateStoryClearNumResponseBase { +export interface UpdateStoryClearNumResponse { type: "update_story_clear_num_res"; // TODO, looks like a table of 9 * 10 u32 fields } - -export interface UpdateStoryClearNumResponse1 - extends UpdateStoryClearNumResponseBase { - format: 1; -} - -export interface UpdateStoryClearNumResponse2 - extends UpdateStoryClearNumResponseBase { - format: 2; -} - -export type UpdateStoryClearNumResponse = - | UpdateStoryClearNumResponse1 - | UpdateStoryClearNumResponse2;