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.
- package/README.md +4 -0
- package/dist/AddLinkRequest-D2IME4eb.js +15 -0
- package/dist/ClientQueueRequest-DFfCiNcz.js +15 -0
- package/dist/ClientQueueResponse-JTrBqrr1.js +63 -0
- package/dist/Codes-CjiW7Pdl.js +409 -0
- package/dist/CreateCategoryRequest-CRUMcPo5.js +22 -0
- package/dist/DeleteCategoryRequest-C8v9oGZ-.js +15 -0
- package/dist/DownloadCommandRequest-B3KV_bvm.js +29 -0
- package/dist/DownloadFileRequest-BjrroO3h.js +18 -0
- package/dist/DownloadQueueRequest-Dil5hl3D.js +15 -0
- package/dist/DownloadQueueResponse-DUam_zNf.js +259 -0
- package/dist/GetPreferencesRequest-DsxlghqT.js +16 -0
- package/dist/PreferencesDetailsResponse-DapscVQi.js +94 -0
- package/dist/PreferencesResponse-8n1STWUZ.js +37 -0
- package/dist/ReloadSharedFilesRequest-kt0Pxs8A.js +13 -0
- package/dist/Request-C0UUuQIX.js +158 -0
- package/dist/SearchProgressResponse-C1CdzKnz.js +15 -0
- package/dist/SearchRequest-DQnKfA5Z.js +55 -0
- package/dist/SearchResultsRequest-2ejFGQmQ.js +13 -0
- package/dist/SearchResultsResponse-DwmvbQop.js +29 -0
- package/dist/SearchStatusRequest-B_xr4-72.js +13 -0
- package/dist/SearchStopRequest-8hwXobty.js +13 -0
- package/dist/ServerConnectRequest-BhNpGiEJ.js +18 -0
- package/dist/ServerDisconnectRequest-BjCitLtU.js +13 -0
- package/dist/ServerListRequest-BWXLGJib.js +13 -0
- package/dist/ServerListResponse-BUJ7sz5p.js +50 -0
- package/dist/ServerUpdateFromUrlRequest-K8C_d0UQ.js +12 -0
- package/dist/SetFileCategoryRequest-VwroLBTV.js +15 -0
- package/dist/SetPreferencesRequest-KZ23VaBY.js +64 -0
- package/dist/SharedFilePriorityRequest-7BriqAcr.js +13 -0
- package/dist/SharedFilesRequest-B72XyRcA.js +15 -0
- package/dist/SharedFilesResponse-CkqvYd3N.js +39 -0
- package/dist/StatsRequest-CGGumOOx.js +15 -0
- package/dist/StatsResponse-DxQk686g.js +76 -0
- package/dist/Tag-CZF6BRMY.js +260 -0
- package/dist/UpdateCategoryRequest-CzKJa_rC.js +22 -0
- package/dist/UpdateRequest-g2ReOQ5m.js +15 -0
- package/dist/UpdateResponse-CGwVjn0Y.js +45 -0
- package/dist/download-details-OM0FJUhZ.js +10 -0
- package/dist/index.d.ts +1042 -933
- package/dist/index.js +1041 -3123
- package/dist/utils-DBnUQnZ-.js +24 -0
- package/package.json +5 -5
- 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 };
|