lavalink-client 2.1.2 → 2.1.4

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.
@@ -6,10 +6,6 @@ import { DestroyReasonsType, Player, PlayerJson, PlayerOptions } from "./Player"
6
6
  import { ManagerQueueOptions } from "./Queue";
7
7
  import { Track, UnresolvedTrack } from "./Track";
8
8
  import { ChannelDeletePacket, GuildShardPayload, ManagerUtils, MiniMap, SearchPlatform, SponsorBlockChaptersLoaded, SponsorBlockChapterStarted, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, TrackEndEvent, TrackExceptionEvent, TrackStartEvent, TrackStuckEvent, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent } from "./Utils";
9
- export interface LavalinkManager {
10
- nodeManager: NodeManager;
11
- utils: ManagerUtils;
12
- }
13
9
  export interface BotClientOptions {
14
10
  /** Bot Client Id */
15
11
  id: string;
@@ -168,31 +164,186 @@ interface LavalinkManagerEvents {
168
164
  "ChaptersLoaded": (player: Player, track: Track | UnresolvedTrack, payload: SponsorBlockChaptersLoaded) => void;
169
165
  }
170
166
  export interface LavalinkManager {
171
- options: ManagerOptions;
167
+ /** @private */
172
168
  on<U extends keyof LavalinkManagerEvents>(event: U, listener: LavalinkManagerEvents[U]): this;
169
+ /** @private */
173
170
  emit<U extends keyof LavalinkManagerEvents>(event: U, ...args: Parameters<LavalinkManagerEvents[U]>): boolean;
174
171
  }
175
172
  export declare class LavalinkManager extends EventEmitter {
176
- static DefaultSources: Record<SearchPlatform, import("./Utils").LavalinkSearchPlatform | import("./Utils").ClientCustomSearchPlatformUtils>;
177
- static SourceLinksRegexes: Record<import("./Utils").SourcesRegex, RegExp>;
173
+ /** The Options of LavalinkManager (changeable) */
174
+ options: ManagerOptions;
175
+ /** LavalinkManager's NodeManager to manage all Nodes */
176
+ nodeManager: NodeManager;
177
+ /** LavalinkManager's Utils Class */
178
+ utils: ManagerUtils;
179
+ /** Wether the manager was initiated or not */
178
180
  initiated: boolean;
181
+ /** All Players stored in a MiniMap */
179
182
  readonly players: MiniMap<string, Player>;
183
+ /**
184
+ * Applies the options provided by the User
185
+ * @param options
186
+ * @returns
187
+ */
180
188
  private applyOptions;
189
+ /**
190
+ * Validates the current manager's options
191
+ * @param options
192
+ */
181
193
  private validateOptions;
194
+ /**
195
+ * Create the Lavalink Manager
196
+ * @param options
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * //const client = new Client({...}); // create your BOT Client (e.g. via discord.js)
201
+ * client.lavalink = new LavalinkManager({
202
+ * nodes: [
203
+ * {
204
+ * authorization: "yourverystrongpassword",
205
+ * host: "localhost",
206
+ * port: 2333,
207
+ * id: "testnode"
208
+ * },
209
+ * sendToShard(guildId, payload) => client.guilds.cache.get(guildId)?.shard?.send(payload),
210
+ * client: {
211
+ * id: process.env.CLIENT_ID,
212
+ * username: "TESTBOT"
213
+ * },
214
+ * // optional Options:
215
+ * autoSkip: true,
216
+ * playerOptions: {
217
+ * applyVolumeAsFilter: false,
218
+ * clientBasedPositionUpdateInterval: 150,
219
+ * defaultSearchPlatform: "ytmsearch",
220
+ * volumeDecrementer: 0.75,
221
+ * //requesterTransformer: YourRequesterTransformerFunction,
222
+ * onDisconnect: {
223
+ * autoReconnect: true,
224
+ * destroyPlayer: false
225
+ * },
226
+ * onEmptyQueue: {
227
+ * destroyAfterMs: 30_000,
228
+ * //autoPlayFunction: YourAutoplayFunction,
229
+ * },
230
+ * useUnresolvedData: true
231
+ * },
232
+ * queueOptions: {
233
+ * maxPreviousTracks: 25,
234
+ * //queueStore: yourCustomQueueStoreManagerClass,
235
+ * //queueChangesWatcher: yourCustomQueueChangesWatcherClass
236
+ * },
237
+ * linksBlacklist: [],
238
+ * linksWhitelist: [],
239
+ * advancedOptions: {
240
+ * debugOptions: {
241
+ * noAudio: false,
242
+ * playerDestroy: {
243
+ * dontThrowError: false,
244
+ * debugLogs: false
245
+ * }
246
+ * }
247
+ * }
248
+ * ]
249
+ * })
250
+ * ```
251
+ */
182
252
  constructor(options: ManagerOptions);
183
- createPlayer(options: PlayerOptions): Player;
253
+ /**
254
+ * Get a Player from Lava
255
+ * @param guildId The guildId of the player
256
+ *
257
+ * @example
258
+ * ```ts
259
+ * const player = client.lavalink.getPlayer(interaction.guildId);
260
+ * ```
261
+ * A quicker and easier way than doing:
262
+ * ```ts
263
+ * const player = client.lavalink.players.get(interaction.guildId);
264
+ * ```
265
+ * @returns
266
+ */
184
267
  getPlayer(guildId: string): Player;
268
+ /**
269
+ * Create a Music-Player. If a player exists, then it returns it before creating a new one
270
+ * @param options
271
+ * @returns
272
+ *
273
+ * @example
274
+ * ```ts
275
+ * const player = client.lavalink.createPlayer({
276
+ * guildId: interaction.guildId,
277
+ * voiceChannelId: interaction.member.voice.channelId,
278
+ * // everything below is optional
279
+ * textChannelId: interaction.channelId,
280
+ * volume: 100,
281
+ * selfDeaf: true,
282
+ * selfMute: false,
283
+ * instaUpdateFiltersFix: true,
284
+ * applyVolumeAsFilter: false
285
+ * //only needed if you want to autopick node by region (configured by you)
286
+ * // vcRegion: interaction.member.voice.rtcRegion,
287
+ * // provide a specific node
288
+ * // node: client.lavalink.nodeManager.leastUsedNodes("memory")[0]
289
+ * });
290
+ * ```
291
+ */
292
+ createPlayer(options: PlayerOptions): Player;
293
+ /**
294
+ * Destroy a player with optional destroy reason and disconnect it from the voice channel
295
+ * @param guildId
296
+ * @param destroyReason
297
+ * @returns
298
+ *
299
+ * @example
300
+ * ```ts
301
+ * client.lavalink.destroyPlayer(interaction.guildId, "forcefully destroyed the player");
302
+ * // recommend to do it on the player tho: player.destroy("forcefully destroyed the player");
303
+ * ```
304
+ */
185
305
  destroyPlayer(guildId: string, destroyReason?: string): Promise<Player>;
306
+ /**
307
+ * Delete's a player from the cache without destroying it on lavalink (only works when it's disconnected)
308
+ * @param guildId
309
+ * @returns
310
+ */
186
311
  deletePlayer(guildId: string): boolean;
312
+ /**
313
+ * Checks wether the the lib is useable based on if any node is connected
314
+ */
187
315
  get useable(): boolean;
188
316
  /**
189
- * Initiates the Manager.
317
+ * Initiates the Manager, creates all nodes and connects all of them
190
318
  * @param clientData
319
+ *
320
+ * @example
321
+ *
322
+ * ```ts
323
+ * // on the bot ready event
324
+ * client.on("ready", () => {
325
+ * client.lavalink.init({
326
+ * id: client.user.id,
327
+ * username: client.user.username
328
+ * });
329
+ * });
330
+ * ```
191
331
  */
192
332
  init(clientData: BotClientOptions): Promise<this>;
193
333
  /**
194
334
  * Sends voice data to the Lavalink server.
335
+ * ! Without this the library won't work
195
336
  * @param data
337
+ *
338
+ * @example
339
+ *
340
+ * ```ts
341
+ * // on the bot "raw" event
342
+ * client.on("raw", (d) => {
343
+ * // required in order to send audio updates and register channel deletion etc.
344
+ * client.lavalink.sendRawData(d)
345
+ * })
346
+ * ```
196
347
  */
197
348
  sendRawData(data: VoicePacket | VoiceServer | VoiceState | ChannelDeletePacket): Promise<void>;
198
349
  }
@@ -2,16 +2,26 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LavalinkManager = void 0;
4
4
  const events_1 = require("events");
5
- const LavalinkManagerStatics_1 = require("./LavalinkManagerStatics");
6
5
  const NodeManager_1 = require("./NodeManager");
7
6
  const Player_1 = require("./Player");
8
7
  const Queue_1 = require("./Queue");
9
8
  const Utils_1 = require("./Utils");
10
9
  class LavalinkManager extends events_1.EventEmitter {
11
- static DefaultSources = LavalinkManagerStatics_1.DefaultSources;
12
- static SourceLinksRegexes = LavalinkManagerStatics_1.SourceLinksRegexes;
10
+ /** The Options of LavalinkManager (changeable) */
11
+ options;
12
+ /** LavalinkManager's NodeManager to manage all Nodes */
13
+ nodeManager;
14
+ /** LavalinkManager's Utils Class */
15
+ utils;
16
+ /** Wether the manager was initiated or not */
13
17
  initiated = false;
18
+ /** All Players stored in a MiniMap */
14
19
  players = new Utils_1.MiniMap();
20
+ /**
21
+ * Applies the options provided by the User
22
+ * @param options
23
+ * @returns
24
+ */
15
25
  applyOptions(options) {
16
26
  this.options = {
17
27
  client: {
@@ -59,6 +69,10 @@ class LavalinkManager extends events_1.EventEmitter {
59
69
  };
60
70
  return;
61
71
  }
72
+ /**
73
+ * Validates the current manager's options
74
+ * @param options
75
+ */
62
76
  validateOptions(options) {
63
77
  if (typeof options?.sendToShard !== "function")
64
78
  throw new SyntaxError("ManagerOption.sendToShard was not provided, which is required!");
@@ -89,6 +103,64 @@ class LavalinkManager extends events_1.EventEmitter {
89
103
  if (typeof options?.queueOptions?.maxPreviousTracks !== "number" || options?.queueOptions?.maxPreviousTracks < 0)
90
104
  options.queueOptions.maxPreviousTracks = 25;
91
105
  }
106
+ /**
107
+ * Create the Lavalink Manager
108
+ * @param options
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * //const client = new Client({...}); // create your BOT Client (e.g. via discord.js)
113
+ * client.lavalink = new LavalinkManager({
114
+ * nodes: [
115
+ * {
116
+ * authorization: "yourverystrongpassword",
117
+ * host: "localhost",
118
+ * port: 2333,
119
+ * id: "testnode"
120
+ * },
121
+ * sendToShard(guildId, payload) => client.guilds.cache.get(guildId)?.shard?.send(payload),
122
+ * client: {
123
+ * id: process.env.CLIENT_ID,
124
+ * username: "TESTBOT"
125
+ * },
126
+ * // optional Options:
127
+ * autoSkip: true,
128
+ * playerOptions: {
129
+ * applyVolumeAsFilter: false,
130
+ * clientBasedPositionUpdateInterval: 150,
131
+ * defaultSearchPlatform: "ytmsearch",
132
+ * volumeDecrementer: 0.75,
133
+ * //requesterTransformer: YourRequesterTransformerFunction,
134
+ * onDisconnect: {
135
+ * autoReconnect: true,
136
+ * destroyPlayer: false
137
+ * },
138
+ * onEmptyQueue: {
139
+ * destroyAfterMs: 30_000,
140
+ * //autoPlayFunction: YourAutoplayFunction,
141
+ * },
142
+ * useUnresolvedData: true
143
+ * },
144
+ * queueOptions: {
145
+ * maxPreviousTracks: 25,
146
+ * //queueStore: yourCustomQueueStoreManagerClass,
147
+ * //queueChangesWatcher: yourCustomQueueChangesWatcherClass
148
+ * },
149
+ * linksBlacklist: [],
150
+ * linksWhitelist: [],
151
+ * advancedOptions: {
152
+ * debugOptions: {
153
+ * noAudio: false,
154
+ * playerDestroy: {
155
+ * dontThrowError: false,
156
+ * debugLogs: false
157
+ * }
158
+ * }
159
+ * }
160
+ * ]
161
+ * })
162
+ * ```
163
+ */
92
164
  constructor(options) {
93
165
  super();
94
166
  if (!options)
@@ -100,6 +172,47 @@ class LavalinkManager extends events_1.EventEmitter {
100
172
  // create classes
101
173
  this.nodeManager = new NodeManager_1.NodeManager(this);
102
174
  }
175
+ /**
176
+ * Get a Player from Lava
177
+ * @param guildId The guildId of the player
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * const player = client.lavalink.getPlayer(interaction.guildId);
182
+ * ```
183
+ * A quicker and easier way than doing:
184
+ * ```ts
185
+ * const player = client.lavalink.players.get(interaction.guildId);
186
+ * ```
187
+ * @returns
188
+ */
189
+ getPlayer(guildId) {
190
+ return this.players.get(guildId);
191
+ }
192
+ /**
193
+ * Create a Music-Player. If a player exists, then it returns it before creating a new one
194
+ * @param options
195
+ * @returns
196
+ *
197
+ * @example
198
+ * ```ts
199
+ * const player = client.lavalink.createPlayer({
200
+ * guildId: interaction.guildId,
201
+ * voiceChannelId: interaction.member.voice.channelId,
202
+ * // everything below is optional
203
+ * textChannelId: interaction.channelId,
204
+ * volume: 100,
205
+ * selfDeaf: true,
206
+ * selfMute: false,
207
+ * instaUpdateFiltersFix: true,
208
+ * applyVolumeAsFilter: false
209
+ * //only needed if you want to autopick node by region (configured by you)
210
+ * // vcRegion: interaction.member.voice.rtcRegion,
211
+ * // provide a specific node
212
+ * // node: client.lavalink.nodeManager.leastUsedNodes("memory")[0]
213
+ * });
214
+ * ```
215
+ */
103
216
  createPlayer(options) {
104
217
  const oldPlayer = this.getPlayer(options?.guildId);
105
218
  if (oldPlayer)
@@ -108,15 +221,29 @@ class LavalinkManager extends events_1.EventEmitter {
108
221
  this.players.set(newPlayer.guildId, newPlayer);
109
222
  return newPlayer;
110
223
  }
111
- getPlayer(guildId) {
112
- return this.players.get(guildId);
113
- }
224
+ /**
225
+ * Destroy a player with optional destroy reason and disconnect it from the voice channel
226
+ * @param guildId
227
+ * @param destroyReason
228
+ * @returns
229
+ *
230
+ * @example
231
+ * ```ts
232
+ * client.lavalink.destroyPlayer(interaction.guildId, "forcefully destroyed the player");
233
+ * // recommend to do it on the player tho: player.destroy("forcefully destroyed the player");
234
+ * ```
235
+ */
114
236
  destroyPlayer(guildId, destroyReason) {
115
237
  const oldPlayer = this.getPlayer(guildId);
116
238
  if (!oldPlayer)
117
239
  return;
118
240
  return oldPlayer.destroy(destroyReason);
119
241
  }
242
+ /**
243
+ * Delete's a player from the cache without destroying it on lavalink (only works when it's disconnected)
244
+ * @param guildId
245
+ * @returns
246
+ */
120
247
  deletePlayer(guildId) {
121
248
  const oldPlayer = this.getPlayer(guildId);
122
249
  if (!oldPlayer)
@@ -130,12 +257,27 @@ class LavalinkManager extends events_1.EventEmitter {
130
257
  }
131
258
  return this.players.delete(guildId);
132
259
  }
260
+ /**
261
+ * Checks wether the the lib is useable based on if any node is connected
262
+ */
133
263
  get useable() {
134
264
  return this.nodeManager.nodes.filter(v => v.connected).size > 0;
135
265
  }
136
266
  /**
137
- * Initiates the Manager.
267
+ * Initiates the Manager, creates all nodes and connects all of them
138
268
  * @param clientData
269
+ *
270
+ * @example
271
+ *
272
+ * ```ts
273
+ * // on the bot ready event
274
+ * client.on("ready", () => {
275
+ * client.lavalink.init({
276
+ * id: client.user.id,
277
+ * username: client.user.username
278
+ * });
279
+ * });
280
+ * ```
139
281
  */
140
282
  async init(clientData) {
141
283
  if (this.initiated)
@@ -165,7 +307,18 @@ class LavalinkManager extends events_1.EventEmitter {
165
307
  }
166
308
  /**
167
309
  * Sends voice data to the Lavalink server.
310
+ * ! Without this the library won't work
168
311
  * @param data
312
+ *
313
+ * @example
314
+ *
315
+ * ```ts
316
+ * // on the bot "raw" event
317
+ * client.on("raw", (d) => {
318
+ * // required in order to send audio updates and register channel deletion etc.
319
+ * client.lavalink.sendRawData(d)
320
+ * })
321
+ * ```
169
322
  */
170
323
  async sendRawData(data) {
171
324
  if (!this.initiated) {
@@ -172,7 +172,7 @@ export declare class Player {
172
172
  * @param query Query for your data
173
173
  * @param requestUser
174
174
  */
175
- search(query: SearchQuery, requestUser: unknown): Promise<import("./Utils").UnresolvedSearchResult | import("./Utils").SearchResult>;
175
+ search(query: SearchQuery, requestUser: unknown): Promise<import("./Utils").SearchResult | import("./Utils").UnresolvedSearchResult>;
176
176
  /**
177
177
  * Pause the player
178
178
  */
@@ -243,7 +243,8 @@ class ManagerUtils {
243
243
  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?.()
244
244
  };
245
245
  const foundSource = Object.keys(LavalinkManagerStatics_1.DefaultSources).find(source => Query.query?.toLowerCase?.()?.startsWith(`${source}:`.toLowerCase()))?.trim?.()?.toLowerCase?.();
246
- if (foundSource && LavalinkManagerStatics_1.DefaultSources[foundSource]) {
246
+ // ignore links...
247
+ if (foundSource && !["https", "http"].includes(foundSource) && LavalinkManagerStatics_1.DefaultSources[foundSource]) {
247
248
  Query.source = LavalinkManagerStatics_1.DefaultSources[foundSource]; // set the source to ytsearch:
248
249
  Query.query = Query.query.slice(`${foundSource}:`.length, Query.query.length); // remove ytsearch: from the query
249
250
  }