amule-ec-client 0.5.2 → 0.6.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.
Files changed (44) hide show
  1. package/README.md +4 -0
  2. package/dist/AddLinkRequest-D2IME4eb.js +15 -0
  3. package/dist/ClientQueueRequest-DFfCiNcz.js +15 -0
  4. package/dist/ClientQueueResponse-JTrBqrr1.js +63 -0
  5. package/dist/Codes-CjiW7Pdl.js +409 -0
  6. package/dist/CreateCategoryRequest-CRUMcPo5.js +22 -0
  7. package/dist/DeleteCategoryRequest-C8v9oGZ-.js +15 -0
  8. package/dist/DownloadCommandRequest-B3KV_bvm.js +29 -0
  9. package/dist/DownloadFileRequest-BjrroO3h.js +18 -0
  10. package/dist/DownloadQueueRequest-Dil5hl3D.js +15 -0
  11. package/dist/DownloadQueueResponse-DUam_zNf.js +259 -0
  12. package/dist/GetPreferencesRequest-DsxlghqT.js +16 -0
  13. package/dist/PreferencesDetailsResponse-DapscVQi.js +94 -0
  14. package/dist/PreferencesResponse-8n1STWUZ.js +37 -0
  15. package/dist/ReloadSharedFilesRequest-kt0Pxs8A.js +13 -0
  16. package/dist/Request-C0UUuQIX.js +158 -0
  17. package/dist/SearchProgressResponse-C1CdzKnz.js +15 -0
  18. package/dist/SearchRequest-DQnKfA5Z.js +55 -0
  19. package/dist/SearchResultsRequest-2ejFGQmQ.js +13 -0
  20. package/dist/SearchResultsResponse-DwmvbQop.js +29 -0
  21. package/dist/SearchStatusRequest-B_xr4-72.js +13 -0
  22. package/dist/SearchStopRequest-8hwXobty.js +13 -0
  23. package/dist/ServerConnectRequest-BhNpGiEJ.js +18 -0
  24. package/dist/ServerDisconnectRequest-BjCitLtU.js +13 -0
  25. package/dist/ServerListRequest-BWXLGJib.js +13 -0
  26. package/dist/ServerListResponse-BUJ7sz5p.js +50 -0
  27. package/dist/ServerUpdateFromUrlRequest-K8C_d0UQ.js +12 -0
  28. package/dist/SetFileCategoryRequest-VwroLBTV.js +15 -0
  29. package/dist/SetPreferencesRequest-KZ23VaBY.js +64 -0
  30. package/dist/SharedFilePriorityRequest-7BriqAcr.js +13 -0
  31. package/dist/SharedFilesRequest-B72XyRcA.js +15 -0
  32. package/dist/SharedFilesResponse-CkqvYd3N.js +39 -0
  33. package/dist/StatsRequest-CGGumOOx.js +15 -0
  34. package/dist/StatsResponse-DxQk686g.js +76 -0
  35. package/dist/Tag-CZF6BRMY.js +260 -0
  36. package/dist/UpdateCategoryRequest-CzKJa_rC.js +22 -0
  37. package/dist/UpdateRequest-g2ReOQ5m.js +15 -0
  38. package/dist/UpdateResponse-CGwVjn0Y.js +45 -0
  39. package/dist/download-details-OM0FJUhZ.js +10 -0
  40. package/dist/index.d.ts +1042 -933
  41. package/dist/index.js +1041 -3123
  42. package/dist/utils-DBnUQnZ-.js +24 -0
  43. package/package.json +5 -5
  44. package/dist/index.js.map +0 -1
