@rhyster/wow-casc-dbc 2.7.5 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -2,6 +2,7 @@ import type ADBReader from './adb.ts';
2
2
  import type { MissingKeyBlock } from './blte.ts';
3
3
  import type { ArchiveIndex } from './parsers/archiveIndex.ts';
4
4
  import type { EncodingData } from './parsers/encodingFile.ts';
5
+ import type { InstallFile, InstallData } from './parsers/installFile.ts';
5
6
  import type { Version } from './parsers/productConfig.ts';
6
7
  import type { FileInfo, RootData } from './parsers/rootFile.ts';
7
8
  interface ClientPreloadData {
@@ -9,6 +10,7 @@ interface ClientPreloadData {
9
10
  archives: Map<string, ArchiveIndex>;
10
11
  encoding: EncodingData;
11
12
  rootFile: RootData;
13
+ install: InstallData;
12
14
  }
13
15
  interface FileFetchResultFull {
14
16
  type: 'full';
@@ -77,8 +79,9 @@ export default class CASCClient {
77
79
  loadBroadcastTACTKeys(adb: ADBReader): void;
78
80
  getFileDataIDByName(name: string): number | undefined;
79
81
  getContentKeysByFileDataID(fileDataID: number): FileInfo[] | undefined;
82
+ getContentKeysFromInstall(name: string): InstallFile[] | undefined;
80
83
  getFileByContentKey(cKey: string, allowMissingKey?: false): Promise<FileFetchResultFull>;
81
84
  getFileByContentKey(cKey: string, allowMissingKey: true): Promise<FileFetchResult>;
82
85
  }
83
- export type { Version, ClientPreloadData, ArchiveIndex, EncodingData, RootData, FileInfo, FileFetchResultFull, FileFetchResultPartial, FileFetchResult, MissingKeyBlock, };
86
+ export type { Version, ClientPreloadData, ArchiveIndex, EncodingData, InstallFile, InstallData, RootData, FileInfo, FileFetchResultFull, FileFetchResultPartial, FileFetchResult, MissingKeyBlock, };
84
87
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,SAAS,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEhE,UAAU,iBAAiB;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACpC,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,QAAQ,CAAC;CACtB;AAED,UAAU,mBAAmB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;CACrB;AAED,UAAU,sBAAsB;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,KAAK,eAAe,GAAG,mBAAmB,GAAG,sBAAsB,CAAC;AAEpE,aAAK,QAAQ;IACT,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACZ;AASD,MAAM,CAAC,OAAO,OAAO,UAAU;IAC3B,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B,SAAgB,OAAO,EAAE,MAAM,CAAC;IAEhC,SAAgB,OAAO,EAAE,OAAO,CAAC;IAEjC,SAAgB,eAAe,sBAA6B;IAE5D,SAAgB,IAAI,2CAAiC;IAE9C,OAAO,CAAC,EAAE,iBAAiB,CAAC;WAEtB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAO7F,OAAc,WAAW;;;;;;;;;;;;;;MAAe;IAGxC,OAAc,YAAY;;;;;;;;;;;;;;;MAAgB;IAG1C,OAAc,QAAQ,kBAAY;IAE3B,QAAQ,EAAE,QAAQ,CAAC;gBAEd,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,WAAgB;IAOvF,OAAO,CAAC,GAAG;IAUL,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+GrB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAWnC,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBnC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAqCnC,qBAAqB,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI;IAkC3C,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAUrD,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,EAAE,GAAG,SAAS;IAQhE,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,mBAAmB,CAAC;IACxF,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC;CAyD3F;AAED,YAAY,EACR,OAAO,EACP,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,eAAe,GAClB,CAAC"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -692,8 +692,8 @@ const parseCDNConfig = (text) => parseConfig(text);
692
692
  const parseBuildConfig = (text) => parseConfig(text);
693
693
 
694
694
  const ENC_MAGIC = 17742;
695
- const MAGIC_OFFSET = 0;
696
- const VERSION_OFFSET = 2;
695
+ const MAGIC_OFFSET$1 = 0;
696
+ const VERSION_OFFSET$1 = 2;
697
697
  const HASH_SIZE_CKEY_OFFSET = 3;
698
698
  const HASH_SIZE_EKEY_OFFSET = 4;
699
699
  const CKEY_PAGE_SIZE_OFFSET = 5;
@@ -708,9 +708,9 @@ const parseEncodingFile = (inputBuffer, eKey, cKey) => {
708
708
  const { buffer } = reader;
709
709
  const encodingHash = crypto__default.createHash("md5").update(buffer).digest("hex");
710
710
  assert__default(encodingHash === cKey, `Invalid encoding hash: expected ${cKey}, got ${encodingHash}`);
711
- const magic = buffer.readUInt16BE(MAGIC_OFFSET);
711
+ const magic = buffer.readUInt16BE(MAGIC_OFFSET$1);
712
712
  assert__default(magic === ENC_MAGIC, `Invalid encoding magic: ${magic.toString(16).padStart(4, "0")}`);
713
- const version = buffer.readUInt8(VERSION_OFFSET);
713
+ const version = buffer.readUInt8(VERSION_OFFSET$1);
714
714
  const hashSizeCKey = buffer.readUInt8(HASH_SIZE_CKEY_OFFSET);
715
715
  const hashSizeEKey = buffer.readUInt8(HASH_SIZE_EKEY_OFFSET);
716
716
  const cKeyPageSizeKB = buffer.readUInt16BE(CKEY_PAGE_SIZE_OFFSET);
@@ -808,6 +808,71 @@ const parseEncodingFile = (inputBuffer, eKey, cKey) => {
808
808
  };
809
809
  };
810
810
 
811
+ const INSTALL_MAGIC = 18766;
812
+ const MAGIC_OFFSET = 0;
813
+ const VERSION_OFFSET = 2;
814
+ const HASH_SIZE_OFFSET = 3;
815
+ const NUM_TAGS_OFFSET = 4;
816
+ const NUM_ENTRIES_OFFSET = 6;
817
+ const TAGS_OFFSET = 10;
818
+ const parseInstallFile = (inputBuffer, eKey, cKey) => {
819
+ const reader = new BLTEReader(inputBuffer, eKey);
820
+ reader.processBytes();
821
+ const { buffer } = reader;
822
+ const installHash = crypto__default.createHash("md5").update(buffer).digest("hex");
823
+ assert__default(installHash === cKey, `Invalid root hash: expected ${cKey}, got ${installHash}`);
824
+ const magic = buffer.readUInt16BE(MAGIC_OFFSET);
825
+ assert__default(magic === INSTALL_MAGIC, `Invalid install magic: ${magic.toString(16).padStart(4, "0")}`);
826
+ const version = buffer.readUInt8(VERSION_OFFSET);
827
+ const hashSize = buffer.readUInt8(HASH_SIZE_OFFSET);
828
+ const numTags = buffer.readUInt16BE(NUM_TAGS_OFFSET);
829
+ const numEntries = buffer.readUInt32BE(NUM_ENTRIES_OFFSET);
830
+ assert__default(version === 1, `Invalid install version: ${version.toString()}`);
831
+ let pointer = TAGS_OFFSET;
832
+ const tags = [];
833
+ for (let i = 0; i < numTags; i += 1) {
834
+ const startOffset = pointer;
835
+ while (buffer[pointer] !== 0) {
836
+ pointer += 1;
837
+ }
838
+ const name = buffer.toString("utf-8", startOffset, pointer);
839
+ pointer += 1;
840
+ const type = buffer.readUInt16BE(pointer);
841
+ pointer += 2;
842
+ const files2 = [];
843
+ const finalOffset = pointer + Math.ceil(numEntries / 8);
844
+ while (pointer < finalOffset) {
845
+ const byte = buffer.readUInt8(pointer);
846
+ pointer += 1;
847
+ for (let j = 7; j >= 0; j -= 1) {
848
+ files2.push((byte & 1 << j) > 0);
849
+ }
850
+ }
851
+ tags.push({ name, type, files: files2 });
852
+ }
853
+ const files = [];
854
+ for (let i = 0; i < numEntries; i += 1) {
855
+ const startOffset = pointer;
856
+ while (buffer[pointer] !== 0) {
857
+ pointer += 1;
858
+ }
859
+ const name = buffer.toString("utf-8", startOffset, pointer);
860
+ pointer += 1;
861
+ const hash = buffer.toString("hex", pointer, pointer + hashSize);
862
+ pointer += hashSize;
863
+ const size = buffer.readUInt32BE(pointer);
864
+ pointer += 4;
865
+ const fileTags = tags.filter((tag) => tag.files[i]);
866
+ files.push({
867
+ name,
868
+ hash,
869
+ size,
870
+ tags: fileTags
871
+ });
872
+ }
873
+ return { tags, files };
874
+ };
875
+
811
876
  const parseProductConfig = (text) => {
812
877
  const lines = text.split(/\r?\n/);
813
878
  const headers = lines[0].split("|").map((header) => header.split("!")[0].replace(" ", ""));
@@ -1606,11 +1671,19 @@ class CASCClient {
1606
1671
  this.log(2 /* info */, "Parsing encoding table...");
1607
1672
  const encoding = parseEncodingFile(encodingBuffer, encodingEKey, encodingCKey);
1608
1673
  this.log(2 /* info */, `Parsed encoding table (${encoding.cKey2EKey.size.toString()} entries)`);
1674
+ const getBuildConfigKeys = (configText) => {
1675
+ if (configText.includes(" ")) {
1676
+ const [cKey2, eKey2] = configText.split(" ");
1677
+ return [cKey2, eKey2];
1678
+ }
1679
+ const cKey = configText;
1680
+ const eKeys = encoding.cKey2EKey.get(cKey);
1681
+ assert__default(eKeys !== void 0, `Failing to find encoding key for ${cKey}`);
1682
+ const eKey = typeof eKeys === "string" ? eKeys : eKeys[0];
1683
+ return [cKey, eKey];
1684
+ };
1609
1685
  this.log(2 /* info */, "Loading root table...");
1610
- const rootCKey = buildConfig.root;
1611
- const rootEKeys = encoding.cKey2EKey.get(rootCKey);
1612
- assert__default(rootEKeys !== void 0, "Failing to find EKey for root table.");
1613
- const rootEKey = typeof rootEKeys === "string" ? rootEKeys : rootEKeys[0];
1686
+ const [rootCKey, rootEKey] = getBuildConfigKeys(buildConfig.root);
1614
1687
  const rootBuffer = await getDataFile(prefixes, rootEKey, "build", this.version.BuildConfig, {
1615
1688
  name: "root",
1616
1689
  showProgress: this.logLevel >= 2 /* info */,
@@ -1620,11 +1693,23 @@ class CASCClient {
1620
1693
  this.log(2 /* info */, "Parsing root file...");
1621
1694
  const rootFile = parseRootFile(rootBuffer, rootEKey, rootCKey);
1622
1695
  this.log(2 /* info */, `Parsed root file (${rootFile.fileDataID2CKey.size.toString()} entries, ${rootFile.nameHash2FileDataID.size.toString()} hashes)`);
1696
+ this.log(2 /* info */, "Loading install manifest...");
1697
+ const [installCKey, installEKey] = getBuildConfigKeys(buildConfig.install);
1698
+ const installBuffer = await getDataFile(prefixes, installEKey, "build", this.version.BuildConfig, {
1699
+ name: "install",
1700
+ showProgress: this.logLevel >= 2 /* info */,
1701
+ showAttemptFail: this.logLevel >= 1 /* warn */
1702
+ });
1703
+ this.log(2 /* info */, `Loaded install manifest (${formatFileSize(installBuffer.byteLength)})`);
1704
+ this.log(2 /* info */, "Parsing install manifest...");
1705
+ const install = parseInstallFile(installBuffer, installEKey, installCKey);
1706
+ this.log(2 /* info */, `Parsed install manifest (${install.tags.length.toString()} tags, ${install.files.length.toString()} files)`);
1623
1707
  this.preload = {
1624
1708
  prefixes,
1625
1709
  archives,
1626
1710
  encoding,
1627
- rootFile
1711
+ rootFile,
1712
+ install
1628
1713
  };
1629
1714
  }
1630
1715
  async loadRemoteListFile() {
@@ -1712,6 +1797,11 @@ class CASCClient {
1712
1797
  const { rootFile } = this.preload;
1713
1798
  return rootFile.fileDataID2CKey.get(fileDataID);
1714
1799
  }
1800
+ getContentKeysFromInstall(name) {
1801
+ assert__default(this.preload, "Client not initialized");
1802
+ const { install } = this.preload;
1803
+ return install.files.filter((file) => file.name === name);
1804
+ }
1715
1805
  async getFileByContentKey(cKey, allowMissingKey = false) {
1716
1806
  assert__default(this.preload, "Client not initialized");
1717
1807
  const { prefixes, encoding, archives } = this.preload;