diff --git a/src/idz/decoder/_car.ts b/src/idz/decoder/_car.ts new file mode 100644 index 0000000..4eaa8c5 --- /dev/null +++ b/src/idz/decoder/_car.ts @@ -0,0 +1,27 @@ +import { Car } 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, + model: buf.readUInt16LE(0x0044), + color: buf.readUInt16LE(0x0046), + transmission: 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), + }; +} diff --git a/src/idz/decoder/createProfile.ts b/src/idz/decoder/createProfile.ts index 91e8ccd..6b88404 100644 --- a/src/idz/decoder/createProfile.ts +++ b/src/idz/decoder/createProfile.ts @@ -2,6 +2,7 @@ import iconv = require("iconv-lite"); import { RequestCode } from "../defs"; import { CreateProfileRequest } from "../request/createProfile"; +import { car } from "./_car"; createProfile.msgCode = 0x0066 as RequestCode; createProfile.msgLen = 0x00c0; @@ -16,16 +17,7 @@ export function createProfile(buf: Buffer): CreateProfileRequest { "shift_jis" ), field_0034: buf.readUInt32LE(0x0034), - field_0040: buf.slice(0x0040, 0x0084), - car_type: buf.readUInt16LE(0x0084), - car_color: buf.readUInt16LE(0x0086), - transmission: buf.readUInt16LE(0x0088) === 0 ? "auto" : "manual", - field_008A: buf.readUInt16LE(0x008a), - field_008C: buf.readUInt16LE(0x008c), - field_0090: - BigInt(buf.readUInt32LE(0x0090)) | - (BigInt(buf.readUInt32LE(0x0094)) << 32n), - field_009C: buf.readUInt16LE(0x009c), + car: car(buf.slice(0x0040, 0x00a0)), gender: buf.readUInt16LE(0x00a0) === 0 ? "male" : "female", field_00A2: buf.readUInt16LE(0x00a2), field_00A4: buf.readUInt16LE(0x00a4), diff --git a/src/idz/decoder/index.ts b/src/idz/decoder/index.ts index e1acaee..d0166c9 100644 --- a/src/idz/decoder/index.ts +++ b/src/idz/decoder/index.ts @@ -16,6 +16,7 @@ import { loadTeamRanking, loadTeamRanking2 } from "./loadTeamRanking"; import { lockGarage } from "./lockGarage"; import { lockProfile } from "./lockProfile"; import { saveExpedition } from "./saveExpedition"; +import { saveGarage } from "./saveGarage"; import { saveProfile } from "./saveProfile"; import { saveSettings } from "./saveSettings"; import { saveStocker } from "./saveStocker"; @@ -52,6 +53,7 @@ const funcList: ReaderFn[] = [ lockGarage, lockProfile, saveExpedition, + saveGarage, saveProfile, saveSettings, saveStocker, diff --git a/src/idz/decoder/saveGarage.ts b/src/idz/decoder/saveGarage.ts new file mode 100644 index 0000000..196a2f9 --- /dev/null +++ b/src/idz/decoder/saveGarage.ts @@ -0,0 +1,23 @@ +import { car } from "./_car"; +import { RequestCode } from "../defs"; +import { SaveGarageRequest } from "../request/saveGarage"; + +saveGarage.msgCode = 0x008e as RequestCode; +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", + profileId: buf.readUInt32LE(0x0004), + payload: car(buf.slice(0x0008, 0x0068)), + field_0068, + field_0080: buf.readUInt8(0x0080), + field_0081: buf.readUInt8(0x0081) !== 0, + }; +} diff --git a/src/idz/encoder/_car.ts b/src/idz/encoder/_car.ts new file mode 100644 index 0000000..76c98a0 --- /dev/null +++ b/src/idz/encoder/_car.ts @@ -0,0 +1,30 @@ +import { Car } from "../model/car"; + +export function car(car: Car): Buffer { + const buf = Buffer.alloc(0x0060); + + buf.writeUInt16LE(car.field_00, 0x0000); + buf.writeUInt16LE(car.field_02, 0x0002); + + for (let i = 0; i < 32; i++) { + buf.writeUInt16LE( + i < car.field_04.length ? car.field_04[i] : 0xff00, + 0x0004 + 2 * i + ); + } + + buf.writeUInt16LE(car.model, 0x0044); + buf.writeUInt8(car.color, 0x0046); + buf.writeUInt16LE(car.transmission, 0x0048); + buf.writeUInt16LE(car.field_4A, 0x004a); + buf.writeUInt32LE(car.field_4C, 0x004c); + buf.writeUInt32LE(car.field_50_lo, 0x0050); + buf.writeUInt32LE(car.field_50_hi, 0x0050); + buf.writeUInt8(car.field_58, 0x0058); + buf.writeUInt8(car.field_5A, 0x005a); + buf.writeUInt8(car.field_5B, 0x005b); + buf.writeUInt16LE(car.field_5C, 0x005c); + buf.writeUInt16LE(car.field_5E, 0x005e); + + return buf; +} diff --git a/src/idz/encoder/discoverProfile.ts b/src/idz/encoder/discoverProfile.ts index 73ce337..acb931a 100644 --- a/src/idz/encoder/discoverProfile.ts +++ b/src/idz/encoder/discoverProfile.ts @@ -4,7 +4,7 @@ export function discoverProfile(res: DiscoverProfileResponse) { const buf = Buffer.alloc(0x0010); buf.writeInt16LE(0x006c, 0x0000); - buf.writeInt8(res.result ? 1 : 0, 0x0004); + buf.writeInt8(res.exists ? 1 : 0, 0x0004); return buf; } diff --git a/src/idz/encoder/index.ts b/src/idz/encoder/index.ts index 5a8e98d..65edd74 100644 --- a/src/idz/encoder/index.ts +++ b/src/idz/encoder/index.ts @@ -16,6 +16,7 @@ import { loadServerList } from "./loadServerList"; import { loadStocker } from "./loadStocker"; import { loadTeamRanking } from "./loadTeamRanking"; import { saveExpedition } from "./saveExpedition"; +import { saveGarage } from "./saveGarage"; import { saveTopic } from "./saveTopic"; import { updateProvisionalStoreRank } from "./updateProvisionalStoreRank"; import { updateStoryClearNum } from "./updateStoryClearNum"; @@ -75,6 +76,9 @@ function encode(res: Response): Buffer { case "save_expedition_res": return saveExpedition(res); + case "save_garage_res": + return saveGarage(res); + case "unlock_profile_res": return unlockProfile(res); diff --git a/src/idz/encoder/loadProfile2.ts b/src/idz/encoder/loadProfile2.ts index 8f36c13..233b259 100644 --- a/src/idz/encoder/loadProfile2.ts +++ b/src/idz/encoder/loadProfile2.ts @@ -1,5 +1,6 @@ import iconv = require("iconv-lite"); +import { car } from "./_car"; import { LoadProfileResponse2 } from "../response/loadProfile2"; export function loadProfile2(res: LoadProfileResponse2) { @@ -24,6 +25,7 @@ export function loadProfile2(res: LoadProfileResponse2) { buf.writeInt32LE(res.fame, 0x0404); iconv.encode(res.name + "\0", "shift_jis").copy(buf, 0x03ee); buf.writeInt32LE(res.teamId, 0x07e0); + car(res.car).copy(buf, 0xc5c); return buf; } diff --git a/src/idz/encoder/saveGarage.ts b/src/idz/encoder/saveGarage.ts new file mode 100644 index 0000000..6310b2f --- /dev/null +++ b/src/idz/encoder/saveGarage.ts @@ -0,0 +1,10 @@ +import { SaveGarageResponse } from "../response/saveGarage"; + +export function saveGarage(res: SaveGarageResponse): Buffer { + const buf = Buffer.alloc(0x0010); + + buf.writeUInt16LE(0x008f, 0x0000); + buf.writeUInt16LE(res.status, 0x0002); + + return buf; +} diff --git a/src/idz/handler/discoverProfile.ts b/src/idz/handler/discoverProfile.ts index 762c7a9..87f6d22 100644 --- a/src/idz/handler/discoverProfile.ts +++ b/src/idz/handler/discoverProfile.ts @@ -8,6 +8,6 @@ export function discoverProfile( ): DiscoverProfileResponse { return { type: "discover_profile_res", - result: true, + exists: true, }; } diff --git a/src/idz/handler/index.ts b/src/idz/handler/index.ts index 7842aca..5d0da83 100644 --- a/src/idz/handler/index.ts +++ b/src/idz/handler/index.ts @@ -14,6 +14,7 @@ import { loadTopTen } from "./loadTopTen"; import { lockGarage } from "./lockGarage"; import { lockProfile } from "./lockProfile"; import { saveExpedition } from "./saveExpedition"; +import { saveGarage } from "./saveGarage"; import { saveProfile } from "./saveProfile"; import { saveSettings } from "./saveSettings"; import { saveStocker } from "./saveStocker"; @@ -81,6 +82,9 @@ export function dispatch(w: World, req: Request): Response { case "update_provisional_store_rank_req": return updateProvisionalStoreRank(w, req); + case "save_garage_req": + return saveGarage(w, req); + case "save_profile_req": return saveProfile(w, req); diff --git a/src/idz/handler/loadProfile.ts b/src/idz/handler/loadProfile.ts index 6213478..f9877a9 100644 --- a/src/idz/handler/loadProfile.ts +++ b/src/idz/handler/loadProfile.ts @@ -1,6 +1,7 @@ import { LoadProfileRequest } from "../request/loadProfile"; import { LoadProfileResponse2 } from "../response/loadProfile2"; import { World } from "../world"; +import { Car } from "../model/car"; export function loadProfile( w: World, @@ -25,5 +26,22 @@ export function loadProfile( ghostEn: false, taResultSkip: false, }, + car: { + field_00: 0, + field_02: 0, + field_04: [], + model: 0, + color: 0, + transmission: 0, + field_4A: 0, + field_4C: 21527, + field_50_lo: 3674393, + field_50_hi: 6407, + field_58: 0, + field_5A: 0, + field_5B: 0, + field_5C: 1, + field_5E: 0, + }, }; } diff --git a/src/idz/handler/saveGarage.ts b/src/idz/handler/saveGarage.ts new file mode 100644 index 0000000..cde8a58 --- /dev/null +++ b/src/idz/handler/saveGarage.ts @@ -0,0 +1,13 @@ +import { SaveGarageRequest } from "../request/saveGarage"; +import { SaveGarageResponse } from "../response/saveGarage"; +import { World } from "../world"; + +export function saveGarage( + w: World, + req: SaveGarageRequest +): SaveGarageResponse { + return { + type: "save_garage_res", + status: 0, // Zero means success for this particular message -.- + }; +} diff --git a/src/idz/model/car.ts b/src/idz/model/car.ts new file mode 100644 index 0000000..2da8d32 --- /dev/null +++ b/src/idz/model/car.ts @@ -0,0 +1,17 @@ +export interface Car { + field_00: number; + field_02: number; + field_04: number[]; + model: number; + color: number; + transmission: number; + field_4A: number; + field_4C: number; + field_50_lo: number; + field_50_hi: number; + field_58: number; + field_5A: number; + field_5B: number; + field_5C: number; + field_5E: number; +} diff --git a/src/idz/request/createProfile.ts b/src/idz/request/createProfile.ts index cf0ee61..1fec795 100644 --- a/src/idz/request/createProfile.ts +++ b/src/idz/request/createProfile.ts @@ -1,17 +1,12 @@ +import { Car } from "../model/car"; + export interface CreateProfileRequest { type: "create_profile_req"; aimeId: number; luid: string; name: string; field_0034: number; - field_0040: Buffer; - car_type: number; - car_color: number; - transmission: "auto" | "manual"; - field_008A: number; - field_008C: number; - field_0090: bigint; - field_009C: number; + car: Car; gender: "male" | "female"; field_00A2: number; field_00A4: number; diff --git a/src/idz/request/index.ts b/src/idz/request/index.ts index 3fe8d16..0e2d2f9 100644 --- a/src/idz/request/index.ts +++ b/src/idz/request/index.ts @@ -16,6 +16,7 @@ import { LoadTopTenRequest } from "./loadTopTen"; import { LockAccountRequest } from "./lockProfile"; import { LockGarageRequest } from "./lockGarage"; import { SaveExpeditionRequest } from "./saveExpedition"; +import { SaveGarageRequest } from "./saveGarage"; import { SaveProfileRequest } from "./saveProfile"; import { SaveSettingsRequest } from "./saveSettings"; import { SaveStockerRequest } from "./saveStocker"; @@ -41,6 +42,7 @@ export type Request = | LockAccountRequest | LockGarageRequest | SaveExpeditionRequest + | SaveGarageRequest | SaveProfileRequest | SaveSettingsRequest | SaveStockerRequest diff --git a/src/idz/request/saveGarage.ts b/src/idz/request/saveGarage.ts new file mode 100644 index 0000000..2fabc63 --- /dev/null +++ b/src/idz/request/saveGarage.ts @@ -0,0 +1,10 @@ +import { Car } from "../model/car"; + +export interface SaveGarageRequest { + type: "save_garage_req"; + profileId: number; + payload: Car; + field_0068: number[]; + field_0080: number; + field_0081: boolean; +} diff --git a/src/idz/response/discoverProfile.ts b/src/idz/response/discoverProfile.ts index 1dc2e57..0537fb0 100644 --- a/src/idz/response/discoverProfile.ts +++ b/src/idz/response/discoverProfile.ts @@ -1,4 +1,4 @@ export interface DiscoverProfileResponse { type: "discover_profile_res"; - result: boolean; + exists: boolean; } diff --git a/src/idz/response/index.ts b/src/idz/response/index.ts index dece624..bbf49b3 100644 --- a/src/idz/response/index.ts +++ b/src/idz/response/index.ts @@ -18,6 +18,7 @@ import { UpdateProvisionalStoreRankResponse } from "./updateProvisionalStoreRank import { UpdateStoryClearNumResponse } from "./updateStoryClearNum"; import { UnlockProfileResponse } from "./unlockProfile"; import { SaveExpeditionResponse } from "./saveExpedition"; +import { SaveGarageResponse } from "./saveGarage"; import { SaveTopicResponse } from "./saveTopic"; export type Response = @@ -41,4 +42,5 @@ export type Response = | UpdateProvisionalStoreRankResponse | UpdateStoryClearNumResponse | SaveExpeditionResponse + | SaveGarageResponse | SaveTopicResponse; diff --git a/src/idz/response/loadProfile2.ts b/src/idz/response/loadProfile2.ts index f3800cc..40732e7 100644 --- a/src/idz/response/loadProfile2.ts +++ b/src/idz/response/loadProfile2.ts @@ -1,4 +1,5 @@ import { Settings } from "../model/settings"; +import { Car } from "../model/car"; export interface LoadProfileResponse2 { type: "load_profile_v2_res"; @@ -9,5 +10,6 @@ export interface LoadProfileResponse2 { dpoint: number; teamId: number; settings: Settings; + car: Car; // giga TODO } diff --git a/src/idz/response/saveGarage.ts b/src/idz/response/saveGarage.ts new file mode 100644 index 0000000..503add8 --- /dev/null +++ b/src/idz/response/saveGarage.ts @@ -0,0 +1,4 @@ +export interface SaveGarageResponse { + type: "save_garage_res"; + status: number; +}