amule-ec-client 0.6.1 → 0.7.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.
Files changed (46) hide show
  1. package/README.md +10 -2
  2. package/dist/{AddLinkRequest-D2IME4eb.js → AddLinkRequest-DEKGy-R2.js} +2 -3
  3. package/dist/{ClientQueueRequest-DFfCiNcz.js → ClientQueueRequest-DrLXSxtp.js} +2 -3
  4. package/dist/{ClientQueueResponse-JTrBqrr1.js → ClientQueueResponse-CXxY_9wU.js} +6 -4
  5. package/dist/{CreateCategoryRequest-CRUMcPo5.js → CreateCategoryRequest-COulF12x.js} +2 -3
  6. package/dist/{DeleteCategoryRequest-C8v9oGZ-.js → DeleteCategoryRequest-D-mljaNV.js} +2 -3
  7. package/dist/{DownloadCommandRequest-B3KV_bvm.js → DownloadCommandRequest-Bf1Ez8Da.js} +2 -3
  8. package/dist/{DownloadFileRequest-BjrroO3h.js → DownloadFileRequest-WfOIV07R.js} +2 -3
  9. package/dist/{DownloadQueueRequest-Dil5hl3D.js → DownloadQueueRequest-Br-pgrRt.js} +2 -3
  10. package/dist/DownloadQueueResponse-C-5d4teB.js +241 -0
  11. package/dist/{GetPreferencesRequest-DsxlghqT.js → GetPreferencesRequest-BE3RbRRn.js} +2 -3
  12. package/dist/{PreferencesDetailsResponse-DapscVQi.js → PreferencesDetailsResponse-D8lBd8Ot.js} +1 -2
  13. package/dist/{PreferencesResponse-8n1STWUZ.js → PreferencesResponse-BmGTQM30.js} +1 -2
  14. package/dist/{ReloadSharedFilesRequest-kt0Pxs8A.js → ReloadSharedFilesRequest-BbDUeGcq.js} +2 -2
  15. package/dist/{Request-C0UUuQIX.js → Request-BvScDpeu.js} +3 -9
  16. package/dist/{SearchProgressResponse-C1CdzKnz.js → SearchProgressResponse-BQPliUup.js} +1 -2
  17. package/dist/{SearchRequest-DQnKfA5Z.js → SearchRequest-DOakj8fA.js} +2 -3
  18. package/dist/{SearchResultsRequest-2ejFGQmQ.js → SearchResultsRequest-oZBs5KKm.js} +2 -2
  19. package/dist/{SearchResultsResponse-DwmvbQop.js → SearchResultsResponse-C9I9x035.js} +1 -2
  20. package/dist/{SearchStatusRequest-B_xr4-72.js → SearchStatusRequest-B1ZzSQlE.js} +2 -2
  21. package/dist/{SearchStopRequest-8hwXobty.js → SearchStopRequest-FfXf_DCn.js} +2 -2
  22. package/dist/{ServerConnectRequest-BhNpGiEJ.js → ServerConnectRequest-Cdiw-KWu.js} +2 -3
  23. package/dist/{ServerDisconnectRequest-BjCitLtU.js → ServerDisconnectRequest-BVXSumxX.js} +2 -2
  24. package/dist/{ServerListRequest-BWXLGJib.js → ServerListRequest-3yMrgZID.js} +2 -2
  25. package/dist/{ServerListResponse-BUJ7sz5p.js → ServerListResponse-Do3iRai0.js} +5 -4
  26. package/dist/{ServerUpdateFromUrlRequest-K8C_d0UQ.js → ServerUpdateFromUrlRequest-DpxBII5W.js} +2 -3
  27. package/dist/{SetFileCategoryRequest-VwroLBTV.js → SetFileCategoryRequest-CFgkJB-H.js} +2 -3
  28. package/dist/{SetPreferencesRequest-KZ23VaBY.js → SetPreferencesRequest-BdZ40Ao_.js} +2 -3
  29. package/dist/{SharedFilePriorityRequest-7BriqAcr.js → SharedFilePriorityRequest-BMNmaL06.js} +2 -3
  30. package/dist/{SharedFilesRequest-B72XyRcA.js → SharedFilesRequest-BZKz0oyn.js} +2 -3
  31. package/dist/SharedFilesResponse-DE0cd1DT.js +45 -0
  32. package/dist/{StatsRequest-CGGumOOx.js → StatsRequest-DVwx5wk1.js} +2 -3
  33. package/dist/{StatsResponse-DxQk686g.js → StatsResponse-CP2F2zt0.js} +25 -2
  34. package/dist/{Codes-CjiW7Pdl.js → Tag-B5gWV2XF.js} +268 -1
  35. package/dist/{UpdateCategoryRequest-CzKJa_rC.js → UpdateCategoryRequest-Bu22YjOm.js} +2 -3
  36. package/dist/{UpdateRequest-g2ReOQ5m.js → UpdateRequest-CaQ867p8.js} +2 -3
  37. package/dist/UpdateState-Dn-SuAsj.js +173 -0
  38. package/dist/index.d.ts +358 -336
  39. package/dist/index.js +93 -51
  40. package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
  41. package/dist/{utils-DBnUQnZ-.js → utils-CNoUroOI.js} +11 -1
  42. package/package.json +1 -1
  43. package/dist/DownloadQueueResponse-DUam_zNf.js +0 -259
  44. package/dist/SharedFilesResponse-CkqvYd3N.js +0 -39
  45. package/dist/Tag-CZF6BRMY.js +0 -260
  46. package/dist/UpdateResponse-CGwVjn0Y.js +0 -45
