lavalink-client 1.1.12 → 1.1.14
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/dist/cjs/structures/Node.d.ts +4 -3
- package/dist/cjs/structures/Node.js +64 -9
- package/dist/cjs/structures/NodeManager.d.ts +16 -0
- package/dist/cjs/structures/NodeManager.js +53 -0
- package/dist/cjs/structures/Player.d.ts +4 -11
- package/dist/cjs/structures/Player.js +7 -63
- package/dist/cjs/structures/Utils.d.ts +18 -0
- package/dist/cjs/structures/Utils.js +26 -0
- package/dist/esm/structures/Node.d.ts +4 -3
- package/dist/esm/structures/Node.js +64 -9
- package/dist/esm/structures/NodeManager.d.ts +16 -0
- package/dist/esm/structures/NodeManager.js +53 -0
- package/dist/esm/structures/Player.d.ts +4 -11
- package/dist/esm/structures/Player.js +7 -63
- package/dist/esm/structures/Utils.d.ts +18 -0
- package/dist/esm/structures/Utils.js +26 -0
- package/dist/types/structures/Node.d.ts +4 -3
- package/dist/types/structures/NodeManager.d.ts +16 -0
- package/dist/types/structures/Player.d.ts +4 -11
- package/dist/types/structures/Utils.d.ts +18 -0
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Dispatcher, Pool } from "undici";
|
|
3
3
|
import { NodeManager } from "./NodeManager";
|
|
4
4
|
import internal from "stream";
|
|
5
|
-
import { InvalidLavalinkRestRequest, LavalinkPlayer, PlayerUpdateInfo, RoutePlanner, Session, Base64, SearchResult } from "./Utils";
|
|
5
|
+
import { InvalidLavalinkRestRequest, LavalinkPlayer, PlayerUpdateInfo, RoutePlanner, Session, Base64, SearchResult, LavaSearchResponse, LavaSearchQuery, SearchQuery } from "./Utils";
|
|
6
6
|
import { DestroyReasonsType } from "./Player";
|
|
7
7
|
import { Track } from "./Track";
|
|
8
8
|
/** Modifies any outgoing REST requests. */
|
|
@@ -135,7 +135,8 @@ export declare class LavalinkNode {
|
|
|
135
135
|
* @returns The returned data
|
|
136
136
|
*/
|
|
137
137
|
request(endpoint: string, modify?: ModifyRequest, parseAsText?: boolean): Promise<unknown>;
|
|
138
|
-
search(
|
|
138
|
+
search(query: SearchQuery, requestUser: unknown): Promise<SearchResult>;
|
|
139
|
+
lavaSearch(query: LavaSearchQuery, requestUser: unknown): Promise<SearchResult | LavaSearchResponse>;
|
|
139
140
|
/**
|
|
140
141
|
* Update the Player State on the Lavalink Server
|
|
141
142
|
* @param data
|
|
@@ -160,7 +161,7 @@ export declare class LavalinkNode {
|
|
|
160
161
|
* Destroys the Node-Connection (Websocket) and all player's of the node
|
|
161
162
|
* @returns
|
|
162
163
|
*/
|
|
163
|
-
destroy(destroyReason?: DestroyReasonsType): void;
|
|
164
|
+
destroy(destroyReason?: DestroyReasonsType, deleteNode?: boolean): void;
|
|
164
165
|
/** Returns if connected to the Node. */
|
|
165
166
|
get connected(): boolean;
|
|
166
167
|
/**
|
|
@@ -96,8 +96,23 @@ class LavalinkNode {
|
|
|
96
96
|
throw new Error(`Node Request resulted into an error, request-URL: ${url} | headers: ${JSON.stringify(request.headers)}`);
|
|
97
97
|
return parseAsText ? await request.body.text() : await request.body.json();
|
|
98
98
|
}
|
|
99
|
-
async search(
|
|
100
|
-
const
|
|
99
|
+
async search(query, requestUser) {
|
|
100
|
+
const Query = this.NodeManager.LavalinkManager.utils.transformQuery(query);
|
|
101
|
+
if (/^https?:\/\//.test(Query.query))
|
|
102
|
+
this.NodeManager.LavalinkManager.utils.validateQueryString(this, Query.source);
|
|
103
|
+
else if (Query.source)
|
|
104
|
+
this.NodeManager.LavalinkManager.utils.validateSourceString(this, Query.source);
|
|
105
|
+
if (["bcsearch", "bandcamp"].includes(Query.source)) {
|
|
106
|
+
throw new Error("Bandcamp Search only works on the player!");
|
|
107
|
+
}
|
|
108
|
+
let uri = `/loadtracks?identifier=`;
|
|
109
|
+
if (!/^https?:\/\//.test(Query.query))
|
|
110
|
+
uri += `${Query.source}:`;
|
|
111
|
+
if (Query.source === "ftts")
|
|
112
|
+
uri += `//${encodeURIComponent(encodeURI(decodeURIComponent(Query.query)))}`;
|
|
113
|
+
else
|
|
114
|
+
uri += encodeURIComponent(decodeURIComponent(Query.query));
|
|
115
|
+
const res = await this.request(uri);
|
|
101
116
|
// transform the data which can be Error, Track or Track[] to enfore [Track]
|
|
102
117
|
const resTracks = res.loadType === "playlist" ? res.data?.tracks : res.loadType === "track" ? [res.data] : res.loadType === "search" ? Array.isArray(res.data) ? res.data : [res.data] : [];
|
|
103
118
|
return {
|
|
@@ -115,6 +130,28 @@ class LavalinkNode {
|
|
|
115
130
|
tracks: (resTracks.length ? resTracks.map(t => this.NodeManager.LavalinkManager.utils.buildTrack(t, requestUser)) : [])
|
|
116
131
|
};
|
|
117
132
|
}
|
|
133
|
+
async lavaSearch(query, requestUser) {
|
|
134
|
+
const Query = this.NodeManager.LavalinkManager.utils.transformLavaSearchQuery(query);
|
|
135
|
+
if (Query.source)
|
|
136
|
+
this.NodeManager.LavalinkManager.utils.validateSourceString(this, Query.source);
|
|
137
|
+
if (/^https?:\/\//.test(Query.query))
|
|
138
|
+
return await this.search({ query: Query.query, source: Query.source }, requestUser);
|
|
139
|
+
if (!["spsearch", "sprec", "amsearch", "dzsearch", "dzisrc", "ytmsearch", "ytsearch"].includes(Query.source))
|
|
140
|
+
throw new SyntaxError(`Query.source must be a source from LavaSrc: "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "ytmsearch" | "ytsearch"`);
|
|
141
|
+
if (!this.info.plugins.find(v => v.name === "lavasearch-plugin"))
|
|
142
|
+
throw new RangeError(`there is no lavasearch-plugin available in the lavalink node: ${this.id}`);
|
|
143
|
+
if (!this.info.plugins.find(v => v.name === "lavasrc-plugin"))
|
|
144
|
+
throw new RangeError(`there is no lavasrc-plugin available in the lavalink node: ${this.id}`);
|
|
145
|
+
const res = await this.request(`/loadsearch?query=${Query.source ? `${Query.source}:` : ""}${encodeURIComponent(Query.query)}${Query.types?.length ? `&types=${Query.types.join(",")}` : ""}`);
|
|
146
|
+
return {
|
|
147
|
+
tracks: res.tracks?.map(v => this.NodeManager.LavalinkManager.utils.buildTrack(v, requestUser)) || [],
|
|
148
|
+
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)) })) || [],
|
|
149
|
+
artists: res.artists?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.NodeManager.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
|
|
150
|
+
playlists: res.playlists?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.NodeManager.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
|
|
151
|
+
texts: res.texts?.map(v => ({ text: v.text, pluginInfo: v?.plugin || v.pluginInfo })) || [],
|
|
152
|
+
pluginInfo: res.pluginInfo || res?.plugin
|
|
153
|
+
};
|
|
154
|
+
}
|
|
118
155
|
/**
|
|
119
156
|
* Update the Player State on the Lavalink Server
|
|
120
157
|
* @param data
|
|
@@ -168,7 +205,7 @@ class LavalinkNode {
|
|
|
168
205
|
}
|
|
169
206
|
this.socket = new ws_1.default(`ws${this.options.secure ? "s" : ""}://${this.options.host}:${this.options.port}/v4/websocket`, { headers });
|
|
170
207
|
this.socket.on("open", this.open.bind(this));
|
|
171
|
-
this.socket.on("close", this.close
|
|
208
|
+
this.socket.on("close", (code, reason) => this.close(code, reason?.toString()));
|
|
172
209
|
this.socket.on("message", this.message.bind(this));
|
|
173
210
|
this.socket.on("error", this.error.bind(this));
|
|
174
211
|
}
|
|
@@ -180,19 +217,24 @@ class LavalinkNode {
|
|
|
180
217
|
* Destroys the Node-Connection (Websocket) and all player's of the node
|
|
181
218
|
* @returns
|
|
182
219
|
*/
|
|
183
|
-
destroy(destroyReason) {
|
|
220
|
+
destroy(destroyReason, deleteNode = true) {
|
|
184
221
|
if (!this.connected)
|
|
185
222
|
return;
|
|
186
223
|
const players = this.NodeManager.LavalinkManager.players.filter(p => p.node.id == this.id);
|
|
187
224
|
if (players)
|
|
188
225
|
players.forEach(p => p.destroy(destroyReason || Player_1.DestroyReasons.NodeDestroy));
|
|
189
|
-
this.socket.close(1000, "
|
|
226
|
+
this.socket.close(1000, "Node-Destroy");
|
|
190
227
|
this.socket.removeAllListeners();
|
|
191
228
|
this.socket = null;
|
|
192
229
|
this.reconnectAttempts = 1;
|
|
193
230
|
clearTimeout(this.reconnectTimeout);
|
|
194
|
-
|
|
195
|
-
|
|
231
|
+
if (deleteNode) {
|
|
232
|
+
this.NodeManager.emit("destroy", this, destroyReason);
|
|
233
|
+
this.NodeManager.nodes.delete(this.id);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
this.NodeManager.emit("disconnect", this, { code: 1000, reason: destroyReason });
|
|
237
|
+
}
|
|
196
238
|
return;
|
|
197
239
|
}
|
|
198
240
|
/** Returns if connected to the Node. */
|
|
@@ -406,7 +448,20 @@ class LavalinkNode {
|
|
|
406
448
|
get poolAddress() {
|
|
407
449
|
return `http${this.options.secure ? "s" : ""}://${this.options.host}:${this.options.port}`;
|
|
408
450
|
}
|
|
409
|
-
reconnect() {
|
|
451
|
+
reconnect(instaReconnect = false) {
|
|
452
|
+
if (instaReconnect) {
|
|
453
|
+
if (this.reconnectAttempts >= this.options.retryAmount) {
|
|
454
|
+
const error = new Error(`Unable to connect after ${this.options.retryAmount} attempts.`);
|
|
455
|
+
this.NodeManager.emit("error", this, error);
|
|
456
|
+
return this.destroy(Player_1.DestroyReasons.NodeReconnectFail);
|
|
457
|
+
}
|
|
458
|
+
this.socket.removeAllListeners();
|
|
459
|
+
this.socket = null;
|
|
460
|
+
this.NodeManager.emit("reconnecting", this);
|
|
461
|
+
this.connect();
|
|
462
|
+
this.reconnectAttempts++;
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
410
465
|
this.reconnectTimeout = setTimeout(() => {
|
|
411
466
|
if (this.reconnectAttempts >= this.options.retryAmount) {
|
|
412
467
|
const error = new Error(`Unable to connect after ${this.options.retryAmount} attempts.`);
|
|
@@ -437,7 +492,7 @@ class LavalinkNode {
|
|
|
437
492
|
}
|
|
438
493
|
close(code, reason) {
|
|
439
494
|
this.NodeManager.emit("disconnect", this, { code, reason });
|
|
440
|
-
if (code !== 1000 || reason !== "
|
|
495
|
+
if (code !== 1000 || reason !== "Node-Destroy")
|
|
441
496
|
this.reconnect();
|
|
442
497
|
}
|
|
443
498
|
error(error) {
|
|
@@ -54,6 +54,22 @@ export declare interface NodeManager {
|
|
|
54
54
|
export declare class NodeManager extends EventEmitter {
|
|
55
55
|
nodes: MiniMap<string, LavalinkNode>;
|
|
56
56
|
constructor(LavalinkManager: LavalinkManager);
|
|
57
|
+
/**
|
|
58
|
+
* Disconnects all Nodes from lavalink ws sockets
|
|
59
|
+
* @param deleteAllNodes if the nodes should also be deleted from nodeManager.nodes
|
|
60
|
+
* @returns amount of disconnected Nodes
|
|
61
|
+
*/
|
|
62
|
+
disconnectAll(deleteAllNodes?: boolean): Promise<number>;
|
|
63
|
+
/**
|
|
64
|
+
* Connects all not connected nodes
|
|
65
|
+
* @returns Amount of connected Nodes
|
|
66
|
+
*/
|
|
67
|
+
connectAll(): Promise<number>;
|
|
68
|
+
/**
|
|
69
|
+
* Forcefully reconnects all nodes
|
|
70
|
+
* @returns amount of nodes
|
|
71
|
+
*/
|
|
72
|
+
reconnectAll(): Promise<number>;
|
|
57
73
|
createNode(options: LavalinkNodeOptions): LavalinkNode;
|
|
58
74
|
leastUsedNodes(sortType?: "memory" | "cpuLavalink" | "cpuSystem" | "calls" | "playingPlayers" | "players"): LavalinkNode[];
|
|
59
75
|
deleteNode(node: LavalinkNodeIdentifier | LavalinkNode): void;
|
|
@@ -13,6 +13,59 @@ class NodeManager extends stream_1.EventEmitter {
|
|
|
13
13
|
if (this.LavalinkManager.options.nodes)
|
|
14
14
|
this.LavalinkManager.options.nodes.forEach(node => this.createNode(node));
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Disconnects all Nodes from lavalink ws sockets
|
|
18
|
+
* @param deleteAllNodes if the nodes should also be deleted from nodeManager.nodes
|
|
19
|
+
* @returns amount of disconnected Nodes
|
|
20
|
+
*/
|
|
21
|
+
async disconnectAll(deleteAllNodes = false) {
|
|
22
|
+
if (!this.nodes.size)
|
|
23
|
+
throw new Error("There are no nodes to disconnect (no nodes in the nodemanager)");
|
|
24
|
+
if (!this.nodes.filter(v => v.connected).size)
|
|
25
|
+
throw new Error("There are no nodes to disconnect (all nodes disconnected)");
|
|
26
|
+
let counter = 0;
|
|
27
|
+
for (const node of [...this.nodes.values()]) {
|
|
28
|
+
if (!node.connected)
|
|
29
|
+
continue;
|
|
30
|
+
await node.destroy(Player_1.DestroyReasons.DisconnectAllNodes, deleteAllNodes);
|
|
31
|
+
counter++;
|
|
32
|
+
}
|
|
33
|
+
return counter;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Connects all not connected nodes
|
|
37
|
+
* @returns Amount of connected Nodes
|
|
38
|
+
*/
|
|
39
|
+
async connectAll() {
|
|
40
|
+
if (!this.nodes.size)
|
|
41
|
+
throw new Error("There are no nodes to connect (no nodes in the nodemanager)");
|
|
42
|
+
if (!this.nodes.filter(v => !v.connected).size)
|
|
43
|
+
throw new Error("There are no nodes to connect (all nodes connected)");
|
|
44
|
+
let counter = 0;
|
|
45
|
+
for (const node of [...this.nodes.values()]) {
|
|
46
|
+
if (node.connected)
|
|
47
|
+
continue;
|
|
48
|
+
await node.connect();
|
|
49
|
+
counter++;
|
|
50
|
+
}
|
|
51
|
+
return counter;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Forcefully reconnects all nodes
|
|
55
|
+
* @returns amount of nodes
|
|
56
|
+
*/
|
|
57
|
+
async reconnectAll() {
|
|
58
|
+
if (!this.nodes.size)
|
|
59
|
+
throw new Error("There are no nodes to reconnect (no nodes in the nodemanager)");
|
|
60
|
+
let counter = 0;
|
|
61
|
+
for (const node of [...this.nodes.values()]) {
|
|
62
|
+
const sessionId = node.sessionId ? `${node.sessionId}` : undefined;
|
|
63
|
+
await node.destroy(Player_1.DestroyReasons.ReconnectAllNodes, false);
|
|
64
|
+
await node.connect(sessionId);
|
|
65
|
+
counter++;
|
|
66
|
+
}
|
|
67
|
+
return counter;
|
|
68
|
+
}
|
|
16
69
|
createNode(options) {
|
|
17
70
|
if (this.nodes.has(options.id || `${options.host}:${options.port}`))
|
|
18
71
|
return this.nodes.get(options.id || `${options.host}:${options.port}`);
|
|
@@ -3,8 +3,8 @@ import { LavalinkManager } from "./LavalinkManager";
|
|
|
3
3
|
import { LavalinkNode } from "./Node";
|
|
4
4
|
import { Queue } from "./Queue";
|
|
5
5
|
import { Track, UnresolvedTrack } from "./Track";
|
|
6
|
-
import { LavalinkPlayerVoiceOptions,
|
|
7
|
-
type PlayerDestroyReasons = "QueueEmpty" | "NodeDestroy" | "NodeDeleted" | "LavalinkNoVoice" | "NodeReconnectFail" | "PlayerReconnectFail" | "Disconnected" | "ChannelDeleted";
|
|
6
|
+
import { LavalinkPlayerVoiceOptions, SearchResult, LavaSearchResponse, LavaSearchQuery, SearchQuery } from "./Utils";
|
|
7
|
+
type PlayerDestroyReasons = "QueueEmpty" | "NodeDestroy" | "NodeDeleted" | "LavalinkNoVoice" | "NodeReconnectFail" | "PlayerReconnectFail" | "Disconnected" | "ChannelDeleted" | "ReconnectAllNodes" | "DisconnectAllNodes";
|
|
8
8
|
export type DestroyReasonsType = PlayerDestroyReasons | string;
|
|
9
9
|
export declare const DestroyReasons: Record<PlayerDestroyReasons, PlayerDestroyReasons>;
|
|
10
10
|
export interface PlayerJson {
|
|
@@ -138,20 +138,13 @@ export declare class Player {
|
|
|
138
138
|
* @param ignoreVolumeDecrementer If it should ignore the volumedecrementer option
|
|
139
139
|
*/
|
|
140
140
|
setVolume(volume: number, ignoreVolumeDecrementer?: boolean): Promise<void>;
|
|
141
|
-
lavaSearch(query:
|
|
142
|
-
query: string;
|
|
143
|
-
source: LavaSrcSearchPlatformBase;
|
|
144
|
-
types?: LavaSearchType[];
|
|
145
|
-
}, requestUser: unknown): Promise<import("./Utils").UnresolvedSearchResult | SearchResult | LavaSearchResponse>;
|
|
141
|
+
lavaSearch(query: LavaSearchQuery, requestUser: unknown): Promise<SearchResult | LavaSearchResponse>;
|
|
146
142
|
/**
|
|
147
143
|
*
|
|
148
144
|
* @param query Query for your data
|
|
149
145
|
* @param requestUser
|
|
150
146
|
*/
|
|
151
|
-
search(query:
|
|
152
|
-
query: string;
|
|
153
|
-
source?: SearchPlatform;
|
|
154
|
-
} | string, requestUser: unknown): Promise<import("./Utils").UnresolvedSearchResult | SearchResult>;
|
|
147
|
+
search(query: SearchQuery, requestUser: unknown): Promise<import("./Utils").UnresolvedSearchResult | SearchResult>;
|
|
155
148
|
/**
|
|
156
149
|
* Pause the player
|
|
157
150
|
*/
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Player = exports.DestroyReasons = void 0;
|
|
4
4
|
const BandCampSearch_1 = require("./CustomSearches/BandCampSearch");
|
|
5
5
|
const Filters_1 = require("./Filters");
|
|
6
|
-
const LavalinkManagerStatics_1 = require("./LavalinkManagerStatics");
|
|
7
6
|
const Queue_1 = require("./Queue");
|
|
8
7
|
const Utils_1 = require("./Utils");
|
|
9
8
|
exports.DestroyReasons = {
|
|
@@ -14,7 +13,9 @@ exports.DestroyReasons = {
|
|
|
14
13
|
NodeReconnectFail: "NodeReconnectFail",
|
|
15
14
|
Disconnected: "Disconnected",
|
|
16
15
|
PlayerReconnectFail: "PlayerReconnectFail",
|
|
17
|
-
ChannelDeleted: "ChannelDeleted"
|
|
16
|
+
ChannelDeleted: "ChannelDeleted",
|
|
17
|
+
DisconnectAllNodes: "DisconnectAllNodes",
|
|
18
|
+
ReconnectAllNodes: "ReconnectAllNodes"
|
|
18
19
|
};
|
|
19
20
|
class Player {
|
|
20
21
|
/** The Guild Id of the Player */
|
|
@@ -211,35 +212,7 @@ class Player {
|
|
|
211
212
|
return;
|
|
212
213
|
}
|
|
213
214
|
async lavaSearch(query, requestUser) {
|
|
214
|
-
|
|
215
|
-
const Query = {
|
|
216
|
-
query: typeof query === "string" ? query : query.query,
|
|
217
|
-
types: query.types ? ["track", "playlist", "artist", "album", "text"].filter(v => query.types?.find(x => x.toLowerCase().startsWith(v))) : ["track", "playlist", "artist", "album", "text"],
|
|
218
|
-
source: LavalinkManagerStatics_1.DefaultSources[(typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager.options.playerOptions.defaultSearchPlatform.toLowerCase()] ?? (typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager.options.playerOptions.defaultSearchPlatform
|
|
219
|
-
};
|
|
220
|
-
// if user does player.search("ytsearch:Hello")
|
|
221
|
-
const foundSource = Object.keys(LavalinkManagerStatics_1.DefaultSources).find(source => Query.query.toLowerCase().startsWith(`${source}:`.toLowerCase()))?.trim?.()?.toLowerCase?.();
|
|
222
|
-
if (foundSource && LavalinkManagerStatics_1.DefaultSources[foundSource]) {
|
|
223
|
-
Query.source = LavalinkManagerStatics_1.DefaultSources[foundSource]; // set the source to ytsearch:
|
|
224
|
-
Query.query = Query.query.slice(`${foundSource}:`.length, Query.query.length); // remove ytsearch: from the query
|
|
225
|
-
}
|
|
226
|
-
if (Query.source)
|
|
227
|
-
this.LavalinkManager.utils.validateSourceString(this.node, Query.source);
|
|
228
|
-
if (!["spsearch", "sprec", "amsearch", "dzsearch", "dzisrc", "ytmsearch", "ytsearch"].includes(Query.source))
|
|
229
|
-
throw new SyntaxError(`Query.source must be a source from LavaSrc: "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "ytmsearch" | "ytsearch"`);
|
|
230
|
-
if (/^https?:\/\//.test(Query.query))
|
|
231
|
-
return await this.search({ query: Query.query, source: Query.source }, requestUser);
|
|
232
|
-
if (!this.node.info.plugins.find(v => v.name === "lavasearch-plugin"))
|
|
233
|
-
throw new RangeError(`there is no lavasearch-plugin available in the lavalink node: ${this.node.id}`);
|
|
234
|
-
const res = await this.node.request(`/loadsearch?query=${Query.source ? `${Query.source}:` : ""}${encodeURIComponent(Query.query)}${Query.types?.length ? `&types=${Query.types.join(",")}` : ""}`);
|
|
235
|
-
return {
|
|
236
|
-
tracks: res.tracks?.map(v => this.LavalinkManager.utils.buildTrack(v, requestUser)) || [],
|
|
237
|
-
albums: res.albums?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
|
|
238
|
-
artists: res.artists?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
|
|
239
|
-
playlists: res.playlists?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
|
|
240
|
-
texts: res.texts?.map(v => ({ text: v.text, pluginInfo: v?.plugin || v.pluginInfo })) || [],
|
|
241
|
-
pluginInfo: res.pluginInfo || res?.plugin
|
|
242
|
-
};
|
|
215
|
+
return this.node.lavaSearch(query, requestUser);
|
|
243
216
|
}
|
|
244
217
|
/**
|
|
245
218
|
*
|
|
@@ -247,43 +220,14 @@ class Player {
|
|
|
247
220
|
* @param requestUser
|
|
248
221
|
*/
|
|
249
222
|
async search(query, requestUser) {
|
|
250
|
-
|
|
251
|
-
const Query = {
|
|
252
|
-
query: typeof query === "string" ? query : query.query,
|
|
253
|
-
source: LavalinkManagerStatics_1.DefaultSources[(typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager.options.playerOptions.defaultSearchPlatform.toLowerCase()] ?? (typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager.options.playerOptions.defaultSearchPlatform
|
|
254
|
-
};
|
|
255
|
-
// if user does player.search("ytsearch:Hello")
|
|
256
|
-
const foundSource = Object.keys(LavalinkManagerStatics_1.DefaultSources).find(source => Query.query?.toLowerCase?.()?.startsWith(`${source}:`.toLowerCase()))?.trim?.()?.toLowerCase?.();
|
|
257
|
-
if (foundSource && LavalinkManagerStatics_1.DefaultSources[foundSource]) {
|
|
258
|
-
Query.source = LavalinkManagerStatics_1.DefaultSources[foundSource]; // set the source to ytsearch:
|
|
259
|
-
Query.query = Query.query.slice(`${foundSource}:`.length, Query.query.length); // remove ytsearch: from the query
|
|
260
|
-
}
|
|
223
|
+
const Query = this.LavalinkManager.utils.transformQuery(query);
|
|
261
224
|
if (/^https?:\/\//.test(Query.query))
|
|
262
225
|
this.LavalinkManager.utils.validateQueryString(this.node, Query.source);
|
|
263
226
|
else if (Query.source)
|
|
264
227
|
this.LavalinkManager.utils.validateSourceString(this.node, Query.source);
|
|
265
|
-
if (["bcsearch", "bandcamp"].includes(Query.source))
|
|
228
|
+
if (["bcsearch", "bandcamp"].includes(Query.source))
|
|
266
229
|
return await (0, BandCampSearch_1.bandCampSearch)(this, Query.query, requestUser);
|
|
267
|
-
|
|
268
|
-
// ftts query parameters: ?voice=Olivia&audio_format=ogg_opus&translate=False&silence=1000&speed=1.0 | example raw get query: https://api.flowery.pw/v1/tts?voice=Olivia&audio_format=ogg_opus&translate=False&silence=0&speed=1.0&text=Hello%20World
|
|
269
|
-
// request the data
|
|
270
|
-
const res = await this.node.request(`/loadtracks?identifier=${!/^https?:\/\//.test(Query.query) ? `${Query.source}:${Query.source === "ftts" ? "//" : ""}` : ""}${encodeURIComponent(Query.query)}`);
|
|
271
|
-
// transform the data which can be Error, Track or Track[] to enfore [Track]
|
|
272
|
-
const resTracks = res.loadType === "playlist" ? res.data?.tracks : res.loadType === "track" ? [res.data] : res.loadType === "search" ? Array.isArray(res.data) ? res.data : [res.data] : [];
|
|
273
|
-
return {
|
|
274
|
-
loadType: res.loadType,
|
|
275
|
-
exception: res.loadType === "error" ? res.data : null,
|
|
276
|
-
pluginInfo: res.pluginInfo || {},
|
|
277
|
-
playlist: res.loadType === "playlist" ? {
|
|
278
|
-
title: res.data.info?.name || res.data.pluginInfo?.name || null,
|
|
279
|
-
author: res.data.info?.author || res.data.pluginInfo?.author || null,
|
|
280
|
-
thumbnail: (res.data.info?.artworkUrl) || (res.data.pluginInfo?.artworkUrl) || ((typeof res.data?.info?.selectedTrack !== "number" || res.data?.info?.selectedTrack === -1) ? null : resTracks[res.data?.info?.selectedTrack] ? (resTracks[res.data?.info?.selectedTrack]?.info?.artworkUrl || resTracks[res.data?.info?.selectedTrack]?.info?.pluginInfo?.artworkUrl) : null) || null,
|
|
281
|
-
uri: res.data.info?.url || res.data.info?.uri || res.data.info?.link || res.data.pluginInfo?.url || res.data.pluginInfo?.uri || res.data.pluginInfo?.link || null,
|
|
282
|
-
selectedTrack: typeof res.data?.info?.selectedTrack !== "number" || res.data?.info?.selectedTrack === -1 ? null : resTracks[res.data?.info?.selectedTrack] ? this.LavalinkManager.utils.buildTrack(resTracks[res.data?.info?.selectedTrack], requestUser) : null,
|
|
283
|
-
duration: resTracks.length ? resTracks.reduce((acc, cur) => acc + (cur?.info?.duration || 0), 0) : 0,
|
|
284
|
-
} : null,
|
|
285
|
-
tracks: resTracks.length ? resTracks.map(t => this.LavalinkManager.utils.buildTrack(t, requestUser)) : []
|
|
286
|
-
};
|
|
230
|
+
return this.node.search(Query, requestUser);
|
|
287
231
|
}
|
|
288
232
|
/**
|
|
289
233
|
* Pause the player
|
|
@@ -89,6 +89,15 @@ export declare class ManagerUtils {
|
|
|
89
89
|
isUnresolvedTrackQuery(data: UnresolvedQuery | any): boolean;
|
|
90
90
|
getClosestTrack(data: UnresolvedTrack, player: Player): Promise<Track | undefined>;
|
|
91
91
|
validateQueryString(node: LavalinkNode, queryString: string): void;
|
|
92
|
+
transformQuery(query: SearchQuery): {
|
|
93
|
+
query: string;
|
|
94
|
+
source: any;
|
|
95
|
+
};
|
|
96
|
+
transformLavaSearchQuery(query: LavaSearchQuery): {
|
|
97
|
+
query: string;
|
|
98
|
+
types: string[];
|
|
99
|
+
source: any;
|
|
100
|
+
};
|
|
92
101
|
validateSourceString(node: LavalinkNode, sourceString: SearchPlatform): void;
|
|
93
102
|
}
|
|
94
103
|
/**
|
|
@@ -322,4 +331,13 @@ export interface LavaSearchResponse {
|
|
|
322
331
|
/** Addition result data provided by plugins */
|
|
323
332
|
pluginInfo: PluginInfo;
|
|
324
333
|
}
|
|
334
|
+
export type SearchQuery = {
|
|
335
|
+
query: string;
|
|
336
|
+
source?: SearchPlatform;
|
|
337
|
+
} | string;
|
|
338
|
+
export type LavaSearchQuery = {
|
|
339
|
+
query: string;
|
|
340
|
+
source: LavaSrcSearchPlatformBase;
|
|
341
|
+
types?: LavaSearchType[];
|
|
342
|
+
};
|
|
325
343
|
export {};
|
|
@@ -194,6 +194,32 @@ class ManagerUtils {
|
|
|
194
194
|
}
|
|
195
195
|
return;
|
|
196
196
|
}
|
|
197
|
+
transformQuery(query) {
|
|
198
|
+
const Query = {
|
|
199
|
+
query: typeof query === "string" ? query : query.query,
|
|
200
|
+
source: LavalinkManagerStatics_1.DefaultSources[(typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager?.options?.playerOptions?.defaultSearchPlatform?.toLowerCase?.()] ?? (typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager?.options?.playerOptions?.defaultSearchPlatform?.toLowerCase?.()
|
|
201
|
+
};
|
|
202
|
+
const foundSource = Object.keys(LavalinkManagerStatics_1.DefaultSources).find(source => Query.query?.toLowerCase?.()?.startsWith(`${source}:`.toLowerCase()))?.trim?.()?.toLowerCase?.();
|
|
203
|
+
if (foundSource && LavalinkManagerStatics_1.DefaultSources[foundSource]) {
|
|
204
|
+
Query.source = LavalinkManagerStatics_1.DefaultSources[foundSource]; // set the source to ytsearch:
|
|
205
|
+
Query.query = Query.query.slice(`${foundSource}:`.length, Query.query.length); // remove ytsearch: from the query
|
|
206
|
+
}
|
|
207
|
+
return Query;
|
|
208
|
+
}
|
|
209
|
+
transformLavaSearchQuery(query) {
|
|
210
|
+
// transform the query object
|
|
211
|
+
const Query = {
|
|
212
|
+
query: typeof query === "string" ? query : query.query,
|
|
213
|
+
types: query.types ? ["track", "playlist", "artist", "album", "text"].filter(v => query.types?.find(x => x.toLowerCase().startsWith(v))) : ["track", "playlist", "artist", "album", /*"text"*/],
|
|
214
|
+
source: LavalinkManagerStatics_1.DefaultSources[(typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager?.options?.playerOptions?.defaultSearchPlatform?.toLowerCase?.()] ?? (typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager?.options?.playerOptions?.defaultSearchPlatform?.toLowerCase?.()
|
|
215
|
+
};
|
|
216
|
+
const foundSource = Object.keys(LavalinkManagerStatics_1.DefaultSources).find(source => Query.query.toLowerCase().startsWith(`${source}:`.toLowerCase()))?.trim?.()?.toLowerCase?.();
|
|
217
|
+
if (foundSource && LavalinkManagerStatics_1.DefaultSources[foundSource]) {
|
|
218
|
+
Query.source = LavalinkManagerStatics_1.DefaultSources[foundSource]; // set the source to ytsearch:
|
|
219
|
+
Query.query = Query.query.slice(`${foundSource}:`.length, Query.query.length); // remove ytsearch: from the query
|
|
220
|
+
}
|
|
221
|
+
return Query;
|
|
222
|
+
}
|
|
197
223
|
validateSourceString(node, sourceString) {
|
|
198
224
|
if (!sourceString)
|
|
199
225
|
throw new Error(`No SourceString was provided`);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Dispatcher, Pool } from "undici";
|
|
3
3
|
import { NodeManager } from "./NodeManager";
|
|
4
4
|
import internal from "stream";
|
|
5
|
-
import { InvalidLavalinkRestRequest, LavalinkPlayer, PlayerUpdateInfo, RoutePlanner, Session, Base64, SearchResult } from "./Utils";
|
|
5
|
+
import { InvalidLavalinkRestRequest, LavalinkPlayer, PlayerUpdateInfo, RoutePlanner, Session, Base64, SearchResult, LavaSearchResponse, LavaSearchQuery, SearchQuery } from "./Utils";
|
|
6
6
|
import { DestroyReasonsType } from "./Player";
|
|
7
7
|
import { Track } from "./Track";
|
|
8
8
|
/** Modifies any outgoing REST requests. */
|
|
@@ -135,7 +135,8 @@ export declare class LavalinkNode {
|
|
|
135
135
|
* @returns The returned data
|
|
136
136
|
*/
|
|
137
137
|
request(endpoint: string, modify?: ModifyRequest, parseAsText?: boolean): Promise<unknown>;
|
|
138
|
-
search(
|
|
138
|
+
search(query: SearchQuery, requestUser: unknown): Promise<SearchResult>;
|
|
139
|
+
lavaSearch(query: LavaSearchQuery, requestUser: unknown): Promise<SearchResult | LavaSearchResponse>;
|
|
139
140
|
/**
|
|
140
141
|
* Update the Player State on the Lavalink Server
|
|
141
142
|
* @param data
|
|
@@ -160,7 +161,7 @@ export declare class LavalinkNode {
|
|
|
160
161
|
* Destroys the Node-Connection (Websocket) and all player's of the node
|
|
161
162
|
* @returns
|
|
162
163
|
*/
|
|
163
|
-
destroy(destroyReason?: DestroyReasonsType): void;
|
|
164
|
+
destroy(destroyReason?: DestroyReasonsType, deleteNode?: boolean): void;
|
|
164
165
|
/** Returns if connected to the Node. */
|
|
165
166
|
get connected(): boolean;
|
|
166
167
|
/**
|
|
@@ -92,8 +92,23 @@ export class LavalinkNode {
|
|
|
92
92
|
throw new Error(`Node Request resulted into an error, request-URL: ${url} | headers: ${JSON.stringify(request.headers)}`);
|
|
93
93
|
return parseAsText ? await request.body.text() : await request.body.json();
|
|
94
94
|
}
|
|
95
|
-
async search(
|
|
96
|
-
const
|
|
95
|
+
async search(query, requestUser) {
|
|
96
|
+
const Query = this.NodeManager.LavalinkManager.utils.transformQuery(query);
|
|
97
|
+
if (/^https?:\/\//.test(Query.query))
|
|
98
|
+
this.NodeManager.LavalinkManager.utils.validateQueryString(this, Query.source);
|
|
99
|
+
else if (Query.source)
|
|
100
|
+
this.NodeManager.LavalinkManager.utils.validateSourceString(this, Query.source);
|
|
101
|
+
if (["bcsearch", "bandcamp"].includes(Query.source)) {
|
|
102
|
+
throw new Error("Bandcamp Search only works on the player!");
|
|
103
|
+
}
|
|
104
|
+
let uri = `/loadtracks?identifier=`;
|
|
105
|
+
if (!/^https?:\/\//.test(Query.query))
|
|
106
|
+
uri += `${Query.source}:`;
|
|
107
|
+
if (Query.source === "ftts")
|
|
108
|
+
uri += `//${encodeURIComponent(encodeURI(decodeURIComponent(Query.query)))}`;
|
|
109
|
+
else
|
|
110
|
+
uri += encodeURIComponent(decodeURIComponent(Query.query));
|
|
111
|
+
const res = await this.request(uri);
|
|
97
112
|
// transform the data which can be Error, Track or Track[] to enfore [Track]
|
|
98
113
|
const resTracks = res.loadType === "playlist" ? res.data?.tracks : res.loadType === "track" ? [res.data] : res.loadType === "search" ? Array.isArray(res.data) ? res.data : [res.data] : [];
|
|
99
114
|
return {
|
|
@@ -111,6 +126,28 @@ export class LavalinkNode {
|
|
|
111
126
|
tracks: (resTracks.length ? resTracks.map(t => this.NodeManager.LavalinkManager.utils.buildTrack(t, requestUser)) : [])
|
|
112
127
|
};
|
|
113
128
|
}
|
|
129
|
+
async lavaSearch(query, requestUser) {
|
|
130
|
+
const Query = this.NodeManager.LavalinkManager.utils.transformLavaSearchQuery(query);
|
|
131
|
+
if (Query.source)
|
|
132
|
+
this.NodeManager.LavalinkManager.utils.validateSourceString(this, Query.source);
|
|
133
|
+
if (/^https?:\/\//.test(Query.query))
|
|
134
|
+
return await this.search({ query: Query.query, source: Query.source }, requestUser);
|
|
135
|
+
if (!["spsearch", "sprec", "amsearch", "dzsearch", "dzisrc", "ytmsearch", "ytsearch"].includes(Query.source))
|
|
136
|
+
throw new SyntaxError(`Query.source must be a source from LavaSrc: "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "ytmsearch" | "ytsearch"`);
|
|
137
|
+
if (!this.info.plugins.find(v => v.name === "lavasearch-plugin"))
|
|
138
|
+
throw new RangeError(`there is no lavasearch-plugin available in the lavalink node: ${this.id}`);
|
|
139
|
+
if (!this.info.plugins.find(v => v.name === "lavasrc-plugin"))
|
|
140
|
+
throw new RangeError(`there is no lavasrc-plugin available in the lavalink node: ${this.id}`);
|
|
141
|
+
const res = await this.request(`/loadsearch?query=${Query.source ? `${Query.source}:` : ""}${encodeURIComponent(Query.query)}${Query.types?.length ? `&types=${Query.types.join(",")}` : ""}`);
|
|
142
|
+
return {
|
|
143
|
+
tracks: res.tracks?.map(v => this.NodeManager.LavalinkManager.utils.buildTrack(v, requestUser)) || [],
|
|
144
|
+
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)) })) || [],
|
|
145
|
+
artists: res.artists?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.NodeManager.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
|
|
146
|
+
playlists: res.playlists?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.NodeManager.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
|
|
147
|
+
texts: res.texts?.map(v => ({ text: v.text, pluginInfo: v?.plugin || v.pluginInfo })) || [],
|
|
148
|
+
pluginInfo: res.pluginInfo || res?.plugin
|
|
149
|
+
};
|
|
150
|
+
}
|
|
114
151
|
/**
|
|
115
152
|
* Update the Player State on the Lavalink Server
|
|
116
153
|
* @param data
|
|
@@ -164,7 +201,7 @@ export class LavalinkNode {
|
|
|
164
201
|
}
|
|
165
202
|
this.socket = new WebSocket(`ws${this.options.secure ? "s" : ""}://${this.options.host}:${this.options.port}/v4/websocket`, { headers });
|
|
166
203
|
this.socket.on("open", this.open.bind(this));
|
|
167
|
-
this.socket.on("close", this.close
|
|
204
|
+
this.socket.on("close", (code, reason) => this.close(code, reason?.toString()));
|
|
168
205
|
this.socket.on("message", this.message.bind(this));
|
|
169
206
|
this.socket.on("error", this.error.bind(this));
|
|
170
207
|
}
|
|
@@ -176,19 +213,24 @@ export class LavalinkNode {
|
|
|
176
213
|
* Destroys the Node-Connection (Websocket) and all player's of the node
|
|
177
214
|
* @returns
|
|
178
215
|
*/
|
|
179
|
-
destroy(destroyReason) {
|
|
216
|
+
destroy(destroyReason, deleteNode = true) {
|
|
180
217
|
if (!this.connected)
|
|
181
218
|
return;
|
|
182
219
|
const players = this.NodeManager.LavalinkManager.players.filter(p => p.node.id == this.id);
|
|
183
220
|
if (players)
|
|
184
221
|
players.forEach(p => p.destroy(destroyReason || DestroyReasons.NodeDestroy));
|
|
185
|
-
this.socket.close(1000, "
|
|
222
|
+
this.socket.close(1000, "Node-Destroy");
|
|
186
223
|
this.socket.removeAllListeners();
|
|
187
224
|
this.socket = null;
|
|
188
225
|
this.reconnectAttempts = 1;
|
|
189
226
|
clearTimeout(this.reconnectTimeout);
|
|
190
|
-
|
|
191
|
-
|
|
227
|
+
if (deleteNode) {
|
|
228
|
+
this.NodeManager.emit("destroy", this, destroyReason);
|
|
229
|
+
this.NodeManager.nodes.delete(this.id);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
this.NodeManager.emit("disconnect", this, { code: 1000, reason: destroyReason });
|
|
233
|
+
}
|
|
192
234
|
return;
|
|
193
235
|
}
|
|
194
236
|
/** Returns if connected to the Node. */
|
|
@@ -402,7 +444,20 @@ export class LavalinkNode {
|
|
|
402
444
|
get poolAddress() {
|
|
403
445
|
return `http${this.options.secure ? "s" : ""}://${this.options.host}:${this.options.port}`;
|
|
404
446
|
}
|
|
405
|
-
reconnect() {
|
|
447
|
+
reconnect(instaReconnect = false) {
|
|
448
|
+
if (instaReconnect) {
|
|
449
|
+
if (this.reconnectAttempts >= this.options.retryAmount) {
|
|
450
|
+
const error = new Error(`Unable to connect after ${this.options.retryAmount} attempts.`);
|
|
451
|
+
this.NodeManager.emit("error", this, error);
|
|
452
|
+
return this.destroy(DestroyReasons.NodeReconnectFail);
|
|
453
|
+
}
|
|
454
|
+
this.socket.removeAllListeners();
|
|
455
|
+
this.socket = null;
|
|
456
|
+
this.NodeManager.emit("reconnecting", this);
|
|
457
|
+
this.connect();
|
|
458
|
+
this.reconnectAttempts++;
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
406
461
|
this.reconnectTimeout = setTimeout(() => {
|
|
407
462
|
if (this.reconnectAttempts >= this.options.retryAmount) {
|
|
408
463
|
const error = new Error(`Unable to connect after ${this.options.retryAmount} attempts.`);
|
|
@@ -433,7 +488,7 @@ export class LavalinkNode {
|
|
|
433
488
|
}
|
|
434
489
|
close(code, reason) {
|
|
435
490
|
this.NodeManager.emit("disconnect", this, { code, reason });
|
|
436
|
-
if (code !== 1000 || reason !== "
|
|
491
|
+
if (code !== 1000 || reason !== "Node-Destroy")
|
|
437
492
|
this.reconnect();
|
|
438
493
|
}
|
|
439
494
|
error(error) {
|
|
@@ -54,6 +54,22 @@ export declare interface NodeManager {
|
|
|
54
54
|
export declare class NodeManager extends EventEmitter {
|
|
55
55
|
nodes: MiniMap<string, LavalinkNode>;
|
|
56
56
|
constructor(LavalinkManager: LavalinkManager);
|
|
57
|
+
/**
|
|
58
|
+
* Disconnects all Nodes from lavalink ws sockets
|
|
59
|
+
* @param deleteAllNodes if the nodes should also be deleted from nodeManager.nodes
|
|
60
|
+
* @returns amount of disconnected Nodes
|
|
61
|
+
*/
|
|
62
|
+
disconnectAll(deleteAllNodes?: boolean): Promise<number>;
|
|
63
|
+
/**
|
|
64
|
+
* Connects all not connected nodes
|
|
65
|
+
* @returns Amount of connected Nodes
|
|
66
|
+
*/
|
|
67
|
+
connectAll(): Promise<number>;
|
|
68
|
+
/**
|
|
69
|
+
* Forcefully reconnects all nodes
|
|
70
|
+
* @returns amount of nodes
|
|
71
|
+
*/
|
|
72
|
+
reconnectAll(): Promise<number>;
|
|
57
73
|
createNode(options: LavalinkNodeOptions): LavalinkNode;
|
|
58
74
|
leastUsedNodes(sortType?: "memory" | "cpuLavalink" | "cpuSystem" | "calls" | "playingPlayers" | "players"): LavalinkNode[];
|
|
59
75
|
deleteNode(node: LavalinkNodeIdentifier | LavalinkNode): void;
|
|
@@ -10,6 +10,59 @@ export class NodeManager extends EventEmitter {
|
|
|
10
10
|
if (this.LavalinkManager.options.nodes)
|
|
11
11
|
this.LavalinkManager.options.nodes.forEach(node => this.createNode(node));
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Disconnects all Nodes from lavalink ws sockets
|
|
15
|
+
* @param deleteAllNodes if the nodes should also be deleted from nodeManager.nodes
|
|
16
|
+
* @returns amount of disconnected Nodes
|
|
17
|
+
*/
|
|
18
|
+
async disconnectAll(deleteAllNodes = false) {
|
|
19
|
+
if (!this.nodes.size)
|
|
20
|
+
throw new Error("There are no nodes to disconnect (no nodes in the nodemanager)");
|
|
21
|
+
if (!this.nodes.filter(v => v.connected).size)
|
|
22
|
+
throw new Error("There are no nodes to disconnect (all nodes disconnected)");
|
|
23
|
+
let counter = 0;
|
|
24
|
+
for (const node of [...this.nodes.values()]) {
|
|
25
|
+
if (!node.connected)
|
|
26
|
+
continue;
|
|
27
|
+
await node.destroy(DestroyReasons.DisconnectAllNodes, deleteAllNodes);
|
|
28
|
+
counter++;
|
|
29
|
+
}
|
|
30
|
+
return counter;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Connects all not connected nodes
|
|
34
|
+
* @returns Amount of connected Nodes
|
|
35
|
+
*/
|
|
36
|
+
async connectAll() {
|
|
37
|
+
if (!this.nodes.size)
|
|
38
|
+
throw new Error("There are no nodes to connect (no nodes in the nodemanager)");
|
|
39
|
+
if (!this.nodes.filter(v => !v.connected).size)
|
|
40
|
+
throw new Error("There are no nodes to connect (all nodes connected)");
|
|
41
|
+
let counter = 0;
|
|
42
|
+
for (const node of [...this.nodes.values()]) {
|
|
43
|
+
if (node.connected)
|
|
44
|
+
continue;
|
|
45
|
+
await node.connect();
|
|
46
|
+
counter++;
|
|
47
|
+
}
|
|
48
|
+
return counter;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Forcefully reconnects all nodes
|
|
52
|
+
* @returns amount of nodes
|
|
53
|
+
*/
|
|
54
|
+
async reconnectAll() {
|
|
55
|
+
if (!this.nodes.size)
|
|
56
|
+
throw new Error("There are no nodes to reconnect (no nodes in the nodemanager)");
|
|
57
|
+
let counter = 0;
|
|
58
|
+
for (const node of [...this.nodes.values()]) {
|
|
59
|
+
const sessionId = node.sessionId ? `${node.sessionId}` : undefined;
|
|
60
|
+
await node.destroy(DestroyReasons.ReconnectAllNodes, false);
|
|
61
|
+
await node.connect(sessionId);
|
|
62
|
+
counter++;
|
|
63
|
+
}
|
|
64
|
+
return counter;
|
|
65
|
+
}
|
|
13
66
|
createNode(options) {
|
|
14
67
|
if (this.nodes.has(options.id || `${options.host}:${options.port}`))
|
|
15
68
|
return this.nodes.get(options.id || `${options.host}:${options.port}`);
|
|
@@ -3,8 +3,8 @@ import { LavalinkManager } from "./LavalinkManager";
|
|
|
3
3
|
import { LavalinkNode } from "./Node";
|
|
4
4
|
import { Queue } from "./Queue";
|
|
5
5
|
import { Track, UnresolvedTrack } from "./Track";
|
|
6
|
-
import { LavalinkPlayerVoiceOptions,
|
|
7
|
-
type PlayerDestroyReasons = "QueueEmpty" | "NodeDestroy" | "NodeDeleted" | "LavalinkNoVoice" | "NodeReconnectFail" | "PlayerReconnectFail" | "Disconnected" | "ChannelDeleted";
|
|
6
|
+
import { LavalinkPlayerVoiceOptions, SearchResult, LavaSearchResponse, LavaSearchQuery, SearchQuery } from "./Utils";
|
|
7
|
+
type PlayerDestroyReasons = "QueueEmpty" | "NodeDestroy" | "NodeDeleted" | "LavalinkNoVoice" | "NodeReconnectFail" | "PlayerReconnectFail" | "Disconnected" | "ChannelDeleted" | "ReconnectAllNodes" | "DisconnectAllNodes";
|
|
8
8
|
export type DestroyReasonsType = PlayerDestroyReasons | string;
|
|
9
9
|
export declare const DestroyReasons: Record<PlayerDestroyReasons, PlayerDestroyReasons>;
|
|
10
10
|
export interface PlayerJson {
|
|
@@ -138,20 +138,13 @@ export declare class Player {
|
|
|
138
138
|
* @param ignoreVolumeDecrementer If it should ignore the volumedecrementer option
|
|
139
139
|
*/
|
|
140
140
|
setVolume(volume: number, ignoreVolumeDecrementer?: boolean): Promise<void>;
|
|
141
|
-
lavaSearch(query:
|
|
142
|
-
query: string;
|
|
143
|
-
source: LavaSrcSearchPlatformBase;
|
|
144
|
-
types?: LavaSearchType[];
|
|
145
|
-
}, requestUser: unknown): Promise<import("./Utils").UnresolvedSearchResult | SearchResult | LavaSearchResponse>;
|
|
141
|
+
lavaSearch(query: LavaSearchQuery, requestUser: unknown): Promise<SearchResult | LavaSearchResponse>;
|
|
146
142
|
/**
|
|
147
143
|
*
|
|
148
144
|
* @param query Query for your data
|
|
149
145
|
* @param requestUser
|
|
150
146
|
*/
|
|
151
|
-
search(query:
|
|
152
|
-
query: string;
|
|
153
|
-
source?: SearchPlatform;
|
|
154
|
-
} | string, requestUser: unknown): Promise<import("./Utils").UnresolvedSearchResult | SearchResult>;
|
|
147
|
+
search(query: SearchQuery, requestUser: unknown): Promise<import("./Utils").UnresolvedSearchResult | SearchResult>;
|
|
155
148
|
/**
|
|
156
149
|
* Pause the player
|
|
157
150
|
*/
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { bandCampSearch } from "./CustomSearches/BandCampSearch";
|
|
2
2
|
import { FilterManager } from "./Filters";
|
|
3
|
-
import { DefaultSources } from "./LavalinkManagerStatics";
|
|
4
3
|
import { Queue, QueueSaver } from "./Queue";
|
|
5
4
|
import { queueTrackEnd } from "./Utils";
|
|
6
5
|
export const DestroyReasons = {
|
|
@@ -11,7 +10,9 @@ export const DestroyReasons = {
|
|
|
11
10
|
NodeReconnectFail: "NodeReconnectFail",
|
|
12
11
|
Disconnected: "Disconnected",
|
|
13
12
|
PlayerReconnectFail: "PlayerReconnectFail",
|
|
14
|
-
ChannelDeleted: "ChannelDeleted"
|
|
13
|
+
ChannelDeleted: "ChannelDeleted",
|
|
14
|
+
DisconnectAllNodes: "DisconnectAllNodes",
|
|
15
|
+
ReconnectAllNodes: "ReconnectAllNodes"
|
|
15
16
|
};
|
|
16
17
|
export class Player {
|
|
17
18
|
/** The Guild Id of the Player */
|
|
@@ -208,35 +209,7 @@ export class Player {
|
|
|
208
209
|
return;
|
|
209
210
|
}
|
|
210
211
|
async lavaSearch(query, requestUser) {
|
|
211
|
-
|
|
212
|
-
const Query = {
|
|
213
|
-
query: typeof query === "string" ? query : query.query,
|
|
214
|
-
types: query.types ? ["track", "playlist", "artist", "album", "text"].filter(v => query.types?.find(x => x.toLowerCase().startsWith(v))) : ["track", "playlist", "artist", "album", "text"],
|
|
215
|
-
source: DefaultSources[(typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager.options.playerOptions.defaultSearchPlatform.toLowerCase()] ?? (typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager.options.playerOptions.defaultSearchPlatform
|
|
216
|
-
};
|
|
217
|
-
// if user does player.search("ytsearch:Hello")
|
|
218
|
-
const foundSource = Object.keys(DefaultSources).find(source => Query.query.toLowerCase().startsWith(`${source}:`.toLowerCase()))?.trim?.()?.toLowerCase?.();
|
|
219
|
-
if (foundSource && DefaultSources[foundSource]) {
|
|
220
|
-
Query.source = DefaultSources[foundSource]; // set the source to ytsearch:
|
|
221
|
-
Query.query = Query.query.slice(`${foundSource}:`.length, Query.query.length); // remove ytsearch: from the query
|
|
222
|
-
}
|
|
223
|
-
if (Query.source)
|
|
224
|
-
this.LavalinkManager.utils.validateSourceString(this.node, Query.source);
|
|
225
|
-
if (!["spsearch", "sprec", "amsearch", "dzsearch", "dzisrc", "ytmsearch", "ytsearch"].includes(Query.source))
|
|
226
|
-
throw new SyntaxError(`Query.source must be a source from LavaSrc: "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "ytmsearch" | "ytsearch"`);
|
|
227
|
-
if (/^https?:\/\//.test(Query.query))
|
|
228
|
-
return await this.search({ query: Query.query, source: Query.source }, requestUser);
|
|
229
|
-
if (!this.node.info.plugins.find(v => v.name === "lavasearch-plugin"))
|
|
230
|
-
throw new RangeError(`there is no lavasearch-plugin available in the lavalink node: ${this.node.id}`);
|
|
231
|
-
const res = await this.node.request(`/loadsearch?query=${Query.source ? `${Query.source}:` : ""}${encodeURIComponent(Query.query)}${Query.types?.length ? `&types=${Query.types.join(",")}` : ""}`);
|
|
232
|
-
return {
|
|
233
|
-
tracks: res.tracks?.map(v => this.LavalinkManager.utils.buildTrack(v, requestUser)) || [],
|
|
234
|
-
albums: res.albums?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
|
|
235
|
-
artists: res.artists?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
|
|
236
|
-
playlists: res.playlists?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
|
|
237
|
-
texts: res.texts?.map(v => ({ text: v.text, pluginInfo: v?.plugin || v.pluginInfo })) || [],
|
|
238
|
-
pluginInfo: res.pluginInfo || res?.plugin
|
|
239
|
-
};
|
|
212
|
+
return this.node.lavaSearch(query, requestUser);
|
|
240
213
|
}
|
|
241
214
|
/**
|
|
242
215
|
*
|
|
@@ -244,43 +217,14 @@ export class Player {
|
|
|
244
217
|
* @param requestUser
|
|
245
218
|
*/
|
|
246
219
|
async search(query, requestUser) {
|
|
247
|
-
|
|
248
|
-
const Query = {
|
|
249
|
-
query: typeof query === "string" ? query : query.query,
|
|
250
|
-
source: DefaultSources[(typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager.options.playerOptions.defaultSearchPlatform.toLowerCase()] ?? (typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager.options.playerOptions.defaultSearchPlatform
|
|
251
|
-
};
|
|
252
|
-
// if user does player.search("ytsearch:Hello")
|
|
253
|
-
const foundSource = Object.keys(DefaultSources).find(source => Query.query?.toLowerCase?.()?.startsWith(`${source}:`.toLowerCase()))?.trim?.()?.toLowerCase?.();
|
|
254
|
-
if (foundSource && DefaultSources[foundSource]) {
|
|
255
|
-
Query.source = DefaultSources[foundSource]; // set the source to ytsearch:
|
|
256
|
-
Query.query = Query.query.slice(`${foundSource}:`.length, Query.query.length); // remove ytsearch: from the query
|
|
257
|
-
}
|
|
220
|
+
const Query = this.LavalinkManager.utils.transformQuery(query);
|
|
258
221
|
if (/^https?:\/\//.test(Query.query))
|
|
259
222
|
this.LavalinkManager.utils.validateQueryString(this.node, Query.source);
|
|
260
223
|
else if (Query.source)
|
|
261
224
|
this.LavalinkManager.utils.validateSourceString(this.node, Query.source);
|
|
262
|
-
if (["bcsearch", "bandcamp"].includes(Query.source))
|
|
225
|
+
if (["bcsearch", "bandcamp"].includes(Query.source))
|
|
263
226
|
return await bandCampSearch(this, Query.query, requestUser);
|
|
264
|
-
|
|
265
|
-
// ftts query parameters: ?voice=Olivia&audio_format=ogg_opus&translate=False&silence=1000&speed=1.0 | example raw get query: https://api.flowery.pw/v1/tts?voice=Olivia&audio_format=ogg_opus&translate=False&silence=0&speed=1.0&text=Hello%20World
|
|
266
|
-
// request the data
|
|
267
|
-
const res = await this.node.request(`/loadtracks?identifier=${!/^https?:\/\//.test(Query.query) ? `${Query.source}:${Query.source === "ftts" ? "//" : ""}` : ""}${encodeURIComponent(Query.query)}`);
|
|
268
|
-
// transform the data which can be Error, Track or Track[] to enfore [Track]
|
|
269
|
-
const resTracks = res.loadType === "playlist" ? res.data?.tracks : res.loadType === "track" ? [res.data] : res.loadType === "search" ? Array.isArray(res.data) ? res.data : [res.data] : [];
|
|
270
|
-
return {
|
|
271
|
-
loadType: res.loadType,
|
|
272
|
-
exception: res.loadType === "error" ? res.data : null,
|
|
273
|
-
pluginInfo: res.pluginInfo || {},
|
|
274
|
-
playlist: res.loadType === "playlist" ? {
|
|
275
|
-
title: res.data.info?.name || res.data.pluginInfo?.name || null,
|
|
276
|
-
author: res.data.info?.author || res.data.pluginInfo?.author || null,
|
|
277
|
-
thumbnail: (res.data.info?.artworkUrl) || (res.data.pluginInfo?.artworkUrl) || ((typeof res.data?.info?.selectedTrack !== "number" || res.data?.info?.selectedTrack === -1) ? null : resTracks[res.data?.info?.selectedTrack] ? (resTracks[res.data?.info?.selectedTrack]?.info?.artworkUrl || resTracks[res.data?.info?.selectedTrack]?.info?.pluginInfo?.artworkUrl) : null) || null,
|
|
278
|
-
uri: res.data.info?.url || res.data.info?.uri || res.data.info?.link || res.data.pluginInfo?.url || res.data.pluginInfo?.uri || res.data.pluginInfo?.link || null,
|
|
279
|
-
selectedTrack: typeof res.data?.info?.selectedTrack !== "number" || res.data?.info?.selectedTrack === -1 ? null : resTracks[res.data?.info?.selectedTrack] ? this.LavalinkManager.utils.buildTrack(resTracks[res.data?.info?.selectedTrack], requestUser) : null,
|
|
280
|
-
duration: resTracks.length ? resTracks.reduce((acc, cur) => acc + (cur?.info?.duration || 0), 0) : 0,
|
|
281
|
-
} : null,
|
|
282
|
-
tracks: resTracks.length ? resTracks.map(t => this.LavalinkManager.utils.buildTrack(t, requestUser)) : []
|
|
283
|
-
};
|
|
227
|
+
return this.node.search(Query, requestUser);
|
|
284
228
|
}
|
|
285
229
|
/**
|
|
286
230
|
* Pause the player
|
|
@@ -89,6 +89,15 @@ export declare class ManagerUtils {
|
|
|
89
89
|
isUnresolvedTrackQuery(data: UnresolvedQuery | any): boolean;
|
|
90
90
|
getClosestTrack(data: UnresolvedTrack, player: Player): Promise<Track | undefined>;
|
|
91
91
|
validateQueryString(node: LavalinkNode, queryString: string): void;
|
|
92
|
+
transformQuery(query: SearchQuery): {
|
|
93
|
+
query: string;
|
|
94
|
+
source: any;
|
|
95
|
+
};
|
|
96
|
+
transformLavaSearchQuery(query: LavaSearchQuery): {
|
|
97
|
+
query: string;
|
|
98
|
+
types: string[];
|
|
99
|
+
source: any;
|
|
100
|
+
};
|
|
92
101
|
validateSourceString(node: LavalinkNode, sourceString: SearchPlatform): void;
|
|
93
102
|
}
|
|
94
103
|
/**
|
|
@@ -322,4 +331,13 @@ export interface LavaSearchResponse {
|
|
|
322
331
|
/** Addition result data provided by plugins */
|
|
323
332
|
pluginInfo: PluginInfo;
|
|
324
333
|
}
|
|
334
|
+
export type SearchQuery = {
|
|
335
|
+
query: string;
|
|
336
|
+
source?: SearchPlatform;
|
|
337
|
+
} | string;
|
|
338
|
+
export type LavaSearchQuery = {
|
|
339
|
+
query: string;
|
|
340
|
+
source: LavaSrcSearchPlatformBase;
|
|
341
|
+
types?: LavaSearchType[];
|
|
342
|
+
};
|
|
325
343
|
export {};
|
|
@@ -191,6 +191,32 @@ export class ManagerUtils {
|
|
|
191
191
|
}
|
|
192
192
|
return;
|
|
193
193
|
}
|
|
194
|
+
transformQuery(query) {
|
|
195
|
+
const Query = {
|
|
196
|
+
query: typeof query === "string" ? query : query.query,
|
|
197
|
+
source: DefaultSources[(typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager?.options?.playerOptions?.defaultSearchPlatform?.toLowerCase?.()] ?? (typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager?.options?.playerOptions?.defaultSearchPlatform?.toLowerCase?.()
|
|
198
|
+
};
|
|
199
|
+
const foundSource = Object.keys(DefaultSources).find(source => Query.query?.toLowerCase?.()?.startsWith(`${source}:`.toLowerCase()))?.trim?.()?.toLowerCase?.();
|
|
200
|
+
if (foundSource && DefaultSources[foundSource]) {
|
|
201
|
+
Query.source = DefaultSources[foundSource]; // set the source to ytsearch:
|
|
202
|
+
Query.query = Query.query.slice(`${foundSource}:`.length, Query.query.length); // remove ytsearch: from the query
|
|
203
|
+
}
|
|
204
|
+
return Query;
|
|
205
|
+
}
|
|
206
|
+
transformLavaSearchQuery(query) {
|
|
207
|
+
// transform the query object
|
|
208
|
+
const Query = {
|
|
209
|
+
query: typeof query === "string" ? query : query.query,
|
|
210
|
+
types: query.types ? ["track", "playlist", "artist", "album", "text"].filter(v => query.types?.find(x => x.toLowerCase().startsWith(v))) : ["track", "playlist", "artist", "album", /*"text"*/],
|
|
211
|
+
source: DefaultSources[(typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager?.options?.playerOptions?.defaultSearchPlatform?.toLowerCase?.()] ?? (typeof query === "string" ? undefined : query.source?.trim?.()?.toLowerCase?.()) ?? this.LavalinkManager?.options?.playerOptions?.defaultSearchPlatform?.toLowerCase?.()
|
|
212
|
+
};
|
|
213
|
+
const foundSource = Object.keys(DefaultSources).find(source => Query.query.toLowerCase().startsWith(`${source}:`.toLowerCase()))?.trim?.()?.toLowerCase?.();
|
|
214
|
+
if (foundSource && DefaultSources[foundSource]) {
|
|
215
|
+
Query.source = DefaultSources[foundSource]; // set the source to ytsearch:
|
|
216
|
+
Query.query = Query.query.slice(`${foundSource}:`.length, Query.query.length); // remove ytsearch: from the query
|
|
217
|
+
}
|
|
218
|
+
return Query;
|
|
219
|
+
}
|
|
194
220
|
validateSourceString(node, sourceString) {
|
|
195
221
|
if (!sourceString)
|
|
196
222
|
throw new Error(`No SourceString was provided`);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Dispatcher, Pool } from "undici";
|
|
3
3
|
import { NodeManager } from "./NodeManager";
|
|
4
4
|
import internal from "stream";
|
|
5
|
-
import { InvalidLavalinkRestRequest, LavalinkPlayer, PlayerUpdateInfo, RoutePlanner, Session, Base64, SearchResult } from "./Utils";
|
|
5
|
+
import { InvalidLavalinkRestRequest, LavalinkPlayer, PlayerUpdateInfo, RoutePlanner, Session, Base64, SearchResult, LavaSearchResponse, LavaSearchQuery, SearchQuery } from "./Utils";
|
|
6
6
|
import { DestroyReasonsType } from "./Player";
|
|
7
7
|
import { Track } from "./Track";
|
|
8
8
|
/** Modifies any outgoing REST requests. */
|
|
@@ -135,7 +135,8 @@ export declare class LavalinkNode {
|
|
|
135
135
|
* @returns The returned data
|
|
136
136
|
*/
|
|
137
137
|
request(endpoint: string, modify?: ModifyRequest, parseAsText?: boolean): Promise<unknown>;
|
|
138
|
-
search(
|
|
138
|
+
search(query: SearchQuery, requestUser: unknown): Promise<SearchResult>;
|
|
139
|
+
lavaSearch(query: LavaSearchQuery, requestUser: unknown): Promise<SearchResult | LavaSearchResponse>;
|
|
139
140
|
/**
|
|
140
141
|
* Update the Player State on the Lavalink Server
|
|
141
142
|
* @param data
|
|
@@ -160,7 +161,7 @@ export declare class LavalinkNode {
|
|
|
160
161
|
* Destroys the Node-Connection (Websocket) and all player's of the node
|
|
161
162
|
* @returns
|
|
162
163
|
*/
|
|
163
|
-
destroy(destroyReason?: DestroyReasonsType): void;
|
|
164
|
+
destroy(destroyReason?: DestroyReasonsType, deleteNode?: boolean): void;
|
|
164
165
|
/** Returns if connected to the Node. */
|
|
165
166
|
get connected(): boolean;
|
|
166
167
|
/**
|
|
@@ -54,6 +54,22 @@ export declare interface NodeManager {
|
|
|
54
54
|
export declare class NodeManager extends EventEmitter {
|
|
55
55
|
nodes: MiniMap<string, LavalinkNode>;
|
|
56
56
|
constructor(LavalinkManager: LavalinkManager);
|
|
57
|
+
/**
|
|
58
|
+
* Disconnects all Nodes from lavalink ws sockets
|
|
59
|
+
* @param deleteAllNodes if the nodes should also be deleted from nodeManager.nodes
|
|
60
|
+
* @returns amount of disconnected Nodes
|
|
61
|
+
*/
|
|
62
|
+
disconnectAll(deleteAllNodes?: boolean): Promise<number>;
|
|
63
|
+
/**
|
|
64
|
+
* Connects all not connected nodes
|
|
65
|
+
* @returns Amount of connected Nodes
|
|
66
|
+
*/
|
|
67
|
+
connectAll(): Promise<number>;
|
|
68
|
+
/**
|
|
69
|
+
* Forcefully reconnects all nodes
|
|
70
|
+
* @returns amount of nodes
|
|
71
|
+
*/
|
|
72
|
+
reconnectAll(): Promise<number>;
|
|
57
73
|
createNode(options: LavalinkNodeOptions): LavalinkNode;
|
|
58
74
|
leastUsedNodes(sortType?: "memory" | "cpuLavalink" | "cpuSystem" | "calls" | "playingPlayers" | "players"): LavalinkNode[];
|
|
59
75
|
deleteNode(node: LavalinkNodeIdentifier | LavalinkNode): void;
|
|
@@ -3,8 +3,8 @@ import { LavalinkManager } from "./LavalinkManager";
|
|
|
3
3
|
import { LavalinkNode } from "./Node";
|
|
4
4
|
import { Queue } from "./Queue";
|
|
5
5
|
import { Track, UnresolvedTrack } from "./Track";
|
|
6
|
-
import { LavalinkPlayerVoiceOptions,
|
|
7
|
-
type PlayerDestroyReasons = "QueueEmpty" | "NodeDestroy" | "NodeDeleted" | "LavalinkNoVoice" | "NodeReconnectFail" | "PlayerReconnectFail" | "Disconnected" | "ChannelDeleted";
|
|
6
|
+
import { LavalinkPlayerVoiceOptions, SearchResult, LavaSearchResponse, LavaSearchQuery, SearchQuery } from "./Utils";
|
|
7
|
+
type PlayerDestroyReasons = "QueueEmpty" | "NodeDestroy" | "NodeDeleted" | "LavalinkNoVoice" | "NodeReconnectFail" | "PlayerReconnectFail" | "Disconnected" | "ChannelDeleted" | "ReconnectAllNodes" | "DisconnectAllNodes";
|
|
8
8
|
export type DestroyReasonsType = PlayerDestroyReasons | string;
|
|
9
9
|
export declare const DestroyReasons: Record<PlayerDestroyReasons, PlayerDestroyReasons>;
|
|
10
10
|
export interface PlayerJson {
|
|
@@ -138,20 +138,13 @@ export declare class Player {
|
|
|
138
138
|
* @param ignoreVolumeDecrementer If it should ignore the volumedecrementer option
|
|
139
139
|
*/
|
|
140
140
|
setVolume(volume: number, ignoreVolumeDecrementer?: boolean): Promise<void>;
|
|
141
|
-
lavaSearch(query:
|
|
142
|
-
query: string;
|
|
143
|
-
source: LavaSrcSearchPlatformBase;
|
|
144
|
-
types?: LavaSearchType[];
|
|
145
|
-
}, requestUser: unknown): Promise<import("./Utils").UnresolvedSearchResult | SearchResult | LavaSearchResponse>;
|
|
141
|
+
lavaSearch(query: LavaSearchQuery, requestUser: unknown): Promise<SearchResult | LavaSearchResponse>;
|
|
146
142
|
/**
|
|
147
143
|
*
|
|
148
144
|
* @param query Query for your data
|
|
149
145
|
* @param requestUser
|
|
150
146
|
*/
|
|
151
|
-
search(query:
|
|
152
|
-
query: string;
|
|
153
|
-
source?: SearchPlatform;
|
|
154
|
-
} | string, requestUser: unknown): Promise<import("./Utils").UnresolvedSearchResult | SearchResult>;
|
|
147
|
+
search(query: SearchQuery, requestUser: unknown): Promise<import("./Utils").UnresolvedSearchResult | SearchResult>;
|
|
155
148
|
/**
|
|
156
149
|
* Pause the player
|
|
157
150
|
*/
|
|
@@ -89,6 +89,15 @@ export declare class ManagerUtils {
|
|
|
89
89
|
isUnresolvedTrackQuery(data: UnresolvedQuery | any): boolean;
|
|
90
90
|
getClosestTrack(data: UnresolvedTrack, player: Player): Promise<Track | undefined>;
|
|
91
91
|
validateQueryString(node: LavalinkNode, queryString: string): void;
|
|
92
|
+
transformQuery(query: SearchQuery): {
|
|
93
|
+
query: string;
|
|
94
|
+
source: any;
|
|
95
|
+
};
|
|
96
|
+
transformLavaSearchQuery(query: LavaSearchQuery): {
|
|
97
|
+
query: string;
|
|
98
|
+
types: string[];
|
|
99
|
+
source: any;
|
|
100
|
+
};
|
|
92
101
|
validateSourceString(node: LavalinkNode, sourceString: SearchPlatform): void;
|
|
93
102
|
}
|
|
94
103
|
/**
|
|
@@ -322,4 +331,13 @@ export interface LavaSearchResponse {
|
|
|
322
331
|
/** Addition result data provided by plugins */
|
|
323
332
|
pluginInfo: PluginInfo;
|
|
324
333
|
}
|
|
334
|
+
export type SearchQuery = {
|
|
335
|
+
query: string;
|
|
336
|
+
source?: SearchPlatform;
|
|
337
|
+
} | string;
|
|
338
|
+
export type LavaSearchQuery = {
|
|
339
|
+
query: string;
|
|
340
|
+
source: LavaSrcSearchPlatformBase;
|
|
341
|
+
types?: LavaSearchType[];
|
|
342
|
+
};
|
|
325
343
|
export {};
|
package/package.json
CHANGED