aqualink 2.6.1-fix3 → 2.6.2
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/build/structures/Aqua.js +140 -64
- package/build/structures/Node.js +41 -10
- package/build/structures/Player.js +16 -9
- package/build/structures/Track.js +2 -0
- package/package.json +2 -1
package/build/structures/Aqua.js
CHANGED
|
@@ -4,16 +4,17 @@ const Player = require("./Player");
|
|
|
4
4
|
const Track = require("./Track");
|
|
5
5
|
const { version: pkgVersion } = require("../../package.json");
|
|
6
6
|
const { EventEmitter } = require('tseep');
|
|
7
|
+
const fs = require('fs-extra');
|
|
7
8
|
|
|
8
9
|
const URL_REGEX = /^https?:\/\//;
|
|
9
10
|
const DEFAULT_OPTIONS = Object.freeze({
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
shouldDeleteMessage: false,
|
|
12
|
+
defaultSearchPlatform: 'ytsearch',
|
|
13
|
+
leaveOnEnd: true,
|
|
14
|
+
restVersion: 'v4',
|
|
15
|
+
plugins: [],
|
|
16
|
+
autoResume: false,
|
|
17
|
+
infiniteReconnects: false
|
|
17
18
|
});
|
|
18
19
|
const LEAST_USED_CACHE_TTL = 50;
|
|
19
20
|
|
|
@@ -32,9 +33,9 @@ class Aqua extends EventEmitter {
|
|
|
32
33
|
this.clientId = null;
|
|
33
34
|
this.initiated = false;
|
|
34
35
|
this.version = pkgVersion;
|
|
35
|
-
|
|
36
|
+
|
|
36
37
|
this.options = Object.assign({}, DEFAULT_OPTIONS, options);
|
|
37
|
-
|
|
38
|
+
|
|
38
39
|
const {
|
|
39
40
|
shouldDeleteMessage,
|
|
40
41
|
defaultSearchPlatform,
|
|
@@ -45,7 +46,7 @@ class Aqua extends EventEmitter {
|
|
|
45
46
|
infiniteReconnects,
|
|
46
47
|
send
|
|
47
48
|
} = this.options;
|
|
48
|
-
|
|
49
|
+
|
|
49
50
|
this.shouldDeleteMessage = shouldDeleteMessage;
|
|
50
51
|
this.defaultSearchPlatform = defaultSearchPlatform;
|
|
51
52
|
this.leaveOnEnd = leaveOnEnd;
|
|
@@ -53,9 +54,9 @@ class Aqua extends EventEmitter {
|
|
|
53
54
|
this.plugins = plugins;
|
|
54
55
|
this.autoResume = autoResume;
|
|
55
56
|
this.infiniteReconnects = infiniteReconnects;
|
|
56
|
-
|
|
57
|
+
|
|
57
58
|
this.send = send || this.defaultSendFunction.bind(this);
|
|
58
|
-
|
|
59
|
+
|
|
59
60
|
this._leastUsedCache = { nodes: [], timestamp: 0 };
|
|
60
61
|
}
|
|
61
62
|
|
|
@@ -69,14 +70,14 @@ class Aqua extends EventEmitter {
|
|
|
69
70
|
if (now - this._leastUsedCache.timestamp < LEAST_USED_CACHE_TTL) {
|
|
70
71
|
return this._leastUsedCache.nodes;
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
+
|
|
73
74
|
const connectedNodes = [];
|
|
74
75
|
for (const node of this.nodeMap.values()) {
|
|
75
76
|
if (node.connected) connectedNodes.push(node);
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
+
|
|
78
79
|
connectedNodes.sort((a, b) => a.rest.calls - b.rest.calls);
|
|
79
|
-
|
|
80
|
+
|
|
80
81
|
this._leastUsedCache = { nodes: connectedNodes, timestamp: now };
|
|
81
82
|
return connectedNodes;
|
|
82
83
|
}
|
|
@@ -84,35 +85,35 @@ class Aqua extends EventEmitter {
|
|
|
84
85
|
async init(clientId) {
|
|
85
86
|
if (this.initiated) return this;
|
|
86
87
|
this.clientId = clientId;
|
|
87
|
-
|
|
88
|
+
|
|
88
89
|
try {
|
|
89
90
|
const nodePromises = [];
|
|
90
91
|
for (const node of this.nodes) {
|
|
91
92
|
nodePromises.push(this.createNode(node));
|
|
92
93
|
}
|
|
93
94
|
await Promise.all(nodePromises);
|
|
94
|
-
|
|
95
|
+
|
|
95
96
|
for (const plugin of this.plugins) {
|
|
96
97
|
plugin.load(this);
|
|
97
98
|
}
|
|
98
|
-
|
|
99
|
+
|
|
99
100
|
this.initiated = true;
|
|
100
101
|
} catch (error) {
|
|
101
102
|
this.initiated = false;
|
|
102
103
|
throw error;
|
|
103
104
|
}
|
|
104
|
-
|
|
105
|
+
|
|
105
106
|
return this;
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
async createNode(options) {
|
|
109
110
|
const nodeId = options.name || options.host;
|
|
110
111
|
this.destroyNode(nodeId);
|
|
111
|
-
|
|
112
|
+
|
|
112
113
|
const node = new Node(this, options, this.options);
|
|
113
114
|
this.nodeMap.set(nodeId, node);
|
|
114
115
|
this._leastUsedCache.timestamp = 0;
|
|
115
|
-
|
|
116
|
+
|
|
116
117
|
try {
|
|
117
118
|
await node.connect();
|
|
118
119
|
this.emit("nodeCreate", node);
|
|
@@ -127,7 +128,7 @@ class Aqua extends EventEmitter {
|
|
|
127
128
|
destroyNode(identifier) {
|
|
128
129
|
const node = this.nodeMap.get(identifier);
|
|
129
130
|
if (!node) return;
|
|
130
|
-
|
|
131
|
+
|
|
131
132
|
node.destroy();
|
|
132
133
|
this.nodeMap.delete(identifier);
|
|
133
134
|
this._leastUsedCache.timestamp = 0;
|
|
@@ -137,14 +138,14 @@ class Aqua extends EventEmitter {
|
|
|
137
138
|
updateVoiceState({ d, t }) {
|
|
138
139
|
const player = this.players.get(d.guild_id);
|
|
139
140
|
if (!player) return;
|
|
140
|
-
|
|
141
|
+
|
|
141
142
|
if (t === "VOICE_SERVER_UPDATE" || (t === "VOICE_STATE_UPDATE" && d.user_id === this.clientId)) {
|
|
142
143
|
if (t === "VOICE_SERVER_UPDATE") {
|
|
143
144
|
player.connection?.setServerUpdate?.(d);
|
|
144
145
|
} else {
|
|
145
146
|
player.connection?.setStateUpdate?.(d);
|
|
146
147
|
}
|
|
147
|
-
|
|
148
|
+
|
|
148
149
|
if (d.channel_id === null) {
|
|
149
150
|
this.cleanupPlayer(player);
|
|
150
151
|
}
|
|
@@ -153,23 +154,23 @@ class Aqua extends EventEmitter {
|
|
|
153
154
|
|
|
154
155
|
fetchRegion(region) {
|
|
155
156
|
if (!region) return this.leastUsedNodes;
|
|
156
|
-
|
|
157
|
+
|
|
157
158
|
const lowerRegion = region.toLowerCase();
|
|
158
159
|
const regionNodes = [];
|
|
159
|
-
|
|
160
|
+
|
|
160
161
|
for (const node of this.nodeMap.values()) {
|
|
161
162
|
if (node.connected && node.regions?.includes(lowerRegion)) {
|
|
162
163
|
regionNodes.push(node);
|
|
163
164
|
}
|
|
164
165
|
}
|
|
165
|
-
|
|
166
|
+
|
|
166
167
|
const loadCache = new Map();
|
|
167
168
|
regionNodes.sort((a, b) => {
|
|
168
169
|
if (!loadCache.has(a)) loadCache.set(a, this.calculateLoad(a));
|
|
169
170
|
if (!loadCache.has(b)) loadCache.set(b, this.calculateLoad(b));
|
|
170
171
|
return loadCache.get(a) - loadCache.get(b);
|
|
171
172
|
});
|
|
172
|
-
|
|
173
|
+
|
|
173
174
|
return regionNodes;
|
|
174
175
|
}
|
|
175
176
|
|
|
@@ -182,27 +183,28 @@ class Aqua extends EventEmitter {
|
|
|
182
183
|
|
|
183
184
|
createConnection(options) {
|
|
184
185
|
if (!this.initiated) throw new Error("Aqua must be initialized before this operation");
|
|
185
|
-
|
|
186
|
+
|
|
186
187
|
const existingPlayer = this.players.get(options.guildId);
|
|
187
188
|
if (existingPlayer && existingPlayer.voiceChannel) return existingPlayer;
|
|
188
|
-
|
|
189
|
+
|
|
189
190
|
const availableNodes = options.region ? this.fetchRegion(options.region) : this.leastUsedNodes;
|
|
190
191
|
const node = availableNodes[0];
|
|
191
192
|
if (!node) throw new Error("No nodes are available");
|
|
192
|
-
|
|
193
|
+
|
|
193
194
|
return this.createPlayer(node, options);
|
|
194
195
|
}
|
|
195
196
|
|
|
196
197
|
createPlayer(node, options) {
|
|
197
198
|
this.destroyPlayer(options.guildId);
|
|
198
|
-
|
|
199
|
+
|
|
199
200
|
const player = new Player(this, node, options);
|
|
200
201
|
this.players.set(options.guildId, player);
|
|
201
|
-
|
|
202
|
+
|
|
202
203
|
player.on("destroy", () => {
|
|
203
204
|
this.players.delete(options.guildId);
|
|
205
|
+
this.emit("playerDestroy", player);
|
|
204
206
|
});
|
|
205
|
-
|
|
207
|
+
|
|
206
208
|
player.connect(options);
|
|
207
209
|
this.emit("playerCreate", player);
|
|
208
210
|
return player;
|
|
@@ -211,7 +213,7 @@ class Aqua extends EventEmitter {
|
|
|
211
213
|
async destroyPlayer(guildId) {
|
|
212
214
|
const player = this.players.get(guildId);
|
|
213
215
|
if (!player) return;
|
|
214
|
-
|
|
216
|
+
|
|
215
217
|
try {
|
|
216
218
|
await player.clearData();
|
|
217
219
|
player.removeAllListeners();
|
|
@@ -224,18 +226,18 @@ class Aqua extends EventEmitter {
|
|
|
224
226
|
|
|
225
227
|
async resolve({ query, source = this.defaultSearchPlatform, requester, nodes }) {
|
|
226
228
|
if (!this.initiated) throw new Error("Aqua must be initialized before this operation");
|
|
227
|
-
|
|
229
|
+
|
|
228
230
|
const requestNode = this.getRequestNode(nodes);
|
|
229
231
|
const formattedQuery = URL_REGEX.test(query) ? query : `${source}:${query}`;
|
|
230
|
-
|
|
232
|
+
|
|
231
233
|
try {
|
|
232
234
|
const endpoint = `/v4/loadtracks?identifier=${encodeURIComponent(formattedQuery)}`;
|
|
233
235
|
const response = await requestNode.rest.makeRequest("GET", endpoint);
|
|
234
|
-
|
|
236
|
+
|
|
235
237
|
if (["empty", "NO_MATCHES"].includes(response.loadType)) {
|
|
236
238
|
return await this.handleNoMatches(query);
|
|
237
239
|
}
|
|
238
|
-
|
|
240
|
+
|
|
239
241
|
return this.constructResponse(response, requester, requestNode);
|
|
240
242
|
} catch (error) {
|
|
241
243
|
if (error.name === "AbortError") {
|
|
@@ -244,19 +246,19 @@ class Aqua extends EventEmitter {
|
|
|
244
246
|
throw new Error(`Failed to resolve track: ${error.message}`);
|
|
245
247
|
}
|
|
246
248
|
}
|
|
247
|
-
|
|
249
|
+
|
|
248
250
|
getRequestNode(nodes) {
|
|
249
251
|
if (!nodes) return this.leastUsedNodes[0];
|
|
250
|
-
|
|
252
|
+
|
|
251
253
|
if (nodes instanceof Node) return nodes;
|
|
252
254
|
if (typeof nodes === "string") {
|
|
253
255
|
const mappedNode = this.nodeMap.get(nodes);
|
|
254
256
|
return mappedNode || this.leastUsedNodes[0];
|
|
255
257
|
}
|
|
256
|
-
|
|
258
|
+
|
|
257
259
|
throw new TypeError(`'nodes' must be a string or Node instance, received: ${typeof nodes}`);
|
|
258
260
|
}
|
|
259
|
-
|
|
261
|
+
|
|
260
262
|
async handleNoMatches(query) {
|
|
261
263
|
return {
|
|
262
264
|
loadType: "empty",
|
|
@@ -266,8 +268,8 @@ class Aqua extends EventEmitter {
|
|
|
266
268
|
tracks: []
|
|
267
269
|
};
|
|
268
270
|
}
|
|
269
|
-
|
|
270
|
-
constructResponse(response, requester, requestNode) {
|
|
271
|
+
|
|
272
|
+
async constructResponse(response, requester, requestNode) {
|
|
271
273
|
const baseResponse = {
|
|
272
274
|
loadType: response.loadType,
|
|
273
275
|
exception: null,
|
|
@@ -275,28 +277,29 @@ class Aqua extends EventEmitter {
|
|
|
275
277
|
pluginInfo: response.pluginInfo ?? {},
|
|
276
278
|
tracks: []
|
|
277
279
|
};
|
|
278
|
-
|
|
280
|
+
|
|
279
281
|
if (response.loadType === "error" || response.loadType === "LOAD_FAILED") {
|
|
280
282
|
baseResponse.exception = response.data ?? response.exception;
|
|
281
283
|
return baseResponse;
|
|
282
284
|
}
|
|
283
|
-
|
|
285
|
+
|
|
284
286
|
const trackFactory = (trackData) => new Track(trackData, requester, requestNode);
|
|
285
|
-
|
|
287
|
+
|
|
286
288
|
switch (response.loadType) {
|
|
287
289
|
case "track":
|
|
288
290
|
if (response.data) {
|
|
289
291
|
baseResponse.tracks.push(trackFactory(response.data));
|
|
290
292
|
}
|
|
291
293
|
break;
|
|
292
|
-
|
|
293
294
|
case "playlist": {
|
|
294
295
|
const info = response.data?.info;
|
|
295
296
|
if (info) {
|
|
296
|
-
|
|
297
|
+
const playlistInfo = {
|
|
297
298
|
name: info.name ?? info.title,
|
|
299
|
+
thumbnail: response.data.pluginInfo?.artworkUrl ?? (response.data.tracks?.[0]?.info?.artworkUrl || null),
|
|
298
300
|
...info
|
|
299
301
|
};
|
|
302
|
+
baseResponse.playlistInfo = playlistInfo;
|
|
300
303
|
}
|
|
301
304
|
|
|
302
305
|
const tracks = response.data?.tracks;
|
|
@@ -322,7 +325,7 @@ class Aqua extends EventEmitter {
|
|
|
322
325
|
break;
|
|
323
326
|
}
|
|
324
327
|
}
|
|
325
|
-
|
|
328
|
+
|
|
326
329
|
return baseResponse;
|
|
327
330
|
}
|
|
328
331
|
|
|
@@ -334,7 +337,7 @@ class Aqua extends EventEmitter {
|
|
|
334
337
|
|
|
335
338
|
async search(query, requester, source = this.defaultSearchPlatform) {
|
|
336
339
|
if (!query || !requester) return null;
|
|
337
|
-
|
|
340
|
+
|
|
338
341
|
try {
|
|
339
342
|
const { tracks } = await this.resolve({ query, source, requester });
|
|
340
343
|
return tracks || null;
|
|
@@ -344,21 +347,94 @@ class Aqua extends EventEmitter {
|
|
|
344
347
|
}
|
|
345
348
|
}
|
|
346
349
|
|
|
347
|
-
async
|
|
348
|
-
|
|
349
|
-
|
|
350
|
+
async savePlayer(filePath = "./AquaPlayers.json") {
|
|
351
|
+
const data = Array.from(this.players.values()).map(player => ({
|
|
352
|
+
guildId: player.guildId,
|
|
353
|
+
textChannel: player.textChannel,
|
|
354
|
+
voiceChannel: player.voiceChannel,
|
|
355
|
+
track: player.current ? {
|
|
356
|
+
identifier: player.current.identifier,
|
|
357
|
+
author: player.current.author,
|
|
358
|
+
title: player.current.title,
|
|
359
|
+
uri: player.current.uri,
|
|
360
|
+
sourceName: player.current.sourceName,
|
|
361
|
+
artworkUrl: player.current.artworkUrl,
|
|
362
|
+
duration: player.current.duration,
|
|
363
|
+
position: player.position,
|
|
364
|
+
} : null,
|
|
365
|
+
requester: player.requester || player.current?.requester,
|
|
366
|
+
volume: player.volume,
|
|
367
|
+
paused: player.paused
|
|
368
|
+
}));
|
|
369
|
+
console.log(`Saving ${data.length} players to ${filePath}`);
|
|
370
|
+
await fs.writeJSON(filePath, data, { spaces: 2 });
|
|
371
|
+
this.emit("debug", "Aqua", `Saved players to ${filePath}`);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
async waitForFirstNode() {
|
|
375
|
+
if (this.leastUsedNodes.length > 0) return;
|
|
376
|
+
return new Promise(resolve => {
|
|
377
|
+
const check = () => {
|
|
378
|
+
if (this.leastUsedNodes.length > 0) {
|
|
379
|
+
resolve();
|
|
380
|
+
} else {
|
|
381
|
+
setTimeout(check, 100);
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
check();
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
async loadPlayers(filePath = "./AquaPlayers.json") {
|
|
389
|
+
if (!fs.existsSync(filePath)) {
|
|
390
|
+
this.emit("debug", "Aqua", `No player data found at ${filePath}`);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
350
393
|
try {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
394
|
+
await this.waitForFirstNode();
|
|
395
|
+
const data = await fs.readJSON(filePath);
|
|
396
|
+
for (const playerData of data) {
|
|
397
|
+
const { guildId, textChannel, voiceChannel, track, volume, paused, requester } = playerData;
|
|
398
|
+
let player = this.players.get(guildId);
|
|
399
|
+
|
|
400
|
+
if (!player) {
|
|
401
|
+
player = await this.createConnection({
|
|
402
|
+
guildId: guildId,
|
|
403
|
+
textChannel: textChannel,
|
|
404
|
+
voiceChannel: voiceChannel,
|
|
405
|
+
defaultVolume: volume || 65,
|
|
406
|
+
deaf: true
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (track && player) {
|
|
411
|
+
const resolved = await this.resolve({ query: track.uri, requester });
|
|
412
|
+
if (resolved.tracks && resolved.tracks.length > 0) {
|
|
413
|
+
player.queue.add(resolved.tracks[0]);
|
|
414
|
+
player.position = track.position || 0;
|
|
415
|
+
} else {
|
|
416
|
+
this.emit("debug", "Aqua", `Could not resolve track for guild ${guildId}: ${track.uri}`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (player) {
|
|
421
|
+
player.paused = paused || false;
|
|
422
|
+
if (!player.playing && !player.paused && player.queue.size > 0) {
|
|
423
|
+
player.play();
|
|
424
|
+
}
|
|
357
425
|
}
|
|
358
426
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
427
|
+
this.emit("debug", "Aqua", `Loaded players from ${filePath}`);
|
|
428
|
+
} catch (error) {
|
|
429
|
+
console.error(`Failed to load players from ${filePath}:`, error);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
async cleanupPlayer(player) {
|
|
434
|
+
if (!player) return;
|
|
435
|
+
|
|
436
|
+
try {
|
|
437
|
+
await player.destroy();
|
|
362
438
|
} catch (error) {
|
|
363
439
|
console.error(`Error during player cleanup: ${error.message}`);
|
|
364
440
|
}
|
package/build/structures/Node.js
CHANGED
|
@@ -96,7 +96,7 @@ class Node {
|
|
|
96
96
|
this.aqua.emit("nodeConnected", this);
|
|
97
97
|
|
|
98
98
|
if (this.autoResume && this.sessionId) {
|
|
99
|
-
await this.
|
|
99
|
+
await this.aqua.loadPlayers();
|
|
100
100
|
}
|
|
101
101
|
} catch (err) {
|
|
102
102
|
this.info = null;
|
|
@@ -245,13 +245,33 @@ class Node {
|
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
async getStats() {
|
|
248
|
-
|
|
248
|
+
|
|
249
|
+
if (this.connected && this.stats) {
|
|
249
250
|
return this.stats;
|
|
250
251
|
}
|
|
251
252
|
|
|
252
253
|
try {
|
|
253
254
|
const newStats = await this.rest.getStats();
|
|
254
|
-
|
|
255
|
+
if (newStats && this.stats) {
|
|
256
|
+
this.stats.players = newStats.players ?? this.stats.players;
|
|
257
|
+
this.stats.playingPlayers = newStats.playingPlayers ?? this.stats.playingPlayers;
|
|
258
|
+
this.stats.uptime = newStats.uptime ?? this.stats.uptime;
|
|
259
|
+
this.stats.ping = newStats.ping ?? this.stats.ping;
|
|
260
|
+
|
|
261
|
+
if (newStats.memory) {
|
|
262
|
+
Object.assign(this.stats.memory, newStats.memory);
|
|
263
|
+
this._calculateMemoryPercentages();
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (newStats.cpu) {
|
|
267
|
+
Object.assign(this.stats.cpu, newStats.cpu);
|
|
268
|
+
this._calculateCpuPercentages();
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (newStats.frameStats) {
|
|
272
|
+
Object.assign(this.stats.frameStats, newStats.frameStats);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
255
275
|
return this.stats;
|
|
256
276
|
} catch (err) {
|
|
257
277
|
this.emitError(`Failed to fetch node stats: ${err.message}`);
|
|
@@ -269,13 +289,12 @@ class Node {
|
|
|
269
289
|
|
|
270
290
|
if (payload.memory) {
|
|
271
291
|
Object.assign(this.stats.memory, payload.memory);
|
|
272
|
-
this.
|
|
273
|
-
this.stats.memory.usedPercentage = (this.stats.memory.used / this.stats.memory.allocated) * 100;
|
|
292
|
+
this._calculateMemoryPercentages();
|
|
274
293
|
}
|
|
275
294
|
|
|
276
295
|
if (payload.cpu) {
|
|
277
296
|
Object.assign(this.stats.cpu, payload.cpu);
|
|
278
|
-
this.
|
|
297
|
+
this._calculateCpuPercentages();
|
|
279
298
|
}
|
|
280
299
|
|
|
281
300
|
if (payload.frameStats) {
|
|
@@ -283,6 +302,21 @@ class Node {
|
|
|
283
302
|
}
|
|
284
303
|
}
|
|
285
304
|
|
|
305
|
+
_calculateMemoryPercentages() {
|
|
306
|
+
const { memory } = this.stats;
|
|
307
|
+
if (memory.allocated > 0) {
|
|
308
|
+
memory.freePercentage = (memory.free / memory.allocated) * 100;
|
|
309
|
+
memory.usedPercentage = (memory.used / memory.allocated) * 100;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
_calculateCpuPercentages() {
|
|
314
|
+
const { cpu } = this.stats;
|
|
315
|
+
if (cpu.cores > 0) {
|
|
316
|
+
cpu.lavalinkLoadPercentage = (cpu.lavalinkLoad / cpu.cores) * 100;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
286
320
|
_handleReadyOp(payload) {
|
|
287
321
|
if (!payload.sessionId) {
|
|
288
322
|
this.emitError("Ready payload missing sessionId");
|
|
@@ -297,10 +331,7 @@ class Node {
|
|
|
297
331
|
|
|
298
332
|
async resumePlayers() {
|
|
299
333
|
try {
|
|
300
|
-
await this.
|
|
301
|
-
resuming: true,
|
|
302
|
-
timeout: this.resumeTimeout
|
|
303
|
-
});
|
|
334
|
+
await this.aqua.loadPlayers();
|
|
304
335
|
|
|
305
336
|
this.aqua.emit("debug", this.name, "Session resumed successfully");
|
|
306
337
|
} catch (err) {
|
|
@@ -62,6 +62,7 @@ class Player extends EventEmitter {
|
|
|
62
62
|
this.position = packet.state.position;
|
|
63
63
|
this.connected = packet.state.connected;
|
|
64
64
|
this.ping = packet.state.ping;
|
|
65
|
+
this.timestamp = packet.state.timestamp;
|
|
65
66
|
|
|
66
67
|
this.aqua.emit("playerUpdate", this, packet);
|
|
67
68
|
});
|
|
@@ -184,18 +185,18 @@ class Player extends EventEmitter {
|
|
|
184
185
|
return this.batchUpdatePlayer({ track: { encoded: this.current.track } }, true);
|
|
185
186
|
}
|
|
186
187
|
|
|
187
|
-
connect(
|
|
188
|
+
connect(options = this) {
|
|
189
|
+
const { guildId, voiceChannel, deaf = true, mute = false } = options;
|
|
188
190
|
this.deaf = deaf;
|
|
189
191
|
this.mute = mute;
|
|
190
|
-
|
|
191
|
-
guild_id:
|
|
192
|
-
channel_id:
|
|
192
|
+
this.send({
|
|
193
|
+
guild_id: guildId,
|
|
194
|
+
channel_id: voiceChannel,
|
|
193
195
|
self_deaf: deaf,
|
|
194
|
-
self_mute: mute
|
|
195
|
-
};
|
|
196
|
-
this.send(payload);
|
|
196
|
+
self_mute: mute,
|
|
197
|
+
});
|
|
197
198
|
this.connected = true;
|
|
198
|
-
this.aqua.emit("debug",
|
|
199
|
+
this.aqua.emit("debug", guildId, `Player connected to voice channel: ${voiceChannel}.`);
|
|
199
200
|
return this;
|
|
200
201
|
}
|
|
201
202
|
|
|
@@ -288,7 +289,13 @@ class Player extends EventEmitter {
|
|
|
288
289
|
if (!channel?.length) throw new TypeError("Channel must be a non-empty string.");
|
|
289
290
|
if (this.connected && channel === this.voiceChannel) throw new ReferenceError(`Player already connected to ${channel}.`);
|
|
290
291
|
this.voiceChannel = channel;
|
|
291
|
-
this.connect({
|
|
292
|
+
this.connect({
|
|
293
|
+
deaf: this.deaf,
|
|
294
|
+
guildId: this.guildId,
|
|
295
|
+
voiceChannel: this.voiceChannel,
|
|
296
|
+
textChannel: this.textChannel,
|
|
297
|
+
mute: this.mute,
|
|
298
|
+
});
|
|
292
299
|
return this;
|
|
293
300
|
}
|
|
294
301
|
|
|
@@ -10,6 +10,7 @@ class Track {
|
|
|
10
10
|
this.identifier = info.identifier || '';
|
|
11
11
|
this.isSeekable = Boolean(info.isSeekable);
|
|
12
12
|
this.author = info.author || '';
|
|
13
|
+
this.position = info.position || 0;
|
|
13
14
|
this.length = info.length || 0;
|
|
14
15
|
this.duration = info.length || 0;
|
|
15
16
|
this.isStream = Boolean(info.isStream);
|
|
@@ -29,6 +30,7 @@ class Track {
|
|
|
29
30
|
return {
|
|
30
31
|
identifier: this.identifier,
|
|
31
32
|
isSeekable: this.isSeekable,
|
|
33
|
+
position: this.position,
|
|
32
34
|
author: this.author,
|
|
33
35
|
length: this.length,
|
|
34
36
|
isStream: this.isStream,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aqualink",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.2",
|
|
4
4
|
"description": "An Lavalink client, focused in pure performance and features",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"ws": "^8.18.2",
|
|
45
|
+
"fs-extra": "^11.3.0",
|
|
45
46
|
"tseep": "^1.3.1"
|
|
46
47
|
},
|
|
47
48
|
"maintainers": [
|