@rhyster/wow-casc-dbc 2.4.0 → 2.5.1

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/index.cjs CHANGED
@@ -485,19 +485,22 @@ class BLTEReader {
485
485
  offset += ivLength;
486
486
  const encryptType = buffer.readUInt8(offset);
487
487
  offset += 1;
488
- assert__default(encryptType === ENC_TYPE_SALSA20, `[BLTE]: Invalid encrypt type: ${encryptType.toString(16).padStart(2, "0")}`);
488
+ assert__default(encryptType === ENC_TYPE_SALSA20, `[BLTE]: Invalid encrypt type: ${encryptType.toString(16).padStart(2, "0")} at block ${index.toString()}`);
489
489
  const keyName = [...keyNameBE.matchAll(/.{2}/g)].map((v) => v[0]).reverse().join("").toLowerCase();
490
490
  const key = this.keys.get(keyName);
491
491
  if (!key) {
492
492
  if (allowMissingKey) {
493
493
  return keyName;
494
494
  }
495
- throw new Error(`[BLTE]: Missing key: ${keyName}`);
495
+ throw new Error(`[BLTE]: Missing key: ${keyName} at block ${index.toString()}`);
496
496
  }
497
497
  const iv = new Uint8Array(8);
498
498
  for (let i = 0; i < 8; i += 1) {
499
- const byte = ivBuffer.byteLength > i ? ivBuffer.readUInt8(i) : void 0;
500
- iv[i] = byte ? byte ^ index >> 8 * i & 255 : 0;
499
+ if (i < ivLength) {
500
+ iv[i] = ivBuffer.readUInt8(i) ^ index >>> 8 * i & 255;
501
+ } else {
502
+ iv[i] = 0;
503
+ }
501
504
  }
502
505
  const handler = new Salsa20(key, iv);
503
506
  const decrypted = handler.process(buffer.subarray(offset));
@@ -507,13 +510,13 @@ class BLTEReader {
507
510
  return this.processBlock(Buffer.from(decrypted.buffer), index, false);
508
511
  }
509
512
  case 70:
510
- throw new Error("[BLTE]: Frame (Recursive) block not supported");
513
+ throw new Error(`[BLTE]: Frame (Recursive) block not supported at block ${index.toString()}`);
511
514
  case 78:
512
515
  return buffer.subarray(1);
513
516
  case 90:
514
517
  return zlib__default.inflateSync(buffer.subarray(1));
515
518
  default:
516
- throw new Error(`[BLTE]: Invalid block flag: ${flag.toString(16).padStart(2, "0")}`);
519
+ throw new Error(`[BLTE]: Invalid block flag: ${flag.toString(16).padStart(2, "0")} at block ${index.toString()}`);
517
520
  }
518
521
  }
519
522
  processBytes(allowMissingKey = false, size = Infinity) {
@@ -912,14 +915,10 @@ const readBitpackedValue = (buffer, fieldOffsetBits, fieldSizeBits, signed = fal
912
915
  signed ? BigInt.asIntN(fieldSizeBits, BigInt(rawValue >>> bitOffset)) : BigInt.asUintN(fieldSizeBits, BigInt(rawValue >>> bitOffset))
913
916
  );
914
917
  }
915
- let remain = sizeBytes;
916
918
  let value = 0n;
917
- while (remain > 0) {
918
- const byteLength = Math.min(remain, 6);
919
- const offset = offsetBytes + remain - byteLength;
920
- const rawValue = buffer.readUIntLE(offset, byteLength);
921
- value = value << BigInt(byteLength * 8) | BigInt(rawValue);
922
- remain -= byteLength;
919
+ for (let i = sizeBytes - 1; i >= 0; i -= 1) {
920
+ const byte = buffer.readUInt8(offsetBytes + i);
921
+ value = value << 8n | BigInt(byte);
923
922
  }
924
923
  return signed ? BigInt.asIntN(fieldSizeBits, value >> BigInt(bitOffset)) : BigInt.asUintN(fieldSizeBits, value >> BigInt(bitOffset));
925
924
  };
