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
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  A TypeScript client library for interacting with aMule's External Connection (EC) protocol.
7
7
 
8
- Ported from [jamule](https://github.com/vexdev/jamule) (Java/Kotlin) to TypeScript.
8
+ This project started as a port from [jamule](https://github.com/vexdev/jamule) (Java/Kotlin) to TypeScript. But as of the date this readme was last updated, this project covers wider functionality.
9
9
 
10
10
  ## Features
11
11
 
@@ -14,6 +14,7 @@ Ported from [jamule](https://github.com/vexdev/jamule) (Java/Kotlin) to TypeScri
14
14
  - ✅ Server statistics
15
15
  - ✅ File searching (local, global, Kad, web)
16
16
  - ✅ Download management
17
+ - ✅ Per-peer source details for active downloads (via incremental updates)
17
18
  - ✅ Shared files listing
18
19
  - ✅ Category management
19
20
  - ✅ ED2K link parsing
@@ -101,7 +102,13 @@ Options:
101
102
  **Downloads**
102
103
 
103
104
  - `downloadSearchResult(hash, category?): Promise<void>` - Download from search results
104
- - `getDownloadQueue(): Promise<AmuleTransferringFile[]>` - Get download queue
105
+ - `getDownloadQueue(): Promise<AmuleTransferringFile[]>` - Get download queue (chunk info and source name buckets, but no per-peer details)
106
+ - `getDownloadQueueWithSources(): Promise<AmuleTransferringFile[]>` - Get download queue with `sources` filled with the connected peers of each download (name, IP, software, speeds, queue rank, ...)
107
+ - `getUpdate(): Promise<UpdateResponse>` - Incremental update snapshot: downloads (with `sources`), shared files and clients. The daemon sends per-connection diffs; the client merges them internally, so every call returns full objects
108
+
109
+ > **Note:** aMule only exposes per-peer info through the incremental update mechanism (`EC_OP_GET_UPDATE`), never nested inside `EC_OP_GET_DLOAD_QUEUE` responses. Peers are linked to downloads through `client.requestFileId === file.ecid`. The internal cache is per connection and resets automatically on reconnect.
110
+ >
111
+ > `sourceNames` (the filenames under which the sources share each file) is also sent by the daemon as a per-connection incremental map — even for full-detail `getDownloadQueue()` requests. `getDownloadQueue()` therefore returns complete name buckets only on the first call of a connection; the update-based methods merge the diffs and are always complete.
105
112
 
106
113
  **Shared Files**
107
114
 
@@ -115,6 +122,7 @@ This library implements the aMule External Connection protocol version 0x0204, c
115
122
  - aMule 2.3.2
116
123
  - aMule 2.3.3
117
124
  - aMule 3.0.0
125
+ - aMule 3.0.1
118
126
 
119
127
  ### Protocol Features
120
128
 
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { a as StringTag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { a as StringTag } from "./Tag-B5gWV2XF.js";
4
3
  //#region src/request/AddLinkRequest.ts
5
4
  /**
6
5
  * Add Link Request - Download from ED2K link
@@ -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/ClientQueueRequest.ts
5
4
  /**
6
5
  * Client Queue Request - Get client upload queue
@@ -1,7 +1,8 @@
1
- import "./Codes-CjiW7Pdl.js";
2
- import { f as findNumericTag, p as findTag } from "./Tag-CZF6BRMY.js";
3
- import { i as toOptionalNumber, n as toOptionalBool, r as toOptionalIp } from "./utils-DBnUQnZ-.js";
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, i as toOptionalIp, n as tagOwnNumericValue, r as toOptionalBool } from "./utils-CNoUroOI.js";
4
4
  //#region src/response/ClientQueueResponse.ts
5
+ var ClientQueueResponse_exports = /* @__PURE__ */ __exportAll({ ClientQueueResponseParser: () => ClientQueueResponseParser });
5
6
  var ClientQueueResponseParser = class {
6
7
  static fromPacket(packet) {
7
8
  return this.fromTags(packet.tags);
@@ -12,6 +13,7 @@ var ClientQueueResponseParser = class {
12
13
  for (const clientTag of clientTags) {
13
14
  const tags = clientTag.nestedTags || [];
14
15
  const client = {
16
+ ecid: tagOwnNumericValue(clientTag),
15
17
  clientName: findTag(tags, 256)?.getValue(),
16
18
  userHashHexString: findTag(tags, 1539)?.getValue()?.toString("hex"),
17
19
  userID: findNumericTag(tags, 1566)?.getInt(),
@@ -60,4 +62,4 @@ var ClientQueueResponseParser = class {
60
62
  }
61
63
  };
62
64
  //#endregion
63
- export { ClientQueueResponseParser };
65
+ export { ClientQueueResponse_exports as n, ClientQueueResponseParser as t };
@@ -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/CreateCategoryRequest.ts
5
4
  /**
6
5
  * Create Category Request - Create a new category
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { l as UIntTag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { l as UIntTag } from "./Tag-B5gWV2XF.js";
4
3
  //#region src/request/DeleteCategoryRequest.ts
5
4
  /**
6
5
  * Delete Category Request - Delete an existing category
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { r as Hash16Tag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { r as Hash16Tag } from "./Tag-B5gWV2XF.js";
4
3
  import "./index.js";
5
4
  //#region src/request/DownloadCommandRequest.ts
6
5
  /**
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { r as Hash16Tag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { r as Hash16Tag } from "./Tag-B5gWV2XF.js";
4
3
  //#region src/request/DownloadFileRequest.ts
5
4
  /**
6
5
  * Download File Request - Download a file from search results
@@ -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/DownloadQueueRequest.ts
5
4
  /**
6
5
  * Download Queue Request - Get download queue
@@ -0,0 +1,241 @@
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 { n as PARTSIZE, t as ChunkStatus } from "./download-details-OM0FJUhZ.js";
4
+ import { a as toOptionalNumber, n as tagOwnNumericValue, r as toOptionalBool } from "./utils-CNoUroOI.js";
5
+ import { r as parseKnownFileFields } from "./SharedFilesResponse-DE0cd1DT.js";
6
+ //#region src/response/DownloadDetailsResponse.ts
7
+ /**
8
+ * Decode an aMule EC RLE-compressed buffer.
9
+ * Format: [value, value, count] repeats value count times; other bytes pass through.
10
+ */
11
+ function rleDecode(buf) {
12
+ let size = 0;
13
+ let index = 0;
14
+ while (index < buf.length) if (index < buf.length - 2 && buf[index + 1] === buf[index]) {
15
+ size += buf[index + 2];
16
+ index += 3;
17
+ } else {
18
+ size += 1;
19
+ index += 1;
20
+ }
21
+ const output = Buffer.alloc(size);
22
+ let outIndex = 0;
23
+ index = 0;
24
+ while (index < buf.length) if (index < buf.length - 2 && buf[index + 1] === buf[index]) {
25
+ const count = buf[index + 2];
26
+ output.fill(buf[index], outIndex, outIndex + count);
27
+ outIndex += count;
28
+ index += 3;
29
+ } else {
30
+ output[outIndex++] = buf[index];
31
+ index += 1;
32
+ }
33
+ return output;
34
+ }
35
+ /**
36
+ * Reconstruct the current state from the previous state and an RLE-decoded XOR diff,
37
+ * mirroring aMule's RLE_Data: resize previous buffer to the diff size (zero-extend on
38
+ * grow, truncate on shrink), then XOR byte-wise.
39
+ */
40
+ function xorReconstruct(previous, decodedDiff) {
41
+ const result = Buffer.alloc(decodedDiff.length, 0);
42
+ previous.copy(result, 0, 0, Math.min(previous.length, decodedDiff.length));
43
+ for (let i = 0; i < decodedDiff.length; i++) result[i] ^= decodedDiff[i];
44
+ return result;
45
+ }
46
+ /**
47
+ * Decode an RLE-decoded buffer of byte-interleaved (column-major) little-endian uint64 values.
48
+ */
49
+ function decodeInterleavedUint64(decoded) {
50
+ if (decoded.length === 0 || decoded.length % 8 !== 0) return [];
51
+ const valueCount = decoded.length / 8;
52
+ const values = new Array(valueCount);
53
+ for (let i = 0; i < valueCount; i++) {
54
+ let value = 0;
55
+ for (let byte = 7; byte >= 0; byte--) value = value * 256 + decoded[i + byte * valueCount];
56
+ values[i] = value;
57
+ }
58
+ return values;
59
+ }
60
+ function stringValue(tag) {
61
+ if (!tag) return "";
62
+ const value = tag.getValue();
63
+ return typeof value === "string" ? value : "";
64
+ }
65
+ function bufferValue(tag) {
66
+ if (!tag) return;
67
+ const value = tag.getValue();
68
+ return Buffer.isBuffer(value) ? value : void 0;
69
+ }
70
+ function nestedTag(parent, tagName) {
71
+ return parent.nestedTags ? findTag(parent.nestedTags, tagName) : void 0;
72
+ }
73
+ function nestedNumeric(parent, tagName) {
74
+ if (!parent.nestedTags) return 0;
75
+ const numeric = findNumericTag(parent.nestedTags, tagName);
76
+ if (numeric) return Number(numeric.getValue());
77
+ return tagOwnNumericValue(findTag(parent.nestedTags, tagName)) ?? 0;
78
+ }
79
+ /**
80
+ * Extract the raw (RLE-encoded) part/gap/req status buffers of a partfile tag.
81
+ */
82
+ function extractPartFileStatusBuffers(fileTag) {
83
+ return {
84
+ partStatus: bufferValue(nestedTag(fileTag, 786)),
85
+ gapStatus: bufferValue(nestedTag(fileTag, 787)),
86
+ reqStatus: bufferValue(nestedTag(fileTag, 788))
87
+ };
88
+ }
89
+ /**
90
+ * Compute per-chunk status from RLE-decoded part/gap/req status buffers.
91
+ */
92
+ function computeChunkInfo(sizeFull, buffers) {
93
+ const partCount = sizeFull > 0 ? Math.ceil(sizeFull / PARTSIZE) : 0;
94
+ const availability = new Array(partCount).fill(0);
95
+ if (buffers.partStatus && buffers.partStatus.length > 0) for (let i = 0; i < Math.min(buffers.partStatus.length, partCount); i++) availability[i] = buffers.partStatus[i];
96
+ const chunks = new Array(partCount).fill(ChunkStatus.COMPLETE);
97
+ if (partCount > 0 && buffers.gapStatus && buffers.gapStatus.length > 0) {
98
+ const gapValues = decodeInterleavedUint64(buffers.gapStatus);
99
+ for (let i = 0; i + 1 < gapValues.length; i += 2) {
100
+ const gapStart = gapValues[i];
101
+ const gapEnd = gapValues[i + 1];
102
+ if (gapStart > sizeFull || gapEnd > sizeFull || gapStart >= gapEnd) continue;
103
+ const startPart = Math.floor(gapStart / PARTSIZE);
104
+ const endPart = Math.min(Math.floor(gapEnd / PARTSIZE) + 1, partCount);
105
+ for (let part = startPart; part < endPart; part++) {
106
+ const chunkStart = part * PARTSIZE;
107
+ if (gapStart < Math.min((part + 1) * 9728e3, sizeFull) && gapEnd > chunkStart) chunks[part] = availability[part] > 0 ? ChunkStatus.AVAILABLE : ChunkStatus.UNAVAILABLE;
108
+ }
109
+ }
110
+ }
111
+ if (partCount > 0 && buffers.reqStatus && buffers.reqStatus.length > 0) {
112
+ const reqValues = decodeInterleavedUint64(buffers.reqStatus);
113
+ for (let i = 0; i + 1 < reqValues.length; i += 2) {
114
+ const reqStart = reqValues[i];
115
+ const reqEnd = reqValues[i + 1];
116
+ if (reqStart > sizeFull || reqEnd > sizeFull || reqStart >= reqEnd) continue;
117
+ const startPart = Math.floor(reqStart / PARTSIZE);
118
+ const endPart = Math.min(Math.floor(reqEnd / PARTSIZE) + 1, partCount);
119
+ for (let part = startPart; part < endPart; part++) {
120
+ if (chunks[part] === ChunkStatus.COMPLETE) continue;
121
+ const chunkStart = part * PARTSIZE;
122
+ if (reqStart < Math.min((part + 1) * 9728e3, sizeFull) && reqEnd > chunkStart) chunks[part] = ChunkStatus.DOWNLOADING;
123
+ }
124
+ }
125
+ }
126
+ return {
127
+ chunks,
128
+ availability,
129
+ partCount,
130
+ sizeFull
131
+ };
132
+ }
133
+ /**
134
+ * Chunk details of a partfile tag from a full (non-incremental) download queue packet.
135
+ * Only valid for EC_OP_GET_DLOAD_QUEUE responses: incremental updates (EC_OP_GET_UPDATE)
136
+ * send XOR diffs for the status buffers and must be reconstructed statefully instead.
137
+ */
138
+ function chunkInfoFromPartFileTag(fileTag) {
139
+ const sizeFull = nestedNumeric(fileTag, 771);
140
+ const raw = extractPartFileStatusBuffers(fileTag);
141
+ return computeChunkInfo(sizeFull, {
142
+ partStatus: raw.partStatus ? rleDecode(raw.partStatus) : void 0,
143
+ gapStatus: raw.gapStatus ? rleDecode(raw.gapStatus) : void 0,
144
+ reqStatus: raw.reqStatus ? rleDecode(raw.reqStatus) : void 0
145
+ });
146
+ }
147
+ /**
148
+ * Raw diff entries of the source-names map of a partfile tag, or undefined when the
149
+ * packet carries no source-names changes for this file.
150
+ *
151
+ * The daemon sends source names (the filenames under which the sources share the file)
152
+ * as a per-connection incremental map (see CPartFile_Encoder::Encode in aMule's
153
+ * ExternalConn.cpp): an EC_TAG_PARTFILE_SOURCE_NAMES container whose children are
154
+ * integer-valued EC_TAG_PARTFILE_SOURCE_NAMES tags (the map key), each carrying a
155
+ * nested count (0 removes the entry) and, only when the entry is new, a nested name
156
+ * string. The map is never reset while the connection lives, not even for
157
+ * EC_DETAIL_FULL requests.
158
+ */
159
+ function sourceNameEntriesFromFileTag(fileTag) {
160
+ const container = nestedTag(fileTag, 789);
161
+ if (!container) return;
162
+ const entries = [];
163
+ for (const child of container.nestedTags || []) {
164
+ if (child.name !== 789) continue;
165
+ const id = tagOwnNumericValue(child);
166
+ if (id === void 0) continue;
167
+ const name = stringValue(nestedTag(child, 789)) || void 0;
168
+ const count = nestedNumeric(child, 796);
169
+ entries.push({
170
+ id,
171
+ name,
172
+ count
173
+ });
174
+ }
175
+ return entries;
176
+ }
177
+ /**
178
+ * Stateless view of source-name diff entries: only entries whose name is present in
179
+ * this very packet (i.e. new for the connection). Complete on the first request of a
180
+ * connection; later requests only carry changes, so prefer the stateful update path
181
+ * for polling.
182
+ */
183
+ function sourceNameCountsFromEntries(entries) {
184
+ return entries.filter((entry) => entry.name !== void 0 && entry.count > 0).map((entry) => ({
185
+ name: entry.name,
186
+ count: entry.count
187
+ }));
188
+ }
189
+ //#endregion
190
+ //#region src/response/DownloadQueueResponse.ts
191
+ var DownloadQueueResponse_exports = /* @__PURE__ */ __exportAll({ DownloadQueueResponseParser: () => DownloadQueueResponseParser });
192
+ var DownloadQueueResponseParser = class {
193
+ static fromPacket(packet) {
194
+ const files = [];
195
+ const partfileTags = packet.tags.filter((tag) => tag.name === 768);
196
+ for (const fileTag of partfileTags) {
197
+ const tags = fileTag.nestedTags || [];
198
+ let a4afSources = void 0;
199
+ const a4afSourcesTag = findTag(tags, 802);
200
+ if (a4afSourcesTag) {
201
+ a4afSources = [];
202
+ a4afSourcesTag.nestedTags = a4afSourcesTag.nestedTags || [];
203
+ for (const sourceTag of a4afSourcesTag.nestedTags) if (sourceTag.name === 15) a4afSources.push(sourceTag.getValue());
204
+ }
205
+ const file = {
206
+ ...parseKnownFileFields(fileTag),
207
+ partMetID: findNumericTag(tags, 770)?.getShort(),
208
+ sizeXfer: toOptionalNumber(findNumericTag(tags, 772)?.getLong()),
209
+ sizeDone: toOptionalNumber(findNumericTag(tags, 774)?.getLong()),
210
+ fileStatus: findNumericTag(tags, 776)?.getInt(),
211
+ stopped: toOptionalBool(findNumericTag(tags, 791)?.getInt()),
212
+ sourceCount: findNumericTag(tags, 778)?.getShort(),
213
+ sourceNotCurrCount: findNumericTag(tags, 780)?.getShort(),
214
+ sourceXferCount: findNumericTag(tags, 781)?.getShort(),
215
+ sourceCountA4AF: findNumericTag(tags, 779)?.getShort(),
216
+ speed: toOptionalNumber(findNumericTag(tags, 775)?.getLong()),
217
+ downPrio: findNumericTag(tags, 777)?.getInt(),
218
+ fileCat: toOptionalNumber(findNumericTag(tags, 783)?.getLong()),
219
+ lastSeenComplete: toOptionalNumber(findNumericTag(tags, 785)?.getLong()),
220
+ lastDateChanged: toOptionalNumber(findNumericTag(tags, 784)?.getLong()),
221
+ downloadActiveTime: findNumericTag(tags, 792)?.getInt(),
222
+ availablePartCount: findNumericTag(tags, 797)?.getShort(),
223
+ a4AFAuto: toOptionalBool(findNumericTag(tags, 801)?.getInt()),
224
+ hashedPartCount: findNumericTag(tags, 800)?.getInt(),
225
+ getLostDueToCorruption: toOptionalNumber(findNumericTag(tags, 793)?.getLong()),
226
+ getGainDueToCompression: toOptionalNumber(findNumericTag(tags, 794)?.getLong()),
227
+ totalPacketsSavedDueToICH: findNumericTag(tags, 795)?.getInt(),
228
+ a4afSources
229
+ };
230
+ if (file.fileHashHexString) {
231
+ file.chunkInfo = chunkInfoFromPartFileTag(fileTag);
232
+ const sourceNameEntries = sourceNameEntriesFromFileTag(fileTag);
233
+ if (sourceNameEntries) file.sourceNames = sourceNameCountsFromEntries(sourceNameEntries);
234
+ }
235
+ files.push(file);
236
+ }
237
+ return { files };
238
+ }
239
+ };
240
+ //#endregion
241
+ export { rleDecode as a, extractPartFileStatusBuffers as i, DownloadQueueResponse_exports as n, sourceNameEntriesFromFileTag as o, computeChunkInfo as r, xorReconstruct as s, DownloadQueueResponseParser as t };
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { l as UIntTag, s as UByteTag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { l as UIntTag, s as UByteTag } from "./Tag-B5gWV2XF.js";
4
3
  //#region src/request/GetPreferencesRequest.ts
5
4
  /**
6
5
  * Preferences Request - Get preferences
@@ -1,5 +1,4 @@
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";
3
2
  //#region src/response/PreferencesDetailsResponse.ts
4
3
  var PreferencesDetailsResponse = class {
5
4
  preferences;
@@ -1,5 +1,4 @@
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";
3
2
  //#region src/response/PreferencesResponse.ts
4
3
  var PreferencesResponse = class {
5
4
  categories;
@@ -1,5 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import "./Tag-B5gWV2XF.js";
3
3
  //#region src/request/ReloadSharedFilesRequest.ts
4
4
  /**
5
5
  * Reload Shared Files Request - Reload shared files list
@@ -1,3 +1,4 @@
1
+ import { p as findTag } from "./Tag-B5gWV2XF.js";
1
2
  //#region src/ec/packet/Flags.ts
2
3
  /**
3
4
  * Packet flags for EC protocol
@@ -80,11 +81,10 @@ var Flags = class Flags {
80
81
  };
81
82
  //#endregion
82
83
  //#region src/ec/packet/Packet.ts
83
- var Packet = class Packet {
84
+ var Packet = class {
84
85
  opCode;
85
86
  flags;
86
87
  tags;
87
- static EC_CURRENT_PROTOCOL_VERSION = 516;
88
88
  constructor(opCode, flags = new Flags(), tags = []) {
89
89
  this.opCode = opCode;
90
90
  this.flags = flags;
@@ -105,16 +105,10 @@ var Packet = class Packet {
105
105
  return this;
106
106
  }
107
107
  /**
108
- * Get protocol version
109
- */
110
- static getProtocolVersion() {
111
- return Packet.EC_CURRENT_PROTOCOL_VERSION;
112
- }
113
- /**
114
108
  * Find a tag by name
115
109
  */
116
110
  findTag(tagName) {
117
- return this.tags.find((tag) => tag.name === tagName);
111
+ return findTag(this.tags, tagName);
118
112
  }
119
113
  /**
120
114
  * Get all tags with a specific name
@@ -1,5 +1,4 @@
1
- import "./Codes-CjiW7Pdl.js";
2
- import { f as findNumericTag } from "./Tag-CZF6BRMY.js";
1
+ import { f as findNumericTag } from "./Tag-B5gWV2XF.js";
3
2
  //#region src/response/SearchProgressResponse.ts
4
3
  var SearchProgressResponse = class SearchProgressResponse {
5
4
  progress;
@@ -1,6 +1,5 @@
1
- import { n as Packet, r as Flags, t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { a as StringTag, l as UIntTag, s as UByteTag, u as ULongTag } from "./Tag-CZF6BRMY.js";
1
+ import { n as Packet, r as Flags, t as Request } from "./Request-BvScDpeu.js";
2
+ import { a as StringTag, l as UIntTag, s as UByteTag, u as ULongTag } from "./Tag-B5gWV2XF.js";
4
3
  import "./index.js";
5
4
  //#region src/request/SearchRequest.ts
6
5
  /**
@@ -1,5 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import "./Tag-B5gWV2XF.js";
3
3
  //#region src/request/SearchResultsRequest.ts
4
4
  /**
5
5
  * Search Results Request - Get search results
@@ -1,5 +1,4 @@
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";
3
2
  //#region src/response/SearchResultsResponse.ts
4
3
  var SearchResultsResponseParser = class {
5
4
  static fromPacket(packet) {
@@ -1,5 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import "./Tag-B5gWV2XF.js";
3
3
  //#region src/request/SearchStatusRequest.ts
4
4
  /**
5
5
  * Search Status Request - Get search progress
@@ -1,5 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import "./Tag-B5gWV2XF.js";
3
3
  //#region src/request/SearchStopRequest.ts
4
4
  /**
5
5
  * Search Stop Request - Stop current search
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { i as Ipv4Tag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { i as Ipv4Tag } from "./Tag-B5gWV2XF.js";
4
3
  //#region src/request/ServerConnectRequest.ts
5
4
  /**
6
5
  * Server Connect Request - Connect to a specific server
@@ -1,5 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import "./Tag-B5gWV2XF.js";
3
3
  //#region src/request/ServerDisconnectRequest.ts
4
4
  /**
5
5
  * Server Disconnect Request - Disconnect from the current server
@@ -1,5 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import "./Tag-B5gWV2XF.js";
3
3
  //#region src/request/ServerListRequest.ts
4
4
  /**
5
5
  * Server List Request - Request the list of servers
@@ -1,7 +1,8 @@
1
- import "./Codes-CjiW7Pdl.js";
2
- import { f as findNumericTag, p as findTag } from "./Tag-CZF6BRMY.js";
3
- import { n as toOptionalBool, t as formatIp } from "./utils-DBnUQnZ-.js";
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 { r as toOptionalBool, t as formatIp } from "./utils-CNoUroOI.js";
4
4
  //#region src/response/ServerListResponse.ts
5
+ var ServerListResponse_exports = /* @__PURE__ */ __exportAll({ ServerListResponseParser: () => ServerListResponseParser });
5
6
  var ServerListResponseParser = class {
6
7
  static fromPacket(packet) {
7
8
  return this.fromTags(packet.tags);
@@ -47,4 +48,4 @@ var ServerListResponseParser = class {
47
48
  }
48
49
  };
49
50
  //#endregion
50
- export { ServerListResponseParser };
51
+ export { ServerListResponse_exports as n, ServerListResponseParser as t };
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { a as StringTag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { a as StringTag } from "./Tag-B5gWV2XF.js";
4
3
  //#region src/request/ServerUpdateFromUrlRequest.ts
5
4
  var ServerUpdateFromUrlRequest = class extends Request {
6
5
  constructor(url) {
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { r as Hash16Tag, s as UByteTag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { r as Hash16Tag, s as UByteTag } from "./Tag-B5gWV2XF.js";
4
3
  //#region src/request/SetFileCategoryRequest.ts
5
4
  /**
6
5
  * Set File Category Request - Change category of a file
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { a as StringTag, d as UShortTag, l as UIntTag, s as UByteTag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { a as StringTag, d as UShortTag, l as UIntTag, s as UByteTag } from "./Tag-B5gWV2XF.js";
4
3
  //#region src/request/SetPreferencesRequest.ts
5
4
  var SetPreferencesRequest = class SetPreferencesRequest extends Request {
6
5
  constructor(prefs) {
@@ -1,6 +1,5 @@
1
- import { t as Request } from "./Request-C0UUuQIX.js";
2
- import "./Codes-CjiW7Pdl.js";
3
- import { l as UIntTag, r as Hash16Tag } from "./Tag-CZF6BRMY.js";
1
+ import { t as Request } from "./Request-BvScDpeu.js";
2
+ import { l as UIntTag, r as Hash16Tag } from "./Tag-B5gWV2XF.js";
4
3
  //#region src/request/SharedFilePriorityRequest.ts
5
4
  var SharedFilePriorityRequest = class extends Request {
6
5
  constructor(hash, priority) {
@@ -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/SharedFilesRequest.ts
5
4
  /**
6
5
  * Shared Files Request - Get shared files list