@@ -0,0 +1,45 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
+ import { f as findNumericTag, p as findTag } from "./Tag-B5gWV2XF.js";
3
+ import { a as toOptionalNumber, n as tagOwnNumericValue } from "./utils-CNoUroOI.js";
4
+ //#region src/response/SharedFilesResponse.ts
5
+ var SharedFilesResponse_exports = /* @__PURE__ */ __exportAll({
6
+ SharedFilesResponseParser: () => SharedFilesResponseParser,
7
+ parseKnownFileFields: () => parseKnownFileFields
8
+ });
9
+ /**
10
+ * Parse the fields shared by every known-file shaped tag (EC_TAG_KNOWNFILE and
11
+ * EC_TAG_PARTFILE both carry them).
12
+ */
13
+ function parseKnownFileFields(fileTag) {
14
+ const tags = fileTag.nestedTags || [];
15
+ const hashTag = findTag(tags, 798);
16
+ const fileNameTag = findTag(tags, 769);
17
+ return {
18
+ ecid: tagOwnNumericValue(fileTag),
19
+ fileHashHexString: hashTag ? hashTag.getValue().toString("hex") : void 0,
20
+ fileName: fileNameTag ? fileNameTag.getValue() : void 0,
21
+ filePath: findTag(tags, 1032)?.getValue(),
22
+ sizeFull: toOptionalNumber(findNumericTag(tags, 771)?.getLong()),
23
+ fileEd2kLink: findTag(tags, 782)?.getValue(),
24
+ upPrio: findNumericTag(tags, 1035)?.getInt(),
25
+ getRequests: findNumericTag(tags, 1027)?.getShort(),
26
+ getAllRequests: findNumericTag(tags, 1028)?.getInt(),
27
+ getAccepts: findNumericTag(tags, 1029)?.getShort(),
28
+ getAllAccepts: findNumericTag(tags, 1030)?.getInt(),
29
+ getXferred: toOptionalNumber(findNumericTag(tags, 1025)?.getLong()),
30
+ getAllXferred: toOptionalNumber(findNumericTag(tags, 1026)?.getLong()),
31
+ getCompleteSourcesLow: findNumericTag(tags, 1033)?.getShort(),
32
+ getCompleteSourcesHigh: findNumericTag(tags, 1034)?.getShort(),
33
+ getCompleteSources: findNumericTag(tags, 1037)?.getShort(),
34
+ getOnQueue: findNumericTag(tags, 1036)?.getShort(),
35
+ getComment: findTag(tags, 1038)?.getValue(),
36
+ getRating: findNumericTag(tags, 1039)?.getInt()
37
+ };
38
+ }
39
+ var SharedFilesResponseParser = class {
40
+ static fromPacket(packet) {
41
+ return { files: packet.tags.filter((tag) => tag.name === 1024).map(parseKnownFileFields) };
42
+ }
43
+ };
44
+ //#endregion
45
+ export { SharedFilesResponse_exports as n, parseKnownFileFields as r, SharedFilesResponseParser as t };
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { s as UByteTag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { s as UByteTag } from "./Tag-B5gWV2XF.js";
4
3
  //#region src/request/StatsRequest.ts
5
4
  /**
6
5
  * Stats Request - Request server statistics
@@ -1,6 +1,11 @@
1
- import "./Codes-CjiW7Pdl.js";
2
- import { f as findNumericTag, p as findTag } from "./Tag-CZF6BRMY.js";
1
+ import { f as findNumericTag, p as findTag } from "./Tag-B5gWV2XF.js";
2
+ import { n as tagOwnNumericValue } from "./utils-CNoUroOI.js";
3
3
  //#region src/response/StatsResponse.ts
4
+ const CONNSTATE_ED2K_CONNECTED = 1;
5
+ const CONNSTATE_ED2K_CONNECTING = 2;
6
+ const CONNSTATE_KAD_CONNECTED = 4;
7
+ const CONNSTATE_KAD_FIREWALLED = 8;
8
+ const CONNSTATE_KAD_RUNNING = 16;
4
9
  var StatsResponseParser = class {
5
10
  static fromPacket(packet) {
6
11
  const uploadOverhead = findNumericTag(packet.tags, 516)?.getValue() || 0;
@@ -25,6 +30,7 @@ var StatsResponseParser = class {
25
30
  let clientId = 0;
26
31
  let kadId;
27
32
  let connectedServer;
33
+ let connectionState;
28
34
  if (connStateTag && connStateTag.nestedTags) {
29
35
  ed2kId = Number(findNumericTag(connStateTag.nestedTags, 6)?.getValue() || 0);
30
36
  clientId = Number(findNumericTag(connStateTag.nestedTags, 10)?.getValue() || 0);
@@ -44,6 +50,22 @@ var StatsResponseParser = class {
44
50
  description: findTag(serverTag.nestedTags || [], 1282)?.getValue()
45
51
  };
46
52
  }
53
+ const stateBits = tagOwnNumericValue(connStateTag) ?? 0;
54
+ connectionState = {
55
+ ed2kConnected: (stateBits & CONNSTATE_ED2K_CONNECTED) !== 0,
56
+ ed2kConnecting: (stateBits & CONNSTATE_ED2K_CONNECTING) !== 0,
57
+ kadConnected: (stateBits & CONNSTATE_KAD_CONNECTED) !== 0,
58
+ kadFirewalled: (stateBits & CONNSTATE_KAD_FIREWALLED) !== 0,
59
+ kadRunning: (stateBits & CONNSTATE_KAD_RUNNING) !== 0,
60
+ ed2kId: ed2kId || void 0,
61
+ clientId: clientId || void 0,
62
+ serverIpv4: connectedServer ? {
63
+ address: connectedServer.ip,
64
+ port: connectedServer.port
65
+ } : void 0,
66
+ serverName: connectedServer?.name,
67
+ serverDescription: connectedServer?.description
68
+ };
47
69
  }
48
70
  const id = clientId || Number(findNumericTag(packet.tags, 10)?.getValue() || 0);
49
71
  return {
@@ -51,6 +73,7 @@ var StatsResponseParser = class {
51
73
  ed2kId,
52
74
  kadId,
53
75
  connectedServer,
76
+ connectionState,
54
77
  uploadOverhead: Number(uploadOverhead),
55
78
  downloadOverhead: Number(downloadOverhead),
56
79
  bannedCount: Number(bannedCount),
@@ -389,6 +389,14 @@ let ECSearchType = /* @__PURE__ */ function(ECSearchType) {
389
389
  ECSearchType[ECSearchType["EC_SEARCH_WEB"] = 3] = "EC_SEARCH_WEB";
390
390
  return ECSearchType;
391
391
  }({});
392
+ let ECSearchFileDownloadStatus = /* @__PURE__ */ function(ECSearchFileDownloadStatus) {
393
+ ECSearchFileDownloadStatus[ECSearchFileDownloadStatus["NEW"] = 0] = "NEW";
394
+ ECSearchFileDownloadStatus[ECSearchFileDownloadStatus["DOWNLOADED"] = 1] = "DOWNLOADED";
395
+ ECSearchFileDownloadStatus[ECSearchFileDownloadStatus["QUEUED"] = 2] = "QUEUED";
396
+ ECSearchFileDownloadStatus[ECSearchFileDownloadStatus["CANCELED"] = 3] = "CANCELED";
397
+ ECSearchFileDownloadStatus[ECSearchFileDownloadStatus["QUEUEDCANCELED"] = 4] = "QUEUEDCANCELED";
398
+ return ECSearchFileDownloadStatus;
399
+ }({});
392
400
  let EcPrefs = /* @__PURE__ */ function(EcPrefs) {
393
401
  EcPrefs[EcPrefs["EC_PREFS_CATEGORIES"] = 1] = "EC_PREFS_CATEGORIES";
394
402
  EcPrefs[EcPrefs["EC_PREFS_GENERAL"] = 2] = "EC_PREFS_GENERAL";
@@ -406,4 +414,263 @@ let EcPrefs = /* @__PURE__ */ function(EcPrefs) {
406
414
  return EcPrefs;
407
415
  }({});
408
416
  //#endregion
409
- export { EcPrefs as a, ECTagName as i, ECOpCode as n, ProtocolVersion as o, ECSearchType as r, ECDetailLevel as t };
417
+ //#region src/ec/tag/Tag.ts
418
+ var Tag = class {
419
+ name;
420
+ type;
421
+ nameValue;
422
+ value;
423
+ nestedTags;
424
+ constructor(name, type, nestedTags = [], nameValue = name) {
425
+ this.name = name;
426
+ this.type = type;
427
+ this.nameValue = nameValue;
428
+ if (nestedTags.length > 0) this.nestedTags = nestedTags;
429
+ }
430
+ getValue() {
431
+ return this.value;
432
+ }
433
+ setValue(value) {
434
+ this.value = value;
435
+ }
436
+ };
437
+ var CustomTag = class extends Tag {
438
+ constructor(name, value, subtags = [], nameValue = name) {
439
+ super(name, 1, subtags, nameValue);
440
+ if (value !== void 0) this.setValue(value);
441
+ }
442
+ parseValue(value) {
443
+ this.setValue(value);
444
+ }
445
+ encodeValue() {
446
+ return this.getValue();
447
+ }
448
+ };
449
+ var UByteTag = class UByteTag extends Tag {
450
+ constructor(name, value, subtags = [], nameValue = name) {
451
+ super(name, 2, subtags, nameValue);
452
+ if (value !== void 0) this.setValue(value);
453
+ }
454
+ static withValue(name, value, subtags = []) {
455
+ return new UByteTag(name, value, subtags);
456
+ }
457
+ parseValue(value) {
458
+ if (value.length === 0) this.setValue(0);
459
+ else if (value.length === 1) this.setValue(value[0]);
460
+ else throw new Error("UInt8Tag value must be 1 byte long");
461
+ }
462
+ encodeValue() {
463
+ const buf = Buffer.allocUnsafe(1);
464
+ buf.writeUInt8(this.getValue());
465
+ return buf;
466
+ }
467
+ getShort() {
468
+ return this.getValue();
469
+ }
470
+ getInt() {
471
+ return this.getValue();
472
+ }
473
+ getLong() {
474
+ return BigInt(this.getValue());
475
+ }
476
+ };
477
+ var UShortTag = class UShortTag extends Tag {
478
+ constructor(name, value, subtags = [], nameValue = name) {
479
+ super(name, 3, subtags, nameValue);
480
+ if (value !== void 0) this.setValue(value);
481
+ }
482
+ static withValue(name, value, subtags = []) {
483
+ return new UShortTag(name, value, subtags);
484
+ }
485
+ parseValue(value) {
486
+ if (value.length === 0) this.setValue(0);
487
+ else if (value.length === 2) this.setValue(value.readUInt16BE(0));
488
+ else throw new Error("UInt16Tag value must be 2 bytes long");
489
+ }
490
+ encodeValue() {
491
+ const buf = Buffer.allocUnsafe(2);
492
+ buf.writeUInt16BE(this.getValue());
493
+ return buf;
494
+ }
495
+ getShort() {
496
+ return this.getValue();
497
+ }
498
+ getInt() {
499
+ return this.getValue();
500
+ }
501
+ getLong() {
502
+ return BigInt(this.getValue());
503
+ }
504
+ };
505
+ var UIntTag = class UIntTag extends Tag {
506
+ constructor(name, value, subtags = [], nameValue = name) {
507
+ super(name, 4, subtags, nameValue);
508
+ if (value !== void 0) this.setValue(value);
509
+ }
510
+ static withValue(name, value, subtags = []) {
511
+ return new UIntTag(name, value, subtags);
512
+ }
513
+ parseValue(value) {
514
+ if (value.length === 0) this.setValue(0);
515
+ else if (value.length === 4) this.setValue(value.readUInt32BE(0));
516
+ else throw new Error("UInt32Tag value must be 4 bytes long");
517
+ }
518
+ encodeValue() {
519
+ const buf = Buffer.allocUnsafe(4);
520
+ buf.writeUInt32BE(this.getValue());
521
+ return buf;
522
+ }
523
+ getShort() {
524
+ throw new Error("Unsigned Integer cannot be cast to short");
525
+ }
526
+ getInt() {
527
+ return this.getValue();
528
+ }
529
+ getLong() {
530
+ return BigInt(this.getValue());
531
+ }
532
+ };
533
+ var ULongTag = class ULongTag extends Tag {
534
+ constructor(name, value, subtags = [], nameValue = name) {
535
+ super(name, 5, subtags, nameValue);
536
+ if (value !== void 0) this.setValue(value);
537
+ }
538
+ static withValue(name, value, subtags = []) {
539
+ return new ULongTag(name, value, subtags);
540
+ }
541
+ parseValue(value) {
542
+ if (value.length === 0) this.setValue(0n);
543
+ else if (value.length === 8) this.setValue(value.readBigUInt64BE(0));
544
+ else throw new Error("UInt64Tag value must be 8 bytes long");
545
+ }
546
+ encodeValue() {
547
+ const buf = Buffer.allocUnsafe(8);
548
+ buf.writeBigUInt64BE(this.getValue());
549
+ return buf;
550
+ }
551
+ getShort() {
552
+ throw new Error("Unsigned Long cannot be cast to short");
553
+ }
554
+ getInt() {
555
+ throw new Error("Unsigned Long cannot be cast to int");
556
+ }
557
+ getLong() {
558
+ return this.getValue();
559
+ }
560
+ };
561
+ var UInt128Tag = class UInt128Tag extends Tag {
562
+ constructor(name, value, subtags = [], nameValue = name) {
563
+ super(name, 10, subtags, nameValue);
564
+ if (value !== void 0) this.setValue(value);
565
+ }
566
+ static withValue(name, value, subtags = []) {
567
+ return new UInt128Tag(name, value, subtags);
568
+ }
569
+ parseValue(value) {
570
+ if (value.length === 0) this.setValue(0n);
571
+ else {
572
+ let result = 0n;
573
+ for (let i = 0; i < value.length; i++) result = result << 8n | BigInt(value[i]);
574
+ this.setValue(result);
575
+ }
576
+ }
577
+ encodeValue() {
578
+ const val = this.getValue();
579
+ const bytes = [];
580
+ let remaining = val;
581
+ while (remaining > 0n) {
582
+ bytes.unshift(Number(remaining & 255n));
583
+ remaining >>= 8n;
584
+ }
585
+ while (bytes.length < 16) bytes.unshift(0);
586
+ return Buffer.from(bytes);
587
+ }
588
+ };
589
+ var StringTag = class StringTag extends Tag {
590
+ constructor(name, value, subtags = [], nameValue = name) {
591
+ super(name, 6, subtags, nameValue);
592
+ if (value !== void 0) this.setValue(value);
593
+ }
594
+ static withValue(name, value, subtags = []) {
595
+ return new StringTag(name, value, subtags);
596
+ }
597
+ parseValue(value) {
598
+ if (value[value.length - 1] !== 0) throw new Error("StringTag value must be null terminated");
599
+ this.setValue(value.toString("utf8", 0, value.length - 1));
600
+ }
601
+ encodeValue() {
602
+ return Buffer.concat([Buffer.from(this.getValue(), "utf8"), Buffer.from([0])]);
603
+ }
604
+ };
605
+ var DoubleTag = class DoubleTag extends Tag {
606
+ constructor(name, value, subtags = [], nameValue = name) {
607
+ super(name, 7, subtags, nameValue);
608
+ if (value !== void 0) this.setValue(value);
609
+ }
610
+ static withValue(name, value, subtags = []) {
611
+ return new DoubleTag(name, value, subtags);
612
+ }
613
+ parseValue(value) {
614
+ const numValue = value.length >= 8 ? value.readDoubleBE(0) : 0;
615
+ this.setValue(numValue);
616
+ }
617
+ encodeValue() {
618
+ const buf = Buffer.allocUnsafe(8);
619
+ buf.writeDoubleBE(this.getValue());
620
+ return buf;
621
+ }
622
+ };
623
+ var Ipv4Tag = class Ipv4Tag extends Tag {
624
+ constructor(name, value, subtags = [], nameValue = name) {
625
+ super(name, 8, subtags, nameValue);
626
+ if (value !== void 0) this.setValue(value);
627
+ }
628
+ static withValue(name, value, subtags = []) {
629
+ return new Ipv4Tag(name, value, subtags);
630
+ }
631
+ parseValue(value) {
632
+ if (value.length !== 6) throw new Error("Ipv4Tag value must be 6 bytes long");
633
+ const address = `${value[0]}.${value[1]}.${value[2]}.${value[3]}`;
634
+ const port = value.readUInt16BE(4);
635
+ this.setValue({
636
+ address,
637
+ port
638
+ });
639
+ }
640
+ encodeValue() {
641
+ const val = this.getValue();
642
+ const parts = val.address.split(".").map(Number);
643
+ const buf = Buffer.allocUnsafe(6);
644
+ buf[0] = parts[0];
645
+ buf[1] = parts[1];
646
+ buf[2] = parts[2];
647
+ buf[3] = parts[3];
648
+ buf.writeUInt16BE(val.port, 4);
649
+ return buf;
650
+ }
651
+ };
652
+ var Hash16Tag = class Hash16Tag extends Tag {
653
+ constructor(name, value, subtags = [], nameValue = name) {
654
+ super(name, 9, subtags, nameValue);
655
+ if (value !== void 0) this.setValue(value);
656
+ }
657
+ static withValue(name, value, subtags = []) {
658
+ return new Hash16Tag(name, value, subtags);
659
+ }
660
+ parseValue(value) {
661
+ if (value.length === 16) this.setValue(value);
662
+ else throw new Error("Hash16Tag value must be 16 bytes long");
663
+ }
664
+ encodeValue() {
665
+ return this.getValue();
666
+ }
667
+ };
668
+ function findTag(tags, name) {
669
+ return tags.find((tag) => tag.name === name);
670
+ }
671
+ function findNumericTag(tags, name) {
672
+ const tag = tags.find((tag) => tag.name === name);
673
+ if (tag && "getInt" in tag && "getShort" in tag && "getLong" in tag) return tag;
674
+ }
675
+ //#endregion
676
+ export { ECSearchType as _, StringTag as a, ProtocolVersion as b, UInt128Tag as c, UShortTag as d, findNumericTag as f, ECSearchFileDownloadStatus as g, ECOpCode as h, Ipv4Tag as i, UIntTag as l, ECDetailLevel as m, DoubleTag as n, Tag as o, findTag as p, Hash16Tag as r, UByteTag as s, CustomTag as t, ULongTag as u, ECTagName as v, EcPrefs as y };
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { a as StringTag, l as UIntTag, s as UByteTag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { a as StringTag, l as UIntTag, s as UByteTag } from "./Tag-B5gWV2XF.js";
4
3
  //#region src/request/UpdateCategoryRequest.ts
5
4
  /**
6
5
  * Update Category Request - Update an existing category
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { s as UByteTag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { s as UByteTag } from "./Tag-B5gWV2XF.js";
4
3
  //#region src/request/UpdateRequest.ts
5
4
  /**
6
5
  * Update Request - Get incremental updates for files, clients, and servers
@@ -0,0 +1,173 @@
1
+ import { f as findNumericTag, p as findTag } from "./Tag-B5gWV2XF.js";
2
+ import { a as toOptionalNumber, i as toOptionalIp, n as tagOwnNumericValue, r as toOptionalBool } from "./utils-CNoUroOI.js";
3
+ import { a as rleDecode, i as extractPartFileStatusBuffers, o as sourceNameEntriesFromFileTag, r as computeChunkInfo, s as xorReconstruct, t as DownloadQueueResponseParser } from "./DownloadQueueResponse-C-5d4teB.js";
4
+ import { t as SharedFilesResponseParser } from "./SharedFilesResponse-DE0cd1DT.js";
5
+ import { t as ClientQueueResponseParser } from "./ClientQueueResponse-CXxY_9wU.js";
6
+ import { t as ServerListResponseParser } from "./ServerListResponse-Do3iRai0.js";
7
+ //#region src/response/UpdateResponse.ts
8
+ var UpdateResponseParser = class {
9
+ static fromPacket(packet) {
10
+ const sharedFiles = SharedFilesResponseParser.fromPacket(packet).files;
11
+ const downloadQueue = DownloadQueueResponseParser.fromPacket(packet).files;
12
+ const clientContainer = findTag(packet.tags, 1536);
13
+ const clients = clientContainer && clientContainer.nestedTags ? ClientQueueResponseParser.fromTags(clientContainer.nestedTags).clients : [];
14
+ const serverContainer = findTag(packet.tags, 1280);
15
+ const servers = serverContainer && serverContainer.nestedTags ? ServerListResponseParser.fromTags(serverContainer.nestedTags).servers : [];
16
+ const friendContainer = findTag(packet.tags, 2048);
17
+ return {
18
+ sharedFiles,
19
+ downloadQueue,
20
+ clients,
21
+ servers,
22
+ friends: friendContainer && friendContainer.nestedTags ? this.parseFriends(friendContainer.nestedTags) : []
23
+ };
24
+ }
25
+ static parseFriends(tags) {
26
+ const friends = [];
27
+ const friendTags = tags.filter((t) => t.name === 2048);
28
+ for (const friendTag of friendTags) {
29
+ const nested = friendTag.nestedTags || [];
30
+ friends.push({
31
+ name: findTag(nested, 2049)?.getValue(),
32
+ userHashHexString: findTag(nested, 2050)?.getValue()?.toString("hex"),
33
+ ip: toOptionalIp(findNumericTag(nested, 2051)?.getInt()),
34
+ port: findNumericTag(nested, 2052)?.getInt(),
35
+ friendSlot: toOptionalBool(findNumericTag(nested, 2056)?.getInt()),
36
+ shared: toOptionalBool(findNumericTag(nested, 2057)?.getInt()),
37
+ client: ClientQueueResponseParser.fromTags(nested).clients[0]
38
+ });
39
+ }
40
+ return friends;
41
+ }
42
+ };
43
+ //#endregion
44
+ //#region src/client/UpdateState.ts
45
+ const STATUS_BUFFER_KEYS = [
46
+ "partStatus",
47
+ "gapStatus",
48
+ "reqStatus"
49
+ ];
50
+ /**
51
+ * Merge update fields into the existing object. Fields absent from an incremental
52
+ * response are undefined after parsing and must not clobber previously known values.
53
+ */
54
+ function mergeDefined(existing, updates) {
55
+ const result = { ...existing };
56
+ for (const [key, value] of Object.entries(updates)) if (value !== void 0) result[key] = value;
57
+ return result;
58
+ }
59
+ var UpdateState = class {
60
+ sessionGeneration;
61
+ downloads = /* @__PURE__ */ new Map();
62
+ sharedFiles = /* @__PURE__ */ new Map();
63
+ clients = /* @__PURE__ */ new Map();
64
+ statusBuffers = /* @__PURE__ */ new Map();
65
+ sourceNames = /* @__PURE__ */ new Map();
66
+ /**
67
+ * @param sessionGeneration Connection generation this state belongs to (see
68
+ * AmuleConnection.getSessionGeneration). The state is only valid while the
69
+ * connection that produced it is alive, since the daemon diffs per connection.
70
+ */
71
+ constructor(sessionGeneration) {
72
+ this.sessionGeneration = sessionGeneration;
73
+ }
74
+ apply(packet) {
75
+ const parsed = UpdateResponseParser.fromPacket(packet);
76
+ for (const file of parsed.downloadQueue) {
77
+ delete file.chunkInfo;
78
+ delete file.sourceNames;
79
+ }
80
+ const downloadQueue = this.mergeCollection(this.downloads, parsed.downloadQueue);
81
+ const sharedFiles = this.mergeCollection(this.sharedFiles, parsed.sharedFiles);
82
+ const clients = this.mergeCollection(this.clients, parsed.clients);
83
+ for (const ecid of [...this.statusBuffers.keys()]) if (!this.downloads.has(ecid)) this.statusBuffers.delete(ecid);
84
+ for (const ecid of [...this.sourceNames.keys()]) if (!this.downloads.has(ecid)) this.sourceNames.delete(ecid);
85
+ this.reconstructFileDetails(packet);
86
+ this.attachSources();
87
+ return {
88
+ downloadQueue,
89
+ sharedFiles,
90
+ clients,
91
+ servers: parsed.servers,
92
+ friends: parsed.friends
93
+ };
94
+ }
95
+ mergeCollection(state, items) {
96
+ const seen = /* @__PURE__ */ new Set();
97
+ const result = [];
98
+ for (const item of items) {
99
+ if (item.ecid === void 0) {
100
+ result.push(item);
101
+ continue;
102
+ }
103
+ seen.add(item.ecid);
104
+ const existing = state.get(item.ecid);
105
+ const merged = existing ? mergeDefined(existing, item) : item;
106
+ state.set(item.ecid, merged);
107
+ result.push(merged);
108
+ }
109
+ for (const ecid of [...state.keys()]) if (!seen.has(ecid)) state.delete(ecid);
110
+ return result;
111
+ }
112
+ /**
113
+ * Reconstruct the incremental per-file details of each partfile in the packet:
114
+ * RLE-decode and XOR-reconstruct the status buffers (recomputing chunk info from the
115
+ * accumulated state), and apply the source-names map diffs (new entry / count change /
116
+ * removal when count is 0).
117
+ */
118
+ reconstructFileDetails(packet) {
119
+ const partfileTags = packet.tags.filter((tag) => tag.name === 768);
120
+ for (const fileTag of partfileTags) {
121
+ const ecid = tagOwnNumericValue(fileTag);
122
+ if (ecid === void 0) continue;
123
+ const file = this.downloads.get(ecid);
124
+ if (!file) continue;
125
+ const raw = extractPartFileStatusBuffers(fileTag);
126
+ const state = this.statusBuffers.get(ecid) || {};
127
+ for (const key of STATUS_BUFFER_KEYS) {
128
+ const rawBuffer = raw[key];
129
+ if (!rawBuffer || rawBuffer.length === 0) continue;
130
+ const decoded = rleDecode(rawBuffer);
131
+ const previous = state[key];
132
+ state[key] = previous ? xorReconstruct(previous, decoded) : decoded;
133
+ }
134
+ this.statusBuffers.set(ecid, state);
135
+ if (file.sizeFull && file.sizeFull > 0) file.chunkInfo = computeChunkInfo(file.sizeFull, state);
136
+ const entries = sourceNameEntriesFromFileTag(fileTag);
137
+ if (entries) {
138
+ const nameMap = this.sourceNames.get(ecid) || /* @__PURE__ */ new Map();
139
+ for (const entry of entries) {
140
+ if (entry.count === 0) {
141
+ nameMap.delete(entry.id);
142
+ continue;
143
+ }
144
+ const existing = nameMap.get(entry.id);
145
+ if (existing) {
146
+ existing.count = entry.count;
147
+ if (entry.name !== void 0) existing.name = entry.name;
148
+ } else if (entry.name !== void 0) nameMap.set(entry.id, {
149
+ name: entry.name,
150
+ count: entry.count
151
+ });
152
+ }
153
+ this.sourceNames.set(ecid, nameMap);
154
+ }
155
+ const nameMap = this.sourceNames.get(ecid);
156
+ if (nameMap) file.sourceNames = [...nameMap.values()];
157
+ }
158
+ }
159
+ /**
160
+ * Group clients by the download they are requesting (client.requestFileId -> file.ecid).
161
+ */
162
+ attachSources() {
163
+ for (const file of this.downloads.values()) file.sources = [];
164
+ for (const client of this.clients.values()) {
165
+ const requestFileId = toOptionalNumber(client.requestFileId);
166
+ if (requestFileId === void 0) continue;
167
+ const file = this.downloads.get(requestFileId);
168
+ if (file) file.sources.push(client);
169
+ }
170
+ }
171
+ };
172
+ //#endregion
173
+ export { UpdateState };