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