lavalink-client 2.1.7 → 2.2.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 +87 -1
- package/dist/cjs/structures/CustomSearches/BandCampSearch.js +3 -2
- package/dist/cjs/structures/Filters.d.ts +1 -1
- package/dist/cjs/structures/Filters.js +5 -5
- package/dist/cjs/structures/LavalinkManager.d.ts +23 -5
- package/dist/cjs/structures/LavalinkManager.js +15 -1
- package/dist/cjs/structures/LavalinkManagerStatics.d.ts +3 -0
- package/dist/cjs/structures/LavalinkManagerStatics.js +8 -1
- package/dist/cjs/structures/Node.d.ts +317 -35
- package/dist/cjs/structures/Node.js +330 -85
- package/dist/cjs/structures/NodeManager.d.ts +1 -1
- package/dist/cjs/structures/Player.d.ts +44 -8
- package/dist/cjs/structures/Player.js +35 -27
- package/dist/cjs/structures/Queue.js +1 -1
- package/dist/cjs/structures/Utils.d.ts +5 -2
- package/dist/cjs/structures/Utils.js +7 -4
- package/dist/esm/structures/CustomSearches/BandCampSearch.js +2 -1
- package/dist/esm/structures/Filters.d.ts +1 -1
- package/dist/esm/structures/Filters.js +5 -5
- package/dist/esm/structures/LavalinkManager.d.ts +23 -5
- package/dist/esm/structures/LavalinkManager.js +15 -1
- package/dist/esm/structures/LavalinkManagerStatics.d.ts +3 -0
- package/dist/esm/structures/LavalinkManagerStatics.js +8 -1
- package/dist/esm/structures/Node.d.ts +317 -35
- package/dist/esm/structures/Node.js +330 -85
- package/dist/esm/structures/NodeManager.d.ts +1 -1
- package/dist/esm/structures/Player.d.ts +44 -8
- package/dist/esm/structures/Player.js +35 -27
- package/dist/esm/structures/Queue.js +1 -1
- package/dist/esm/structures/Utils.d.ts +5 -2
- package/dist/esm/structures/Utils.js +7 -4
- package/dist/types/structures/Filters.d.ts +1 -1
- package/dist/types/structures/LavalinkManager.d.ts +23 -5
- package/dist/types/structures/LavalinkManagerStatics.d.ts +3 -0
- package/dist/types/structures/Node.d.ts +317 -35
- package/dist/types/structures/NodeManager.d.ts +1 -1
- package/dist/types/structures/Player.d.ts +44 -8
- package/dist/types/structures/Utils.d.ts +5 -2
- package/package.json +5 -4
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { isAbsolute } from "path";
|
|
2
|
-
import { Pool } from "undici";
|
|
3
2
|
import WebSocket from "ws";
|
|
4
3
|
import { DestroyReasons } from "./Player";
|
|
5
4
|
import { NodeSymbol, queueTrackEnd } from "./Utils";
|
|
6
5
|
export const validSponsorBlocks = ["sponsor", "selfpromo", "interaction", "intro", "outro", "preview", "music_offtopic", "filler"];
|
|
6
|
+
/**
|
|
7
|
+
* Lavalink Node creator class
|
|
8
|
+
*/
|
|
7
9
|
export class LavalinkNode {
|
|
8
10
|
/** The provided Options of the Node */
|
|
9
11
|
options;
|
|
10
12
|
/** The amount of rest calls the node has made. */
|
|
11
13
|
calls = 0;
|
|
14
|
+
/** Stats from lavalink, will be updated via an interval by lavalink. */
|
|
12
15
|
stats = {
|
|
13
16
|
players: 0,
|
|
14
17
|
playingPlayers: 0,
|
|
@@ -30,6 +33,7 @@ export class LavalinkNode {
|
|
|
30
33
|
sent: 0,
|
|
31
34
|
}
|
|
32
35
|
};
|
|
36
|
+
/** The current sessionId, only present when connected */
|
|
33
37
|
sessionId = null;
|
|
34
38
|
/** Wether the node resuming is enabled or not */
|
|
35
39
|
resuming = { enabled: true, timeout: null };
|
|
@@ -43,97 +47,155 @@ export class LavalinkNode {
|
|
|
43
47
|
reconnectAttempts = 1;
|
|
44
48
|
/** The Socket of the Lavalink */
|
|
45
49
|
socket = null;
|
|
46
|
-
/** The Rest Server for this Lavalink */
|
|
47
|
-
rest;
|
|
48
50
|
/** Version of what the Lavalink Server should be */
|
|
49
51
|
version = "v4";
|
|
50
52
|
/**
|
|
51
53
|
* Create a new Node
|
|
52
54
|
* @param options Lavalink Node Options
|
|
53
55
|
* @param manager Node Manager
|
|
56
|
+
*
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* // don't create a node manually, instead use:
|
|
61
|
+
*
|
|
62
|
+
* client.lavalink.nodeManager.createNode(options)
|
|
63
|
+
* ```
|
|
54
64
|
*/
|
|
55
65
|
constructor(options, manager) {
|
|
56
66
|
this.options = {
|
|
57
67
|
secure: false,
|
|
58
68
|
retryAmount: 5,
|
|
59
69
|
retryDelay: 30e3,
|
|
60
|
-
|
|
70
|
+
requestSignalTimeoutMS: 10000,
|
|
61
71
|
...options
|
|
62
72
|
};
|
|
63
73
|
this.NodeManager = manager;
|
|
64
74
|
this.validate();
|
|
65
75
|
if (this.options.secure && this.options.port !== 443)
|
|
66
76
|
throw new SyntaxError("If secure is true, then the port must be 443");
|
|
67
|
-
this.rest = new Pool(this.poolAddress, this.options.poolOptions);
|
|
68
77
|
this.options.regions = (this.options.regions || []).map(a => a.toLowerCase());
|
|
69
78
|
Object.defineProperty(this, NodeSymbol, { configurable: true, value: true });
|
|
70
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse url params correctly for lavalink requests, including support for urls and uris.
|
|
82
|
+
* @param url input url object
|
|
83
|
+
* @param extraQueryUrlParams UrlSearchParams to use in a encodedURI, useful for example for flowertts
|
|
84
|
+
* @returns the url as a valid string
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* player.node.getRequestingUrl(new URL(`http://localhost:2333/v4/loadtracks?identifier=Never gonna give you up`));
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
getRequestingUrl(url, extraQueryUrlParams) {
|
|
92
|
+
if (!url.searchParams.size)
|
|
93
|
+
return `${url.origin}${url.pathname}`;
|
|
94
|
+
const keysToAdd = [];
|
|
95
|
+
for (const [paramKey, paramValue] of url.searchParams.entries()) {
|
|
96
|
+
const decoded = decodeURIComponent(paramValue).trim(); // double decoding, once internally, a second time if decoded by provided user.
|
|
97
|
+
if (decoded.includes("://") && !/^https?:\/\//.test(decoded)) { // uri, but not url.
|
|
98
|
+
const [key, ...values] = decoded.split("://");
|
|
99
|
+
keysToAdd.push(`${paramKey}=${encodeURI(`${key}://${encodeURIComponent(values.join("://"))}${extraQueryUrlParams && extraQueryUrlParams?.size > 0 ? `?${extraQueryUrlParams.toString()}` : ""}`)}`);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
keysToAdd.push(`${paramKey}=${encodeURIComponent(decoded)}`);
|
|
103
|
+
}
|
|
104
|
+
return `${url.origin}${url.pathname}?${keysToAdd.join("&")}`;
|
|
105
|
+
}
|
|
71
106
|
/**
|
|
72
107
|
* Raw Request util function
|
|
73
108
|
* @param endpoint endpoint string
|
|
74
109
|
* @param modify modify the request
|
|
75
|
-
* @
|
|
110
|
+
* @param extraQueryUrlParams UrlSearchParams to use in a encodedURI, useful for example for flowertts
|
|
111
|
+
* @returns object containing request and option information
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* player.node.rawRequest(`/loadtracks?identifier=Never gonna give you up`, (options) => options.method = "GET");
|
|
116
|
+
* ```
|
|
76
117
|
*/
|
|
77
118
|
async rawRequest(endpoint, modify) {
|
|
78
119
|
const options = {
|
|
79
120
|
path: `/${this.version}/${endpoint.replace(/^\//gm, "")}`,
|
|
80
121
|
method: "GET",
|
|
81
122
|
headers: {
|
|
82
|
-
Authorization: this.options.authorization
|
|
123
|
+
"Authorization": this.options.authorization
|
|
83
124
|
},
|
|
84
|
-
|
|
125
|
+
signal: this.options.requestSignalTimeoutMS && this.options.requestSignalTimeoutMS > 0 ? AbortSignal.timeout(this.options.requestSignalTimeoutMS) : undefined,
|
|
85
126
|
};
|
|
86
127
|
modify?.(options);
|
|
87
|
-
const url = new URL(`${this.
|
|
128
|
+
const url = new URL(`${this.restAddress}${options.path}`);
|
|
88
129
|
url.searchParams.append("trace", "true");
|
|
89
|
-
|
|
90
|
-
|
|
130
|
+
const urlToUse = this.getRequestingUrl(url, options?.extraQueryUrlParams);
|
|
131
|
+
delete options.path;
|
|
132
|
+
delete options.extraQueryUrlParams;
|
|
133
|
+
const request = await fetch(urlToUse, options);
|
|
91
134
|
this.calls++;
|
|
92
135
|
return { request, options };
|
|
93
136
|
}
|
|
94
137
|
/**
|
|
95
|
-
* Makes an API call to the Node
|
|
138
|
+
* Makes an API call to the Node. Should only be used for manual parsing like for not supported plugins
|
|
96
139
|
* @param endpoint The endpoint that we will make the call to
|
|
97
140
|
* @param modify Used to modify the request before being sent
|
|
98
141
|
* @returns The returned data
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* player.node.request(`/loadtracks?identifier=Never gonna give you up`, (options) => options.method = "GET", false);
|
|
146
|
+
* ```
|
|
99
147
|
*/
|
|
100
148
|
async request(endpoint, modify, parseAsText = false) {
|
|
101
149
|
const { request, options } = await this.rawRequest(endpoint, modify);
|
|
102
150
|
if (["DELETE", "PUT"].includes(options.method))
|
|
103
151
|
return;
|
|
104
|
-
if (request.
|
|
152
|
+
if (request.status === 404)
|
|
105
153
|
throw new Error(`Node Request resulted into an error, request-PATH: ${options.path} | headers: ${JSON.stringify(request.headers)}`);
|
|
106
|
-
return parseAsText ? await request.
|
|
154
|
+
return parseAsText ? await request.text() : await request.json();
|
|
107
155
|
}
|
|
108
156
|
/**
|
|
109
157
|
* Search something raw on the node, please note only add tracks to players of that node
|
|
110
158
|
* @param query SearchQuery Object
|
|
111
159
|
* @param requestUser Request User for creating the player(s)
|
|
160
|
+
* @param throwOnEmpty Wether to throw on an empty result or not
|
|
112
161
|
* @returns Searchresult
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```ts
|
|
165
|
+
* // use player.search() instead
|
|
166
|
+
* player.node.search({ query: "Never gonna give you up by Rick Astley", source: "soundcloud" }, interaction.user);
|
|
167
|
+
* player.node.search({ query: "https://deezer.com/track/123456789" }, interaction.user);
|
|
168
|
+
* ```
|
|
113
169
|
*/
|
|
114
|
-
async search(query, requestUser) {
|
|
170
|
+
async search(query, requestUser, throwOnEmpty = false) {
|
|
115
171
|
const Query = this.NodeManager.LavalinkManager.utils.transformQuery(query);
|
|
116
172
|
this.NodeManager.LavalinkManager.utils.validateQueryString(this, Query.query, Query.source);
|
|
117
173
|
if (Query.source)
|
|
118
174
|
this.NodeManager.LavalinkManager.utils.validateSourceString(this, Query.source);
|
|
119
|
-
if (["bcsearch", "bandcamp"].includes(Query.source)) {
|
|
120
|
-
throw new Error("Bandcamp Search only works on the player!");
|
|
175
|
+
if (["bcsearch", "bandcamp"].includes(Query.source) && !this.info.sourceManagers.includes("bandcamp")) {
|
|
176
|
+
throw new Error("Bandcamp Search only works on the player (lavaplayer version < 2.2.0!");
|
|
121
177
|
}
|
|
122
178
|
let uri = `/loadtracks?identifier=`;
|
|
123
179
|
if (/^https?:\/\//.test(Query.query) || ["http", "https", "link", "uri"].includes(Query.source)) { // if it's a link simply encode it
|
|
124
|
-
uri += encodeURIComponent(
|
|
180
|
+
uri += encodeURIComponent(Query.query);
|
|
125
181
|
}
|
|
126
182
|
else { // if not make a query out of it
|
|
127
183
|
if (Query.source !== "local")
|
|
128
184
|
uri += `${Query.source}:`; // only add the query source string if it's not a local track
|
|
129
185
|
if (Query.source === "ftts")
|
|
130
|
-
uri += `//${encodeURIComponent(
|
|
186
|
+
uri += `//${encodeURIComponent(Query.query)}`;
|
|
131
187
|
else
|
|
132
|
-
uri += encodeURIComponent(
|
|
188
|
+
uri += encodeURIComponent(Query.query);
|
|
133
189
|
}
|
|
134
|
-
const res = await this.request(uri)
|
|
190
|
+
const res = await this.request(uri, (options) => {
|
|
191
|
+
if (typeof query === "object" && typeof query.extraQueryUrlParams?.size === "number" && query.extraQueryUrlParams?.size > 0) {
|
|
192
|
+
options.extraQueryUrlParams = query.extraQueryUrlParams;
|
|
193
|
+
}
|
|
194
|
+
});
|
|
135
195
|
// transform the data which can be Error, Track or Track[] to enfore [Track]
|
|
136
196
|
const resTracks = res.loadType === "playlist" ? res.data?.tracks : res.loadType === "track" ? [res.data] : res.loadType === "search" ? Array.isArray(res.data) ? res.data : [res.data] : [];
|
|
197
|
+
if (throwOnEmpty === true && (res.loadType === "empty" || !resTracks.length))
|
|
198
|
+
throw new Error("Nothing found");
|
|
137
199
|
return {
|
|
138
200
|
loadType: res.loadType,
|
|
139
201
|
exception: res.loadType === "error" ? res.data : null,
|
|
@@ -150,6 +212,19 @@ export class LavalinkNode {
|
|
|
150
212
|
tracks: (resTracks.length ? resTracks.map(t => this.NodeManager.LavalinkManager.utils.buildTrack(t, requestUser)) : [])
|
|
151
213
|
};
|
|
152
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Search something using the lavaSearchPlugin (filtered searches by types)
|
|
217
|
+
* @param query LavaSearchQuery Object
|
|
218
|
+
* @param requestUser Request User for creating the player(s)
|
|
219
|
+
* @param throwOnEmpty Wether to throw on an empty result or not
|
|
220
|
+
* @returns LavaSearchresult
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* // use player.search() instead
|
|
225
|
+
* player.node.lavaSearch({ types: ["playlist", "album"], query: "Rick Astley", source: "spotify" }, interaction.user);
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
153
228
|
async lavaSearch(query, requestUser, throwOnEmpty = false) {
|
|
154
229
|
const Query = this.NodeManager.LavalinkManager.utils.transformLavaSearchQuery(query);
|
|
155
230
|
if (Query.source)
|
|
@@ -163,9 +238,9 @@ export class LavalinkNode {
|
|
|
163
238
|
if (!this.info.plugins.find(v => v.name === "lavasrc-plugin"))
|
|
164
239
|
throw new RangeError(`there is no lavasrc-plugin available in the lavalink node: ${this.id}`);
|
|
165
240
|
const { request } = await this.rawRequest(`/loadsearch?query=${Query.source ? `${Query.source}:` : ""}${encodeURIComponent(Query.query)}${Query.types?.length ? `&types=${Query.types.join(",")}` : ""}`);
|
|
166
|
-
|
|
241
|
+
const res = (request.status === 204 ? {} : await request.json());
|
|
242
|
+
if (throwOnEmpty === true && !Object.entries(res).flat().filter(Boolean).length)
|
|
167
243
|
throw new Error("Nothing found");
|
|
168
|
-
const res = (request.statusCode === 204 ? {} : await request.body.json());
|
|
169
244
|
return {
|
|
170
245
|
tracks: res.tracks?.map(v => this.NodeManager.LavalinkManager.utils.buildTrack(v, requestUser)) || [],
|
|
171
246
|
albums: res.albums?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.NodeManager.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
|
|
@@ -177,8 +252,14 @@ export class LavalinkNode {
|
|
|
177
252
|
}
|
|
178
253
|
/**
|
|
179
254
|
* Update the Player State on the Lavalink Server
|
|
180
|
-
* @param data
|
|
181
|
-
* @returns
|
|
255
|
+
* @param data data to send to lavalink and sync locally
|
|
256
|
+
* @returns result from lavalink
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```ts
|
|
260
|
+
* // use player.search() instead
|
|
261
|
+
* player.node.updatePlayer({ guildId: player.guildId, playerOptions: { paused: true } }); // example to pause it
|
|
262
|
+
* ```
|
|
182
263
|
*/
|
|
183
264
|
async updatePlayer(data) {
|
|
184
265
|
if (!this.sessionId)
|
|
@@ -190,7 +271,7 @@ export class LavalinkNode {
|
|
|
190
271
|
r.headers["Content-Type"] = "application/json";
|
|
191
272
|
r.body = JSON.stringify(data.playerOptions);
|
|
192
273
|
if (data.noReplace) {
|
|
193
|
-
const url = new URL(`${this.
|
|
274
|
+
const url = new URL(`${this.restAddress}${r.path}`);
|
|
194
275
|
url.searchParams.append("noReplace", data.noReplace === true && typeof data.noReplace === "boolean" ? "true" : "false");
|
|
195
276
|
r.path = url.pathname + url.search;
|
|
196
277
|
}
|
|
@@ -200,7 +281,13 @@ export class LavalinkNode {
|
|
|
200
281
|
/**
|
|
201
282
|
* Destroys the Player on the Lavalink Server
|
|
202
283
|
* @param guildId
|
|
203
|
-
* @returns
|
|
284
|
+
* @returns request result
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```ts
|
|
288
|
+
* // use player.destroy() instead
|
|
289
|
+
* player.node.destroyPlayer(player.guildId);
|
|
290
|
+
* ```
|
|
204
291
|
*/
|
|
205
292
|
async destroyPlayer(guildId) {
|
|
206
293
|
if (!this.sessionId)
|
|
@@ -210,7 +297,15 @@ export class LavalinkNode {
|
|
|
210
297
|
/**
|
|
211
298
|
* Connect to the Lavalink Node
|
|
212
299
|
* @param sessionId Provide the Session Id of the previous connection, to resume the node and it's player(s)
|
|
213
|
-
* @returns
|
|
300
|
+
* @returns void
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* ```ts
|
|
304
|
+
* player.node.connect(); // if provided on bootup in managerOptions#nodes, this will be called automatically when doing lavalink.init()
|
|
305
|
+
*
|
|
306
|
+
* // or connect from a resuming session:
|
|
307
|
+
* player.node.connect("sessionId");
|
|
308
|
+
* ```
|
|
214
309
|
*/
|
|
215
310
|
connect(sessionId) {
|
|
216
311
|
if (this.connected)
|
|
@@ -230,13 +325,28 @@ export class LavalinkNode {
|
|
|
230
325
|
this.socket.on("message", this.message.bind(this));
|
|
231
326
|
this.socket.on("error", this.error.bind(this));
|
|
232
327
|
}
|
|
233
|
-
/**
|
|
328
|
+
/**
|
|
329
|
+
* Get the id of the node
|
|
330
|
+
*
|
|
331
|
+
* @example
|
|
332
|
+
* ```ts
|
|
333
|
+
* const nodeId = player.node.id;
|
|
334
|
+
* console.log("node id is: ", nodeId)
|
|
335
|
+
* ```
|
|
336
|
+
*/
|
|
234
337
|
get id() {
|
|
235
338
|
return this.options.id || `${this.options.host}:${this.options.port}`;
|
|
236
339
|
}
|
|
237
340
|
/**
|
|
238
341
|
* Destroys the Node-Connection (Websocket) and all player's of the node
|
|
239
|
-
* @
|
|
342
|
+
* @param destroyReason Destroyreason to use when destroying the players
|
|
343
|
+
* @param deleteNode wether to delete the nodte from the nodes list too, if false it will emit a disconnect. @default true
|
|
344
|
+
* @returns void
|
|
345
|
+
*
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* player.node.destroy("custom Player Destroy Reason", true);
|
|
349
|
+
* ```
|
|
240
350
|
*/
|
|
241
351
|
destroy(destroyReason, deleteNode = true) {
|
|
242
352
|
if (!this.connected)
|
|
@@ -258,14 +368,47 @@ export class LavalinkNode {
|
|
|
258
368
|
}
|
|
259
369
|
return;
|
|
260
370
|
}
|
|
261
|
-
/**
|
|
371
|
+
/**
|
|
372
|
+
* Returns if connected to the Node.
|
|
373
|
+
*
|
|
374
|
+
* @example
|
|
375
|
+
* ```ts
|
|
376
|
+
* const isConnected = player.node.connected;
|
|
377
|
+
* console.log("node is connected: ", isConnected ? "yes" : "no")
|
|
378
|
+
* ```
|
|
379
|
+
*/
|
|
262
380
|
get connected() {
|
|
263
381
|
if (!this.socket)
|
|
264
382
|
return false;
|
|
265
383
|
return this.socket.readyState === WebSocket.OPEN;
|
|
266
384
|
}
|
|
385
|
+
/**
|
|
386
|
+
* Returns the current ConnectionStatus
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* ```ts
|
|
390
|
+
* try {
|
|
391
|
+
* const statusOfConnection = player.node.connectionStatus;
|
|
392
|
+
* console.log("node's connection status is:", statusOfConnection)
|
|
393
|
+
* } catch (error) {
|
|
394
|
+
* console.error("no socket available?", error)
|
|
395
|
+
* }
|
|
396
|
+
* ```
|
|
397
|
+
*/
|
|
398
|
+
get connectionStatus() {
|
|
399
|
+
if (!this.socket)
|
|
400
|
+
throw new Error("no websocket was initialized yet");
|
|
401
|
+
return ["CONNECTING", "OPEN", "CLOSING", "CLOSED"][this.socket.readyState] || "UNKNOWN";
|
|
402
|
+
}
|
|
267
403
|
/**
|
|
268
404
|
* Gets all Players of a Node
|
|
405
|
+
* @returns array of players inside of lavalink
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* ```ts
|
|
409
|
+
* const node = lavalink.nodes.get("NODEID");
|
|
410
|
+
* const playersOfLavalink = await node?.fetchAllPlayers();
|
|
411
|
+
* ```
|
|
269
412
|
*/
|
|
270
413
|
async fetchAllPlayers() {
|
|
271
414
|
if (!this.sessionId)
|
|
@@ -278,6 +421,13 @@ export class LavalinkNode {
|
|
|
278
421
|
}
|
|
279
422
|
/**
|
|
280
423
|
* Gets specific Player Information
|
|
424
|
+
* @returns lavalink player object if player exists on lavalink
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* ```ts
|
|
428
|
+
* const node = lavalink.nodes.get("NODEID");
|
|
429
|
+
* const playerInformation = await node?.fetchPlayer("guildId");
|
|
430
|
+
* ```
|
|
281
431
|
*/
|
|
282
432
|
async fetchPlayer(guildId) {
|
|
283
433
|
if (!this.sessionId)
|
|
@@ -288,6 +438,13 @@ export class LavalinkNode {
|
|
|
288
438
|
* Updates the session with and enables/disables resuming and timeout
|
|
289
439
|
* @param resuming Whether resuming is enabled for this session or not
|
|
290
440
|
* @param timeout The timeout in seconds (default is 60s)
|
|
441
|
+
* @returns the result of the request
|
|
442
|
+
*
|
|
443
|
+
* @example
|
|
444
|
+
* ```ts
|
|
445
|
+
* const node = player.node || lavalink.nodes.get("NODEID");
|
|
446
|
+
* await node?.updateSession(true, 180e3); // will enable resuming for 180seconds
|
|
447
|
+
* ```
|
|
291
448
|
*/
|
|
292
449
|
async updateSession(resuming, timeout) {
|
|
293
450
|
if (!this.sessionId)
|
|
@@ -312,20 +469,35 @@ export class LavalinkNode {
|
|
|
312
469
|
*/
|
|
313
470
|
decode = {
|
|
314
471
|
/**
|
|
315
|
-
* Decode a single track into its info
|
|
316
|
-
* @param encoded
|
|
317
|
-
* @
|
|
472
|
+
* Decode a single track into its info
|
|
473
|
+
* @param encoded valid encoded base64 string from a track
|
|
474
|
+
* @param requester the requesteruser for building the track
|
|
475
|
+
* @returns decoded track from lavalink
|
|
476
|
+
*
|
|
477
|
+
* @example
|
|
478
|
+
* ```ts
|
|
479
|
+
* const encodedBase64 = 'QAACDgMACk5vIERpZ2dpdHkAC0JsYWNrc3RyZWV0AAAAAAAEo4AABjkxNjQ5NgABAB9odHRwczovL2RlZXplci5jb20vdHJhY2svOTE2NDk2AQBpaHR0cHM6Ly9lLWNkbnMtaW1hZ2VzLmR6Y2RuLm5ldC9pbWFnZXMvY292ZXIvZGFlN2EyNjViNzlmYjcxMjc4Y2RlMjUwNDg0OWQ2ZjcvMTAwMHgxMDAwLTAwMDAwMC04MC0wLTAuanBnAQAMVVNJUjE5NjAwOTc4AAZkZWV6ZXIBAChObyBEaWdnaXR5OiBUaGUgVmVyeSBCZXN0IE9mIEJsYWNrc3RyZWV0AQAjaHR0cHM6Ly93d3cuZGVlemVyLmNvbS9hbGJ1bS8xMDMyNTQBACJodHRwczovL3d3dy5kZWV6ZXIuY29tL2FydGlzdC8xODYxAQBqaHR0cHM6Ly9lLWNkbnMtaW1hZ2VzLmR6Y2RuLm5ldC9pbWFnZXMvYXJ0aXN0L2YxNmNhYzM2ZmVjMzkxZjczN2I3ZDQ4MmY1YWM3M2UzLzEwMDB4MTAwMC0wMDAwMDAtODAtMC0wLmpwZwEAT2h0dHBzOi8vY2RuLXByZXZpZXctYS5kemNkbi5uZXQvc3RyZWFtL2MtYTE1Yjg1NzFhYTYyMDBjMDQ0YmY1OWM3NmVkOTEyN2MtNi5tcDMAAAAAAAAAAAA=';
|
|
480
|
+
* const track = await player.node.decode.singleTrack(encodedBase64, interaction.user);
|
|
481
|
+
* ```
|
|
318
482
|
*/
|
|
319
483
|
singleTrack: async (encoded, requester) => {
|
|
320
484
|
if (!encoded)
|
|
321
485
|
throw new SyntaxError("No encoded (Base64 string) was provided");
|
|
322
486
|
// return the decoded + builded track
|
|
323
|
-
return this.NodeManager.LavalinkManager.utils
|
|
487
|
+
return this.NodeManager.LavalinkManager.utils?.buildTrack(await this.request(`/decodetrack?encodedTrack=${encodeURIComponent(encoded.replace(/\s/g, ""))}`), requester);
|
|
324
488
|
},
|
|
325
489
|
/**
|
|
490
|
+
* Decodes multiple tracks into their info
|
|
491
|
+
* @param encodeds valid encoded base64 string array from all tracks
|
|
492
|
+
* @param requester the requesteruser for building the tracks
|
|
493
|
+
* @returns array of all tracks you decoded
|
|
326
494
|
*
|
|
327
|
-
* @
|
|
328
|
-
*
|
|
495
|
+
* @example
|
|
496
|
+
* ```ts
|
|
497
|
+
* const encodedBase64_1 = 'QAACDgMACk5vIERpZ2dpdHkAC0JsYWNrc3RyZWV0AAAAAAAEo4AABjkxNjQ5NgABAB9odHRwczovL2RlZXplci5jb20vdHJhY2svOTE2NDk2AQBpaHR0cHM6Ly9lLWNkbnMtaW1hZ2VzLmR6Y2RuLm5ldC9pbWFnZXMvY292ZXIvZGFlN2EyNjViNzlmYjcxMjc4Y2RlMjUwNDg0OWQ2ZjcvMTAwMHgxMDAwLTAwMDAwMC04MC0wLTAuanBnAQAMVVNJUjE5NjAwOTc4AAZkZWV6ZXIBAChObyBEaWdnaXR5OiBUaGUgVmVyeSBCZXN0IE9mIEJsYWNrc3RyZWV0AQAjaHR0cHM6Ly93d3cuZGVlemVyLmNvbS9hbGJ1bS8xMDMyNTQBACJodHRwczovL3d3dy5kZWV6ZXIuY29tL2FydGlzdC8xODYxAQBqaHR0cHM6Ly9lLWNkbnMtaW1hZ2VzLmR6Y2RuLm5ldC9pbWFnZXMvYXJ0aXN0L2YxNmNhYzM2ZmVjMzkxZjczN2I3ZDQ4MmY1YWM3M2UzLzEwMDB4MTAwMC0wMDAwMDAtODAtMC0wLmpwZwEAT2h0dHBzOi8vY2RuLXByZXZpZXctYS5kemNkbi5uZXQvc3RyZWFtL2MtYTE1Yjg1NzFhYTYyMDBjMDQ0YmY1OWM3NmVkOTEyN2MtNi5tcDMAAAAAAAAAAAA=';
|
|
498
|
+
* const encodedBase64_2 = 'QAABJAMAClRhbGsgYSBMb3QACjQwNHZpbmNlbnQAAAAAAAHr1gBxTzpodHRwczovL2FwaS12Mi5zb3VuZGNsb3VkLmNvbS9tZWRpYS9zb3VuZGNsb3VkOnRyYWNrczo4NTE0MjEwNzYvMzUyYTRiOTAtNzYxOS00M2E5LWJiOGItMjIxMzE0YzFjNjNhL3N0cmVhbS9obHMAAQAsaHR0cHM6Ly9zb3VuZGNsb3VkLmNvbS80MDR2aW5jZW50L3RhbGstYS1sb3QBADpodHRwczovL2kxLnNuZGNkbi5jb20vYXJ0d29ya3MtRTN1ek5Gc0Y4QzBXLTAtb3JpZ2luYWwuanBnAQAMUVpITkExOTg1Nzg0AApzb3VuZGNsb3VkAAAAAAAAAAA=';
|
|
499
|
+
* const tracks = await player.node.decode.multipleTracks([encodedBase64_1, encodedBase64_2], interaction.user);
|
|
500
|
+
* ```
|
|
329
501
|
*/
|
|
330
502
|
multipleTracks: async (encodeds, requester) => {
|
|
331
503
|
if (!Array.isArray(encodeds) || !encodeds.every(v => typeof v === "string" && v.length > 1))
|
|
@@ -341,14 +513,24 @@ export class LavalinkNode {
|
|
|
341
513
|
};
|
|
342
514
|
/**
|
|
343
515
|
* Request Lavalink statistics.
|
|
344
|
-
* @returns
|
|
516
|
+
* @returns the lavalink node stats
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* ```ts
|
|
520
|
+
* const lavalinkStats = await player.node.fetchStats();
|
|
521
|
+
* ```
|
|
345
522
|
*/
|
|
346
523
|
async fetchStats() {
|
|
347
524
|
return await this.request(`/stats`);
|
|
348
525
|
}
|
|
349
526
|
/**
|
|
350
527
|
* Request Lavalink version.
|
|
351
|
-
* @returns
|
|
528
|
+
* @returns the current used lavalink version
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* ```ts
|
|
532
|
+
* const lavalinkVersion = await player.node.fetchVersion();
|
|
533
|
+
* ```
|
|
352
534
|
*/
|
|
353
535
|
async fetchVersion() {
|
|
354
536
|
// need to adjust path for no-prefix version info
|
|
@@ -356,7 +538,14 @@ export class LavalinkNode {
|
|
|
356
538
|
}
|
|
357
539
|
/**
|
|
358
540
|
* Request Lavalink information.
|
|
359
|
-
* @returns
|
|
541
|
+
* @returns lavalink info object
|
|
542
|
+
*
|
|
543
|
+
* @example
|
|
544
|
+
* ```ts
|
|
545
|
+
* const lavalinkInfo = await player.node.fetchInfo();
|
|
546
|
+
* const availablePlugins:string[] = lavalinkInfo.plugins.map(plugin => plugin.name);
|
|
547
|
+
* const availableSources:string[] = lavalinkInfo.sourceManagers;
|
|
548
|
+
* ```
|
|
360
549
|
*/
|
|
361
550
|
async fetchInfo() {
|
|
362
551
|
return await this.request(`/info`);
|
|
@@ -366,7 +555,15 @@ export class LavalinkNode {
|
|
|
366
555
|
*/
|
|
367
556
|
routePlannerApi = {
|
|
368
557
|
/**
|
|
369
|
-
* Get routplanner Info from Lavalink
|
|
558
|
+
* Get routplanner Info from Lavalink for ip rotation
|
|
559
|
+
* @returns the status of the routeplanner
|
|
560
|
+
*
|
|
561
|
+
* @example
|
|
562
|
+
* ```ts
|
|
563
|
+
* const routePlannerStatus = await player.node.routePlannerApi.getStatus();
|
|
564
|
+
* const usedBlock = routePlannerStatus.details?.ipBlock;
|
|
565
|
+
* const currentIp = routePlannerStatus.currentAddress;
|
|
566
|
+
* ```
|
|
370
567
|
*/
|
|
371
568
|
getStatus: async () => {
|
|
372
569
|
if (!this.sessionId)
|
|
@@ -374,8 +571,14 @@ export class LavalinkNode {
|
|
|
374
571
|
return await this.request(`/routeplanner/status`);
|
|
375
572
|
},
|
|
376
573
|
/**
|
|
377
|
-
* Release blacklisted IP address into pool of IPs
|
|
574
|
+
* Release blacklisted IP address into pool of IPs for ip rotation
|
|
378
575
|
* @param address IP address
|
|
576
|
+
* @returns request data of the request
|
|
577
|
+
*
|
|
578
|
+
* @example
|
|
579
|
+
* ```ts
|
|
580
|
+
* await player.node.routePlannerApi.unmarkFailedAddress("ipv6address");
|
|
581
|
+
* ```
|
|
379
582
|
*/
|
|
380
583
|
unmarkFailedAddress: async (address) => {
|
|
381
584
|
if (!this.sessionId)
|
|
@@ -389,6 +592,12 @@ export class LavalinkNode {
|
|
|
389
592
|
},
|
|
390
593
|
/**
|
|
391
594
|
* Release all blacklisted IP addresses into pool of IPs
|
|
595
|
+
* @returns request data of the request
|
|
596
|
+
*
|
|
597
|
+
* @example
|
|
598
|
+
* ```ts
|
|
599
|
+
* await player.node.routePlannerApi.unmarkAllFailedAddresses();
|
|
600
|
+
* ```
|
|
392
601
|
*/
|
|
393
602
|
unmarkAllFailedAddresses: async () => {
|
|
394
603
|
if (!this.sessionId)
|
|
@@ -400,7 +609,7 @@ export class LavalinkNode {
|
|
|
400
609
|
});
|
|
401
610
|
}
|
|
402
611
|
};
|
|
403
|
-
/**
|
|
612
|
+
/** @private Utils for validating the */
|
|
404
613
|
validate() {
|
|
405
614
|
if (!this.options.authorization)
|
|
406
615
|
throw new SyntaxError("LavalinkNode requires 'authorization'");
|
|
@@ -409,6 +618,12 @@ export class LavalinkNode {
|
|
|
409
618
|
if (!this.options.port)
|
|
410
619
|
throw new SyntaxError("LavalinkNode requires 'port'");
|
|
411
620
|
}
|
|
621
|
+
/**
|
|
622
|
+
* Sync the data of the player you make an action to lavalink to
|
|
623
|
+
* @param data data to use to update the player
|
|
624
|
+
* @param res result data from lavalink, to override, if available
|
|
625
|
+
* @returns boolean
|
|
626
|
+
*/
|
|
412
627
|
syncPlayerData(data, res) {
|
|
413
628
|
if (typeof data === "object" && typeof data?.guildId === "string" && typeof data.playerOptions === "object" && Object.keys(data.playerOptions).length > 1) {
|
|
414
629
|
const player = this.NodeManager.LavalinkManager.getPlayer(data.guildId);
|
|
@@ -419,8 +634,9 @@ export class LavalinkNode {
|
|
|
419
634
|
player.playing = !data.playerOptions.paused;
|
|
420
635
|
}
|
|
421
636
|
if (typeof data.playerOptions.position === "number") {
|
|
422
|
-
player.position = data.playerOptions.position;
|
|
637
|
+
// player.position = data.playerOptions.position;
|
|
423
638
|
player.lastPosition = data.playerOptions.position;
|
|
639
|
+
player.lastPositionChange = Date.now();
|
|
424
640
|
}
|
|
425
641
|
if (typeof data.playerOptions.voice !== "undefined")
|
|
426
642
|
player.voice = data.playerOptions.voice;
|
|
@@ -471,9 +687,22 @@ export class LavalinkNode {
|
|
|
471
687
|
}
|
|
472
688
|
return true;
|
|
473
689
|
}
|
|
474
|
-
|
|
690
|
+
/**
|
|
691
|
+
* Get the rest Adress for making requests
|
|
692
|
+
*/
|
|
693
|
+
get restAddress() {
|
|
475
694
|
return `http${this.options.secure ? "s" : ""}://${this.options.host}:${this.options.port}`;
|
|
476
695
|
}
|
|
696
|
+
/**
|
|
697
|
+
* Reconnect to the lavalink node
|
|
698
|
+
* @param instaReconnect @default false wether to instantly try to reconnect
|
|
699
|
+
* @returns void
|
|
700
|
+
*
|
|
701
|
+
* @example
|
|
702
|
+
* ```ts
|
|
703
|
+
* await player.node.reconnect();
|
|
704
|
+
* ```
|
|
705
|
+
*/
|
|
477
706
|
reconnect(instaReconnect = false) {
|
|
478
707
|
if (instaReconnect) {
|
|
479
708
|
if (this.reconnectAttempts >= this.options.retryAmount) {
|
|
@@ -501,28 +730,32 @@ export class LavalinkNode {
|
|
|
501
730
|
this.reconnectAttempts++;
|
|
502
731
|
}, this.options.retryDelay || 1000);
|
|
503
732
|
}
|
|
733
|
+
/** @private util function for handling opening events from websocket */
|
|
504
734
|
async open() {
|
|
505
735
|
if (this.reconnectTimeout)
|
|
506
736
|
clearTimeout(this.reconnectTimeout);
|
|
507
737
|
// reset the reconnect attempts amount
|
|
508
738
|
this.reconnectAttempts = 1;
|
|
509
|
-
this.info = await this.fetchInfo().catch(() => null);
|
|
739
|
+
this.info = await this.fetchInfo().catch((e) => (console.error(e, "ON-OPEN-FETCH"), null));
|
|
510
740
|
if (!this.info && ["v3", "v4"].includes(this.version)) {
|
|
511
|
-
const errorString = `Lavalink Node (${this.
|
|
741
|
+
const errorString = `Lavalink Node (${this.restAddress}) does not provide any /${this.version}/info`;
|
|
512
742
|
throw new Error(errorString);
|
|
513
743
|
}
|
|
514
744
|
this.NodeManager.emit("connect", this);
|
|
515
745
|
}
|
|
746
|
+
/** @private util function for handling closing events from websocket */
|
|
516
747
|
close(code, reason) {
|
|
517
748
|
this.NodeManager.emit("disconnect", this, { code, reason });
|
|
518
749
|
if (code !== 1000 || reason !== "Node-Destroy")
|
|
519
750
|
this.reconnect();
|
|
520
751
|
}
|
|
752
|
+
/** @private util function for handling error events from websocket */
|
|
521
753
|
error(error) {
|
|
522
754
|
if (!error)
|
|
523
755
|
return;
|
|
524
756
|
this.NodeManager.emit("error", this, error);
|
|
525
757
|
}
|
|
758
|
+
/** @private util function for handling message events from websocket */
|
|
526
759
|
async message(d) {
|
|
527
760
|
if (Array.isArray(d))
|
|
528
761
|
d = Buffer.concat(d);
|
|
@@ -543,42 +776,15 @@ export class LavalinkNode {
|
|
|
543
776
|
if (!player)
|
|
544
777
|
return;
|
|
545
778
|
const oldPlayer = player?.toJSON();
|
|
546
|
-
|
|
547
|
-
clearInterval(player.get("internal_updateInterval"));
|
|
548
|
-
// override the position
|
|
549
|
-
player.position = payload.state.position || 0;
|
|
779
|
+
player.lastPositionChange = Date.now();
|
|
550
780
|
player.lastPosition = payload.state.position || 0;
|
|
551
781
|
player.connected = payload.state.connected;
|
|
552
782
|
player.ping.ws = payload.state.ping >= 0 ? payload.state.ping : player.ping.ws <= 0 && player.connected ? null : player.ping.ws || 0;
|
|
553
783
|
if (!player.createdTimeStamp && payload.state.time)
|
|
554
784
|
player.createdTimeStamp = payload.state.time;
|
|
555
|
-
if (
|
|
556
|
-
player.
|
|
557
|
-
|
|
558
|
-
if (player.filterManager.filterUpdatedState >= 1) {
|
|
559
|
-
player.filterManager.filterUpdatedState++;
|
|
560
|
-
const maxMins = 8;
|
|
561
|
-
const currentDuration = player.queue.current?.info?.duration || 0;
|
|
562
|
-
if (currentDuration <= maxMins * 6e4 || isAbsolute(player.queue.current?.info?.uri)) {
|
|
563
|
-
if (player.filterManager.filterUpdatedState >= ((this.NodeManager.LavalinkManager.options.playerOptions.clientBasedPositionUpdateInterval || 250) > 400 ? 2 : 3)) {
|
|
564
|
-
player.filterManager.filterUpdatedState = 0;
|
|
565
|
-
player.seek(player.position);
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
else {
|
|
569
|
-
player.filterManager.filterUpdatedState = 0;
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
}, this.NodeManager.LavalinkManager.options.playerOptions.clientBasedPositionUpdateInterval || 250));
|
|
573
|
-
}
|
|
574
|
-
else {
|
|
575
|
-
if (player.filterManager.filterUpdatedState >= 1) { // if no interval but instafix available, findable via the "filterUpdatedState" property
|
|
576
|
-
const maxMins = 8;
|
|
577
|
-
const currentDuration = player.queue.current?.info?.duration || 0;
|
|
578
|
-
if (currentDuration <= maxMins * 6e4 || isAbsolute(player.queue.current?.info?.uri))
|
|
579
|
-
player.seek(player.position);
|
|
580
|
-
player.filterManager.filterUpdatedState = 0;
|
|
581
|
-
}
|
|
785
|
+
if (player.filterManager.filterUpdatedState === true && ((player.queue.current?.info?.duration || 0) <= (player.LavalinkManager.options.advancedOptions.maxFilterFixDuration || 600000) || isAbsolute(player.queue.current?.info?.uri))) {
|
|
786
|
+
player.filterManager.filterUpdatedState = false;
|
|
787
|
+
await player.seek(player.position);
|
|
582
788
|
}
|
|
583
789
|
this.NodeManager.LavalinkManager.emit("playerUpdate", oldPlayer, player);
|
|
584
790
|
}
|
|
@@ -598,7 +804,7 @@ export class LavalinkNode {
|
|
|
598
804
|
return;
|
|
599
805
|
}
|
|
600
806
|
}
|
|
601
|
-
|
|
807
|
+
/** @private middleware util function for handling all kind of events from websocket */
|
|
602
808
|
async handleEvent(payload) {
|
|
603
809
|
if (!payload.guildId)
|
|
604
810
|
return;
|
|
@@ -625,7 +831,7 @@ export class LavalinkNode {
|
|
|
625
831
|
this.SponsorBlockSegmentLoaded(player, player.queue.current, payload);
|
|
626
832
|
break;
|
|
627
833
|
case "SegmentSkipped":
|
|
628
|
-
this.
|
|
834
|
+
this.SponsorBlockSegmentSkipped(player, player.queue.current, payload);
|
|
629
835
|
break;
|
|
630
836
|
case "ChaptersLoaded":
|
|
631
837
|
this.SponsorBlockChaptersLoaded(player, player.queue.current, payload);
|
|
@@ -639,7 +845,7 @@ export class LavalinkNode {
|
|
|
639
845
|
}
|
|
640
846
|
return;
|
|
641
847
|
}
|
|
642
|
-
|
|
848
|
+
/** @private util function for handling trackStart event */
|
|
643
849
|
trackStart(player, track, payload) {
|
|
644
850
|
player.playing = true;
|
|
645
851
|
player.paused = false;
|
|
@@ -648,6 +854,7 @@ export class LavalinkNode {
|
|
|
648
854
|
return;
|
|
649
855
|
return this.NodeManager.LavalinkManager.emit("trackStart", player, track, payload);
|
|
650
856
|
}
|
|
857
|
+
/** @private util function for handling trackEnd event */
|
|
651
858
|
async trackEnd(player, track, payload) {
|
|
652
859
|
// If there are no songs in the queue
|
|
653
860
|
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.get("internal_stopPlaying")))
|
|
@@ -684,6 +891,7 @@ export class LavalinkNode {
|
|
|
684
891
|
// play track if autoSkip is true
|
|
685
892
|
return this.NodeManager.LavalinkManager.options.autoSkip && player.play({ noReplace: true });
|
|
686
893
|
}
|
|
894
|
+
/** @private util function for handling trackStuck event */
|
|
687
895
|
async trackStuck(player, track, payload) {
|
|
688
896
|
this.NodeManager.LavalinkManager.emit("trackStuck", player, track, payload);
|
|
689
897
|
// If there are no songs in the queue
|
|
@@ -697,6 +905,7 @@ export class LavalinkNode {
|
|
|
697
905
|
// play track if autoSkip is true
|
|
698
906
|
return (this.NodeManager.LavalinkManager.options.autoSkip && player.queue.current) && player.play({ noReplace: true });
|
|
699
907
|
}
|
|
908
|
+
/** @private util function for handling trackError event */
|
|
700
909
|
async trackError(player, track, payload) {
|
|
701
910
|
this.NodeManager.LavalinkManager.emit("trackError", player, track, payload);
|
|
702
911
|
return; // get's handled by trackEnd
|
|
@@ -711,23 +920,37 @@ export class LavalinkNode {
|
|
|
711
920
|
// play track if autoSkip is true
|
|
712
921
|
return (this.NodeManager.LavalinkManager.options.autoSkip && player.queue.current) && player.play({ noReplace: true });
|
|
713
922
|
}
|
|
923
|
+
/** @private util function for handling socketClosed event */
|
|
714
924
|
socketClosed(player, payload) {
|
|
715
925
|
return this.NodeManager.LavalinkManager.emit("playerSocketClosed", player, payload);
|
|
716
926
|
}
|
|
717
|
-
|
|
927
|
+
/** @private util function for handling SponsorBlock Segmentloaded event */
|
|
718
928
|
SponsorBlockSegmentLoaded(player, track, payload) {
|
|
719
929
|
return this.NodeManager.LavalinkManager.emit("SegmentsLoaded", player, track, payload);
|
|
720
930
|
}
|
|
721
|
-
|
|
931
|
+
/** @private util function for handling SponsorBlock SegmentSkipped event */
|
|
932
|
+
SponsorBlockSegmentSkipped(player, track, payload) {
|
|
722
933
|
return this.NodeManager.LavalinkManager.emit("SegmentSkipped", player, track, payload);
|
|
723
934
|
}
|
|
935
|
+
/** @private util function for handling SponsorBlock Chaptersloaded event */
|
|
724
936
|
SponsorBlockChaptersLoaded(player, track, payload) {
|
|
725
937
|
return this.NodeManager.LavalinkManager.emit("ChaptersLoaded", player, track, payload);
|
|
726
938
|
}
|
|
939
|
+
/** @private util function for handling SponsorBlock Chaptersstarted event */
|
|
727
940
|
SponsorBlockChapterStarted(player, track, payload) {
|
|
728
941
|
return this.NodeManager.LavalinkManager.emit("ChapterStarted", player, track, payload);
|
|
729
942
|
}
|
|
730
|
-
|
|
943
|
+
/**
|
|
944
|
+
* Get the current sponsorblocks for the sponsorblock plugin
|
|
945
|
+
* @param player passthrough the player
|
|
946
|
+
* @returns sponsorblock seggment from lavalink
|
|
947
|
+
*
|
|
948
|
+
* @example
|
|
949
|
+
* ```ts
|
|
950
|
+
* // use it on the player via player.getSponsorBlock();
|
|
951
|
+
* const sponsorBlockSegments = await player.node.getSponsorBlock(player);
|
|
952
|
+
* ```
|
|
953
|
+
*/
|
|
731
954
|
async getSponsorBlock(player) {
|
|
732
955
|
// no plugin enabled
|
|
733
956
|
if (!this.info.plugins.find(v => v.name === "sponsorblock-plugin"))
|
|
@@ -735,6 +958,17 @@ export class LavalinkNode {
|
|
|
735
958
|
// do the request
|
|
736
959
|
return await this.request(`/sessions/${this.sessionId}/players/${player.guildId}/sponsorblock/categories`);
|
|
737
960
|
}
|
|
961
|
+
/**
|
|
962
|
+
* Set the current sponsorblocks for the sponsorblock plugin
|
|
963
|
+
* @param player passthrough the player
|
|
964
|
+
* @returns void
|
|
965
|
+
*
|
|
966
|
+
* @example
|
|
967
|
+
* ```ts
|
|
968
|
+
* // use it on the player via player.setSponsorBlock();
|
|
969
|
+
* const sponsorBlockSegments = await player.node.setSponsorBlock(player, ["sponsor", "selfpromo"]);
|
|
970
|
+
* ```
|
|
971
|
+
*/
|
|
738
972
|
async setSponsorBlock(player, segments = ["sponsor", "selfpromo"]) {
|
|
739
973
|
// no plugin enabled
|
|
740
974
|
if (!this.info.plugins.find(v => v.name === "sponsorblock-plugin"))
|
|
@@ -753,6 +987,17 @@ export class LavalinkNode {
|
|
|
753
987
|
});
|
|
754
988
|
return;
|
|
755
989
|
}
|
|
990
|
+
/**
|
|
991
|
+
* Delete the sponsorblock plugins
|
|
992
|
+
* @param player passthrough the player
|
|
993
|
+
* @returns void
|
|
994
|
+
*
|
|
995
|
+
* @example
|
|
996
|
+
* ```ts
|
|
997
|
+
* // use it on the player via player.deleteSponsorBlock();
|
|
998
|
+
* const sponsorBlockSegments = await player.node.deleteSponsorBlock(player);
|
|
999
|
+
* ```
|
|
1000
|
+
*/
|
|
756
1001
|
async deleteSponsorBlock(player) {
|
|
757
1002
|
// no plugin enabled
|
|
758
1003
|
if (!this.info.plugins.find(v => v.name === "sponsorblock-plugin"))
|
|
@@ -763,7 +1008,7 @@ export class LavalinkNode {
|
|
|
763
1008
|
});
|
|
764
1009
|
return;
|
|
765
1010
|
}
|
|
766
|
-
|
|
1011
|
+
/** private util function for handling the queue end event */
|
|
767
1012
|
async queueEnd(player, track, payload) {
|
|
768
1013
|
// add previous track to the queue!
|
|
769
1014
|
player.queue.current = null;
|