aqualink 2.17.1 → 2.17.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/README.md +7 -5
- package/build/index.d.ts +24 -4
- package/build/structures/AqualinkEvents.js +4 -2
- package/build/structures/Player.js +52 -5
- package/build/structures/Rest.js +43 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -180,16 +180,18 @@ const aqua = new Aqua(client, nodes, {
|
|
|
180
180
|
|
|
181
181
|
client.aqua = aqua;
|
|
182
182
|
|
|
183
|
-
client.once(Events.
|
|
183
|
+
client.once(Events.ClientReady, () => {
|
|
184
184
|
client.aqua.init(client.user.id);
|
|
185
185
|
console.log(`Logged in as ${client.user.tag}`);
|
|
186
186
|
});
|
|
187
187
|
|
|
188
|
-
client.on(Events.Raw, (d) => {
|
|
189
|
-
if (
|
|
190
|
-
|
|
188
|
+
client.on(Events.Raw, (d, t) => {
|
|
189
|
+
if (d.t === "VOICE_SERVER_UPDATE" || d.t === "VOICE_STATE_UPDATE") {
|
|
190
|
+
return client.aqua.updateVoiceState(d, t);
|
|
191
|
+
}
|
|
191
192
|
});
|
|
192
193
|
|
|
194
|
+
|
|
193
195
|
client.on(Events.MessageCreate, async (message) => {
|
|
194
196
|
if (message.author.bot || !message.content.startsWith("!play")) return;
|
|
195
197
|
|
|
@@ -446,4 +448,4 @@ Join our thriving community of developers and bot creators!
|
|
|
446
448
|
|
|
447
449
|
<sub>Built with 💙 by the Aqualink Team</sub>
|
|
448
450
|
|
|
449
|
-
</div>
|
|
451
|
+
</div>
|
package/build/index.d.ts
CHANGED
|
@@ -38,8 +38,7 @@ declare module "aqualink" {
|
|
|
38
38
|
_rebuildLocks: Set<string>;
|
|
39
39
|
_leastUsedNodesCache: Node[] | null;
|
|
40
40
|
_leastUsedNodesCacheTime: number;
|
|
41
|
-
_nodeLoadCache: Map<string, number>;
|
|
42
|
-
_nodeLoadCacheTime: Map<string, number>;
|
|
41
|
+
_nodeLoadCache: Map<string, {load: number; time: number}>;
|
|
43
42
|
_cleanupTimer: NodeJS.Timer | null;
|
|
44
43
|
_onNodeConnect?: (node: Node) => void;
|
|
45
44
|
_onNodeDisconnect?: (node: Node) => void;
|
|
@@ -126,6 +125,7 @@ declare module "aqualink" {
|
|
|
126
125
|
infiniteReconnects: boolean;
|
|
127
126
|
connected: boolean;
|
|
128
127
|
info: NodeInfo | null;
|
|
128
|
+
isNodelink: boolean;
|
|
129
129
|
ws: any | null; // WebSocket
|
|
130
130
|
reconnectAttempted: number;
|
|
131
131
|
reconnectTimeoutId: NodeJS.Timeout | null;
|
|
@@ -198,6 +198,8 @@ declare module "aqualink" {
|
|
|
198
198
|
mute: boolean;
|
|
199
199
|
autoplayRetries: number;
|
|
200
200
|
reconnectionRetries: number;
|
|
201
|
+
_resuming: boolean;
|
|
202
|
+
_reconnecting: boolean;
|
|
201
203
|
previousIdentifiers: Set<string>;
|
|
202
204
|
self_deaf: boolean;
|
|
203
205
|
self_mute: boolean;
|
|
@@ -242,6 +244,11 @@ declare module "aqualink" {
|
|
|
242
244
|
setAutoplay(enabled: boolean): Player;
|
|
243
245
|
updatePlayer(data: any): Promise<any>;
|
|
244
246
|
cleanup(): Promise<void>;
|
|
247
|
+
getActiveMixer(guildId: string): Promise<any[]>;
|
|
248
|
+
updateMixerVolume(guildId: string, mix: string, volume: number): Promise<any>;
|
|
249
|
+
removeMixer(guildId: string, mix: string): Promise<any>;
|
|
250
|
+
addMixer(guildId: string, options: MixerOptions): Promise<any>;
|
|
251
|
+
getLoadLyrics(encodedTrack: string): Promise<LyricsResponse | null>;
|
|
245
252
|
|
|
246
253
|
// Data Methods
|
|
247
254
|
set(key: string, value: any): void;
|
|
@@ -276,7 +283,7 @@ declare module "aqualink" {
|
|
|
276
283
|
}
|
|
277
284
|
|
|
278
285
|
export class Track {
|
|
279
|
-
constructor(data?: TrackData, requester?: any,
|
|
286
|
+
constructor(data?: TrackData, requester?: any, node?: Node);
|
|
280
287
|
|
|
281
288
|
// Properties
|
|
282
289
|
identifier: string;
|
|
@@ -326,6 +333,7 @@ declare module "aqualink" {
|
|
|
326
333
|
baseUrl: string;
|
|
327
334
|
defaultHeaders: Record<string, string>;
|
|
328
335
|
agent: any; // HTTP/HTTPS Agent
|
|
336
|
+
useHttp2: boolean;
|
|
329
337
|
|
|
330
338
|
// Core Methods
|
|
331
339
|
setSessionId(sessionId: string): void;
|
|
@@ -347,6 +355,11 @@ declare module "aqualink" {
|
|
|
347
355
|
getRoutePlannerStatus(): Promise<any>;
|
|
348
356
|
freeRoutePlannerAddress(address: string): Promise<any>;
|
|
349
357
|
freeAllRoutePlannerAddresses(): Promise<any>;
|
|
358
|
+
addMixer(guildId: string, options: MixerOptions): Promise<any>;
|
|
359
|
+
getActiveMixer(guildId: string): Promise<any[]>;
|
|
360
|
+
updateMixerVolume(guildId: string, mix: string, volume: number): Promise<any>;
|
|
361
|
+
removeMixer(guildId: string, mix: string): Promise<any>;
|
|
362
|
+
getLoadLyrics(encodedTrack: string): Promise<LyricsResponse>;
|
|
350
363
|
destroy(): void;
|
|
351
364
|
}
|
|
352
365
|
|
|
@@ -452,7 +465,7 @@ declare module "aqualink" {
|
|
|
452
465
|
updateSequence(seq: number): void;
|
|
453
466
|
destroy(): void;
|
|
454
467
|
attemptResume(): Promise<boolean>;
|
|
455
|
-
resendVoiceUpdate(
|
|
468
|
+
resendVoiceUpdate(): boolean;
|
|
456
469
|
|
|
457
470
|
// Internal Methods
|
|
458
471
|
_extractRegion(endpoint: string): string | null;
|
|
@@ -736,6 +749,13 @@ declare module "aqualink" {
|
|
|
736
749
|
smoothing?: number;
|
|
737
750
|
}
|
|
738
751
|
|
|
752
|
+
export interface MixerOptions {
|
|
753
|
+
identifier?: string;
|
|
754
|
+
encoded?: string;
|
|
755
|
+
userData?: any;
|
|
756
|
+
volume?: number;
|
|
757
|
+
}
|
|
758
|
+
|
|
739
759
|
// Voice Update Interfaces
|
|
740
760
|
export interface VoiceStateUpdate {
|
|
741
761
|
d: {
|
|
@@ -37,7 +37,9 @@ const AqualinkEvents = {
|
|
|
37
37
|
PlayerConnected: 'playerConnected',
|
|
38
38
|
PlayerDestroyed: 'playerDestroy',
|
|
39
39
|
PlayerMigrated: 'playerMigrated',
|
|
40
|
-
PauseEvent: 'pauseEvent'
|
|
40
|
+
PauseEvent: 'pauseEvent',
|
|
41
|
+
MixStarted: 'mixStarted',
|
|
42
|
+
MixEnded: 'mixEnded'
|
|
41
43
|
};
|
|
42
44
|
|
|
43
|
-
module.exports = { AqualinkEvents };
|
|
45
|
+
module.exports = { AqualinkEvents };
|
|
@@ -22,10 +22,12 @@ const EVENT_HANDLERS = Object.freeze({
|
|
|
22
22
|
FiltersChangedEvent: 'filtersChanged',
|
|
23
23
|
SeekEvent: 'seekEvent',
|
|
24
24
|
PlayerCreatedEvent: 'playerCreated',
|
|
25
|
-
|
|
25
|
+
PauseEvent: 'pauseEvent',
|
|
26
26
|
PlayerConnectedEvent: 'playerConnected',
|
|
27
27
|
PlayerDestroyedEvent: 'playerDestroyed',
|
|
28
|
-
LyricsNotFoundEvent: 'lyricsNotFound'
|
|
28
|
+
LyricsNotFoundEvent: 'lyricsNotFound',
|
|
29
|
+
MixStartedEvent: 'mixStarted',
|
|
30
|
+
MixEndedEvent: 'mixEnded'
|
|
29
31
|
})
|
|
30
32
|
|
|
31
33
|
const WATCHDOG_INTERVAL = 15000
|
|
@@ -460,11 +462,54 @@ class Player extends EventEmitter {
|
|
|
460
462
|
return this
|
|
461
463
|
}
|
|
462
464
|
|
|
465
|
+
async getActiveMixer(guildId) {
|
|
466
|
+
if (this.destroyed) return null
|
|
467
|
+
return await this.nodes.rest.getActiveMixer(guildId)
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
async updateMixerVolume(guildId, mix, volume) {
|
|
471
|
+
if (this.destroyed) return null
|
|
472
|
+
return await this.nodes.rest.updateMixerVolume(guildId, mix, volume)
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
async removeMixer(guildId, mix) {
|
|
476
|
+
if (this.destroyed) return null
|
|
477
|
+
return await this.nodes.rest.removeMixer(guildId, mix)
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
async addMixer(guildId, options) {
|
|
481
|
+
if (this.destroyed) return null
|
|
482
|
+
|
|
483
|
+
if (options.identifier && !options.encoded) {
|
|
484
|
+
try {
|
|
485
|
+
const resolved = await this.aqua.resolve({
|
|
486
|
+
query: options.identifier,
|
|
487
|
+
requester: options.requester || this.current?.requester
|
|
488
|
+
})
|
|
489
|
+
|
|
490
|
+
if (resolved?.tracks?.[0]) {
|
|
491
|
+
const track = resolved.tracks[0]
|
|
492
|
+
options = {
|
|
493
|
+
...options,
|
|
494
|
+
encoded: track.track || track.encoded,
|
|
495
|
+
userData: options.userData
|
|
496
|
+
}
|
|
497
|
+
} else {
|
|
498
|
+
throw new Error('Failed to resolve track identifier')
|
|
499
|
+
}
|
|
500
|
+
} catch (error) {
|
|
501
|
+
throw new Error(`Failed to resolve track: ${error.message}`)
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
return await this.nodes.rest.addMixer(guildId, options)
|
|
506
|
+
}
|
|
507
|
+
|
|
463
508
|
stop() {
|
|
464
509
|
if (this.destroyed || !this.playing) return this
|
|
465
510
|
this.playing = this.paused = false
|
|
466
511
|
this.position = 0
|
|
467
|
-
this.batchUpdatePlayer({ guildId: this.guildId, track: { encoded: null } }, true).catch(() => { })
|
|
512
|
+
this.batchUpdatePlayer({ guildId: this.guildId, track: { encoded: null, paused: this.paused } }, true).catch(() => { })
|
|
468
513
|
return this
|
|
469
514
|
}
|
|
470
515
|
|
|
@@ -684,7 +729,9 @@ class Player extends EventEmitter {
|
|
|
684
729
|
playerCreated(p, t, payload) { _functions.emitIfActive(this, AqualinkEvents.PlayerCreated, payload) }
|
|
685
730
|
playerConnected(p, t, payload) { _functions.emitIfActive(this, AqualinkEvents.PlayerConnected, payload) }
|
|
686
731
|
playerDestroyed(p, t, payload) { _functions.emitIfActive(this, AqualinkEvents.PlayerDestroyed, payload) }
|
|
687
|
-
|
|
732
|
+
pauseEvent(p, t, payload) { _functions.emitIfActive(this, AqualinkEvents.PauseEvent, payload) }
|
|
733
|
+
mixStarted(p, t, payload) { _functions.emitIfActive(this, AqualinkEvents.MixStarted, t, payload) }
|
|
734
|
+
mixEnded(p, t, payload) { _functions.emitIfActive(this, AqualinkEvents.MixEnded, t, payload) }
|
|
688
735
|
|
|
689
736
|
async _attemptVoiceResume() {
|
|
690
737
|
if (!this.connection?.sessionId) throw new Error('No session')
|
|
@@ -845,4 +892,4 @@ class Player extends EventEmitter {
|
|
|
845
892
|
}
|
|
846
893
|
}
|
|
847
894
|
|
|
848
|
-
module.exports = Player
|
|
895
|
+
module.exports = Player
|
package/build/structures/Rest.js
CHANGED
|
@@ -317,7 +317,7 @@ class Rest {
|
|
|
317
317
|
|
|
318
318
|
_closeH2() {
|
|
319
319
|
if (this._h2Timer) { clearTimeout(this._h2Timer); this._h2Timer = null }
|
|
320
|
-
if (this._h2) { try { this._h2.close() } catch {} this._h2 = null }
|
|
320
|
+
if (this._h2) { try { this._h2.close() } catch { } this._h2 = null }
|
|
321
321
|
}
|
|
322
322
|
|
|
323
323
|
_h2Request(method, path, headers, payload) {
|
|
@@ -480,14 +480,14 @@ class Rest {
|
|
|
480
480
|
try {
|
|
481
481
|
const lyrics = await this.makeRequest('GET', `${this._getSessionPath()}/players/${guildId}/track/lyrics?skipTrackSource=${skip}`)
|
|
482
482
|
if (this._validLyrics(lyrics)) return lyrics
|
|
483
|
-
} catch {}
|
|
483
|
+
} catch { }
|
|
484
484
|
}
|
|
485
485
|
|
|
486
486
|
if (hasEncoded) {
|
|
487
487
|
try {
|
|
488
488
|
const lyrics = await this.makeRequest('GET', `${this._endpoints.lyrics}?track=${encodeURIComponent(encoded)}&skipTrackSource=${skip}`)
|
|
489
489
|
if (this._validLyrics(lyrics)) return lyrics
|
|
490
|
-
} catch {}
|
|
490
|
+
} catch { }
|
|
491
491
|
}
|
|
492
492
|
|
|
493
493
|
if (title) {
|
|
@@ -495,7 +495,7 @@ class Rest {
|
|
|
495
495
|
try {
|
|
496
496
|
const lyrics = await this.makeRequest('GET', `${this._endpoints.lyrics}/search?query=${encodeURIComponent(query)}`)
|
|
497
497
|
if (this._validLyrics(lyrics)) return lyrics
|
|
498
|
-
} catch {}
|
|
498
|
+
} catch { }
|
|
499
499
|
}
|
|
500
500
|
|
|
501
501
|
return null
|
|
@@ -524,6 +524,44 @@ class Rest {
|
|
|
524
524
|
}
|
|
525
525
|
}
|
|
526
526
|
|
|
527
|
+
async addMixer(guildId, options) {
|
|
528
|
+
if (!this.node.isNodelink) throw new Error('Mixer endpoints are only available on Nodelink nodes')
|
|
529
|
+
if (!options?.encoded && !options?.identifier) throw new Error('You must provide either encoded or identifier')
|
|
530
|
+
|
|
531
|
+
const track = {}
|
|
532
|
+
if (options.encoded) track.encoded = options.encoded
|
|
533
|
+
if (options.identifier) track.identifier = options.identifier
|
|
534
|
+
if (options.userData) track.userData = options.userData
|
|
535
|
+
|
|
536
|
+
const payload = {
|
|
537
|
+
track,
|
|
538
|
+
volume: options.volume !== undefined ? options.volume : 0.8
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
return await this.makeRequest("POST", `/v4/sessions/${this.sessionId}/players/${guildId}/mix`, payload)
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
async getActiveMixer(guildId) {
|
|
545
|
+
if (!this.node.isNodelink) throw new Error('Mixer endpoints are only available on Nodelink nodes')
|
|
546
|
+
const response = await this.makeRequest("GET", `/v4/sessions/${this.sessionId}/players/${guildId}/mix`)
|
|
547
|
+
return response?.mixes || []
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
async updateMixerVolume(guildId, mix, volume) {
|
|
551
|
+
if (!this.node.isNodelink) throw new Error('Mixer endpoints are only available on Nodelink nodes')
|
|
552
|
+
if (!guildId || !mix || typeof volume !== 'number') throw new Error('You forget to set the guild_id, mix or volume options')
|
|
553
|
+
|
|
554
|
+
return await this.makeRequest("PATCH", `/v4/sessions/${this.sessionId}/players/${guildId}/mix/${mix}`, { volume })
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
async removeMixer(guildId, mix) {
|
|
558
|
+
if (!this.node.isNodelink) throw new Error('Mixer endpoints are only available on Nodelink nodes')
|
|
559
|
+
if (!guildId || !mix) throw new Error('You forget to set the guild_id and/or mix options')
|
|
560
|
+
|
|
561
|
+
return await this.makeRequest("DELETE", `/v4/sessions/${this.sessionId}/players/${guildId}/mix/${mix}`)
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
|
|
527
565
|
destroy() {
|
|
528
566
|
if (this.agent) { this.agent.destroy(); this.agent = null }
|
|
529
567
|
this._closeH2()
|
|
@@ -532,4 +570,4 @@ class Rest {
|
|
|
532
570
|
}
|
|
533
571
|
}
|
|
534
572
|
|
|
535
|
-
module.exports = Rest
|
|
573
|
+
module.exports = Rest
|