Skip to content

Commit

Permalink
added a bunch more data
Browse files Browse the repository at this point in the history
  • Loading branch information
diogotr7 committed May 9, 2024
1 parent 5032f6b commit a59a28e
Show file tree
Hide file tree
Showing 10 changed files with 388 additions and 67 deletions.
40 changes: 36 additions & 4 deletions src/BufferReader.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { Color } from "./character/Color";

function H(n: number): string {
return n.toString(16).padStart(2, "0");
}

export class BufferReader {
private view: DataView;
private offset: number;
Expand Down Expand Up @@ -35,6 +41,36 @@ export class BufferReader {
return low + high * 2 ** 32;
}

readFloat32(): number {
const value = this.view.getFloat32(this.offset, true);
this.offset += Float32Array.BYTES_PER_ELEMENT;
return value;
}

readKeyedFloat32(key: number, count: number = 0): number {
this.expectUint32(key);
const data = this.readFloat32();
this.expectUint32(count);
return data;
}

readKeyedColor(key: number, count: number = 0): Color {
this.expectUint32(key);
const r = this.readByte();
const g = this.readByte();
const b = this.readByte();
const a = this.readByte();
this.expectUint32(count);
return `#${H(r)}${H(g)}${H(b)}${H(a)}`;
}

readKeyedUint32(key: number, count: number = 0): number {
this.expectUint32(key);
const value = this.readUint32();
this.expectUint32(count);
return value;
}

readGuid(): string {
//16 bytes
const a = this.readByte();
Expand All @@ -54,10 +90,6 @@ export class BufferReader {
const o = this.readByte();
const p = this.readByte();

function H(n: number): string {
return n.toString(16).padStart(2, "0");
}

// I hate this
return `${H(h)}${H(g)}${H(f)}${H(e)}-${H(d)}${H(c)}-${H(b)}${H(a)}-${H(
p
Expand Down
13 changes: 10 additions & 3 deletions src/character/Character.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { BufferReader } from "../BufferReader";
import { Body, readBody } from "./Body";
import { FaceMaterial, readFaceMaterial } from "./FaceMaterial";
import { HeadMaterial, readHeadMaterial } from "./HeadMaterial";

export function toHexString(byteArray: Uint8Array) {
return Array.from(byteArray, function (byte) {
Expand All @@ -13,6 +15,8 @@ export type Character = {
bodyType: BodyType;
dna: string;
body: Body;
headMaterial: HeadMaterial;
faceMaterial: FaceMaterial;
};

export function readCharacter(bytes: Uint8Array): Character {
Expand All @@ -23,10 +27,11 @@ export function readCharacter(bytes: Uint8Array): Character {
reader.expectEmptyGuid();
reader.expectUint64(0xd8);
const dnaBytes = reader.readBytes(0xd8);
const totalCount = reader.readUint64();
console.log(`Total count: ${totalCount}`);

// eslint-disable-next-line @typescript-eslint/no-unused-vars
reader.readUint64();
const body = readBody(reader);
const headMaterial = readHeadMaterial(reader);
const faceMaterial = readFaceMaterial(reader, headMaterial.materialType);

let bodyType: BodyType;
if (bodyTypeGuid === "25f439d5-146b-4a61-a999-a486dfb68a49")
Expand All @@ -39,5 +44,7 @@ export function readCharacter(bytes: Uint8Array): Character {
bodyType,
dna: toHexString(dnaBytes),
body,
headMaterial,
faceMaterial,
};
}
1 change: 1 addition & 0 deletions src/character/Color.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type Color = `#${string}`;
57 changes: 57 additions & 0 deletions src/character/FaceColors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { BufferReader } from "../BufferReader";
import { Color } from "./Color";

export type FaceColors = {
HeadColor: Color;
EyeMakeupColor1: Color;
EyeMakeupColor2: Color;
EyeMakeupColor3: Color;
CheekMakeupColor1: Color;
CheekMakeupColor2: Color;
CheekMakeupColor3: Color;
LipMakeupColor1: Color;
LipMakeupColor2: Color;
LipMakeupColor3: Color;
Data10: number;
Data11: number;
Data12: number;
Data13: number;
Data14: number;
Data15: number;
Data16: number;
Data17: number;
Data18: number;
Data19: number;
Data20: number;
Data21: number;
};

export function readFaceColors(reader: BufferReader): FaceColors {
reader.expectUint32(0x16);
reader.expectUint32(0);

return {
HeadColor: reader.readKeyedColor(0xbd530797),
EyeMakeupColor1: reader.readKeyedColor(0xb29b1d90),
EyeMakeupColor2: reader.readKeyedColor(0xe3230e2f),
EyeMakeupColor3: reader.readKeyedColor(0x2ec0e736),
CheekMakeupColor1: reader.readKeyedColor(0x1a081a93),
CheekMakeupColor2: reader.readKeyedColor(0x4bb0092c),
CheekMakeupColor3: reader.readKeyedColor(0x8653e035),
LipMakeupColor1: reader.readKeyedColor(0x7d86e792),
LipMakeupColor2: reader.readKeyedColor(0x2c3ef42d),
LipMakeupColor3: reader.readKeyedColor(0xe1dd1d34),
Data10: reader.readKeyedUint32(0x64a583ec),
Data11: reader.readKeyedUint32(0x77f57018),
Data12: reader.readKeyedUint32(0xe9f3e598),
Data13: reader.readKeyedUint32(0xfaa3166c),
Data14: reader.readKeyedUint32(0x3cb379f2),
Data15: reader.readKeyedUint32(0x2fe38a06),
Data16: reader.readKeyedUint32(0x32b762f1),
Data17: reader.readKeyedUint32(0x21e79105),
Data18: reader.readKeyedUint32(0xf7e50257),
Data19: reader.readKeyedUint32(0xe4b5f1a3),
Data20: reader.readKeyedUint32(0x7b8b1fd6),
Data21: reader.readKeyedUint32(0x68dbec22),
};
}
60 changes: 60 additions & 0 deletions src/character/FaceInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { BufferReader } from "../BufferReader";

export type FaceInfo = {
freckleAmount: number;
freckleOpacity: number;
sunSpotsAmount: number;
sunSpotOpacity: number;
eyeMetallic1: number;
eyeMetallic2: number;
eyeMetallic3: number;
eyeSmoothness1: number;
eyeSmoothness2: number;
eyeSmoothness3: number;
eyeOpacity: number;
cheekMetallic1: number;
cheekMetallic2: number;
cheekMetallic3: number;
cheekSmoothness1: number;
cheekSmoothness2: number;
cheekSmoothness3: number;
cheekOpacity: number;
lipMetallic1: number;
lipMetallic2: number;
lipMetallic3: number;
lipSmoothness1: number;
lipSmoothness2: number;
lipSmoothness3: number;
lipOpacity: number;
};
export function readFaceInfo(reader: BufferReader): FaceInfo {
reader.expectUint32(0x19);
reader.expectUint32(0);
return {
freckleAmount: reader.readKeyedFloat32(0xe87727e2),
freckleOpacity: reader.readKeyedFloat32(0x9361cb58),
sunSpotsAmount: reader.readKeyedFloat32(0x554ad20f),
sunSpotOpacity: reader.readKeyedFloat32(0xcfc41264),
eyeMetallic1: reader.readKeyedFloat32(0xb95883b0),
eyeMetallic2: reader.readKeyedFloat32(0x9cf750c3),
eyeMetallic3: reader.readKeyedFloat32(0xa90644df),
eyeSmoothness1: reader.readKeyedFloat32(0xc871a987),
eyeSmoothness2: reader.readKeyedFloat32(0xedde7af4),
eyeSmoothness3: reader.readKeyedFloat32(0xd82f6ee8),
eyeOpacity: reader.readKeyedFloat32(0xcae526ba),
cheekMetallic1: reader.readKeyedFloat32(0x0526ed02),
cheekMetallic2: reader.readKeyedFloat32(0x20893e71),
cheekMetallic3: reader.readKeyedFloat32(0x15782a6d),
cheekSmoothness1: reader.readKeyedFloat32(0x9be3d5d7),
cheekSmoothness2: reader.readKeyedFloat32(0xbe4c06a4),
cheekSmoothness3: reader.readKeyedFloat32(0x8bbd12b8),
cheekOpacity: reader.readKeyedFloat32(0x11a1a1d3),
lipMetallic1: reader.readKeyedFloat32(0x92571ac3),
lipMetallic2: reader.readKeyedFloat32(0xb7f8c9b0),
lipMetallic3: reader.readKeyedFloat32(0x8209ddac),
lipSmoothness1: reader.readKeyedFloat32(0xaa9201e7),
lipSmoothness2: reader.readKeyedFloat32(0x8f3dd294),
lipSmoothness3: reader.readKeyedFloat32(0xbaccc688),
lipOpacity: reader.readKeyedFloat32(0x589ddcf4),
};
}
35 changes: 35 additions & 0 deletions src/character/FaceMaterial.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { BufferReader } from "../BufferReader";
import { FaceColors, readFaceColors } from "./FaceColors";
import { FaceInfo, readFaceInfo } from "./FaceInfo";
import { HeadMaterialType } from "./HeadMaterial";
import { MakeupMaterial, readMakeupMaterial } from "./MakeupMaterial";

export type FaceMaterial = {
makeup: MakeupMaterial[];
faceColors: FaceColors;
faceInfo: FaceInfo;
};

export function readFaceMaterial(
reader: BufferReader,
headMaterialType: HeadMaterialType
): FaceMaterial {
//weird special case.
reader.expectUint32(
headMaterialType === HeadMaterialType.HeadMaterialF11
? 0xa5378a05
: 0x72129e8e
);

const childCount = reader.readUint32();
const makeup: MakeupMaterial[] = [];
for (let i = 0; i < childCount; i++) {
makeup.push(readMakeupMaterial(reader));
}

const faceInfo = readFaceInfo(reader);
const faceColors = readFaceColors(reader);
reader.expectUint32(5);

return { makeup, faceColors, faceInfo };
}
66 changes: 33 additions & 33 deletions src/character/FacialHair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type FacialHair = {
export function readFacialHair(reader: BufferReader): FacialHair {
reader.expectUint32(0x98efbb1c);
const guid = reader.readGuid();
const facialHairType = facialHairTypeMap.get(guid) ?? FacialHairType.None;
const facialHairType = facialHairTypeMap[guid] ?? FacialHairType.None;
const childCount = reader.readUint32();

switch (childCount) {
Expand Down Expand Up @@ -71,35 +71,35 @@ enum FacialHairType {
Beard30,
}

const facialHairTypeMap = new Map<string, FacialHairType>([
["3df7bdc3-ea80-47db-bbb7-8a6f28701c3e", FacialHairType.Beard01],
["e6c2c999-3731-4163-9f1a-e37df9b9a267", FacialHairType.Beard02],
["c9e19547-ba61-473f-b9b6-e5b8a14cb57e", FacialHairType.Beard03],
["a55229ce-89bb-405c-a225-e507e7de07ef", FacialHairType.Beard04],
["3545b83d-46c3-45d1-965a-3cfc15136ea3", FacialHairType.Beard05],
["ffb50f1a-cf01-4275-8216-71df949a2a9c", FacialHairType.Beard06],
["adc4a371-415f-4cbb-8873-569d4aec2b23", FacialHairType.Beard07],
["6c77f900-4da0-4378-891a-387d4c2572d2", FacialHairType.Beard08],
["15cc8f8d-2172-47d9-a94d-a7d504b9024d", FacialHairType.Beard09],
["184e3d83-9a08-4a6a-afd0-311836cc760e", FacialHairType.Beard10],
["59bb4f34-dd05-4f40-93f9-0161642598e0", FacialHairType.Beard11],
["b075b2cf-16a4-4152-954b-02f9fdaf3ea5", FacialHairType.Beard12],
["ee80bd3d-3b43-4ca3-b2de-e519efd4c9d7", FacialHairType.Beard13],
["f3248be1-955f-429b-ab7b-9634a531e253", FacialHairType.Beard14],
["e7eeecde-9633-481e-8b4c-f0e45a1a7e03", FacialHairType.Beard15],
["34d313db-db6f-45b0-82d9-25ae51fa7df0", FacialHairType.Beard16],
["2d459cc1-f95d-4baa-a118-cbc05bca9d97", FacialHairType.Beard17],
["2dec0896-245b-4ab1-b13d-44b0046c6774", FacialHairType.Beard18],
["547dcea1-2559-4f54-af6a-e7f025552e96", FacialHairType.Beard19],
["7b5556a2-c331-4192-b1f9-0941d778b7e3", FacialHairType.Beard20],
["8590e357-d3a7-4d39-88ff-d199ecb236c7", FacialHairType.Beard21],
["c5b7f31a-f0b5-4229-91c3-be2f859966fa", FacialHairType.Beard22],
["8ce83349-a151-4d98-ab07-d710bb8bc5fc", FacialHairType.Beard23],
["92b25f3c-740d-47ec-aae6-f2f20b2ecf68", FacialHairType.Beard24],
["88c8eee7-42cf-4baf-8286-c736a2c1bd93", FacialHairType.Beard25],
["4e1f14bc-3db8-483b-ab97-c948d8e984b8", FacialHairType.Beard26],
["bda4e041-2f54-4ec6-9bd8-6807e80ddfd6", FacialHairType.Beard27],
["e27a835b-965f-487b-bef7-ac8be077cc62", FacialHairType.Beard28],
["09b25ba2-4e5d-4135-8d27-5649227b7a74", FacialHairType.Beard29],
["31de0f7c-a059-4a5c-8917-d699a79af303", FacialHairType.Beard30],
]);
const facialHairTypeMap: Record<string, FacialHairType> = {
"3df7bdc3-ea80-47db-bbb7-8a6f28701c3e": FacialHairType.Beard01,
"e6c2c999-3731-4163-9f1a-e37df9b9a267": FacialHairType.Beard02,
"c9e19547-ba61-473f-b9b6-e5b8a14cb57e": FacialHairType.Beard03,
"a55229ce-89bb-405c-a225-e507e7de07ef": FacialHairType.Beard04,
"3545b83d-46c3-45d1-965a-3cfc15136ea3": FacialHairType.Beard05,
"ffb50f1a-cf01-4275-8216-71df949a2a9c": FacialHairType.Beard06,
"adc4a371-415f-4cbb-8873-569d4aec2b23": FacialHairType.Beard07,
"6c77f900-4da0-4378-891a-387d4c2572d2": FacialHairType.Beard08,
"15cc8f8d-2172-47d9-a94d-a7d504b9024d": FacialHairType.Beard09,
"184e3d83-9a08-4a6a-afd0-311836cc760e": FacialHairType.Beard10,
"59bb4f34-dd05-4f40-93f9-0161642598e0": FacialHairType.Beard11,
"b075b2cf-16a4-4152-954b-02f9fdaf3ea5": FacialHairType.Beard12,
"ee80bd3d-3b43-4ca3-b2de-e519efd4c9d7": FacialHairType.Beard13,
"f3248be1-955f-429b-ab7b-9634a531e253": FacialHairType.Beard14,
"e7eeecde-9633-481e-8b4c-f0e45a1a7e03": FacialHairType.Beard15,
"34d313db-db6f-45b0-82d9-25ae51fa7df0": FacialHairType.Beard16,
"2d459cc1-f95d-4baa-a118-cbc05bca9d97": FacialHairType.Beard17,
"2dec0896-245b-4ab1-b13d-44b0046c6774": FacialHairType.Beard18,
"547dcea1-2559-4f54-af6a-e7f025552e96": FacialHairType.Beard19,
"7b5556a2-c331-4192-b1f9-0941d778b7e3": FacialHairType.Beard20,
"8590e357-d3a7-4d39-88ff-d199ecb236c7": FacialHairType.Beard21,
"c5b7f31a-f0b5-4229-91c3-be2f859966fa": FacialHairType.Beard22,
"8ce83349-a151-4d98-ab07-d710bb8bc5fc": FacialHairType.Beard23,
"92b25f3c-740d-47ec-aae6-f2f20b2ecf68": FacialHairType.Beard24,
"88c8eee7-42cf-4baf-8286-c736a2c1bd93": FacialHairType.Beard25,
"4e1f14bc-3db8-483b-ab97-c948d8e984b8": FacialHairType.Beard26,
"bda4e041-2f54-4ec6-9bd8-6807e80ddfd6": FacialHairType.Beard27,
"e27a835b-965f-487b-bef7-ac8be077cc62": FacialHairType.Beard28,
"09b25ba2-4e5d-4135-8d27-5649227b7a74": FacialHairType.Beard29,
"31de0f7c-a059-4a5c-8917-d699a79af303": FacialHairType.Beard30,
};
54 changes: 27 additions & 27 deletions src/character/Hair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,37 +34,37 @@ export enum HairType {
Hair24,
}

export const hairTypes = new Map<string, HairType>([
["71dd6cea-e225-4aaf-b9d7-562d2083ae3b", HairType.Bald01],
["968d0d95-2224-47dc-a05a-da423a4a1c81", HairType.Hair02],
["a8beac2a-3a3a-455b-9d2b-cfcadf290419", HairType.Hair03],
["e35c9137-dc5b-457f-b86a-f4f47d4ea96a", HairType.Hair04],
["78ba4b65-a6a6-4c08-b78a-4d4b0adc020d", HairType.Hair05],
["041df6b0-2498-4799-a7a5-d2d40856c409", HairType.Hair06],
["57eedc17-d982-485f-98bc-161df3822022", HairType.Hair07],
["7222de26-f519-4d98-99f7-0aa602ae4c05", HairType.Hair08],
["ebd09681-1909-4047-8989-774974da71b7", HairType.Hair09],
["9b688d20-e494-4c80-b0b7-e2989ddd4cbc", HairType.Hair10],
["ad65b2a4-6ee8-4f9f-ac86-0b1725e3e5a1", HairType.Hair11],
["8b40a194-fc32-4668-bd77-dc7e54708725", HairType.Hair12],
["f2343738-d0bc-4a99-bd11-98aa9cd5063d", HairType.Hair13],
["b0ef56d6-fafb-4b52-8713-2c00577605a5", HairType.Hair14],
["bc8dbe98-2990-46ee-ac08-268dddb15bd7", HairType.Hair15],
["f6a28414-2326-41e1-a9f0-ad76600b4f5b", HairType.Hair16],
["74a0634c-0ca6-4e8c-a0fc-21cfa6a0663b", HairType.Hair17],
["854f7b6c-7054-4f51-867c-f5fe8247b884", HairType.Hair18],
["73005464-e866-44f6-a192-c091bcb15fb3", HairType.Hair19],
["c0ff663f-006f-4668-9a7a-2c125c55e291", HairType.Hair20],
["ce9137d2-9c06-412a-ab90-5da4e988902b", HairType.Hair21],
["d7cb9d99-2e76-43ab-b21e-7c0f9f1df419", HairType.Hair22],
["63a60790-fc1c-47bb-b0df-d1452e8cde2b", HairType.Hair23],
["03762539-c42e-4314-9710-97430c72da98", HairType.Hair24],
]);
export const hairTypes: Record<string, HairType> = {
"71dd6cea-e225-4aaf-b9d7-562d2083ae3b": HairType.Bald01,
"968d0d95-2224-47dc-a05a-da423a4a1c81": HairType.Hair02,
"a8beac2a-3a3a-455b-9d2b-cfcadf290419": HairType.Hair03,
"e35c9137-dc5b-457f-b86a-f4f47d4ea96a": HairType.Hair04,
"78ba4b65-a6a6-4c08-b78a-4d4b0adc020d": HairType.Hair05,
"041df6b0-2498-4799-a7a5-d2d40856c409": HairType.Hair06,
"57eedc17-d982-485f-98bc-161df3822022": HairType.Hair07,
"7222de26-f519-4d98-99f7-0aa602ae4c05": HairType.Hair08,
"ebd09681-1909-4047-8989-774974da71b7": HairType.Hair09,
"9b688d20-e494-4c80-b0b7-e2989ddd4cbc": HairType.Hair10,
"ad65b2a4-6ee8-4f9f-ac86-0b1725e3e5a1": HairType.Hair11,
"8b40a194-fc32-4668-bd77-dc7e54708725": HairType.Hair12,
"f2343738-d0bc-4a99-bd11-98aa9cd5063d": HairType.Hair13,
"b0ef56d6-fafb-4b52-8713-2c00577605a5": HairType.Hair14,
"bc8dbe98-2990-46ee-ac08-268dddb15bd7": HairType.Hair15,
"f6a28414-2326-41e1-a9f0-ad76600b4f5b": HairType.Hair16,
"74a0634c-0ca6-4e8c-a0fc-21cfa6a0663b": HairType.Hair17,
"854f7b6c-7054-4f51-867c-f5fe8247b884": HairType.Hair18,
"73005464-e866-44f6-a192-c091bcb15fb3": HairType.Hair19,
"c0ff663f-006f-4668-9a7a-2c125c55e291": HairType.Hair20,
"ce9137d2-9c06-412a-ab90-5da4e988902b": HairType.Hair21,
"d7cb9d99-2e76-43ab-b21e-7c0f9f1df419": HairType.Hair22,
"63a60790-fc1c-47bb-b0df-d1452e8cde2b": HairType.Hair23,
"03762539-c42e-4314-9710-97430c72da98": HairType.Hair24,
};

export function readHair(reader: BufferReader): Hair {
reader.expectUint32(0x13601a95);
const guid = reader.readGuid();
const hairType = hairTypes.get(guid) ?? HairType.None;
const hairType = hairTypes[guid] ?? HairType.None;

const childCount = reader.readUint64();
switch (childCount) {
Expand Down
Loading

0 comments on commit a59a28e

Please sign in to comment.