@@ -0,0 +1,15 @@
1
+ import { t as Request } from "./Request-C0UUuQIX.js";
2
+ import "./Codes-CjiW7Pdl.js";
3
+ import { s as UByteTag } from "./Tag-CZF6BRMY.js";
4
+ //#region src/request/DownloadQueueRequest.ts
5
+ /**
6
+ * Download Queue Request - Get download queue
7
+ */
8
+ var DownloadQueueRequest = class extends Request {
9
+ constructor(detailLevel = 2) {
10
+ super(13);
11
+ this.addTag(new UByteTag(4, detailLevel));
12
+ }
13
+ };
14
+ //#endregion
15
+ export { DownloadQueueRequest };
@@ -0,0 +1,259 @@
1
+ import "./Codes-CjiW7Pdl.js";
2
+ import { f as findNumericTag, p as findTag } from "./Tag-CZF6BRMY.js";
3
+ import { n as PARTSIZE, t as ChunkStatus } from "./download-details-OM0FJUhZ.js";
4
+ import { i as toOptionalNumber, n as toOptionalBool, t as formatIp } from "./utils-DBnUQnZ-.js";
5
+ //#region src/response/DownloadDetailsResponse.ts
6
+ function rleDecode(buf) {
7
+ const output = [];
8
+ let index = 0;
9
+ while (index < buf.length) if (index < buf.length - 2 && buf[index + 1] === buf[index]) {
10
+ const value = buf[index];
11
+ const count = buf[index + 2];
12
+ for (let i = 0; i < count; i++) output.push(value);
13
+ index += 3;
14
+ } else {
15
+ output.push(buf[index]);
16
+ index += 1;
17
+ }
18
+ return Buffer.from(output);
19
+ }
20
+ function decodePartStatus(buf) {
21
+ const decoded = rleDecode(buf);
22
+ const result = new Array(decoded.length);
23
+ for (let i = 0; i < decoded.length; i++) result[i] = decoded[i];
24
+ return result;
25
+ }
26
+ function decodeUint64Array(buf) {
27
+ const decoded = rleDecode(buf);
28
+ if (decoded.length === 0 || decoded.length % 8 !== 0) return [];
29
+ const valueCount = decoded.length / 8;
30
+ const values = new Array(valueCount);
31
+ for (let i = 0; i < valueCount; i++) {
32
+ let value = 0;
33
+ for (let byte = 7; byte >= 0; byte--) value = value * 256 + decoded[i + byte * valueCount];
34
+ values[i] = value;
35
+ }
36
+ return values;
37
+ }
38
+ function stringValue(tag) {
39
+ if (!tag) return "";
40
+ const value = tag.getValue();
41
+ return typeof value === "string" ? value : "";
42
+ }
43
+ function bufferValue(tag) {
44
+ if (!tag) return;
45
+ const value = tag.getValue();
46
+ return Buffer.isBuffer(value) ? value : void 0;
47
+ }
48
+ function nestedTag(parent, tagName) {
49
+ return parent.nestedTags ? findTag(parent.nestedTags, tagName) : void 0;
50
+ }
51
+ function nestedNumeric(parent, tagName) {
52
+ if (!parent.nestedTags) return 0;
53
+ const numeric = findNumericTag(parent.nestedTags, tagName);
54
+ if (numeric) return Number(numeric.getValue());
55
+ const tag = findTag(parent.nestedTags, tagName);
56
+ if (!tag) return 0;
57
+ const value = tag.getValue();
58
+ if (typeof value === "number") return value;
59
+ if (typeof value === "bigint") return Number(value);
60
+ return 0;
61
+ }
62
+ function nestedString(parent, tagName) {
63
+ if (!parent.nestedTags) return "";
64
+ return stringValue(findTag(parent.nestedTags, tagName));
65
+ }
66
+ function nestedIp(parent, tagName) {
67
+ const ipAsNumber = nestedNumeric(parent, tagName);
68
+ if (ipAsNumber === 0) return "";
69
+ return formatIp(ipAsNumber);
70
+ }
71
+ var DownloadChunkDetailsResponseParser = class {
72
+ static fromPacket(packet) {
73
+ const result = {};
74
+ const partfileTags = packet.tags.filter((tag) => tag.name === 768);
75
+ for (const fileTag of partfileTags) {
76
+ const hash = bufferValue(nestedTag(fileTag, 798));
77
+ if (!hash) continue;
78
+ const fileHash = hash.toString("hex");
79
+ const sizeFull = nestedNumeric(fileTag, 771);
80
+ const partCount = sizeFull > 0 ? Math.ceil(sizeFull / PARTSIZE) : 0;
81
+ const partStatusBuf = bufferValue(nestedTag(fileTag, 786));
82
+ const gapStatusBuf = bufferValue(nestedTag(fileTag, 787));
83
+ const reqStatusBuf = bufferValue(nestedTag(fileTag, 788));
84
+ const availability = new Array(partCount).fill(0);
85
+ if (partStatusBuf && partStatusBuf.length > 0) {
86
+ const decodedAvailability = decodePartStatus(partStatusBuf);
87
+ for (let i = 0; i < Math.min(decodedAvailability.length, partCount); i++) availability[i] = decodedAvailability[i];
88
+ }
89
+ const chunks = new Array(partCount).fill(ChunkStatus.COMPLETE);
90
+ if (partCount > 0 && gapStatusBuf && gapStatusBuf.length > 0) {
91
+ const gapValues = decodeUint64Array(gapStatusBuf);
92
+ for (let i = 0; i + 1 < gapValues.length; i += 2) {
93
+ const gapStart = gapValues[i];
94
+ const gapEnd = gapValues[i + 1];
95
+ if (gapStart > sizeFull || gapEnd > sizeFull || gapStart >= gapEnd) continue;
96
+ const startPart = Math.floor(gapStart / PARTSIZE);
97
+ const endPart = Math.min(Math.floor(gapEnd / PARTSIZE) + 1, partCount);
98
+ for (let part = startPart; part < endPart; part++) {
99
+ const chunkStart = part * PARTSIZE;
100
+ if (gapStart < Math.min((part + 1) * 9728e3, sizeFull) && gapEnd > chunkStart) chunks[part] = availability[part] > 0 ? ChunkStatus.AVAILABLE : ChunkStatus.UNAVAILABLE;
101
+ }
102
+ }
103
+ }
104
+ if (partCount > 0 && reqStatusBuf && reqStatusBuf.length > 0) {
105
+ const reqValues = decodeUint64Array(reqStatusBuf);
106
+ for (let i = 0; i + 1 < reqValues.length; i += 2) {
107
+ const reqStart = reqValues[i];
108
+ const reqEnd = reqValues[i + 1];
109
+ if (reqStart > sizeFull || reqEnd > sizeFull || reqStart >= reqEnd) continue;
110
+ const startPart = Math.floor(reqStart / PARTSIZE);
111
+ const endPart = Math.min(Math.floor(reqEnd / PARTSIZE) + 1, partCount);
112
+ for (let part = startPart; part < endPart; part++) {
113
+ if (chunks[part] === ChunkStatus.COMPLETE) continue;
114
+ const chunkStart = part * PARTSIZE;
115
+ if (reqStart < Math.min((part + 1) * 9728e3, sizeFull) && reqEnd > chunkStart) chunks[part] = ChunkStatus.DOWNLOADING;
116
+ }
117
+ }
118
+ }
119
+ result[fileHash] = {
120
+ chunks,
121
+ availability,
122
+ partCount,
123
+ sizeFull
124
+ };
125
+ }
126
+ return result;
127
+ }
128
+ };
129
+ var DownloadSourceDetailsResponseParser = class {
130
+ static fromPacket(packet) {
131
+ const result = {};
132
+ const partfileTags = packet.tags.filter((tag) => tag.name === 768);
133
+ for (const fileTag of partfileTags) {
134
+ const hash = bufferValue(nestedTag(fileTag, 798));
135
+ if (!hash) continue;
136
+ const fileHash = hash.toString("hex");
137
+ const sourceNames = [];
138
+ const sources = [];
139
+ for (const nested of fileTag.nestedTags || []) {
140
+ if (nested.name !== 1536) continue;
141
+ sources.push({
142
+ clientName: nestedString(nested, 256) || "Unknown",
143
+ userHash: bufferValue(nestedTag(nested, 1539))?.toString("hex") || "",
144
+ software: nestedString(nested, 1537),
145
+ softwareVersion: nestedString(nested, 1557),
146
+ score: nestedNumeric(nested, 1538),
147
+ uploadSpeed: nestedNumeric(nested, 1549),
148
+ downloadSpeed: nestedNumeric(nested, 1550),
149
+ uploadState: nestedNumeric(nested, 1564),
150
+ downloadState: nestedNumeric(nested, 1548),
151
+ ip: nestedIp(nested, 1552),
152
+ port: nestedNumeric(nested, 1553),
153
+ remoteQueueRank: nestedNumeric(nested, 1562),
154
+ waitingPosition: nestedNumeric(nested, 1558),
155
+ identState: nestedNumeric(nested, 1559),
156
+ obfuscationStatus: nestedNumeric(nested, 1560),
157
+ remoteFilename: nestedString(nested, 1575),
158
+ availableParts: nestedNumeric(nested, 1578),
159
+ sourceFrom: nestedNumeric(nested, 1551)
160
+ });
161
+ }
162
+ const namesTag = nestedTag(fileTag, 789);
163
+ const countsTag = nestedTag(fileTag, 796);
164
+ const nameTags = namesTag?.nestedTags || [];
165
+ const countTags = countsTag?.nestedTags || [];
166
+ for (let i = 0; i < nameTags.length; i++) {
167
+ const name = stringValue(nameTags[i]);
168
+ if (!name) continue;
169
+ const rawCount = countTags[i]?.getValue();
170
+ const count = typeof rawCount === "number" ? rawCount : typeof rawCount === "bigint" ? Number(rawCount) : 1;
171
+ sourceNames.push({
172
+ name,
173
+ count
174
+ });
175
+ }
176
+ result[fileHash] = {
177
+ sources,
178
+ sourceNames
179
+ };
180
+ }
181
+ return result;
182
+ }
183
+ };
184
+ //#endregion
185
+ //#region src/response/DownloadQueueResponse.ts
186
+ var DownloadQueueResponseParser = class {
187
+ static fromPacket(packet) {
188
+ const files = [];
189
+ const chunkDetailsByHash = DownloadChunkDetailsResponseParser.fromPacket(packet);
190
+ const sourceDetailsByHash = DownloadSourceDetailsResponseParser.fromPacket(packet);
191
+ const partfileTags = packet.tags.filter((tag) => tag.name === 768);
192
+ for (const fileTag of partfileTags) {
193
+ const tags = fileTag.nestedTags || [];
194
+ const hashTag = findTag(tags, 798);
195
+ const fileNameTag = findTag(tags, 769);
196
+ let a4afSources = void 0;
197
+ const a4afSourcesTag = findTag(tags, 802);
198
+ if (a4afSourcesTag) {
199
+ a4afSources = [];
200
+ a4afSourcesTag.nestedTags = a4afSourcesTag.nestedTags || [];
201
+ for (const sourceTag of a4afSourcesTag.nestedTags) if (sourceTag.name === 15) a4afSources.push(sourceTag.getValue());
202
+ }
203
+ const file = {
204
+ fileHashHexString: hashTag ? hashTag.getValue().toString("hex") : void 0,
205
+ fileName: fileNameTag ? fileNameTag.getValue() : void 0,
206
+ filePath: findTag(tags, 1032)?.getValue(),
207
+ sizeFull: toOptionalNumber(findNumericTag(tags, 771)?.getLong()),
208
+ fileEd2kLink: findTag(tags, 782)?.getValue(),
209
+ partMetID: findNumericTag(tags, 770)?.getShort(),
210
+ sizeXfer: toOptionalNumber(findNumericTag(tags, 772)?.getLong()),
211
+ sizeDone: toOptionalNumber(findNumericTag(tags, 774)?.getLong()),
212
+ fileStatus: findNumericTag(tags, 776)?.getInt(),
213
+ stopped: toOptionalBool(findNumericTag(tags, 791)?.getInt()),
214
+ sourceCount: findNumericTag(tags, 778)?.getShort(),
215
+ sourceNotCurrCount: findNumericTag(tags, 780)?.getShort(),
216
+ sourceXferCount: findNumericTag(tags, 781)?.getShort(),
217
+ sourceCountA4AF: findNumericTag(tags, 779)?.getShort(),
218
+ speed: toOptionalNumber(findNumericTag(tags, 775)?.getLong()),
219
+ downPrio: findNumericTag(tags, 777)?.getInt(),
220
+ fileCat: toOptionalNumber(findNumericTag(tags, 783)?.getLong()),
221
+ lastSeenComplete: toOptionalNumber(findNumericTag(tags, 785)?.getLong()),
222
+ lastDateChanged: toOptionalNumber(findNumericTag(tags, 784)?.getLong()),
223
+ downloadActiveTime: findNumericTag(tags, 792)?.getInt(),
224
+ availablePartCount: findNumericTag(tags, 797)?.getShort(),
225
+ a4AFAuto: toOptionalBool(findNumericTag(tags, 801)?.getInt()),
226
+ hashingProgress: toOptionalBool(findNumericTag(tags, 800)?.getInt()),
227
+ getLostDueToCorruption: toOptionalNumber(findNumericTag(tags, 793)?.getLong()),
228
+ getGainDueToCompression: toOptionalNumber(findNumericTag(tags, 794)?.getLong()),
229
+ totalPacketsSavedDueToICH: findNumericTag(tags, 795)?.getInt(),
230
+ upPrio: findNumericTag(tags, 1035)?.getInt(),
231
+ getRequests: findNumericTag(tags, 1027)?.getShort(),
232
+ getAllRequests: findNumericTag(tags, 1028)?.getInt(),
233
+ getAccepts: findNumericTag(tags, 1029)?.getShort(),
234
+ getAllAccepts: findNumericTag(tags, 1030)?.getInt(),
235
+ getXferred: toOptionalNumber(findNumericTag(tags, 1025)?.getLong()),
236
+ getAllXferred: toOptionalNumber(findNumericTag(tags, 1026)?.getLong()),
237
+ getCompleteSourcesLow: findNumericTag(tags, 1033)?.getShort(),
238
+ getCompleteSourcesHigh: findNumericTag(tags, 1034)?.getShort(),
239
+ getCompleteSources: findNumericTag(tags, 1037)?.getShort(),
240
+ getOnQueue: findNumericTag(tags, 1036)?.getShort(),
241
+ getComment: findTag(tags, 1038)?.getValue(),
242
+ getRating: findNumericTag(tags, 1039)?.getInt(),
243
+ a4afSources
244
+ };
245
+ if (file.fileHashHexString) {
246
+ file.chunkInfo = chunkDetailsByHash[file.fileHashHexString];
247
+ const sourceDetails = sourceDetailsByHash[file.fileHashHexString];
248
+ if (sourceDetails) {
249
+ file.sources = sourceDetails.sources;
250
+ file.sourceNames = sourceDetails.sourceNames;
251
+ }
252
+ }
253
+ files.push(file);
254
+ }
255
+ return { files };
256
+ }
257
+ };
258
+ //#endregion
259
+ export { DownloadQueueResponseParser };
@@ -0,0 +1,16 @@
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";
4
+ //#region src/request/GetPreferencesRequest.ts
5
+ /**
6
+ * Preferences Request - Get preferences
7
+ */
8
+ var GetPreferencesRequest = class extends Request {
9
+ constructor(pref) {
10
+ super(63);
11
+ this.addTag(new UByteTag(4, 2));
12
+ this.addTag(new UIntTag(4096, pref));
13
+ }
14
+ };
15
+ //#endregion
16
+ export { GetPreferencesRequest };
@@ -0,0 +1,94 @@
1
+ import "./Codes-CjiW7Pdl.js";
2
+ import { f as findNumericTag, p as findTag } from "./Tag-CZF6BRMY.js";
3
+ //#region src/response/PreferencesDetailsResponse.ts
4
+ var PreferencesDetailsResponse = class {
5
+ preferences;
6
+ constructor(preferences) {
7
+ this.preferences = preferences;
8
+ }
9
+ };
10
+ function getNestedTag(parent, name) {
11
+ if (!parent?.nestedTags) return;
12
+ return findTag(parent.nestedTags, name);
13
+ }
14
+ function getNestedNumber(parent, name, fallback) {
15
+ if (!parent?.nestedTags) return fallback;
16
+ const numeric = findNumericTag(parent.nestedTags, name);
17
+ if (numeric) return Number(numeric.getValue());
18
+ const tag = findTag(parent.nestedTags, name);
19
+ if (!tag) return fallback;
20
+ const value = tag.getValue();
21
+ if (typeof value === "number") return value;
22
+ if (typeof value === "bigint") return Number(value);
23
+ return fallback;
24
+ }
25
+ function getNestedBool(parent, name, fallback) {
26
+ const tag = getNestedTag(parent, name);
27
+ if (!tag) return fallback;
28
+ const value = tag.getValue();
29
+ if (typeof value === "boolean") return value;
30
+ if (typeof value === "number") return value !== 0;
31
+ if (typeof value === "bigint") return value !== 0n;
32
+ if (Buffer.isBuffer(value)) return value.length === 0 || value.some((byte) => byte !== 0);
33
+ return true;
34
+ }
35
+ function getNestedString(parent, name, fallback) {
36
+ const tag = getNestedTag(parent, name);
37
+ if (!tag) return fallback;
38
+ const value = tag.getValue();
39
+ return typeof value === "string" ? value : fallback;
40
+ }
41
+ var PreferencesDetailsResponseParser = class {
42
+ static fromPacket(packet) {
43
+ const generalTag = findTag(packet.tags, 4608);
44
+ const connectionTag = findTag(packet.tags, 4864);
45
+ const serversTag = findTag(packet.tags, 5888);
46
+ const securityTag = findTag(packet.tags, 7168);
47
+ return new PreferencesDetailsResponse({
48
+ general: {
49
+ userNick: getNestedString(generalTag, 4609, ""),
50
+ checkNewVersion: getNestedBool(generalTag, 4612, false)
51
+ },
52
+ connection: {
53
+ uploadCapacity: getNestedNumber(connectionTag, 4866, 0),
54
+ downloadCapacity: getNestedNumber(connectionTag, 4865, 0),
55
+ maxUploadSpeed: getNestedNumber(connectionTag, 4868, 0),
56
+ maxDownloadSpeed: getNestedNumber(connectionTag, 4867, 0),
57
+ slotAllocation: getNestedNumber(connectionTag, 4869, 2),
58
+ tcpPort: getNestedNumber(connectionTag, 4870, 4662),
59
+ udpPort: getNestedNumber(connectionTag, 4871, 4672),
60
+ maxFileSources: getNestedNumber(connectionTag, 4873, 300),
61
+ maxConnections: getNestedNumber(connectionTag, 4874, 500),
62
+ autoconnect: getNestedBool(connectionTag, 4875, false),
63
+ reconnect: getNestedBool(connectionTag, 4876, false),
64
+ networkED2K: getNestedBool(connectionTag, 4877, true),
65
+ networkKademlia: getNestedBool(connectionTag, 4878, false)
66
+ },
67
+ servers: {
68
+ removeDead: getNestedBool(serversTag, 5889, true),
69
+ deadRetries: getNestedNumber(serversTag, 5890, 3),
70
+ useScoreSystem: getNestedBool(serversTag, 5895, true),
71
+ smartIdCheck: getNestedBool(serversTag, 5896, true),
72
+ updateUrl: getNestedString(serversTag, 5900, "")
73
+ },
74
+ security: {
75
+ canSeeShares: getNestedNumber(securityTag, 7169, 2),
76
+ ipFilterClients: getNestedBool(securityTag, 7170, true),
77
+ ipFilterServers: getNestedBool(securityTag, 7171, true),
78
+ ipFilterAutoUpdate: getNestedBool(securityTag, 7172, false),
79
+ ipFilterUpdateUrl: getNestedString(securityTag, 7173, ""),
80
+ ipFilterLevel: getNestedNumber(securityTag, 7174, 127),
81
+ filterLan: getNestedBool(securityTag, 7175, true),
82
+ useSecIdent: getNestedBool(securityTag, 7176, true),
83
+ obfuscationSupported: getNestedBool(securityTag, 7177, true),
84
+ obfuscationRequested: getNestedBool(securityTag, 7178, false),
85
+ obfuscationRequired: getNestedBool(securityTag, 7179, false)
86
+ }
87
+ });
88
+ }
89
+ static preferenceMaskForAllSections() {
90
+ return 2118;
91
+ }
92
+ };
93
+ //#endregion
94
+ export { PreferencesDetailsResponseParser };
@@ -0,0 +1,37 @@
1
+ import "./Codes-CjiW7Pdl.js";
2
+ import { f as findNumericTag, p as findTag } from "./Tag-CZF6BRMY.js";
3
+ //#region src/response/PreferencesResponse.ts
4
+ var PreferencesResponse = class {
5
+ categories;
6
+ constructor(categories) {
7
+ this.categories = categories;
8
+ }
9
+ };
10
+ var PreferencesResponseParser = class {
11
+ static fromPacket(packet) {
12
+ const categories = [];
13
+ const prefsCategoriesTag = findTag(packet.tags, 4352);
14
+ if (prefsCategoriesTag && prefsCategoriesTag.nestedTags) {
15
+ for (const categoryTag of prefsCategoriesTag.nestedTags) if (categoryTag.name === 4353) {
16
+ const nestedTags = categoryTag.nestedTags || [];
17
+ const idTag = categoryTag;
18
+ const nameTag = findTag(nestedTags, 4354);
19
+ const pathTag = findTag(nestedTags, 4355);
20
+ const commentTag = findTag(nestedTags, 4356);
21
+ const colorTag = findNumericTag(nestedTags, 4357);
22
+ const priorityTag = findNumericTag(nestedTags, 4358);
23
+ if (nameTag) categories.push({
24
+ id: idTag ? Number(idTag.getInt()) : 0,
25
+ name: nameTag.getValue() || "",
26
+ path: pathTag ? pathTag.getValue() : "",
27
+ comment: commentTag ? commentTag.getValue() : "",
28
+ color: colorTag ? Number(colorTag.getInt()) : 0,
29
+ priority: priorityTag ? Number(priorityTag.getInt()) : 0
30
+ });
31
+ }
32
+ }
33
+ return new PreferencesResponse(categories);
34
+ }
35
+ };
36
+ //#endregion
37
+ export { PreferencesResponseParser };
@@ -0,0 +1,13 @@
1
+ import { t as Request } from "./Request-C0UUuQIX.js";
2
+ import "./Codes-CjiW7Pdl.js";
3
+ //#region src/request/ReloadSharedFilesRequest.ts
4
+ /**
5
+ * Reload Shared Files Request - Reload shared files list
6
+ */
7
+ var ReloadSharedFilesRequest = class extends Request {
8
+ constructor() {
9
+ super(35);
10
+ }
11
+ };
12
+ //#endregion
13
+ export { ReloadSharedFilesRequest };
@@ -0,0 +1,158 @@
1
+ //#region src/ec/packet/Flags.ts
2
+ /**
3
+ * Packet flags for EC protocol
4
+ */
5
+ var Flags = class Flags {
6
+ static FLAG_ACCEPTS = 16;
7
+ static FLAG_ZLIB = 1;
8
+ static FLAG_UTF8_NUMBERS = 2;
9
+ static FLAG_ALWAYS_SET = 32;
10
+ flags;
11
+ constructor(flags) {
12
+ this.flags = flags ?? 0;
13
+ }
14
+ /**
15
+ * Create flags from buffer
16
+ */
17
+ static fromBuffer(buffer, offset = 0) {
18
+ return new Flags(buffer.readUInt32BE(offset));
19
+ }
20
+ /**
21
+ * Write flags to buffer
22
+ */
23
+ writeToBuffer(buffer, offset = 0) {
24
+ buffer.writeUInt32BE(this.flags, offset);
25
+ }
26
+ /**
27
+ * Check if UTF-8 number encoding is supported/accepted
28
+ */
29
+ isUtf8NumbersAccepted() {
30
+ return (this.flags & Flags.FLAG_ACCEPTS) > 0 && (this.flags & Flags.FLAG_UTF8_NUMBERS) > 0;
31
+ }
32
+ /**
33
+ * Check if ZLIB compression is supported/accepted
34
+ */
35
+ isZlibAccepted() {
36
+ return (this.flags & Flags.FLAG_ACCEPTS) > 0 && (this.flags & Flags.FLAG_ZLIB) > 0;
37
+ }
38
+ /**
39
+ * Check if UTF-8 number encoding is used
40
+ */
41
+ isUtf8Numbers() {
42
+ return (this.flags & Flags.FLAG_UTF8_NUMBERS) > 0;
43
+ }
44
+ /**
45
+ * Check if ZLIB compression is used
46
+ */
47
+ isZlib() {
48
+ return (this.flags & Flags.FLAG_ZLIB) > 0;
49
+ }
50
+ /**
51
+ * Create flags accepting UTF-8 numbers and ZLIB
52
+ */
53
+ static accept() {
54
+ return new Flags(Flags.FLAG_ACCEPTS | Flags.FLAG_UTF8_NUMBERS | Flags.FLAG_ZLIB | Flags.FLAG_ALWAYS_SET);
55
+ }
56
+ /**
57
+ * Create flags using UTF-8 numbers
58
+ */
59
+ static useUtf8Numbers() {
60
+ return new Flags(Flags.FLAG_UTF8_NUMBERS | Flags.FLAG_ALWAYS_SET);
61
+ }
62
+ /**
63
+ * Create flags without UTF-8 numbers (required for search)
64
+ */
65
+ static noUtf8() {
66
+ return new Flags(Flags.FLAG_ALWAYS_SET);
67
+ }
68
+ /**
69
+ * Create flags using ZLIB compression
70
+ */
71
+ static useZlib() {
72
+ return new Flags(Flags.FLAG_ZLIB | Flags.FLAG_ALWAYS_SET);
73
+ }
74
+ /**
75
+ * Get numeric value of flags
76
+ */
77
+ getValue() {
78
+ return this.flags;
79
+ }
80
+ };
81
+ //#endregion
82
+ //#region src/ec/packet/Packet.ts
83
+ var Packet = class Packet {
84
+ opCode;
85
+ flags;
86
+ tags;
87
+ static EC_CURRENT_PROTOCOL_VERSION = 516;
88
+ constructor(opCode, flags = new Flags(), tags = []) {
89
+ this.opCode = opCode;
90
+ this.flags = flags;
91
+ this.tags = tags;
92
+ }
93
+ /**
94
+ * Add a tag to the packet
95
+ */
96
+ addTag(tag) {
97
+ this.tags.push(tag);
98
+ return this;
99
+ }
100
+ /**
101
+ * Add multiple tags to the packet
102
+ */
103
+ addTags(tags) {
104
+ this.tags.push(...tags);
105
+ return this;
106
+ }
107
+ /**
108
+ * Get protocol version
109
+ */
110
+ static getProtocolVersion() {
111
+ return Packet.EC_CURRENT_PROTOCOL_VERSION;
112
+ }
113
+ /**
114
+ * Find a tag by name
115
+ */
116
+ findTag(tagName) {
117
+ return this.tags.find((tag) => tag.name === tagName);
118
+ }
119
+ /**
120
+ * Get all tags with a specific name
121
+ */
122
+ findAllTags(tagName) {
123
+ return this.tags.filter((tag) => tag.name === tagName);
124
+ }
125
+ /**
126
+ * Check if packet has a specific tag
127
+ */
128
+ hasTag(tagName) {
129
+ return this.findTag(tagName) !== void 0;
130
+ }
131
+ };
132
+ //#endregion
133
+ //#region src/request/Request.ts
134
+ /**
135
+ * Base Request class
136
+ */
137
+ var Request = class {
138
+ opCode;
139
+ tags = [];
140
+ constructor(opCode) {
141
+ this.opCode = opCode;
142
+ }
143
+ /**
144
+ * Add a tag to the request
145
+ */
146
+ addTag(tag) {
147
+ this.tags.push(tag);
148
+ }
149
+ /**
150
+ * Build the packet for this request
151
+ */
152
+ buildPacket() {
153
+ const flags = Flags.useUtf8Numbers();
154
+ return new Packet(this.opCode, flags, this.tags);
155
+ }
156
+ };
157
+ //#endregion
158
+ export { Packet as n, Flags as r, Request as t };
@@ -0,0 +1,15 @@
1
+ import "./Codes-CjiW7Pdl.js";
2
+ import { f as findNumericTag } from "./Tag-CZF6BRMY.js";
3
+ //#region src/response/SearchProgressResponse.ts
4
+ var SearchProgressResponse = class SearchProgressResponse {
5
+ progress;
6
+ constructor(progress) {
7
+ this.progress = progress;
8
+ }
9
+ static fromPacket(packet) {
10
+ const progressTag = findNumericTag(packet.tags, 1800);
11
+ return new SearchProgressResponse(progressTag ? Number(progressTag.getValue()) / 100 : 0);
12
+ }
13
+ };
14
+ //#endregion
15
+ export { SearchProgressResponse };
@@ -0,0 +1,55 @@
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";
4
+ import "./index.js";
5
+ //#region src/request/SearchRequest.ts
6
+ /**
7
+ * Search Request - Start a search
8
+ *
9
+ * In the EC protocol, search is structured as:
10
+ * - EC_TAG_SEARCH_TYPE (UByte) containing subtag:
11
+ * - EC_TAG_SEARCH_NAME (String) with the search query
12
+ * - Uses non-UTF8 flags (Flags.noUtf8())
13
+ */
14
+ var SearchRequest = class extends Request {
15
+ query;
16
+ searchType;
17
+ filters;
18
+ constructor(query, searchType = 0, filters) {
19
+ super(38);
20
+ this.query = query;
21
+ this.searchType = searchType;
22
+ this.filters = filters;
23
+ }
24
+ /**
25
+ * Override buildPacket to use non-UTF8 flags and correct tag structure
26
+ */
27
+ buildPacket() {
28
+ const flags = Flags.noUtf8();
29
+ const tags = this.buildTags();
30
+ return new Packet(this.opCode, flags, tags);
31
+ }
32
+ buildTags() {
33
+ const tags = [];
34
+ const searchTypeTag = new UByteTag(1793, this.convertSearchType(this.searchType), [new StringTag(1794, this.query)]);
35
+ tags.push(searchTypeTag);
36
+ if (this.filters) {
37
+ if (this.filters.minSize !== void 0) tags.push(new ULongTag(1795, BigInt(this.filters.minSize)));
38
+ if (this.filters.maxSize !== void 0) tags.push(new ULongTag(1796, BigInt(this.filters.maxSize)));
39
+ if (this.filters.fileType !== void 0) tags.push(new StringTag(1797, this.filters.fileType));
40
+ if (this.filters.extension !== void 0) tags.push(new StringTag(1798, this.filters.extension));
41
+ if (this.filters.availability !== void 0) tags.push(new UIntTag(1799, this.filters.availability));
42
+ }
43
+ return tags;
44
+ }
45
+ convertSearchType(searchType) {
46
+ switch (searchType) {
47
+ case 0: return 0;
48
+ case 1: return 1;
49
+ case 2: return 2;
50
+ case 3: return 3;
51
+ }
52
+ }
53
+ };
54
+ //#endregion
55
+ export { SearchRequest };
@@ -0,0 +1,13 @@
1
+ import { t as Request } from "./Request-C0UUuQIX.js";
2
+ import "./Codes-CjiW7Pdl.js";
3
+ //#region src/request/SearchResultsRequest.ts
4
+ /**
5
+ * Search Results Request - Get search results
6
+ */
7
+ var SearchResultsRequest = class extends Request {
8
+ constructor() {
9
+ super(40);
10
+ }
11
+ };
12
+ //#endregion
13
+ export { SearchResultsRequest };