@@ -1678,9 +1677,12 @@ class CASCClient {
1678
1677
  const reader = new BLTEReader(blte, eKey, this.keys);
1679
1678
  if (!allowMissingKey) {
1680
1679
  reader.processBytes(allowMissingKey);
1680
+ const hash = crypto__default.createHash("md5").update(reader.buffer).digest("hex");
1681
+ assert__default(hash === cKey, `Invalid hash: expected ${cKey}, got ${hash}`);
1681
1682
  return {
1682
1683
  type: "full",
1683
- buffer: reader.buffer
1684
+ buffer: reader.buffer,
1685
+ blocks: void 0
1684
1686
  };
1685
1687
  }
1686
1688
  const blocks = reader.processBytes(allowMissingKey);
@@ -1689,7 +1691,8 @@ class CASCClient {
1689
1691
  assert__default(hash === cKey, `Invalid hash: expected ${cKey}, got ${hash}`);
1690
1692
  return {
1691
1693
  type: "full",
1692
- buffer: reader.buffer
1694
+ buffer: reader.buffer,
1695
+ blocks: void 0
1693
1696
  };
1694
1697
  }
1695
1698
  return {
@@ -1740,6 +1743,15 @@ const castBigInt64 = (value, srcSigned, dstSigned) => {
1740
1743
  }
1741
1744
  return dstSigned ? castBuffer.readBigInt64LE(0) : castBuffer.readBigUInt64LE(0);
1742
1745
  };
1746
+ const getCastBuffer = (value, srcSize, dstSize) => {
1747
+ const castBuffer = Buffer.alloc(dstSize);
1748
+ let remain = value;
1749
+ for (let i = 0; i < srcSize && remain > 0n; i += 1, remain >>= 8n) {
1750
+ const byte = Number(BigInt.asUintN(8, remain));
1751
+ castBuffer.writeUInt8(byte, i);
1752
+ }
1753
+ return castBuffer;
1754
+ };
1743
1755
  class DBDParser {
1744
1756
  constructor(wdc) {
1745
1757
  __publicField$1(this, "wdc");
@@ -1867,9 +1879,12 @@ class DBDParser {
1867
1879
  }
1868
1880
  } else if (column.type === "float") {
1869
1881
  if (column.arraySize) {
1870
- assert__default(typeof cell.data === "bigint", `Invalid data type for float array column ${column.name}`);
1882
+ const castBuffer = getCastBuffer(
1883
+ typeof cell.data === "number" ? BigInt(cell.data) : cell.data,
1884
+ srcSize,
1885
+ 4 * column.arraySize
1886
+ );
1871
1887
  const values = [];
1872
- const castBuffer = Buffer.from(cell.data.toString(16).padStart(8 * column.arraySize, "0"), "hex");
1873
1888
  for (let i = 0; i < column.arraySize; i += 1) {
1874
1889
  const value = castBuffer.readFloatLE(i * 4);
1875
1890
  values.push(Math.round(value * 100) / 100);
@@ -1879,25 +1894,49 @@ class DBDParser {
1879
1894
  assert__default(typeof cell.data === "number", `Invalid data type for float column ${column.name}`);
1880
1895
  data[column.name] = castFloat(cell.data, srcSize, srcSigned);
1881
1896
  }
1882
- } else if (typeof cell.data === "number") {
1883
- data[column.name] = castIntegerBySize(
1884
- cell.data,
1885
- srcSize,
1886
- srcSigned,
1887
- dstSize ?? srcSize,
1888
- column.isSigned
1889
- );
1890
- } else {
1891
- assert__default(!column.size || column.size === 64, `Unexpected size ${column.size?.toString() ?? ""} for column ${column.name}`);
1892
- if (srcSigned !== column.isSigned) {
1893
- data[column.name] = castBigInt64(
1897
+ } else if (column.type === "int") {
1898
+ if (column.arraySize) {
1899
+ assert__default(dstSize, `Missing size for int array column ${column.name}`);
1900
+ const castBuffer = getCastBuffer(
1901
+ typeof cell.data === "number" ? BigInt(cell.data) : cell.data,
1902
+ srcSize,
1903
+ 4 * column.arraySize
1904
+ );
1905
+ const values = [];
1906
+ if (column.isSigned) {
1907
+ for (let i = 0; i < column.arraySize; i += 1) {
1908
+ const value = castBuffer.readIntLE(i * dstSize, dstSize);
1909
+ values.push(value);
1910
+ }
1911
+ } else {
1912
+ for (let i = 0; i < column.arraySize; i += 1) {
1913
+ const value = castBuffer.readUIntLE(i * dstSize, dstSize);
1914
+ values.push(value);
1915
+ }
1916
+ }
1917
+ data[column.name] = values;
1918
+ } else if (typeof cell.data === "number") {
1919
+ data[column.name] = castIntegerBySize(
1894
1920
  cell.data,
1921
+ srcSize,
1895
1922
  srcSigned,
1923
+ dstSize ?? srcSize,
1896
1924
  column.isSigned
1897
1925
  );
1898
1926
  } else {
1899
- data[column.name] = cell.data;
1927
+ assert__default(!column.size || column.size === 64, `Unexpected size ${column.size?.toString() ?? ""} for column ${column.name}`);
1928
+ if (srcSigned !== column.isSigned) {
1929
+ data[column.name] = castBigInt64(
1930
+ cell.data,
1931
+ srcSigned,
1932
+ column.isSigned
1933
+ );
1934
+ } else {
1935
+ data[column.name] = cell.data;
1936
+ }
1900
1937
  }
1938
+ } else {
1939
+ throw new Error(`Unsupported column type ${column.type} for column ${column.name}`);
1901
1940
  }
1902
1941
  fieldIndex += 1;
1903
1942
  } else if (column.isRelation) {
package/dist/index.d.cts CHANGED
@@ -68,6 +68,7 @@ interface ClientPreloadData {
68
68
  interface FileFetchResultFull {
69
69
  type: 'full';
70
70
  buffer: Buffer;
71
+ blocks: undefined;
71
72
  }
72
73
  interface FileFetchResultPartial {
73
74
  type: 'partial';
package/dist/index.d.mts CHANGED
@@ -68,6 +68,7 @@ interface ClientPreloadData {
68
68
  interface FileFetchResultFull {
69
69
  type: 'full';
70
70
  buffer: Buffer;
71
+ blocks: undefined;
71
72
  }
72
73
  interface FileFetchResultPartial {
73
74
  type: 'partial';
package/dist/index.d.ts CHANGED
@@ -68,6 +68,7 @@ interface ClientPreloadData {
68
68
  interface FileFetchResultFull {
69
69
  type: 'full';
70
70
  buffer: Buffer;
71
+ blocks: undefined;
71
72
  }
72
73
  interface FileFetchResultPartial {
73
74
  type: 'partial';
package/dist/index.mjs CHANGED
@@ -473,19 +473,22 @@ class BLTEReader {
473
473
  offset += ivLength;
474
474
  const encryptType = buffer.readUInt8(offset);
475
475
  offset += 1;
476
- assert(encryptType === ENC_TYPE_SALSA20, `[BLTE]: Invalid encrypt type: ${encryptType.toString(16).padStart(2, "0")}`);
476
+ assert(encryptType === ENC_TYPE_SALSA20, `[BLTE]: Invalid encrypt type: ${encryptType.toString(16).padStart(2, "0")} at block ${index.toString()}`);
477
477
  const keyName = [...keyNameBE.matchAll(/.{2}/g)].map((v) => v[0]).reverse().join("").toLowerCase();
478
478
  const key = this.keys.get(keyName);
479
479
  if (!key) {
480
480
  if (allowMissingKey) {
481
481
  return keyName;
482
482
  }
483
- throw new Error(`[BLTE]: Missing key: ${keyName}`);
483
+ throw new Error(`[BLTE]: Missing key: ${keyName} at block ${index.toString()}`);
484
484
  }
485
485
  const iv = new Uint8Array(8);
486
486
  for (let i = 0; i < 8; i += 1) {
487
- const byte = ivBuffer.byteLength > i ? ivBuffer.readUInt8(i) : void 0;
488
- iv[i] = byte ? byte ^ index >> 8 * i & 255 : 0;
487
+ if (i < ivLength) {
488
+ iv[i] = ivBuffer.readUInt8(i) ^ index >>> 8 * i & 255;
489
+ } else {
490
+ iv[i] = 0;
491
+ }
489
492
  }
490
493
  const handler = new Salsa20(key, iv);
491
494
  const decrypted = handler.process(buffer.subarray(offset));
@@ -495,13 +498,13 @@ class BLTEReader {
495
498
  return this.processBlock(Buffer.from(decrypted.buffer), index, false);
496
499
  }
497
500
  case 70:
498
- throw new Error("[BLTE]: Frame (Recursive) block not supported");
501
+ throw new Error(`[BLTE]: Frame (Recursive) block not supported at block ${index.toString()}`);
499
502
  case 78:
500
503
  return buffer.subarray(1);
501
504
  case 90:
502
505
  return zlib.inflateSync(buffer.subarray(1));
503
506
  default:
504
- throw new Error(`[BLTE]: Invalid block flag: ${flag.toString(16).padStart(2, "0")}`);
507
+ throw new Error(`[BLTE]: Invalid block flag: ${flag.toString(16).padStart(2, "0")} at block ${index.toString()}`);
505
508
  }
506
509
  }
507
510
  processBytes(allowMissingKey = false, size = Infinity) {
@@ -900,14 +903,10 @@ const readBitpackedValue = (buffer, fieldOffsetBits, fieldSizeBits, signed = fal
900
903
  signed ? BigInt.asIntN(fieldSizeBits, BigInt(rawValue >>> bitOffset)) : BigInt.asUintN(fieldSizeBits, BigInt(rawValue >>> bitOffset))
901
904
  );
902
905
  }
903
- let remain = sizeBytes;
904
906
  let value = 0n;
905
- while (remain > 0) {
906
- const byteLength = Math.min(remain, 6);
907
- const offset = offsetBytes + remain - byteLength;
908
- const rawValue = buffer.readUIntLE(offset, byteLength);
909
- value = value << BigInt(byteLength * 8) | BigInt(rawValue);
910
- remain -= byteLength;
907
+ for (let i = sizeBytes - 1; i >= 0; i -= 1) {
908
+ const byte = buffer.readUInt8(offsetBytes + i);
909
+ value = value << 8n | BigInt(byte);
911
910
  }
912
911
  return signed ? BigInt.asIntN(fieldSizeBits, value >> BigInt(bitOffset)) : BigInt.asUintN(fieldSizeBits, value >> BigInt(bitOffset));
913
912
  };
@@ -1666,9 +1665,12 @@ class CASCClient {
1666
1665
  const reader = new BLTEReader(blte, eKey, this.keys);
1667
1666
  if (!allowMissingKey) {
1668
1667
  reader.processBytes(allowMissingKey);
1668
+ const hash = crypto.createHash("md5").update(reader.buffer).digest("hex");
1669
+ assert(hash === cKey, `Invalid hash: expected ${cKey}, got ${hash}`);
1669
1670
  return {
1670
1671
  type: "full",
1671
- buffer: reader.buffer
1672
+ buffer: reader.buffer,
1673
+ blocks: void 0
1672
1674
  };
1673
1675
  }
1674
1676
  const blocks = reader.processBytes(allowMissingKey);
@@ -1677,7 +1679,8 @@ class CASCClient {
1677
1679
  assert(hash === cKey, `Invalid hash: expected ${cKey}, got ${hash}`);
1678
1680
  return {
1679
1681
  type: "full",
1680
- buffer: reader.buffer
1682
+ buffer: reader.buffer,
1683
+ blocks: void 0
1681
1684
  };
1682
1685
  }
1683
1686
  return {
@@ -1728,6 +1731,15 @@ const castBigInt64 = (value, srcSigned, dstSigned) => {
1728
1731
  }
1729
1732
  return dstSigned ? castBuffer.readBigInt64LE(0) : castBuffer.readBigUInt64LE(0);
1730
1733
  };
1734
+ const getCastBuffer = (value, srcSize, dstSize) => {
1735
+ const castBuffer = Buffer.alloc(dstSize);
1736
+ let remain = value;
1737
+ for (let i = 0; i < srcSize && remain > 0n; i += 1, remain >>= 8n) {
1738
+ const byte = Number(BigInt.asUintN(8, remain));
1739
+ castBuffer.writeUInt8(byte, i);
1740
+ }
1741
+ return castBuffer;
1742
+ };
1731
1743
  class DBDParser {
1732
1744
  constructor(wdc) {
1733
1745
  __publicField$1(this, "wdc");
@@ -1855,9 +1867,12 @@ class DBDParser {
1855
1867
  }
1856
1868
  } else if (column.type === "float") {
1857
1869
  if (column.arraySize) {
1858
- assert(typeof cell.data === "bigint", `Invalid data type for float array column ${column.name}`);
1870
+ const castBuffer = getCastBuffer(
1871
+ typeof cell.data === "number" ? BigInt(cell.data) : cell.data,
1872
+ srcSize,
1873
+ 4 * column.arraySize
1874
+ );
1859
1875
  const values = [];
1860
- const castBuffer = Buffer.from(cell.data.toString(16).padStart(8 * column.arraySize, "0"), "hex");
1861
1876
  for (let i = 0; i < column.arraySize; i += 1) {
1862
1877
  const value = castBuffer.readFloatLE(i * 4);
1863
1878
  values.push(Math.round(value * 100) / 100);
@@ -1867,25 +1882,49 @@ class DBDParser {
1867
1882
  assert(typeof cell.data === "number", `Invalid data type for float column ${column.name}`);
1868
1883
  data[column.name] = castFloat(cell.data, srcSize, srcSigned);
1869
1884
  }
1870
- } else if (typeof cell.data === "number") {
1871
- data[column.name] = castIntegerBySize(
1872
- cell.data,
1873
- srcSize,
1874
- srcSigned,
1875
- dstSize ?? srcSize,
1876
- column.isSigned
1877
- );
1878
- } else {
1879
- assert(!column.size || column.size === 64, `Unexpected size ${column.size?.toString() ?? ""} for column ${column.name}`);
1880
- if (srcSigned !== column.isSigned) {
1881
- data[column.name] = castBigInt64(
1885
+ } else if (column.type === "int") {
1886
+ if (column.arraySize) {
1887
+ assert(dstSize, `Missing size for int array column ${column.name}`);
1888
+ const castBuffer = getCastBuffer(
1889
+ typeof cell.data === "number" ? BigInt(cell.data) : cell.data,
1890
+ srcSize,
1891
+ 4 * column.arraySize
1892
+ );
1893
+ const values = [];
1894
+ if (column.isSigned) {
1895
+ for (let i = 0; i < column.arraySize; i += 1) {
1896
+ const value = castBuffer.readIntLE(i * dstSize, dstSize);
1897
+ values.push(value);
1898
+ }
1899
+ } else {
1900
+ for (let i = 0; i < column.arraySize; i += 1) {
1901
+ const value = castBuffer.readUIntLE(i * dstSize, dstSize);
1902
+ values.push(value);
1903
+ }
1904
+ }
1905
+ data[column.name] = values;
1906
+ } else if (typeof cell.data === "number") {
1907
+ data[column.name] = castIntegerBySize(
1882
1908
  cell.data,
1909
+ srcSize,
1883
1910
  srcSigned,
1911
+ dstSize ?? srcSize,
1884
1912
  column.isSigned
1885
1913
  );
1886
1914
  } else {
1887
- data[column.name] = cell.data;
1915
+ assert(!column.size || column.size === 64, `Unexpected size ${column.size?.toString() ?? ""} for column ${column.name}`);
1916
+ if (srcSigned !== column.isSigned) {
1917
+ data[column.name] = castBigInt64(
1918
+ cell.data,
1919
+ srcSigned,
1920
+ column.isSigned
1921
+ );
1922
+ } else {
1923
+ data[column.name] = cell.data;
1924
+ }
1888
1925
  }
1926
+ } else {
1927
+ throw new Error(`Unsupported column type ${column.type} for column ${column.name}`);
1889
1928
  }
1890
1929
  fieldIndex += 1;
1891
1930
  } else if (column.isRelation) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhyster/wow-casc-dbc",
3
- "version": "2.4.0",
3
+ "version": "2.5.1",
4
4
  "description": "Fetch World of Warcraft data files from CASC and parse DBC/DB2 files.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -40,20 +40,21 @@
40
40
  "@types/async": "^3.2.24",
41
41
  "@types/cli-progress": "^3.11.5",
42
42
  "@types/jest": "^29.5.12",
43
- "@types/node": "^20.12.7",
44
- "@typescript-eslint/eslint-plugin": "^7.8.0",
45
- "@typescript-eslint/parser": "^7.8.0",
43
+ "@types/node": "^20.14.2",
44
+ "@typescript-eslint/eslint-plugin": "^7.12.0",
45
+ "@typescript-eslint/parser": "^7.12.0",
46
46
  "eslint": "^8.57.0",
47
47
  "eslint-config-airbnb-base": "^15.0.0",
48
48
  "eslint-config-airbnb-typescript": "^18.0.0",
49
49
  "jest": "^29.7.0",
50
- "ts-jest": "^29.1.2",
51
- "tsx": "^4.7.3",
50
+ "ts-jest": "^29.1.4",
51
+ "tsx": "^4.11.2",
52
52
  "typescript": "^5.4.5",
53
53
  "unbuild": "^2.0.0"
54
54
  },
55
55
  "dependencies": {
56
56
  "async": "^3.2.5",
57
57
  "cli-progress": "^3.12.0"
58
- }
58
+ },
59
+ "packageManager": "pnpm@9.2.0+sha512.98a80fd11c2e7096747762304106432b3ddc67dcf54b5a8c01c93f68a2cd5e05e6821849522a06fb76284d41a2660d5e334f2ee3bbf29183bf2e739b1dafa771"
59
60
  }