lavalink-client 2.0.1 → 2.1.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 CHANGED
@@ -180,4 +180,31 @@ Check out the [Documentation](https://lc4.gitbook.io/lavalink-client) for **Exam
180
180
  ```
181
181
  In one of the next updates, there will be more queueWatcher options and more custom nodeevents to trace
182
182
 
183
- Most features of this update got tested, but if you encounter any bugs feel free to open an issue!
183
+ Most features of this update got tested, but if you encounter any bugs feel free to open an issue!
184
+
185
+ ## **Version 2.1.0**
186
+ - Fixed that, if you skip and have trackloop enabled, it doesn't skip the track
187
+ - I fixed that in the past, but for some reason i removed the fix on accident ig.
188
+ - Reworked the Filter Manager for custom filters via [LavalinkFilterPlugin](https://github.com/rohank05/lavalink-filter-plugin) / [LavalinkLavaDSPX-Plugin](https://github.com/devoxin/LavaDSPX-Plugin/)
189
+ - Note that the [LavalinkLavaDSPX-Plugin](https://github.com/devoxin/LavaDSPX-Plugin/) is by a Community Member of Lavalink and UNOFFICIAL
190
+ - They now have individual state-variabels (booleans): `player.filterManager.filters.lavalinkLavaDspxPlugin`
191
+ - `player.filterManager.filters.lavalinkLavaDspxPlugin.echo`
192
+ - `player.filterManager.filters.lavalinkLavaDspxPlugin.normalization`
193
+ - `player.filterManager.filters.lavalinkLavaDspxPlugin.highPass`
194
+ - `player.filterManager.filters.lavalinkLavaDspxPlugin.lowPass`
195
+ - and for: `player.filterManager.filters.lavalinkFilterPlugin` (this plugins seems to not work on v4 at the moment)
196
+ - `player.filterManager.filters.lavalinkLavaDspxPlugin.echo`
197
+ - `player.filterManager.filters.lavalinkLavaDspxPlugin.reverb`
198
+ - They also now have individual state-changing-methods: `player.filterManager.lavalinkLavaDspxPlugin`
199
+ - `player.filterManager.lavalinkLavaDspxPlugin.toggleEcho(decay:number, echoLength:number)`
200
+ - `player.filterManager.lavalinkLavaDspxPlugin.toggleNormalization(maxAmplitude:number, adaptive:boolean)`
201
+ - `player.filterManager.lavalinkLavaDspxPlugin.toggleHighPass(boostFactor:number, cutoffFrequency:number)`
202
+ - `player.filterManager.lavalinkLavaDspxPlugin.toggleLowPass(boostFactor:number, cutoffFrequency:number)`
203
+ - and for: `player.filterManager.lavalinkFilterPlugin`
204
+ - `player.filterManager.lavalinkFilterPlugin.toggleEcho(delay:number, decay:number)`
205
+ - `player.filterManager.lavalinkFilterPlugin.toggleReverb(delays:number[], gains:number[])`
206
+
207
+ ## **Version 2.1.1**
208
+ - Enforce link searches for users with following searchPlatform Options: "http" | "https" | "link" | "uri"
209
+ - Additionally strongend the code behind that
210
+ - Added searchPlatform for local tracks (aka files on the lavalink server...): "local"
@@ -86,20 +86,28 @@ export declare class FilterManager {
86
86
  * @returns
87
87
  */
88
88
  toggleLowPass(smoothing?: number): Promise<boolean>;
89
- /**
90
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
91
- * @param delay
92
- * @param decay
93
- * @returns
94
- */
95
- toggleEcho(delay?: number, decay?: number): Promise<boolean>;
96
- /**
97
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
98
- * @param delays
99
- * @param gains
100
- * @returns
101
- */
102
- toggleReverb(delays?: number[], gains?: number[]): Promise<boolean>;
89
+ lavalinkLavaDspxPlugin: {
90
+ toggleLowPass: (boostFactor?: number, cutoffFrequency?: number) => Promise<boolean>;
91
+ toggleHighPass: (boostFactor?: number, cutoffFrequency?: number) => Promise<boolean>;
92
+ toggleNormalization: (maxAmplitude?: number, adaptive?: boolean) => Promise<boolean>;
93
+ toggleEcho: (decay?: number, echoLength?: number) => Promise<boolean>;
94
+ };
95
+ lavalinkFilterPlugin: {
96
+ /**
97
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
98
+ * @param delay
99
+ * @param decay
100
+ * @returns
101
+ */
102
+ toggleEcho: (delay?: number, decay?: number) => Promise<boolean>;
103
+ /**
104
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
105
+ * @param delays
106
+ * @param gains
107
+ * @returns
108
+ */
109
+ toggleReverb: (delays?: number[], gains?: number[]) => Promise<boolean>;
110
+ };
103
111
  /**
104
112
  * Enables / Disabels a Nightcore-like filter Effect. Disables/Overwrides both: custom and Vaporwave Filter
105
113
  * @param speed
@@ -160,10 +168,23 @@ export interface PlayerFilters {
160
168
  audioOutput: AudioOutputs;
161
169
  /** Lavalink Volume FILTER (not player Volume, think of it as a gain booster) */
162
170
  volume: boolean;
163
- /** only with the custom lavalink filter plugin */
164
- echo: boolean;
165
- /** only with the custom lavalink filter plugin */
166
- reverb: boolean;
171
+ /** Filters for the Lavalink Filter Plugin */
172
+ lavalinkFilterPlugin: {
173
+ /** if echo filter is enabled / not */
174
+ echo: boolean;
175
+ /** if reverb filter is enabled / not */
176
+ reverb: boolean;
177
+ };
178
+ lavalinkLavaDspxPlugin: {
179
+ /** if lowPass filter is enabled / not */
180
+ lowPass: boolean;
181
+ /** if highPass filter is enabled / not */
182
+ highPass: boolean;
183
+ /** if normalization filter is enabled / not */
184
+ normalization: boolean;
185
+ /** if echo filter is enabled / not */
186
+ echo: boolean;
187
+ };
167
188
  }
168
189
  /**
169
190
  * There are 15 bands (0-14) that can be changed.
@@ -174,9 +195,9 @@ export interface PlayerFilters {
174
195
  */
175
196
  export interface EQBand {
176
197
  /** On what band position (0-14) it should work */
177
- band: IntegerNumber;
198
+ band: IntegerNumber | number;
178
199
  /** The gain (-0.25 to 1.0) */
179
- gain: FloatNumber;
200
+ gain: FloatNumber | number;
180
201
  }
181
202
  /**
182
203
  * Uses equalization to eliminate part of a band, usually targeting vocals.
@@ -265,20 +286,6 @@ export interface LowPassFilter {
265
286
  /** The smoothing factor (1.0 < x) */
266
287
  smoothing?: number;
267
288
  }
268
- /**
269
- * A Plugin Filter
270
- */
271
- export interface EchoFilter {
272
- delay: number;
273
- decay: number;
274
- }
275
- /**
276
- * A Plugin Filter
277
- */
278
- export interface ReverbFilter {
279
- delays: number[];
280
- gains: number[];
281
- }
282
289
  /**
283
290
  * Filter Data stored in the Client and partially sent to Lavalink
284
291
  */
@@ -292,15 +299,34 @@ export interface FilterData {
292
299
  distortion?: DistortionFilter;
293
300
  channelMix?: ChannelMixFilter;
294
301
  lowPass?: LowPassFilter;
295
- pluginFilters?: Record<PluginFiltersKey, PluginFiltersValues>;
296
- }
297
- export type PluginFiltersKey = "lavalink-filter-plugin" | string;
298
- export interface PluginFiltersValues extends LavalinkFiltersPlugin {
299
- [key: string]: string | number | string[] | number[] | EchoFilter | ReverbFilter;
300
- }
301
- export interface LavalinkFiltersPlugin {
302
- "echo": EchoFilter;
303
- "reverb": ReverbFilter;
302
+ pluginFilters?: {
303
+ "lavalink-filter-plugin"?: {
304
+ "echo"?: {
305
+ delay?: number;
306
+ decay?: number;
307
+ };
308
+ "reverb"?: {
309
+ delays?: number[];
310
+ gains?: number[];
311
+ };
312
+ };
313
+ "high-pass"?: {
314
+ cutoffFrequency?: number;
315
+ boostFactor?: number;
316
+ };
317
+ "low-pass"?: {
318
+ cutoffFrequency?: number;
319
+ boostFactor?: number;
320
+ };
321
+ normalization?: {
322
+ maxAmplitude?: number;
323
+ adaptive?: boolean;
324
+ };
325
+ echo?: {
326
+ echoLength?: number;
327
+ decay?: number;
328
+ };
329
+ };
304
330
  }
305
331
  /**
306
332
  * Actual Filter Data sent to Lavalink
@@ -15,13 +15,21 @@ class FilterManager {
15
15
  vaporwave: false,
16
16
  custom: false,
17
17
  nightcore: false,
18
- echo: false,
19
- reverb: false,
20
18
  rotation: false,
21
19
  karaoke: false,
22
20
  tremolo: false,
23
21
  vibrato: false,
24
22
  lowPass: false,
23
+ lavalinkFilterPlugin: {
24
+ echo: false,
25
+ reverb: false,
26
+ },
27
+ lavalinkLavaDspxPlugin: {
28
+ lowPass: false,
29
+ highPass: false,
30
+ normalization: false,
31
+ echo: false,
32
+ },
25
33
  audioOutput: "stereo",
26
34
  };
27
35
  /** The Filter Data sent to Lavalink, only if the filter is enabled (ofc.) */
@@ -61,7 +69,23 @@ class FilterManager {
61
69
  delays: [],
62
70
  gains: [] // [0.84, 0.83, 0.82, 0.81]
63
71
  }
64
- }
72
+ },
73
+ "high-pass": { // Cuts off frequencies lower than the specified {cutoffFrequency}.
74
+ // "cutoffFrequency": 1475, // Integer, higher than zero, in Hz.
75
+ // "boostFactor": 1.0 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
76
+ },
77
+ "low-pass": { // Cuts off frequencies higher than the specified {cutoffFrequency}.
78
+ // "cutoffFrequency": 284, // Integer, higher than zero, in Hz.
79
+ // "boostFactor": 1.24389 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
80
+ },
81
+ "normalization": { // Attenuates peaking where peaks are defined as having a higher value than {maxAmplitude}.
82
+ // "maxAmplitude": 0.6327, // Float, within the range of 0.0 - 1.0. A value of 0.0 mutes the output.
83
+ // "adaptive": true // false
84
+ },
85
+ "echo": { // Self-explanatory; provides an echo effect.
86
+ // "echoLength": 0.5649, // Float, higher than 0.0, in seconds (1.0 = 1 second).
87
+ // "decay": 0.4649 // Float, within the range of 0.0 - 1.0. A value of 1.0 means no decay, and a value of 0.0 means
88
+ },
65
89
  },
66
90
  channelMix: exports.audioOutputsData.stereo,
67
91
  /*distortion: {
@@ -94,10 +118,18 @@ class FilterManager {
94
118
  delete sendData.tremolo;
95
119
  if (!this.filters.vibrato)
96
120
  delete sendData.vibrato;
97
- if (!this.filters.echo)
121
+ if (!this.filters.lavalinkFilterPlugin.echo)
98
122
  delete sendData.pluginFilters?.["lavalink-filter-plugin"]?.echo;
99
- if (!this.filters.reverb)
123
+ if (!this.filters.lavalinkFilterPlugin.reverb)
100
124
  delete sendData.pluginFilters?.["lavalink-filter-plugin"]?.reverb;
125
+ if (!this.filters.lavalinkLavaDspxPlugin.echo)
126
+ delete sendData.pluginFilters?.echo;
127
+ if (!this.filters.lavalinkLavaDspxPlugin.normalization)
128
+ delete sendData.pluginFilters?.normalization;
129
+ if (!this.filters.lavalinkLavaDspxPlugin.highPass)
130
+ delete sendData.pluginFilters?.["high-pass"];
131
+ if (!this.filters.lavalinkLavaDspxPlugin.lowPass)
132
+ delete sendData.pluginFilters?.["low-pass"];
101
133
  if (sendData.pluginFilters?.["lavalink-filter-plugin"] && Object.values(sendData.pluginFilters?.["lavalink-filter-plugin"]).length === 0)
102
134
  delete sendData.pluginFilters["lavalink-filter-plugin"];
103
135
  if (sendData.pluginFilters && Object.values(sendData.pluginFilters).length === 0)
@@ -121,7 +153,7 @@ class FilterManager {
121
153
  // delete disabled filters
122
154
  if (key === "pluginFilters") {
123
155
  // for(const key of [...Object.keys(sendData.pluginFilters)]) {
124
- // if (this.player.node.info && !this.player.node.info?.plugins?.find?.(v => v.name === key)) delete sendData[key];
156
+ // // if (this.player.node.info && !this.player.node.info?.plugins?.find?.(v => v.name === key)) delete sendData[key];
125
157
  // }
126
158
  }
127
159
  else if (this.player.node.info && !this.player.node.info?.filters?.includes?.(key))
@@ -148,9 +180,13 @@ class FilterManager {
148
180
  this.filters.rotation = this.data.rotation.rotationHz !== 0;
149
181
  this.filters.vibrato = this.data.vibrato.frequency !== 0 || this.data.vibrato.depth !== 0;
150
182
  this.filters.tremolo = this.data.tremolo.frequency !== 0 || this.data.tremolo.depth !== 0;
151
- const lavalinkFilterData = (this.data.pluginFilters?.["lavalink-filter-plugin"] || { echo: { decay: 0, delay: 0 }, reverb: { gains: [], delays: [] } });
152
- this.filters.echo = lavalinkFilterData.echo.decay !== 0 || lavalinkFilterData.echo.delay !== 0;
153
- this.filters.reverb = lavalinkFilterData.reverb?.delays?.length !== 0 || lavalinkFilterData.reverb?.gains?.length !== 0;
183
+ const lavalinkFilterData = (this.data.pluginFilters?.["lavalink-filter-plugin"] || { echo: { decay: this.data.pluginFilters?.echo?.decay && !this.data.pluginFilters?.echo?.echoLength ? this.data.pluginFilters.echo.decay : 0, delay: this.data.pluginFilters?.echo?.delay || 0 }, reverb: { gains: [], delays: [], ...((this.data.pluginFilters.reverb) || {}) } });
184
+ this.filters.lavalinkFilterPlugin.echo = lavalinkFilterData.echo.decay !== 0 || lavalinkFilterData.echo.delay !== 0;
185
+ this.filters.lavalinkFilterPlugin.reverb = lavalinkFilterData.reverb?.delays?.length !== 0 || lavalinkFilterData.reverb?.gains?.length !== 0;
186
+ this.filters.lavalinkLavaDspxPlugin.highPass = Object.values(this.data.pluginFilters["high-pass"] || {}).length > 0;
187
+ this.filters.lavalinkLavaDspxPlugin.lowPass = Object.values(this.data.pluginFilters["low-pass"] || {}).length > 0;
188
+ this.filters.lavalinkLavaDspxPlugin.normalization = Object.values(this.data.pluginFilters.normalization || {}).length > 0;
189
+ this.filters.lavalinkLavaDspxPlugin.echo = Object.values(this.data.pluginFilters.echo || {}).length > 0 && typeof this.data.pluginFilters?.echo?.delay === "undefined";
154
190
  this.filters.lowPass = this.data.lowPass.smoothing !== 0;
155
191
  this.filters.karaoke = Object.values(this.data.karaoke).some(v => v !== 0);
156
192
  if ((this.filters.nightcore || this.filters.vaporwave) && oldFilterTimescale) {
@@ -166,8 +202,12 @@ class FilterManager {
166
202
  * Reset all Filters
167
203
  */
168
204
  async resetFilters() {
169
- this.filters.echo = false;
170
- this.filters.reverb = false;
205
+ this.filters.lavalinkLavaDspxPlugin.echo = false;
206
+ this.filters.lavalinkLavaDspxPlugin.normalization = false;
207
+ this.filters.lavalinkLavaDspxPlugin.highPass = false;
208
+ this.filters.lavalinkLavaDspxPlugin.lowPass = false;
209
+ this.filters.lavalinkFilterPlugin.echo = false;
210
+ this.filters.lavalinkFilterPlugin.reverb = false;
171
211
  this.filters.nightcore = false;
172
212
  this.filters.lowPass = false;
173
213
  this.filters.rotation = false;
@@ -197,14 +237,30 @@ class FilterManager {
197
237
  pluginFilters: {
198
238
  "lavalink-filter-plugin": {
199
239
  echo: {
200
- delay: 0,
201
- decay: 0
240
+ // delay: 0, // in seconds
241
+ // decay: 0 // 0 < 1
202
242
  },
203
243
  reverb: {
204
- delays: [],
205
- gains: []
206
- },
207
- }
244
+ // delays: [], // [0.037, 0.042, 0.048, 0.053]
245
+ // gains: [] // [0.84, 0.83, 0.82, 0.81]
246
+ }
247
+ },
248
+ "high-pass": { // Cuts off frequencies lower than the specified {cutoffFrequency}.
249
+ // "cutoffFrequency": 1475, // Integer, higher than zero, in Hz.
250
+ // "boostFactor": 1.0 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
251
+ },
252
+ "low-pass": { // Cuts off frequencies higher than the specified {cutoffFrequency}.
253
+ // "cutoffFrequency": 284, // Integer, higher than zero, in Hz.
254
+ // "boostFactor": 1.24389 // Float, higher than 0.0. This alters volume output. A value of 1.0 means no volume change.
255
+ },
256
+ "normalization": { // Attenuates peaking where peaks are defined as having a higher value than {maxAmplitude}.
257
+ // "maxAmplitude": 0.6327, // Float, within the range of 0.0 - 1.0. A value of 0.0 mutes the output.
258
+ // "adaptive": true // false
259
+ },
260
+ "echo": { // Self-explanatory; provides an echo effect.
261
+ // "echoLength": 0.5649, // Float, higher than 0.0, in seconds (1.0 = 1 second).
262
+ // "decay": 0.4649 // Float, within the range of 0.0 - 1.0. A value of 1.0 means no decay, and a value of 0.0 means
263
+ },
208
264
  },
209
265
  rotation: {
210
266
  rotationHz: 0
@@ -372,52 +428,156 @@ class FilterManager {
372
428
  await this.applyPlayerFilters();
373
429
  return this.filters.lowPass;
374
430
  }
375
- /**
376
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
377
- * @param delay
378
- * @param decay
379
- * @returns
380
- */
381
- async toggleEcho(delay = 4, decay = 0.8) {
382
- if (this.player.node.info && !this.player.node.info?.filters?.includes("echo"))
383
- throw new Error("Node#Info#filters does not include the 'echo' Filter (Node has it not enable aka not installed!)");
384
- if (!this.data)
385
- this.data = {};
386
- if (!this.data.pluginFilters)
387
- this.data.pluginFilters = {};
388
- if (!this.data.pluginFilters["lavalink-filter-plugin"])
389
- this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
390
- if (!this.data.pluginFilters["lavalink-filter-plugin"].echo)
391
- this.data.pluginFilters["lavalink-filter-plugin"].echo = { decay: 0, delay: 0 };
392
- this.data.pluginFilters["lavalink-filter-plugin"].echo.delay = this.filters.echo ? 0 : delay;
393
- this.data.pluginFilters["lavalink-filter-plugin"].echo.decay = this.filters.echo ? 0 : decay;
394
- this.filters.echo = !this.filters.echo;
395
- await this.applyPlayerFilters();
396
- return this.filters.echo;
397
- }
398
- /**
399
- * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
400
- * @param delays
401
- * @param gains
402
- * @returns
403
- */
404
- async toggleReverb(delays = [0.037, 0.042, 0.048, 0.053], gains = [0.84, 0.83, 0.82, 0.81]) {
405
- if (this.player.node.info && !this.player.node.info?.filters?.includes("reverb"))
406
- throw new Error("Node#Info#filters does not include the 'reverb' Filter (Node has it not enable aka not installed!)");
407
- if (!this.data)
408
- this.data = {};
409
- if (!this.data.pluginFilters)
410
- this.data.pluginFilters = {};
411
- if (!this.data.pluginFilters["lavalink-filter-plugin"])
412
- this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
413
- if (!this.data.pluginFilters["lavalink-filter-plugin"].reverb)
414
- this.data.pluginFilters["lavalink-filter-plugin"].reverb = { delays: [], gains: [] };
415
- this.data.pluginFilters["lavalink-filter-plugin"].reverb.delays = this.filters.reverb ? [] : delays;
416
- this.data.pluginFilters["lavalink-filter-plugin"].reverb.gains = this.filters.reverb ? [] : gains;
417
- this.filters.reverb = !this.filters.reverb;
418
- await this.applyPlayerFilters();
419
- return this.filters.reverb;
420
- }
431
+ lavalinkLavaDspxPlugin = {
432
+ toggleLowPass: async (boostFactor = 1.0, cutoffFrequency = 80) => {
433
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
434
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
435
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("low-pass"))
436
+ throw new Error("Node#Info#filters does not include the 'low-pass' Filter (Node has it not enable)");
437
+ if (!this.data)
438
+ this.data = {};
439
+ if (!this.data.pluginFilters)
440
+ this.data.pluginFilters = {};
441
+ if (!this.data.pluginFilters["low-pass"])
442
+ this.data.pluginFilters["low-pass"] = {};
443
+ if (this.filters.lavalinkLavaDspxPlugin.lowPass) {
444
+ delete this.data.pluginFilters["low-pass"];
445
+ }
446
+ else {
447
+ this.data.pluginFilters["low-pass"] = {
448
+ boostFactor: boostFactor,
449
+ cutoffFrequency: cutoffFrequency
450
+ };
451
+ }
452
+ this.filters.lavalinkLavaDspxPlugin.lowPass = !this.filters.lavalinkLavaDspxPlugin.lowPass;
453
+ await this.applyPlayerFilters();
454
+ return this.filters.lavalinkLavaDspxPlugin.lowPass;
455
+ },
456
+ toggleHighPass: async (boostFactor = 1.0, cutoffFrequency = 80) => {
457
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
458
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
459
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("high-pass"))
460
+ throw new Error("Node#Info#filters does not include the 'high-pass' Filter (Node has it not enable)");
461
+ if (!this.data)
462
+ this.data = {};
463
+ if (!this.data.pluginFilters)
464
+ this.data.pluginFilters = {};
465
+ if (!this.data.pluginFilters["high-pass"])
466
+ this.data.pluginFilters["high-pass"] = {};
467
+ if (this.filters.lavalinkLavaDspxPlugin.highPass) {
468
+ delete this.data.pluginFilters["high-pass"];
469
+ }
470
+ else {
471
+ this.data.pluginFilters["high-pass"] = {
472
+ boostFactor: boostFactor,
473
+ cutoffFrequency: cutoffFrequency
474
+ };
475
+ }
476
+ this.filters.lavalinkLavaDspxPlugin.highPass = !this.filters.lavalinkLavaDspxPlugin.highPass;
477
+ await this.applyPlayerFilters();
478
+ return this.filters.lavalinkLavaDspxPlugin.highPass;
479
+ },
480
+ toggleNormalization: async (maxAmplitude = 0.75, adaptive = true) => {
481
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
482
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
483
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("normalization"))
484
+ throw new Error("Node#Info#filters does not include the 'normalization' Filter (Node has it not enable)");
485
+ if (!this.data)
486
+ this.data = {};
487
+ if (!this.data.pluginFilters)
488
+ this.data.pluginFilters = {};
489
+ if (!this.data.pluginFilters.normalization)
490
+ this.data.pluginFilters.normalization = {};
491
+ if (this.filters.lavalinkLavaDspxPlugin.normalization) {
492
+ delete this.data.pluginFilters.normalization;
493
+ }
494
+ else {
495
+ this.data.pluginFilters.normalization = {
496
+ adaptive: adaptive,
497
+ maxAmplitude: maxAmplitude
498
+ };
499
+ }
500
+ this.filters.lavalinkLavaDspxPlugin.normalization = !this.filters.lavalinkLavaDspxPlugin.normalization;
501
+ await this.applyPlayerFilters();
502
+ return this.filters.lavalinkLavaDspxPlugin.normalization;
503
+ },
504
+ toggleEcho: async (decay = 0.5, echoLength = 0.5) => {
505
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavadspx-plugin"))
506
+ throw new Error("Node#Info#plugins does not include the lavadspx plugin");
507
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("echo"))
508
+ throw new Error("Node#Info#filters does not include the 'echo' Filter (Node has it not enable)");
509
+ if (!this.data)
510
+ this.data = {};
511
+ if (!this.data.pluginFilters)
512
+ this.data.pluginFilters = {};
513
+ if (!this.data.pluginFilters.echo)
514
+ this.data.pluginFilters.echo = {};
515
+ if (this.filters.lavalinkLavaDspxPlugin.echo) {
516
+ delete this.data.pluginFilters.echo;
517
+ }
518
+ else {
519
+ this.data.pluginFilters.echo = {
520
+ decay: decay,
521
+ echoLength: echoLength
522
+ };
523
+ }
524
+ this.filters.lavalinkLavaDspxPlugin.echo = !this.filters.lavalinkLavaDspxPlugin.echo;
525
+ await this.applyPlayerFilters();
526
+ return this.filters.lavalinkLavaDspxPlugin.echo;
527
+ }
528
+ };
529
+ lavalinkFilterPlugin = {
530
+ /**
531
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
532
+ * @param delay
533
+ * @param decay
534
+ * @returns
535
+ */
536
+ toggleEcho: async (delay = 4, decay = 0.8) => {
537
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavalink-filter-plugin"))
538
+ throw new Error("Node#Info#plugins does not include the lavalink-filter-plugin plugin");
539
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("echo"))
540
+ throw new Error("Node#Info#filters does not include the 'echo' Filter (Node has it not enable aka not installed!)");
541
+ if (!this.data)
542
+ this.data = {};
543
+ if (!this.data.pluginFilters)
544
+ this.data.pluginFilters = {};
545
+ if (!this.data.pluginFilters["lavalink-filter-plugin"])
546
+ this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
547
+ if (!this.data.pluginFilters["lavalink-filter-plugin"].echo)
548
+ this.data.pluginFilters["lavalink-filter-plugin"].echo = { decay: 0, delay: 0 };
549
+ this.data.pluginFilters["lavalink-filter-plugin"].echo.delay = this.filters.lavalinkFilterPlugin.echo ? 0 : delay;
550
+ this.data.pluginFilters["lavalink-filter-plugin"].echo.decay = this.filters.lavalinkFilterPlugin.echo ? 0 : decay;
551
+ this.filters.lavalinkFilterPlugin.echo = !this.filters.lavalinkFilterPlugin.echo;
552
+ await this.applyPlayerFilters();
553
+ return this.filters.lavalinkFilterPlugin.echo;
554
+ },
555
+ /**
556
+ * Enabels / Disables the Echo effect, IMPORTANT! Only works with the correct Lavalink Plugin installed. (Optional: provide your Own Data)
557
+ * @param delays
558
+ * @param gains
559
+ * @returns
560
+ */
561
+ toggleReverb: async (delays = [0.037, 0.042, 0.048, 0.053], gains = [0.84, 0.83, 0.82, 0.81]) => {
562
+ if (this.player.node.info && !this.player.node.info?.plugins?.find(v => v.name === "lavalink-filter-plugin"))
563
+ throw new Error("Node#Info#plugins does not include the lavalink-filter-plugin plugin");
564
+ if (this.player.node.info && !this.player.node.info?.filters?.includes("reverb"))
565
+ throw new Error("Node#Info#filters does not include the 'reverb' Filter (Node has it not enable aka not installed!)");
566
+ if (!this.data)
567
+ this.data = {};
568
+ if (!this.data.pluginFilters)
569
+ this.data.pluginFilters = {};
570
+ if (!this.data.pluginFilters["lavalink-filter-plugin"])
571
+ this.data.pluginFilters["lavalink-filter-plugin"] = { echo: { decay: 0, delay: 0 }, reverb: { delays: [], gains: [] } };
572
+ if (!this.data.pluginFilters["lavalink-filter-plugin"].reverb)
573
+ this.data.pluginFilters["lavalink-filter-plugin"].reverb = { delays: [], gains: [] };
574
+ this.data.pluginFilters["lavalink-filter-plugin"].reverb.delays = this.filters.lavalinkFilterPlugin.reverb ? [] : delays;
575
+ this.data.pluginFilters["lavalink-filter-plugin"].reverb.gains = this.filters.lavalinkFilterPlugin.reverb ? [] : gains;
576
+ this.filters.lavalinkFilterPlugin.reverb = !this.filters.lavalinkFilterPlugin.reverb;
577
+ await this.applyPlayerFilters();
578
+ return this.filters.lavalinkFilterPlugin.reverb;
579
+ }
580
+ };
421
581
  /**
422
582
  * Enables / Disabels a Nightcore-like filter Effect. Disables/Overwrides both: custom and Vaporwave Filter
423
583
  * @param speed
@@ -173,7 +173,7 @@ export interface LavalinkManager {
173
173
  emit<U extends keyof LavalinkManagerEvents>(event: U, ...args: Parameters<LavalinkManagerEvents[U]>): boolean;
174
174
  }
175
175
  export declare class LavalinkManager extends EventEmitter {
176
- static DefaultSources: Record<SearchPlatform, import("./Utils").LavalinkSearchPlatform>;
176
+ static DefaultSources: Record<SearchPlatform, import("./Utils").LavalinkSearchPlatform | import("./Utils").ClientCustomSearchPlatformUtils>;
177
177
  static SourceLinksRegexes: Record<import("./Utils").SourcesRegex, RegExp>;
178
178
  initiated: boolean;
179
179
  readonly players: MiniMap<string, Player>;
@@ -1,5 +1,5 @@
1
- import { LavalinkSearchPlatform, SearchPlatform, SourcesRegex } from "./Utils";
2
- export declare const DefaultSources: Record<SearchPlatform, LavalinkSearchPlatform>;
1
+ import { ClientCustomSearchPlatformUtils, LavalinkSearchPlatform, SearchPlatform, SourcesRegex } from "./Utils";
2
+ export declare const DefaultSources: Record<SearchPlatform, LavalinkSearchPlatform | ClientCustomSearchPlatformUtils>;
3
3
  export declare const LavalinkPlugins: {
4
4
  DuncteBot_Plugin: string;
5
5
  LavaSrc: string;
@@ -47,10 +47,20 @@ exports.DefaultSources = {
47
47
  "speak": "speak",
48
48
  "tts": "tts",
49
49
  "ftts": "ftts",
50
+ "flowery": "ftts",
51
+ "flowery.tts": "ftts",
52
+ "flowerytts": "ftts",
50
53
  // Client sided search platforms
51
54
  "bandcamp": "bcsearch",
52
55
  "bc": "bcsearch",
53
56
  "bcsearch": "bcsearch",
57
+ // local files
58
+ "local": "local",
59
+ // http requests
60
+ "http": "http",
61
+ "https": "https",
62
+ "link": "link",
63
+ "uri": "uri"
54
64
  };
55
65
  exports.LavalinkPlugins = {
56
66
  DuncteBot_Plugin: "DuncteBot-plugin",
@@ -124,12 +124,17 @@ class LavalinkNode {
124
124
  throw new Error("Bandcamp Search only works on the player!");
125
125
  }
126
126
  let uri = `/loadtracks?identifier=`;
127
- if (!/^https?:\/\//.test(Query.query))
128
- uri += `${Query.source}:`;
129
- if (Query.source === "ftts")
130
- uri += `//${encodeURIComponent(encodeURI(decodeURIComponent(Query.query)))}`;
131
- else
127
+ if (/^https?:\/\//.test(Query.query) || ["http", "https", "link", "uri"].includes(Query.source)) { // if it's a link simply encode it
132
128
  uri += encodeURIComponent(decodeURIComponent(Query.query));
129
+ }
130
+ else { // if not make a query out of it
131
+ if (Query.source !== "local")
132
+ uri += `${Query.source}:`; // only add the query source string if it's not a local track
133
+ if (Query.source === "ftts")
134
+ uri += `//${encodeURIComponent(encodeURI(decodeURIComponent(Query.query)))}`;
135
+ else
136
+ uri += encodeURIComponent(decodeURIComponent(Query.query));
137
+ }
133
138
  const res = await this.request(uri);
134
139
  // transform the data which can be Error, Track or Track[] to enfore [Track]
135
140
  const resTracks = res.loadType === "playlist" ? res.data?.tracks : res.loadType === "track" ? [res.data] : res.loadType === "search" ? Array.isArray(res.data) ? res.data : [res.data] : [];
@@ -663,7 +668,7 @@ class LavalinkNode {
663
668
  return this.NodeManager.LavalinkManager.options.autoSkip && player.play({ noReplace: true });
664
669
  }
665
670
  // remove tracks from the queue
666
- if (player.repeatMode !== "track")
671
+ if (player.repeatMode !== "track" || player.get("internal_skipped"))
667
672
  await (0, Utils_1.queueTrackEnd)(player);
668
673
  else if (player.queue.current) { // If there was a current Track already and repeatmode === true, add it to the queue.
669
674
  player.queue.previous.unshift(player.queue.current);
@@ -671,6 +676,7 @@ class LavalinkNode {
671
676
  player.queue.previous.splice(player.queue.options.maxPreviousTracks, player.queue.previous.length);
672
677
  await player.queue.utils.save();
673
678
  }
679
+ player.set("internal_skipped", false);
674
680
  // if no track available, end queue
675
681
  if (!player.queue.current)
676
682
  return this.queueEnd(player, track, payload);
@@ -333,6 +333,7 @@ class Player {
333
333
  if (!this.playing)
334
334
  return await this.play();
335
335
  const now = performance.now();
336
+ this.set("internal_skipped", true);
336
337
  await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { track: { encoded: null } } });
337
338
  this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
338
339
  return this;
@@ -18,7 +18,9 @@ export type DuncteSearchPlatform = "speak" | "tts";
18
18
  export type LavalinkClientSearchPlatform = "bcsearch";
19
19
  export type LavalinkClientSearchPlatformResolve = "bandcamp" | "bc";
20
20
  export type LavalinkSearchPlatform = "ytsearch" | "ytmsearch" | "scsearch" | LavaSrcSearchPlatform | DuncteSearchPlatform | LavalinkClientSearchPlatform;
21
- export type ClientSearchPlatform = "youtube" | "yt" | "youtube music" | "youtubemusic" | "ytm" | "musicyoutube" | "music youtube" | "soundcloud" | "sc" | "am" | "apple music" | "applemusic" | "apple" | "musicapple" | "music apple" | "sp" | "spsuggestion" | "spotify" | "spotify.com" | "spotifycom" | "dz" | "deezer" | "yandex" | "yandex music" | "yandexmusic" | LavalinkClientSearchPlatformResolve | LavalinkClientSearchPlatform;
21
+ export type ClientCustomSearchPlatformUtils = "local" | "http" | "https" | "link" | "uri";
22
+ export type ClientSearchPlatform = ClientCustomSearchPlatformUtils | // for file/link requests
23
+ "youtube" | "yt" | "youtube music" | "youtubemusic" | "ytm" | "musicyoutube" | "music youtube" | "soundcloud" | "sc" | "am" | "apple music" | "applemusic" | "apple" | "musicapple" | "music apple" | "sp" | "spsuggestion" | "spotify" | "spotify.com" | "spotifycom" | "dz" | "deezer" | "yandex" | "yandex music" | "yandexmusic" | "flowerytts" | "flowery" | "flowery.tts" | LavalinkClientSearchPlatformResolve | LavalinkClientSearchPlatform;
22
24
  export type SearchPlatform = LavalinkSearchPlatform | ClientSearchPlatform;
23
25
  export type SourcesRegex = "YoutubeRegex" | "YoutubeMusicRegex" | "SoundCloudRegex" | "SoundCloudMobileRegex" | "DeezerTrackRegex" | "DeezerArtistRegex" | "DeezerEpisodeRegex" | "DeezerMixesRegex" | "DeezerPageLinkRegex" | "DeezerPlaylistRegex" | "DeezerAlbumRegex" | "AllDeezerRegex" | "AllDeezerRegexWithoutPageLink" | "SpotifySongRegex" | "SpotifyPlaylistRegex" | "SpotifyArtistRegex" | "SpotifyEpisodeRegex" | "SpotifyShowRegex" | "SpotifyAlbumRegex" | "AllSpotifyRegex" | "mp3Url" | "m3uUrl" | "m3u8Url" | "mp4Url" | "m4aUrl" | "wavUrl" | "aacpUrl" | "tiktok" | "mixcloud" | "musicYandex" | "radiohost" | "bandcamp" | "appleMusic" | "TwitchTv" | "vimeo";
24
26
  export interface PlaylistInfo {