aqualink 2.9.13 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -58
- package/build/handlers/autoplay.js +39 -44
- package/build/structures/Aqua.js +437 -468
- package/build/structures/Connection.js +91 -88
- package/build/structures/Filters.js +178 -167
- package/build/structures/Node.js +99 -96
- package/build/structures/Player.js +275 -296
- package/build/structures/Rest.js +265 -146
- package/build/structures/Track.js +51 -126
- package/package.json +17 -2
package/build/structures/Rest.js
CHANGED
|
@@ -1,281 +1,400 @@
|
|
|
1
|
-
const { Agent: HttpsAgent, request: httpsRequest } = require('node:https')
|
|
2
|
-
const { Agent: HttpAgent, request: httpRequest } = require('node:http')
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
1
|
+
const { Agent: HttpsAgent, request: httpsRequest } = require('node:https');
|
|
2
|
+
const { Agent: HttpAgent, request: httpRequest } = require('node:http');
|
|
3
|
+
const { URL } = require('node:url');
|
|
4
|
+
|
|
5
|
+
const JSON_TYPE_REGEX = /^application\/json/i;
|
|
6
|
+
const MAX_RESPONSE_SIZE = 10485760; // 10MB
|
|
7
|
+
const BASE64_REGEX = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
8
|
+
const METADATA_PHRASES = [
|
|
9
|
+
'Official Visualizer',
|
|
10
|
+
'Official',
|
|
11
|
+
'Official Video',
|
|
12
|
+
'Music Video',
|
|
13
|
+
'Live',
|
|
14
|
+
'Lyrics',
|
|
15
|
+
'Audio',
|
|
16
|
+
'HD',
|
|
17
|
+
'Remix',
|
|
18
|
+
'Cover',
|
|
19
|
+
'Acoustic',
|
|
20
|
+
'Instrumental',
|
|
21
|
+
'Karaoke',
|
|
22
|
+
'ft',
|
|
23
|
+
'feat'
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const METADATA_REGEX = new RegExp(
|
|
27
|
+
`\\s*[[({](${METADATA_PHRASES.map(phrase =>
|
|
28
|
+
phrase.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
29
|
+
).join('|')})[^\\]}()]*[\\])}]`,
|
|
30
|
+
'gi'
|
|
31
|
+
);
|
|
32
|
+
const BRACKETS_REGEX = /\s*(\[[^\]]*\]|\([^\)]*\)|\{[^\}]*\})\s*/g;
|
|
33
|
+
|
|
34
|
+
const ERRORS = {
|
|
35
|
+
NO_SESSION: 'Session ID required',
|
|
36
|
+
INVALID_TRACK: 'Invalid encoded track format',
|
|
37
|
+
INVALID_TRACKS: 'One or more tracks have invalid format',
|
|
38
|
+
RESPONSE_TOO_LARGE: 'Response too large',
|
|
39
|
+
JSON_PARSE: 'JSON parse error: ',
|
|
40
|
+
REQUEST_TIMEOUT: 'Request timeout: '
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const cleanTitle = title => title
|
|
44
|
+
.replace(METADATA_REGEX, '')
|
|
45
|
+
.replace(BRACKETS_REGEX, '')
|
|
46
|
+
.trim();
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
const isValidBase64 = str => {
|
|
50
|
+
if (typeof str !== 'string' || str.length === 0) return false;
|
|
51
|
+
const len = str.length;
|
|
52
|
+
|
|
53
|
+
if (len % 4 !== 0) return false;
|
|
54
|
+
|
|
55
|
+
if (!BASE64_REGEX.test(str)) return false;
|
|
56
|
+
|
|
57
|
+
let pad = 0;
|
|
58
|
+
for (let i = len - 1; i >= 0; i--) {
|
|
59
|
+
if (str[i] !== '=') break;
|
|
60
|
+
pad++;
|
|
61
|
+
}
|
|
62
|
+
return pad <= 2;
|
|
63
|
+
};
|
|
7
64
|
|
|
8
65
|
class Rest {
|
|
9
66
|
constructor(aqua, { secure = false, host, port, sessionId = null, password, timeout = 15000 }) {
|
|
10
|
-
this.aqua = aqua
|
|
11
|
-
this.sessionId = sessionId
|
|
12
|
-
this.version = 'v4'
|
|
13
|
-
this.
|
|
14
|
-
this.
|
|
67
|
+
this.aqua = aqua;
|
|
68
|
+
this.sessionId = sessionId;
|
|
69
|
+
this.version = 'v4';
|
|
70
|
+
this.secure = secure;
|
|
71
|
+
this.timeout = timeout;
|
|
72
|
+
|
|
73
|
+
this.baseUrl = new URL(`${secure ? 'https' : 'http'}://${host}:${port}`);
|
|
74
|
+
this.headers = Object.freeze({
|
|
15
75
|
'Content-Type': 'application/json',
|
|
16
|
-
'Authorization': password
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
this.secure = secure
|
|
76
|
+
'Authorization': password,
|
|
77
|
+
'Accept': 'application/json'
|
|
78
|
+
});
|
|
20
79
|
|
|
21
|
-
const AgentClass = secure ? HttpsAgent : HttpAgent
|
|
80
|
+
const AgentClass = secure ? HttpsAgent : HttpAgent;
|
|
22
81
|
this.agent = new AgentClass({
|
|
23
82
|
keepAlive: true,
|
|
24
|
-
maxSockets:
|
|
25
|
-
maxFreeSockets:
|
|
83
|
+
maxSockets: 10,
|
|
84
|
+
maxFreeSockets: 5,
|
|
26
85
|
timeout: this.timeout,
|
|
27
|
-
freeSocketTimeout:
|
|
28
|
-
keepAliveMsecs: 1000
|
|
29
|
-
|
|
86
|
+
freeSocketTimeout: 30000,
|
|
87
|
+
keepAliveMsecs: 1000,
|
|
88
|
+
scheduling: 'fifo'
|
|
89
|
+
});
|
|
30
90
|
|
|
31
|
-
this.request = secure ? httpsRequest : httpRequest
|
|
91
|
+
this.request = secure ? httpsRequest : httpRequest;
|
|
32
92
|
}
|
|
33
93
|
|
|
34
94
|
setSessionId(sessionId) {
|
|
35
|
-
this.sessionId = sessionId
|
|
95
|
+
this.sessionId = sessionId;
|
|
36
96
|
}
|
|
37
97
|
|
|
38
98
|
_validateSessionId() {
|
|
39
|
-
if (!this.sessionId)
|
|
40
|
-
throw new Error('Session ID required')
|
|
41
|
-
}
|
|
99
|
+
if (!this.sessionId) throw new Error(ERRORS.NO_SESSION);
|
|
42
100
|
}
|
|
43
101
|
|
|
44
102
|
_isValidEncodedTrack(track) {
|
|
45
|
-
return
|
|
103
|
+
return isValidBase64(track);
|
|
46
104
|
}
|
|
47
105
|
|
|
48
106
|
async makeRequest(method, endpoint, body = null) {
|
|
49
|
-
const url =
|
|
107
|
+
const url = new URL(endpoint, this.baseUrl);
|
|
50
108
|
const options = {
|
|
51
109
|
method,
|
|
52
110
|
headers: this.headers,
|
|
53
111
|
timeout: this.timeout,
|
|
54
112
|
agent: this.agent
|
|
55
|
-
}
|
|
113
|
+
};
|
|
56
114
|
|
|
57
115
|
return new Promise((resolve, reject) => {
|
|
58
116
|
const req = this.request(url, options, res => {
|
|
59
|
-
if (res.statusCode === 204)
|
|
117
|
+
if (res.statusCode === 204) {
|
|
118
|
+
res.resume();
|
|
119
|
+
return resolve(null);
|
|
120
|
+
}
|
|
60
121
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
122
|
+
const chunks = [];
|
|
123
|
+
let totalLength = 0;
|
|
124
|
+
const isJson = JSON_TYPE_REGEX.test(res.headers['content-type'] || '');
|
|
64
125
|
|
|
65
126
|
res.on('data', chunk => {
|
|
66
|
-
totalLength += chunk.length
|
|
127
|
+
totalLength += chunk.length;
|
|
67
128
|
if (totalLength > MAX_RESPONSE_SIZE) {
|
|
68
|
-
req.destroy()
|
|
69
|
-
return reject(new Error(
|
|
129
|
+
req.destroy();
|
|
130
|
+
return reject(new Error(ERRORS.RESPONSE_TOO_LARGE));
|
|
70
131
|
}
|
|
71
|
-
chunks.push(chunk)
|
|
72
|
-
})
|
|
132
|
+
chunks.push(chunk);
|
|
133
|
+
});
|
|
73
134
|
|
|
74
135
|
res.on('end', () => {
|
|
75
|
-
if (totalLength === 0) return resolve(null)
|
|
76
|
-
|
|
77
|
-
const data = Buffer.concat(chunks
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
} else {
|
|
86
|
-
resolve(data)
|
|
136
|
+
if (totalLength === 0) return resolve(null);
|
|
137
|
+
|
|
138
|
+
const data = Buffer.concat(chunks);
|
|
139
|
+
if (!isJson) return resolve(data.toString());
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
resolve(JSON.parse(data));
|
|
143
|
+
} catch (err) {
|
|
144
|
+
reject(new Error(`${ERRORS.JSON_PARSE}${err.message}`));
|
|
87
145
|
}
|
|
88
|
-
})
|
|
89
|
-
})
|
|
146
|
+
});
|
|
90
147
|
|
|
91
|
-
|
|
148
|
+
res.on('error', reject);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
req.on('error', reject);
|
|
92
152
|
req.on('timeout', () => {
|
|
93
|
-
req.destroy()
|
|
94
|
-
reject(new Error(
|
|
95
|
-
})
|
|
153
|
+
req.destroy();
|
|
154
|
+
reject(new Error(`${ERRORS.REQUEST_TIMEOUT}${this.timeout}ms`));
|
|
155
|
+
});
|
|
96
156
|
|
|
97
157
|
if (body) {
|
|
98
|
-
const payload = typeof body === 'string' ? body : JSON.stringify(body)
|
|
99
|
-
req.
|
|
158
|
+
const payload = typeof body === 'string' ? body : JSON.stringify(body);
|
|
159
|
+
req.setHeader('Content-Length', Buffer.byteLength(payload));
|
|
160
|
+
req.write(payload);
|
|
100
161
|
}
|
|
101
162
|
|
|
102
|
-
req.end()
|
|
103
|
-
})
|
|
163
|
+
req.end();
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async batchRequests(requests) {
|
|
168
|
+
return Promise.all(requests.map(({ method, endpoint, body }) =>
|
|
169
|
+
this.makeRequest(method, endpoint, body)
|
|
170
|
+
));
|
|
104
171
|
}
|
|
105
172
|
|
|
106
|
-
// Lavalink player operations
|
|
107
173
|
async updatePlayer({ guildId, data }) {
|
|
108
|
-
this._validateSessionId()
|
|
109
|
-
return this.makeRequest(
|
|
174
|
+
this._validateSessionId();
|
|
175
|
+
return this.makeRequest(
|
|
176
|
+
'PATCH',
|
|
177
|
+
`/${this.version}/sessions/${this.sessionId}/players/${guildId}?noReplace=false`,
|
|
178
|
+
data
|
|
179
|
+
);
|
|
110
180
|
}
|
|
111
181
|
|
|
112
182
|
async getPlayer(guildId) {
|
|
113
|
-
this._validateSessionId()
|
|
114
|
-
return this.makeRequest(
|
|
183
|
+
this._validateSessionId();
|
|
184
|
+
return this.makeRequest(
|
|
185
|
+
'GET',
|
|
186
|
+
`/${this.version}/sessions/${this.sessionId}/players/${guildId}`
|
|
187
|
+
);
|
|
115
188
|
}
|
|
116
189
|
|
|
117
190
|
async getPlayers() {
|
|
118
|
-
this._validateSessionId()
|
|
119
|
-
return this.makeRequest(
|
|
191
|
+
this._validateSessionId();
|
|
192
|
+
return this.makeRequest(
|
|
193
|
+
'GET',
|
|
194
|
+
`/${this.version}/sessions/${this.sessionId}/players`
|
|
195
|
+
);
|
|
120
196
|
}
|
|
121
197
|
|
|
122
198
|
async destroyPlayer(guildId) {
|
|
123
|
-
this._validateSessionId()
|
|
124
|
-
return this.makeRequest(
|
|
199
|
+
this._validateSessionId();
|
|
200
|
+
return this.makeRequest(
|
|
201
|
+
'DELETE',
|
|
202
|
+
`/${this.version}/sessions/${this.sessionId}/players/${guildId}`
|
|
203
|
+
);
|
|
125
204
|
}
|
|
126
205
|
|
|
127
|
-
// Track operations
|
|
128
206
|
async loadTracks(identifier) {
|
|
129
|
-
|
|
207
|
+
const params = new URLSearchParams({ identifier });
|
|
208
|
+
return this.makeRequest(
|
|
209
|
+
'GET',
|
|
210
|
+
`/${this.version}/loadtracks?${params}`
|
|
211
|
+
);
|
|
130
212
|
}
|
|
131
213
|
|
|
132
214
|
async decodeTrack(encodedTrack) {
|
|
133
215
|
if (!this._isValidEncodedTrack(encodedTrack)) {
|
|
134
|
-
throw new Error(
|
|
216
|
+
throw new Error(ERRORS.INVALID_TRACK);
|
|
135
217
|
}
|
|
136
|
-
|
|
218
|
+
const params = new URLSearchParams({ encodedTrack });
|
|
219
|
+
return this.makeRequest('GET', `/${this.version}/decodetrack?${params}`);
|
|
137
220
|
}
|
|
138
221
|
|
|
139
222
|
async decodeTracks(encodedTracks) {
|
|
140
|
-
const
|
|
141
|
-
if (
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
return this.makeRequest('POST', `/${this.version}/decodetracks`, validTracks)
|
|
223
|
+
const invalid = encodedTracks.find(t => !this._isValidEncodedTrack(t));
|
|
224
|
+
if (invalid) throw new Error(ERRORS.INVALID_TRACKS);
|
|
225
|
+
|
|
226
|
+
return this.makeRequest('POST', `/${this.version}/decodetracks`, encodedTracks);
|
|
145
227
|
}
|
|
146
228
|
|
|
147
|
-
// Server info
|
|
229
|
+
// Server info and management
|
|
148
230
|
async getStats() {
|
|
149
|
-
return this.makeRequest('GET', `/${this.version}/stats`)
|
|
231
|
+
return this.makeRequest('GET', `/${this.version}/stats`);
|
|
150
232
|
}
|
|
151
233
|
|
|
152
234
|
async getInfo() {
|
|
153
|
-
return this.makeRequest('GET', `/${this.version}/info`)
|
|
235
|
+
return this.makeRequest('GET', `/${this.version}/info`);
|
|
154
236
|
}
|
|
155
237
|
|
|
156
238
|
async getVersion() {
|
|
157
|
-
return this.makeRequest('GET', `/${this.version}/version`)
|
|
239
|
+
return this.makeRequest('GET', `/${this.version}/version`);
|
|
158
240
|
}
|
|
159
241
|
|
|
160
|
-
// Route planner
|
|
161
242
|
async getRoutePlannerStatus() {
|
|
162
|
-
return this.makeRequest('GET', `/${this.version}/routeplanner/status`)
|
|
243
|
+
return this.makeRequest('GET', `/${this.version}/routeplanner/status`);
|
|
163
244
|
}
|
|
164
245
|
|
|
165
246
|
async freeRoutePlannerAddress(address) {
|
|
166
|
-
return this.makeRequest(
|
|
247
|
+
return this.makeRequest(
|
|
248
|
+
'POST',
|
|
249
|
+
`/${this.version}/routeplanner/free/address`,
|
|
250
|
+
{ address }
|
|
251
|
+
);
|
|
167
252
|
}
|
|
168
253
|
|
|
169
254
|
async freeAllRoutePlannerAddresses() {
|
|
170
|
-
return this.makeRequest(
|
|
255
|
+
return this.makeRequest(
|
|
256
|
+
'POST',
|
|
257
|
+
`/${this.version}/routeplanner/free/all`
|
|
258
|
+
);
|
|
171
259
|
}
|
|
172
260
|
|
|
173
|
-
//
|
|
261
|
+
// Optimized lyrics handling
|
|
174
262
|
async getLyrics({ track, skipTrackSource = false }) {
|
|
175
263
|
if (!this._isValidTrackForLyrics(track)) {
|
|
176
|
-
this.aqua.emit('error', '[Aqua/Lyrics] Invalid track object')
|
|
177
|
-
return null
|
|
264
|
+
this.aqua.emit('error', '[Aqua/Lyrics] Invalid track object');
|
|
265
|
+
return null;
|
|
178
266
|
}
|
|
179
267
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
for (const strategy of strategies) {
|
|
268
|
+
// Priority 1: Current player track
|
|
269
|
+
if (track.guild_id) {
|
|
183
270
|
try {
|
|
184
|
-
const
|
|
185
|
-
if (
|
|
186
|
-
return result
|
|
187
|
-
}
|
|
271
|
+
const lyrics = await this._getPlayerTrackLyrics(track.guild_id, skipTrackSource);
|
|
272
|
+
if (this._isValidLyrics(lyrics)) return lyrics;
|
|
188
273
|
} catch (error) {
|
|
189
|
-
this.aqua.emit('debug', `[Aqua/Lyrics]
|
|
274
|
+
this.aqua.emit('debug', `[Aqua/Lyrics] Player track failed: ${error.message}`);
|
|
190
275
|
}
|
|
191
276
|
}
|
|
192
277
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
_getLyricsStrategies(track, skipTrackSource) {
|
|
202
|
-
const strategies = []
|
|
203
|
-
|
|
204
|
-
if (track.guild_id) {
|
|
205
|
-
strategies.push(() => this._getPlayerLyrics(track, skipTrackSource))
|
|
278
|
+
// Priority 2: Encoded track
|
|
279
|
+
if (track.encoded && this._isValidEncodedTrack(track.encoded)) {
|
|
280
|
+
try {
|
|
281
|
+
const lyrics = await this._getEncodedTrackLyrics(track.encoded, skipTrackSource);
|
|
282
|
+
if (this._isValidLyrics(lyrics)) return lyrics;
|
|
283
|
+
} catch (error) {
|
|
284
|
+
this.aqua.emit('debug', `[Aqua/Lyrics] Encoded track failed: ${error.message}`);
|
|
285
|
+
}
|
|
206
286
|
}
|
|
207
287
|
|
|
208
|
-
|
|
209
|
-
|
|
288
|
+
// Priority 3: Title/author search
|
|
289
|
+
if (track.info?.title) {
|
|
290
|
+
try {
|
|
291
|
+
const query = this._buildSearchQuery(track.info);
|
|
292
|
+
const lyrics = await this._searchLyrics(query);
|
|
293
|
+
if (this._isValidLyrics(lyrics)) return lyrics;
|
|
294
|
+
} catch (error) {
|
|
295
|
+
this.aqua.emit('debug', `[Aqua/Lyrics] Search failed: ${error.message}`);
|
|
296
|
+
}
|
|
210
297
|
}
|
|
211
298
|
|
|
212
|
-
|
|
213
|
-
|
|
299
|
+
// Priority 4: Cleaned title search
|
|
300
|
+
if (track.info?.title && track.info?.author) {
|
|
301
|
+
try {
|
|
302
|
+
const cleanedTitle = cleanTitle(track.info.title);
|
|
303
|
+
const query = `${cleanedTitle} ${track.info.author}`;
|
|
304
|
+
const lyrics = await this._searchLyrics(query);
|
|
305
|
+
if (this._isValidLyrics(lyrics)) return lyrics;
|
|
306
|
+
} catch (error) {
|
|
307
|
+
this.aqua.emit('debug', `[Aqua/Lyrics] Clean search failed: ${error.message}`);
|
|
308
|
+
}
|
|
214
309
|
}
|
|
215
310
|
|
|
216
|
-
|
|
311
|
+
this.aqua.emit('debug', '[Aqua/Lyrics] No lyrics found');
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async _getPlayerTrackLyrics(guildId, skipTrackSource) {
|
|
316
|
+
this._validateSessionId();
|
|
317
|
+
const params = new URLSearchParams({
|
|
318
|
+
skipTrackSource: skipTrackSource ? 'true' : 'false'
|
|
319
|
+
});
|
|
320
|
+
return this.makeRequest(
|
|
321
|
+
'GET',
|
|
322
|
+
`/${this.version}/sessions/${this.sessionId}/players/${guildId}/track/lyrics?${params}`
|
|
323
|
+
);
|
|
217
324
|
}
|
|
218
325
|
|
|
219
|
-
async
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
326
|
+
async _getEncodedTrackLyrics(encodedTrack, skipTrackSource) {
|
|
327
|
+
const params = new URLSearchParams({
|
|
328
|
+
track: encodedTrack,
|
|
329
|
+
skipTrackSource: skipTrackSource ? 'true' : 'false'
|
|
330
|
+
});
|
|
331
|
+
return this.makeRequest('GET', `/${this.version}/lyrics?${params}`);
|
|
332
|
+
}
|
|
223
333
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
return await this.makeRequest('GET', `${baseUrl}/track/lyrics${query}`)
|
|
228
|
-
}
|
|
334
|
+
async _searchLyrics(query) {
|
|
335
|
+
const params = new URLSearchParams({ query });
|
|
336
|
+
return this.makeRequest('GET', `/${this.version}/lyrics/search?${params}`);
|
|
229
337
|
}
|
|
230
338
|
|
|
231
|
-
|
|
232
|
-
return
|
|
339
|
+
_isValidTrackForLyrics(track) {
|
|
340
|
+
return track && (
|
|
341
|
+
track.guild_id ||
|
|
342
|
+
(track.encoded && this._isValidEncodedTrack(track.encoded)) ||
|
|
343
|
+
track.info?.title
|
|
344
|
+
);
|
|
233
345
|
}
|
|
234
346
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
347
|
+
_isValidLyrics(response) {
|
|
348
|
+
return response &&
|
|
349
|
+
response.status !== 204 &&
|
|
350
|
+
!(Array.isArray(response) && response.length === 0);
|
|
238
351
|
}
|
|
239
352
|
|
|
240
|
-
|
|
241
|
-
return
|
|
353
|
+
_buildSearchQuery(info) {
|
|
354
|
+
return [info.title, info.author]
|
|
355
|
+
.filter(Boolean)
|
|
356
|
+
.join(' ');
|
|
242
357
|
}
|
|
243
358
|
|
|
359
|
+
// Live lyrics management
|
|
244
360
|
async subscribeLiveLyrics(guildId, skipTrackSource = false) {
|
|
245
|
-
this._validateSessionId()
|
|
361
|
+
this._validateSessionId();
|
|
246
362
|
try {
|
|
247
|
-
const
|
|
363
|
+
const params = new URLSearchParams({
|
|
364
|
+
skipTrackSource: skipTrackSource ? 'true' : 'false'
|
|
365
|
+
});
|
|
248
366
|
const result = await this.makeRequest(
|
|
249
367
|
'POST',
|
|
250
|
-
`/${this.version}/sessions/${this.sessionId}/players/${guildId}/lyrics/subscribe
|
|
251
|
-
)
|
|
252
|
-
return result === null
|
|
368
|
+
`/${this.version}/sessions/${this.sessionId}/players/${guildId}/lyrics/subscribe?${params}`
|
|
369
|
+
);
|
|
370
|
+
return result === null;
|
|
253
371
|
} catch (error) {
|
|
254
|
-
this.aqua.emit('debug', `[Aqua/Lyrics] Subscribe failed: ${error.message}`)
|
|
255
|
-
return false
|
|
372
|
+
this.aqua.emit('debug', `[Aqua/Lyrics] Subscribe failed: ${error.message}`);
|
|
373
|
+
return false;
|
|
256
374
|
}
|
|
257
375
|
}
|
|
258
376
|
|
|
259
377
|
async unsubscribeLiveLyrics(guildId) {
|
|
260
|
-
this._validateSessionId()
|
|
378
|
+
this._validateSessionId();
|
|
261
379
|
try {
|
|
262
380
|
const result = await this.makeRequest(
|
|
263
381
|
'DELETE',
|
|
264
382
|
`/${this.version}/sessions/${this.sessionId}/players/${guildId}/lyrics/subscribe`
|
|
265
|
-
)
|
|
266
|
-
return result === null
|
|
383
|
+
);
|
|
384
|
+
return result === null;
|
|
267
385
|
} catch (error) {
|
|
268
|
-
this.aqua.emit('debug', `[Aqua/Lyrics] Unsubscribe failed: ${error.message}`)
|
|
269
|
-
return false
|
|
386
|
+
this.aqua.emit('debug', `[Aqua/Lyrics] Unsubscribe failed: ${error.message}`);
|
|
387
|
+
return false;
|
|
270
388
|
}
|
|
271
389
|
}
|
|
272
390
|
|
|
273
|
-
//
|
|
391
|
+
// Resource cleanup
|
|
274
392
|
destroy() {
|
|
275
393
|
if (this.agent) {
|
|
276
|
-
this.agent.destroy()
|
|
394
|
+
this.agent.destroy();
|
|
395
|
+
this.agent = null;
|
|
277
396
|
}
|
|
278
397
|
}
|
|
279
398
|
}
|
|
280
399
|
|
|
281
|
-
module.exports = Rest
|
|
400
|
+
module.exports = Rest;
|