lavalink-client 1.0.5 → 1.0.6
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 +1 -0
- package/dist/cjs/structures/LavalinkManager.d.ts +3 -0
- package/dist/cjs/structures/Node.d.ts +3 -3
- package/dist/cjs/structures/Node.js +6 -4
- package/dist/cjs/structures/Utils.js +58 -6
- package/dist/esm/structures/LavalinkManager.d.ts +3 -0
- package/dist/esm/structures/Node.d.ts +3 -3
- package/dist/esm/structures/Node.js +6 -4
- package/dist/esm/structures/Utils.js +58 -6
- package/dist/types/structures/LavalinkManager.d.ts +3 -0
- package/dist/types/structures/Node.d.ts +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,9 @@ export interface LavalinkManager {
|
|
|
11
11
|
utils: ManagerUitls;
|
|
12
12
|
}
|
|
13
13
|
export interface BotClientOptions {
|
|
14
|
+
/** Bot Client Id */
|
|
14
15
|
id: string;
|
|
16
|
+
/** Bot Client Username */
|
|
15
17
|
username?: string;
|
|
16
18
|
/** So users can pass entire objects / classes */
|
|
17
19
|
[x: string | number | symbol | undefined]: any;
|
|
@@ -39,6 +41,7 @@ export interface LavalinkPlayerOptions {
|
|
|
39
41
|
autoPlayFunction?: (player: Player, lastPlayedTrack: Track) => Promise<void>;
|
|
40
42
|
destroyAfterMs?: number;
|
|
41
43
|
};
|
|
44
|
+
useUnresolvedData?: boolean;
|
|
42
45
|
}
|
|
43
46
|
export interface ManagerOptions {
|
|
44
47
|
nodes: LavalinkNodeOptions[];
|
|
@@ -4,7 +4,7 @@ import { NodeManager } from "./NodeManager";
|
|
|
4
4
|
import internal from "stream";
|
|
5
5
|
import { InvalidLavalinkRestRequest, LavalinkPlayer, PlayerUpdateInfo, RoutePlanner, Session, Base64 } from "./Utils";
|
|
6
6
|
import { DestroyReasonsType } from "./Player";
|
|
7
|
-
import {
|
|
7
|
+
import { Track } from "./Track";
|
|
8
8
|
/** Modifies any outgoing REST requests. */
|
|
9
9
|
export type ModifyRequest = (options: Dispatcher.RequestOptions) => void;
|
|
10
10
|
export interface LavalinkNodeOptions {
|
|
@@ -185,13 +185,13 @@ export declare class LavalinkNode {
|
|
|
185
185
|
* @param encoded
|
|
186
186
|
* @returns
|
|
187
187
|
*/
|
|
188
|
-
singleTrack: (encoded: Base64) => Promise<
|
|
188
|
+
singleTrack: (encoded: Base64, requester: unknown) => Promise<Track>;
|
|
189
189
|
/**
|
|
190
190
|
*
|
|
191
191
|
* @param encodeds Decodes multiple tracks into their info
|
|
192
192
|
* @returns
|
|
193
193
|
*/
|
|
194
|
-
multipleTracks: (encodeds: Base64[]) => Promise<
|
|
194
|
+
multipleTracks: (encodeds: Base64[], requester: unknown) => Promise<Track[]>;
|
|
195
195
|
};
|
|
196
196
|
/**
|
|
197
197
|
* Request Lavalink statistics.
|
|
@@ -227,25 +227,27 @@ class LavalinkNode {
|
|
|
227
227
|
* @param encoded
|
|
228
228
|
* @returns
|
|
229
229
|
*/
|
|
230
|
-
singleTrack: async (encoded) => {
|
|
230
|
+
singleTrack: async (encoded, requester) => {
|
|
231
231
|
if (!encoded)
|
|
232
232
|
throw new SyntaxError("No encoded (Base64 string) was provided");
|
|
233
|
-
return
|
|
233
|
+
// return the decoded + builded track
|
|
234
|
+
return this.NodeManager.LavalinkManager.utils.buildTrack(await this.request(`/decodetrack?encodedTrack=${encoded}`), requester);
|
|
234
235
|
},
|
|
235
236
|
/**
|
|
236
237
|
*
|
|
237
238
|
* @param encodeds Decodes multiple tracks into their info
|
|
238
239
|
* @returns
|
|
239
240
|
*/
|
|
240
|
-
multipleTracks: async (encodeds) => {
|
|
241
|
+
multipleTracks: async (encodeds, requester) => {
|
|
241
242
|
if (!Array.isArray(encodeds) || !encodeds.every(v => typeof v === "string" && v.length > 1))
|
|
242
243
|
throw new SyntaxError("You need to provide encodeds, which is an array of base64 strings");
|
|
244
|
+
// return the decoded + builded tracks
|
|
243
245
|
return await this.request(`/decodetracks`, r => {
|
|
244
246
|
r.method = "POST";
|
|
245
247
|
r.body = JSON.stringify(encodeds);
|
|
246
248
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
247
249
|
r.headers["Content-Type"] = "application/json";
|
|
248
|
-
});
|
|
250
|
+
}).then((r) => r.map(track => this.NodeManager.LavalinkManager.utils.buildTrack(track, requester)));
|
|
249
251
|
}
|
|
250
252
|
};
|
|
251
253
|
/**
|
|
@@ -6,6 +6,8 @@ exports.TrackSymbol = Symbol("LC-Track");
|
|
|
6
6
|
exports.UnresolvedTrackSymbol = Symbol("LC-Track-Unresolved");
|
|
7
7
|
exports.QueueSymbol = Symbol("LC-Queue");
|
|
8
8
|
exports.NodeSymbol = Symbol("LC-Node");
|
|
9
|
+
/** @hidden */
|
|
10
|
+
const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
9
11
|
class ManagerUitls {
|
|
10
12
|
constructor(LavalinkManager) {
|
|
11
13
|
this.manager = LavalinkManager;
|
|
@@ -23,7 +25,7 @@ class ManagerUitls {
|
|
|
23
25
|
identifier: data.info?.identifier,
|
|
24
26
|
title: data.info?.title,
|
|
25
27
|
author: data.info?.author,
|
|
26
|
-
duration: data.info?.length,
|
|
28
|
+
duration: data.info?.length || data.info?.duration,
|
|
27
29
|
artworkUrl: data.info?.artworkUrl || data.pluginInfo?.artworkUrl || data.plugin?.artworkUrl,
|
|
28
30
|
uri: data.info?.uri,
|
|
29
31
|
sourceName: data.info?.sourceName,
|
|
@@ -95,13 +97,21 @@ class ManagerUitls {
|
|
|
95
97
|
* @returns
|
|
96
98
|
*/
|
|
97
99
|
isTrack(data) {
|
|
98
|
-
|
|
100
|
+
if (!data)
|
|
101
|
+
return false;
|
|
102
|
+
if (data[exports.TrackSymbol] === true)
|
|
103
|
+
return true;
|
|
104
|
+
return typeof data?.encoded === "string" && typeof data?.info === "object" && !("resolve" in data);
|
|
99
105
|
}
|
|
100
106
|
/**
|
|
101
107
|
* Checks if the provided argument is a valid UnresolvedTrack.
|
|
102
108
|
* @param track
|
|
103
109
|
*/
|
|
104
110
|
isUnresolvedTrack(data) {
|
|
111
|
+
if (!data)
|
|
112
|
+
return false;
|
|
113
|
+
if (data[exports.UnresolvedTrackSymbol] === true)
|
|
114
|
+
return true;
|
|
105
115
|
return typeof data === "object" && "info" in data && typeof data.info.title === "string" && typeof data.resolve === "function";
|
|
106
116
|
}
|
|
107
117
|
/**
|
|
@@ -277,6 +287,32 @@ async function queueTrackEnd(player) {
|
|
|
277
287
|
return player.queue.current;
|
|
278
288
|
}
|
|
279
289
|
exports.queueTrackEnd = queueTrackEnd;
|
|
290
|
+
async function applyUnresolvedData(resTrack, data, utils) {
|
|
291
|
+
if (!resTrack?.info || !data?.info)
|
|
292
|
+
return;
|
|
293
|
+
if (utils.manager.options.playerOptions?.useUnresolvedData === true) { // overwrite values
|
|
294
|
+
if (data.info.uri)
|
|
295
|
+
resTrack.info.uri = data.info.uri;
|
|
296
|
+
if (data.info.artworkUrl?.length)
|
|
297
|
+
resTrack.info.artworkUrl = data.info.artworkUrl;
|
|
298
|
+
if (data.info.title?.length)
|
|
299
|
+
resTrack.info.title = data.info.title;
|
|
300
|
+
if (data.info.author?.length)
|
|
301
|
+
resTrack.info.author = data.info.author;
|
|
302
|
+
}
|
|
303
|
+
else { // only overwrite if undefined / invalid
|
|
304
|
+
if ((resTrack.info.title == 'Unknown title' || resTrack.info.title == "Unspecified description") && resTrack.info.title != data.info.title)
|
|
305
|
+
resTrack.info.title = data.info.title;
|
|
306
|
+
if (resTrack.info.author != data.info.author)
|
|
307
|
+
resTrack.info.author = data.info.author;
|
|
308
|
+
if (resTrack.info.artworkUrl != data.info.artworkUrl)
|
|
309
|
+
resTrack.info.artworkUrl = data.info.artworkUrl;
|
|
310
|
+
}
|
|
311
|
+
for (const key of Object.keys(data.info))
|
|
312
|
+
if (typeof resTrack.info[key] === "undefined" && key !== "resolve" && data.info[key])
|
|
313
|
+
resTrack.info[key] = data.info[key]; // add non-existing values
|
|
314
|
+
return resTrack;
|
|
315
|
+
}
|
|
280
316
|
async function getClosestTrack(data, player, utils) {
|
|
281
317
|
if (!player || !player.node)
|
|
282
318
|
throw new RangeError("No player with a lavalink node was provided");
|
|
@@ -288,19 +324,35 @@ async function getClosestTrack(data, player, utils) {
|
|
|
288
324
|
throw new SyntaxError("the track title is required for unresolved tracks");
|
|
289
325
|
if (!data.requester)
|
|
290
326
|
throw new SyntaxError("The requester is required");
|
|
327
|
+
// try to decode the track, if possible
|
|
291
328
|
if (typeof data.encoded === "string") {
|
|
292
|
-
const r = await player.node.decode.singleTrack(data.encoded);
|
|
329
|
+
const r = await player.node.decode.singleTrack(data.encoded, data.requester);
|
|
293
330
|
if (r)
|
|
294
|
-
return
|
|
331
|
+
return applyUnresolvedData(r, data, utils);
|
|
295
332
|
}
|
|
333
|
+
// try to fetch the track via a uri if possible
|
|
296
334
|
if (typeof data.info.uri === "string") {
|
|
297
335
|
const r = await player.search({ query: data?.info?.uri }, data.requester).then(v => v.tracks[0]);
|
|
298
336
|
if (r)
|
|
299
|
-
return r;
|
|
337
|
+
return applyUnresolvedData(r, data, utils);
|
|
300
338
|
}
|
|
339
|
+
// search the track as closely as possible
|
|
301
340
|
const query = [data.info?.title, data.info?.author].filter(str => !!str).join(" by ");
|
|
302
341
|
const sourceName = data.info?.sourceName;
|
|
303
342
|
return await player.search({
|
|
304
343
|
query, source: sourceName !== "bandcamp" && sourceName !== "twitch" && sourceName !== "flowery-tts" ? sourceName : player.LavalinkManager.options?.playerOptions?.defaultSearchPlatform,
|
|
305
|
-
}, data.requester).then(
|
|
344
|
+
}, data.requester).then(res => {
|
|
345
|
+
let trackToUse = null;
|
|
346
|
+
// try to find via author name
|
|
347
|
+
if (data.info.author && !trackToUse)
|
|
348
|
+
trackToUse = res.tracks.find(track => [data.info.author, `${data.info.author} - Topic`].some(name => new RegExp(`^${escapeRegExp(name)}$`, "i").test(track.info.author)) || new RegExp(`^${escapeRegExp(data.info.title)}$`, "i").test(track.info.title));
|
|
349
|
+
// try to find via duration
|
|
350
|
+
if (data.info.duration && !trackToUse)
|
|
351
|
+
trackToUse = res.tracks.find(track => (track.info.duration >= (data.info.duration - 1500)) && (track.info.duration <= (data.info.duration + 1500)));
|
|
352
|
+
// try to find via isrc
|
|
353
|
+
if (data.info.isrc && !trackToUse)
|
|
354
|
+
trackToUse = res.tracks.find(track => track.info.isrc === data.info.isrc);
|
|
355
|
+
// apply unresolved data and return the track
|
|
356
|
+
return applyUnresolvedData(trackToUse || res.tracks[0], data, utils);
|
|
357
|
+
});
|
|
306
358
|
}
|
|
@@ -11,7 +11,9 @@ export interface LavalinkManager {
|
|
|
11
11
|
utils: ManagerUitls;
|
|
12
12
|
}
|
|
13
13
|
export interface BotClientOptions {
|
|
14
|
+
/** Bot Client Id */
|
|
14
15
|
id: string;
|
|
16
|
+
/** Bot Client Username */
|
|
15
17
|
username?: string;
|
|
16
18
|
/** So users can pass entire objects / classes */
|
|
17
19
|
[x: string | number | symbol | undefined]: any;
|
|
@@ -39,6 +41,7 @@ export interface LavalinkPlayerOptions {
|
|
|
39
41
|
autoPlayFunction?: (player: Player, lastPlayedTrack: Track) => Promise<void>;
|
|
40
42
|
destroyAfterMs?: number;
|
|
41
43
|
};
|
|
44
|
+
useUnresolvedData?: boolean;
|
|
42
45
|
}
|
|
43
46
|
export interface ManagerOptions {
|
|
44
47
|
nodes: LavalinkNodeOptions[];
|
|
@@ -4,7 +4,7 @@ import { NodeManager } from "./NodeManager";
|
|
|
4
4
|
import internal from "stream";
|
|
5
5
|
import { InvalidLavalinkRestRequest, LavalinkPlayer, PlayerUpdateInfo, RoutePlanner, Session, Base64 } from "./Utils";
|
|
6
6
|
import { DestroyReasonsType } from "./Player";
|
|
7
|
-
import {
|
|
7
|
+
import { Track } from "./Track";
|
|
8
8
|
/** Modifies any outgoing REST requests. */
|
|
9
9
|
export type ModifyRequest = (options: Dispatcher.RequestOptions) => void;
|
|
10
10
|
export interface LavalinkNodeOptions {
|
|
@@ -185,13 +185,13 @@ export declare class LavalinkNode {
|
|
|
185
185
|
* @param encoded
|
|
186
186
|
* @returns
|
|
187
187
|
*/
|
|
188
|
-
singleTrack: (encoded: Base64) => Promise<
|
|
188
|
+
singleTrack: (encoded: Base64, requester: unknown) => Promise<Track>;
|
|
189
189
|
/**
|
|
190
190
|
*
|
|
191
191
|
* @param encodeds Decodes multiple tracks into their info
|
|
192
192
|
* @returns
|
|
193
193
|
*/
|
|
194
|
-
multipleTracks: (encodeds: Base64[]) => Promise<
|
|
194
|
+
multipleTracks: (encodeds: Base64[], requester: unknown) => Promise<Track[]>;
|
|
195
195
|
};
|
|
196
196
|
/**
|
|
197
197
|
* Request Lavalink statistics.
|
|
@@ -223,25 +223,27 @@ export class LavalinkNode {
|
|
|
223
223
|
* @param encoded
|
|
224
224
|
* @returns
|
|
225
225
|
*/
|
|
226
|
-
singleTrack: async (encoded) => {
|
|
226
|
+
singleTrack: async (encoded, requester) => {
|
|
227
227
|
if (!encoded)
|
|
228
228
|
throw new SyntaxError("No encoded (Base64 string) was provided");
|
|
229
|
-
return
|
|
229
|
+
// return the decoded + builded track
|
|
230
|
+
return this.NodeManager.LavalinkManager.utils.buildTrack(await this.request(`/decodetrack?encodedTrack=${encoded}`), requester);
|
|
230
231
|
},
|
|
231
232
|
/**
|
|
232
233
|
*
|
|
233
234
|
* @param encodeds Decodes multiple tracks into their info
|
|
234
235
|
* @returns
|
|
235
236
|
*/
|
|
236
|
-
multipleTracks: async (encodeds) => {
|
|
237
|
+
multipleTracks: async (encodeds, requester) => {
|
|
237
238
|
if (!Array.isArray(encodeds) || !encodeds.every(v => typeof v === "string" && v.length > 1))
|
|
238
239
|
throw new SyntaxError("You need to provide encodeds, which is an array of base64 strings");
|
|
240
|
+
// return the decoded + builded tracks
|
|
239
241
|
return await this.request(`/decodetracks`, r => {
|
|
240
242
|
r.method = "POST";
|
|
241
243
|
r.body = JSON.stringify(encodeds);
|
|
242
244
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
243
245
|
r.headers["Content-Type"] = "application/json";
|
|
244
|
-
});
|
|
246
|
+
}).then((r) => r.map(track => this.NodeManager.LavalinkManager.utils.buildTrack(track, requester)));
|
|
245
247
|
}
|
|
246
248
|
};
|
|
247
249
|
/**
|
|
@@ -3,6 +3,8 @@ export const TrackSymbol = Symbol("LC-Track");
|
|
|
3
3
|
export const UnresolvedTrackSymbol = Symbol("LC-Track-Unresolved");
|
|
4
4
|
export const QueueSymbol = Symbol("LC-Queue");
|
|
5
5
|
export const NodeSymbol = Symbol("LC-Node");
|
|
6
|
+
/** @hidden */
|
|
7
|
+
const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6
8
|
export class ManagerUitls {
|
|
7
9
|
constructor(LavalinkManager) {
|
|
8
10
|
this.manager = LavalinkManager;
|
|
@@ -20,7 +22,7 @@ export class ManagerUitls {
|
|
|
20
22
|
identifier: data.info?.identifier,
|
|
21
23
|
title: data.info?.title,
|
|
22
24
|
author: data.info?.author,
|
|
23
|
-
duration: data.info?.length,
|
|
25
|
+
duration: data.info?.length || data.info?.duration,
|
|
24
26
|
artworkUrl: data.info?.artworkUrl || data.pluginInfo?.artworkUrl || data.plugin?.artworkUrl,
|
|
25
27
|
uri: data.info?.uri,
|
|
26
28
|
sourceName: data.info?.sourceName,
|
|
@@ -92,13 +94,21 @@ export class ManagerUitls {
|
|
|
92
94
|
* @returns
|
|
93
95
|
*/
|
|
94
96
|
isTrack(data) {
|
|
95
|
-
|
|
97
|
+
if (!data)
|
|
98
|
+
return false;
|
|
99
|
+
if (data[TrackSymbol] === true)
|
|
100
|
+
return true;
|
|
101
|
+
return typeof data?.encoded === "string" && typeof data?.info === "object" && !("resolve" in data);
|
|
96
102
|
}
|
|
97
103
|
/**
|
|
98
104
|
* Checks if the provided argument is a valid UnresolvedTrack.
|
|
99
105
|
* @param track
|
|
100
106
|
*/
|
|
101
107
|
isUnresolvedTrack(data) {
|
|
108
|
+
if (!data)
|
|
109
|
+
return false;
|
|
110
|
+
if (data[UnresolvedTrackSymbol] === true)
|
|
111
|
+
return true;
|
|
102
112
|
return typeof data === "object" && "info" in data && typeof data.info.title === "string" && typeof data.resolve === "function";
|
|
103
113
|
}
|
|
104
114
|
/**
|
|
@@ -271,6 +281,32 @@ export async function queueTrackEnd(player) {
|
|
|
271
281
|
// return the new current Track
|
|
272
282
|
return player.queue.current;
|
|
273
283
|
}
|
|
284
|
+
async function applyUnresolvedData(resTrack, data, utils) {
|
|
285
|
+
if (!resTrack?.info || !data?.info)
|
|
286
|
+
return;
|
|
287
|
+
if (utils.manager.options.playerOptions?.useUnresolvedData === true) { // overwrite values
|
|
288
|
+
if (data.info.uri)
|
|
289
|
+
resTrack.info.uri = data.info.uri;
|
|
290
|
+
if (data.info.artworkUrl?.length)
|
|
291
|
+
resTrack.info.artworkUrl = data.info.artworkUrl;
|
|
292
|
+
if (data.info.title?.length)
|
|
293
|
+
resTrack.info.title = data.info.title;
|
|
294
|
+
if (data.info.author?.length)
|
|
295
|
+
resTrack.info.author = data.info.author;
|
|
296
|
+
}
|
|
297
|
+
else { // only overwrite if undefined / invalid
|
|
298
|
+
if ((resTrack.info.title == 'Unknown title' || resTrack.info.title == "Unspecified description") && resTrack.info.title != data.info.title)
|
|
299
|
+
resTrack.info.title = data.info.title;
|
|
300
|
+
if (resTrack.info.author != data.info.author)
|
|
301
|
+
resTrack.info.author = data.info.author;
|
|
302
|
+
if (resTrack.info.artworkUrl != data.info.artworkUrl)
|
|
303
|
+
resTrack.info.artworkUrl = data.info.artworkUrl;
|
|
304
|
+
}
|
|
305
|
+
for (const key of Object.keys(data.info))
|
|
306
|
+
if (typeof resTrack.info[key] === "undefined" && key !== "resolve" && data.info[key])
|
|
307
|
+
resTrack.info[key] = data.info[key]; // add non-existing values
|
|
308
|
+
return resTrack;
|
|
309
|
+
}
|
|
274
310
|
async function getClosestTrack(data, player, utils) {
|
|
275
311
|
if (!player || !player.node)
|
|
276
312
|
throw new RangeError("No player with a lavalink node was provided");
|
|
@@ -282,19 +318,35 @@ async function getClosestTrack(data, player, utils) {
|
|
|
282
318
|
throw new SyntaxError("the track title is required for unresolved tracks");
|
|
283
319
|
if (!data.requester)
|
|
284
320
|
throw new SyntaxError("The requester is required");
|
|
321
|
+
// try to decode the track, if possible
|
|
285
322
|
if (typeof data.encoded === "string") {
|
|
286
|
-
const r = await player.node.decode.singleTrack(data.encoded);
|
|
323
|
+
const r = await player.node.decode.singleTrack(data.encoded, data.requester);
|
|
287
324
|
if (r)
|
|
288
|
-
return
|
|
325
|
+
return applyUnresolvedData(r, data, utils);
|
|
289
326
|
}
|
|
327
|
+
// try to fetch the track via a uri if possible
|
|
290
328
|
if (typeof data.info.uri === "string") {
|
|
291
329
|
const r = await player.search({ query: data?.info?.uri }, data.requester).then(v => v.tracks[0]);
|
|
292
330
|
if (r)
|
|
293
|
-
return r;
|
|
331
|
+
return applyUnresolvedData(r, data, utils);
|
|
294
332
|
}
|
|
333
|
+
// search the track as closely as possible
|
|
295
334
|
const query = [data.info?.title, data.info?.author].filter(str => !!str).join(" by ");
|
|
296
335
|
const sourceName = data.info?.sourceName;
|
|
297
336
|
return await player.search({
|
|
298
337
|
query, source: sourceName !== "bandcamp" && sourceName !== "twitch" && sourceName !== "flowery-tts" ? sourceName : player.LavalinkManager.options?.playerOptions?.defaultSearchPlatform,
|
|
299
|
-
}, data.requester).then(
|
|
338
|
+
}, data.requester).then(res => {
|
|
339
|
+
let trackToUse = null;
|
|
340
|
+
// try to find via author name
|
|
341
|
+
if (data.info.author && !trackToUse)
|
|
342
|
+
trackToUse = res.tracks.find(track => [data.info.author, `${data.info.author} - Topic`].some(name => new RegExp(`^${escapeRegExp(name)}$`, "i").test(track.info.author)) || new RegExp(`^${escapeRegExp(data.info.title)}$`, "i").test(track.info.title));
|
|
343
|
+
// try to find via duration
|
|
344
|
+
if (data.info.duration && !trackToUse)
|
|
345
|
+
trackToUse = res.tracks.find(track => (track.info.duration >= (data.info.duration - 1500)) && (track.info.duration <= (data.info.duration + 1500)));
|
|
346
|
+
// try to find via isrc
|
|
347
|
+
if (data.info.isrc && !trackToUse)
|
|
348
|
+
trackToUse = res.tracks.find(track => track.info.isrc === data.info.isrc);
|
|
349
|
+
// apply unresolved data and return the track
|
|
350
|
+
return applyUnresolvedData(trackToUse || res.tracks[0], data, utils);
|
|
351
|
+
});
|
|
300
352
|
}
|
|
@@ -11,7 +11,9 @@ export interface LavalinkManager {
|
|
|
11
11
|
utils: ManagerUitls;
|
|
12
12
|
}
|
|
13
13
|
export interface BotClientOptions {
|
|
14
|
+
/** Bot Client Id */
|
|
14
15
|
id: string;
|
|
16
|
+
/** Bot Client Username */
|
|
15
17
|
username?: string;
|
|
16
18
|
/** So users can pass entire objects / classes */
|
|
17
19
|
[x: string | number | symbol | undefined]: any;
|
|
@@ -39,6 +41,7 @@ export interface LavalinkPlayerOptions {
|
|
|
39
41
|
autoPlayFunction?: (player: Player, lastPlayedTrack: Track) => Promise<void>;
|
|
40
42
|
destroyAfterMs?: number;
|
|
41
43
|
};
|
|
44
|
+
useUnresolvedData?: boolean;
|
|
42
45
|
}
|
|
43
46
|
export interface ManagerOptions {
|
|
44
47
|
nodes: LavalinkNodeOptions[];
|
|
@@ -4,7 +4,7 @@ import { NodeManager } from "./NodeManager";
|
|
|
4
4
|
import internal from "stream";
|
|
5
5
|
import { InvalidLavalinkRestRequest, LavalinkPlayer, PlayerUpdateInfo, RoutePlanner, Session, Base64 } from "./Utils";
|
|
6
6
|
import { DestroyReasonsType } from "./Player";
|
|
7
|
-
import {
|
|
7
|
+
import { Track } from "./Track";
|
|
8
8
|
/** Modifies any outgoing REST requests. */
|
|
9
9
|
export type ModifyRequest = (options: Dispatcher.RequestOptions) => void;
|
|
10
10
|
export interface LavalinkNodeOptions {
|
|
@@ -185,13 +185,13 @@ export declare class LavalinkNode {
|
|
|
185
185
|
* @param encoded
|
|
186
186
|
* @returns
|
|
187
187
|
*/
|
|
188
|
-
singleTrack: (encoded: Base64) => Promise<
|
|
188
|
+
singleTrack: (encoded: Base64, requester: unknown) => Promise<Track>;
|
|
189
189
|
/**
|
|
190
190
|
*
|
|
191
191
|
* @param encodeds Decodes multiple tracks into their info
|
|
192
192
|
* @returns
|
|
193
193
|
*/
|
|
194
|
-
multipleTracks: (encodeds: Base64[]) => Promise<
|
|
194
|
+
multipleTracks: (encodeds: Base64[], requester: unknown) => Promise<Track[]>;
|
|
195
195
|
};
|
|
196
196
|
/**
|
|
197
197
|
* Request Lavalink statistics.
|
package/package.json
CHANGED