magmastream 2.10.3-dev.2 → 2.10.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.
- package/dist/structures/Enums.d.ts +145 -1
- package/dist/structures/Enums.js +148 -1
- package/dist/structures/Filters.d.ts +120 -1
- package/dist/structures/Filters.js +348 -11
- package/dist/structures/Manager.d.ts +9 -0
- package/dist/structures/Manager.js +169 -30
- package/dist/structures/Node.d.ts +89 -2
- package/dist/structures/Node.js +504 -53
- package/dist/structures/Player.d.ts +85 -2
- package/dist/structures/Player.js +300 -12
- package/dist/structures/Rest.d.ts +61 -2
- package/dist/structures/Rest.js +210 -1
- package/dist/structures/Types.d.ts +645 -90
- package/dist/structures/Utils.d.ts +1 -1
- package/dist/structures/Utils.js +60 -18
- package/dist/utils/managerCheck.js +3 -2
- package/package.json +3 -2
|
@@ -21,6 +21,45 @@ function escapeRegExp(value) {
|
|
|
21
21
|
}
|
|
22
22
|
const YOUTUBE_URL_PATTERN = /(youtube\.com|youtu\.be)/;
|
|
23
23
|
const BLOCKED_WORDS_PATTERN = new RegExp(`\\b(${blockedWords_1.blockedWords.map(escapeRegExp).join("|")})\\b`, "gi");
|
|
24
|
+
const PORTABLE_SEARCH_PREFIXES = new Set(Object.values(Enums_1.SearchPlatform).map((source) => source.toLowerCase()));
|
|
25
|
+
const NODELINK_SEARCH_PREFIXES = new Set(Object.values(Enums_1.NodeLinkSearchPlatform).map((source) => source.toLowerCase()));
|
|
26
|
+
const NODELINK_RECOMMENDATION_PREFIXES = new Set(Object.values(Enums_1.NodeLinkRecommendationPlatform).map((source) => source.toLowerCase()));
|
|
27
|
+
const NODELINK_ONLY_SEARCH_PREFIXES = new Set([...NODELINK_SEARCH_PREFIXES].filter((source) => !PORTABLE_SEARCH_PREFIXES.has(source)));
|
|
28
|
+
const NODELINK_SEARCH_TYPE_MODIFIERS = new Set(Object.values(Enums_1.NodeLinkSearchType).map((type) => type.toLowerCase()));
|
|
29
|
+
const KNOWN_LOADTRACKS_PREFIXES = new Set([
|
|
30
|
+
...Object.values(Enums_1.SearchPlatform).map((source) => source.toLowerCase()),
|
|
31
|
+
...NODELINK_SEARCH_PREFIXES,
|
|
32
|
+
...NODELINK_RECOMMENDATION_PREFIXES,
|
|
33
|
+
"search",
|
|
34
|
+
"local",
|
|
35
|
+
"sprec",
|
|
36
|
+
"dzrec",
|
|
37
|
+
"tdrec",
|
|
38
|
+
"vkrec",
|
|
39
|
+
"qbrec",
|
|
40
|
+
"ymrec",
|
|
41
|
+
"ytrec",
|
|
42
|
+
"jsrec",
|
|
43
|
+
"lmrec",
|
|
44
|
+
]);
|
|
45
|
+
const NODELINK_ONLY_LOADTRACKS_PREFIXES = new Set(["ytrec", "jsrec", "lmrec"]);
|
|
46
|
+
const SEARCH_TYPE_PATTERN = /^[A-Za-z0-9]+$/;
|
|
47
|
+
function getIdentifierPrefix(identifier) {
|
|
48
|
+
const match = /^([A-Za-z0-9]+):/.exec(identifier);
|
|
49
|
+
return match?.[1]?.toLowerCase() ?? null;
|
|
50
|
+
}
|
|
51
|
+
function getIdentifierSearchType(identifier) {
|
|
52
|
+
const match = /^[A-Za-z0-9]+:([A-Za-z0-9]+):/.exec(identifier);
|
|
53
|
+
return match?.[1]?.toLowerCase() ?? null;
|
|
54
|
+
}
|
|
55
|
+
function getNodeLoad(node) {
|
|
56
|
+
const cores = node.stats.cpu?.cores ?? 0;
|
|
57
|
+
const nodeLinkLoad = node.stats.cpu?.nodelinkLoad;
|
|
58
|
+
if (typeof nodeLinkLoad === "number" && Number.isFinite(nodeLinkLoad))
|
|
59
|
+
return nodeLinkLoad * 100;
|
|
60
|
+
const load = node.stats.cpu?.lavalinkLoad ?? 0;
|
|
61
|
+
return cores > 0 && Number.isFinite(load) ? (load / cores) * 100 : 0;
|
|
62
|
+
}
|
|
24
63
|
/**
|
|
25
64
|
* The main hub for interacting with Lavalink and using Magmastream.
|
|
26
65
|
*/
|
|
@@ -202,19 +241,27 @@ class Manager extends events_1.EventEmitter {
|
|
|
202
241
|
* @returns The search result.
|
|
203
242
|
*/
|
|
204
243
|
async search(query, requester) {
|
|
205
|
-
const
|
|
244
|
+
const _query = typeof query === "string" ? { query } : query;
|
|
245
|
+
const _source = _query.source ?? this.options.defaultSearchPlatform ?? Enums_1.SearchPlatform.YouTube;
|
|
246
|
+
const isUrl = /^https?:\/\//.test(_query.query);
|
|
247
|
+
const isPrefixedIdentifier = this.isPrefixedLoadTracksIdentifier(_query.query);
|
|
248
|
+
const searchType = this.normalizeSearchType(_query.searchType);
|
|
249
|
+
const search = this.buildLoadTracksIdentifier(_source, _query.query, searchType, isUrl, isPrefixedIdentifier);
|
|
250
|
+
const node = this.getSearchNode(_source, search, searchType);
|
|
206
251
|
if (!node) {
|
|
207
252
|
throw new MagmastreamError_1.MagmaStreamError({
|
|
208
253
|
code: Enums_1.MagmaStreamErrorCode.MANAGER_NO_NODES,
|
|
209
|
-
message:
|
|
254
|
+
message: this.requiresNodeLinkSearchNode(_source, search, searchType)
|
|
255
|
+
? "No available NodeLink nodes to perform the NodeLink-specific search."
|
|
256
|
+
: this.requiresLavalinkSearchNode(search)
|
|
257
|
+
? "No available Lavalink nodes to perform the Lavalink-specific search."
|
|
258
|
+
: "No available nodes to perform the search.",
|
|
210
259
|
context: { query, requester },
|
|
211
260
|
});
|
|
212
261
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const search = isUrl ? _query.query : `${_source}:${_query.query}`;
|
|
217
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, isUrl ? `[MANAGER] Performing search for: ${_query.query}` : `[MANAGER] Performing ${_source} search for: ${_query.query}`);
|
|
262
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, isUrl || isPrefixedIdentifier
|
|
263
|
+
? `[MANAGER] Performing search on ${node.options.identifier} for: ${search}`
|
|
264
|
+
: `[MANAGER] Performing ${_source}${searchType ? `:${searchType}` : ""} search on ${node.options.identifier} for: ${_query.query}`);
|
|
218
265
|
try {
|
|
219
266
|
const lavalinkResponse = (await node.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(search)}`));
|
|
220
267
|
if (!lavalinkResponse) {
|
|
@@ -231,6 +278,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
231
278
|
result = { loadType: lavalinkResponse.loadType, tracks };
|
|
232
279
|
break;
|
|
233
280
|
}
|
|
281
|
+
case Enums_1.LoadTypes.Episode:
|
|
234
282
|
case Enums_1.LoadTypes.Short:
|
|
235
283
|
case Enums_1.LoadTypes.Track: {
|
|
236
284
|
const track = Utils_1.TrackUtils.build(lavalinkResponse.data, requester);
|
|
@@ -250,7 +298,8 @@ class Manager extends events_1.EventEmitter {
|
|
|
250
298
|
tracks,
|
|
251
299
|
playlist: {
|
|
252
300
|
name: playlistData.info.name,
|
|
253
|
-
playlistInfo: playlistData.
|
|
301
|
+
playlistInfo: playlistData.info,
|
|
302
|
+
pluginInfo: playlistData.pluginInfo,
|
|
254
303
|
requester: requester,
|
|
255
304
|
tracks,
|
|
256
305
|
duration: tracks.reduce((acc, cur) => acc + (cur.duration || 0), 0),
|
|
@@ -263,7 +312,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
263
312
|
}
|
|
264
313
|
if (this.options.normalizeYouTubeTitles && "tracks" in result) {
|
|
265
314
|
const processTrack = (track) => {
|
|
266
|
-
if (!YOUTUBE_URL_PATTERN.test(track.uri))
|
|
315
|
+
if (!track.uri || !YOUTUBE_URL_PATTERN.test(track.uri))
|
|
267
316
|
return track;
|
|
268
317
|
const { cleanTitle, cleanAuthor } = this.parseYouTubeTitle(track.title, track.author);
|
|
269
318
|
track.title = cleanTitle;
|
|
@@ -406,23 +455,21 @@ class Manager extends events_1.EventEmitter {
|
|
|
406
455
|
*/
|
|
407
456
|
async decodeTracks(tracks) {
|
|
408
457
|
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Decoding tracks: ${Utils_1.JSONUtils.safe(tracks, 2)}`);
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
return resolve(decodedTrackData);
|
|
425
|
-
});
|
|
458
|
+
const node = this.useableNode;
|
|
459
|
+
if (!node) {
|
|
460
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
461
|
+
code: Enums_1.MagmaStreamErrorCode.MANAGER_NO_NODES,
|
|
462
|
+
message: "No available nodes to decode tracks.",
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
const decodedTrackData = await node.rest.decodeTracks(tracks);
|
|
466
|
+
if (!decodedTrackData) {
|
|
467
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
468
|
+
code: Enums_1.MagmaStreamErrorCode.REST_REQUEST_FAILED,
|
|
469
|
+
message: "No decoded tracks returned from node.",
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
return decodedTrackData;
|
|
426
473
|
}
|
|
427
474
|
/**
|
|
428
475
|
* Decodes a base64 encoded track and returns a TrackData.
|
|
@@ -607,14 +654,28 @@ class Manager extends events_1.EventEmitter {
|
|
|
607
654
|
const filterActions = {
|
|
608
655
|
bassboost: () => player.filters.bassBoost(state.filters.bassBoostlevel),
|
|
609
656
|
distort: (isEnabled) => player.filters.distort(isEnabled),
|
|
657
|
+
pluginFilters: () => player.filters.setPluginFilters(state.filters.pluginFilters),
|
|
658
|
+
setChannelMix: () => player.filters.setChannelMix(state.filters.channelMix),
|
|
610
659
|
setDistortion: () => player.filters.setDistortion(state.filters.distortion),
|
|
611
660
|
eightD: (isEnabled) => player.filters.eightD(isEnabled),
|
|
612
661
|
setKaraoke: () => player.filters.setKaraoke(state.filters.karaoke),
|
|
662
|
+
setLowPass: () => player.filters.setLowPass(state.filters.lowPass),
|
|
663
|
+
setHighPass: () => player.filters.setHighPass(state.filters.highpass),
|
|
664
|
+
setEcho: () => player.filters.setEcho(state.filters.echo),
|
|
665
|
+
setReverb: () => player.filters.setReverb(state.filters.reverb),
|
|
666
|
+
setChorus: () => player.filters.setChorus(state.filters.chorus),
|
|
667
|
+
setCompressor: () => player.filters.setCompressor(state.filters.compressor),
|
|
668
|
+
setFlanger: () => player.filters.setFlanger(state.filters.flanger),
|
|
669
|
+
setPhaser: () => player.filters.setPhaser(state.filters.phaser),
|
|
670
|
+
setPhonograph: () => player.filters.setPhonograph(state.filters.phonograph),
|
|
671
|
+
setSpatial: () => player.filters.setSpatial(state.filters.spatial),
|
|
672
|
+
setTape: () => player.filters.setTape(state.filters.tape),
|
|
613
673
|
nightcore: (isEnabled) => player.filters.nightcore(isEnabled),
|
|
614
674
|
slowmo: (isEnabled) => player.filters.slowmo(isEnabled),
|
|
615
675
|
soft: (isEnabled) => player.filters.soft(isEnabled),
|
|
616
676
|
trebleBass: (isEnabled) => player.filters.trebleBass(isEnabled),
|
|
617
677
|
setTimescale: () => player.filters.setTimescale(state.filters.timescale),
|
|
678
|
+
setTremolo: () => player.filters.setTremolo(state.filters.tremolo),
|
|
618
679
|
tv: (isEnabled) => player.filters.tv(isEnabled),
|
|
619
680
|
vibrato: () => player.filters.setVibrato(state.filters.vibrato),
|
|
620
681
|
vaporwave: (isEnabled) => player.filters.vaporwave(isEnabled),
|
|
@@ -717,6 +778,87 @@ class Manager extends events_1.EventEmitter {
|
|
|
717
778
|
this.emit(Enums_1.ManagerEventTypes.Debug, "[MANAGER] Finished loading saved players.");
|
|
718
779
|
this.emit(Enums_1.ManagerEventTypes.RestoreComplete, node);
|
|
719
780
|
}
|
|
781
|
+
normalizeSearchType(searchType) {
|
|
782
|
+
if (searchType === undefined || searchType === null)
|
|
783
|
+
return null;
|
|
784
|
+
if (typeof searchType !== "string" || !SEARCH_TYPE_PATTERN.test(searchType)) {
|
|
785
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
786
|
+
code: Enums_1.MagmaStreamErrorCode.MANAGER_SEARCH_FAILED,
|
|
787
|
+
message: 'Search option "searchType" must be an alphanumeric NodeLink search type modifier.',
|
|
788
|
+
context: { searchType },
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
return searchType.toLowerCase();
|
|
792
|
+
}
|
|
793
|
+
buildLoadTracksIdentifier(source, query, searchType, isUrl, isPrefixedIdentifier) {
|
|
794
|
+
if (isUrl)
|
|
795
|
+
return query;
|
|
796
|
+
if (isPrefixedIdentifier) {
|
|
797
|
+
if (!searchType || this.hasNodeLinkSearchTypeModifier(query))
|
|
798
|
+
return query;
|
|
799
|
+
const prefix = getIdentifierPrefix(query);
|
|
800
|
+
if (!prefix)
|
|
801
|
+
return query;
|
|
802
|
+
return `${prefix}:${searchType}:${query.slice(prefix.length + 1)}`;
|
|
803
|
+
}
|
|
804
|
+
return searchType ? `${source}:${searchType}:${query}` : `${source}:${query}`;
|
|
805
|
+
}
|
|
806
|
+
isNodeLinkSearchSource(source) {
|
|
807
|
+
return typeof source === "string" && (NODELINK_ONLY_SEARCH_PREFIXES.has(source.toLowerCase()) || NODELINK_RECOMMENDATION_PREFIXES.has(source.toLowerCase()));
|
|
808
|
+
}
|
|
809
|
+
isPrefixedLoadTracksIdentifier(identifier) {
|
|
810
|
+
const prefix = getIdentifierPrefix(identifier);
|
|
811
|
+
return prefix !== null && KNOWN_LOADTRACKS_PREFIXES.has(prefix);
|
|
812
|
+
}
|
|
813
|
+
hasNodeLinkSearchTypeModifier(identifier) {
|
|
814
|
+
const prefix = getIdentifierPrefix(identifier);
|
|
815
|
+
const searchType = getIdentifierSearchType(identifier);
|
|
816
|
+
return prefix !== null && searchType !== null && KNOWN_LOADTRACKS_PREFIXES.has(prefix) && NODELINK_SEARCH_TYPE_MODIFIERS.has(searchType);
|
|
817
|
+
}
|
|
818
|
+
requiresNodeLinkSearchNode(source, identifier, searchType) {
|
|
819
|
+
if (searchType)
|
|
820
|
+
return true;
|
|
821
|
+
if (this.isNodeLinkSearchSource(source))
|
|
822
|
+
return true;
|
|
823
|
+
const prefix = getIdentifierPrefix(identifier);
|
|
824
|
+
if (prefix === null)
|
|
825
|
+
return false;
|
|
826
|
+
if (NODELINK_ONLY_SEARCH_PREFIXES.has(prefix) || NODELINK_ONLY_LOADTRACKS_PREFIXES.has(prefix))
|
|
827
|
+
return true;
|
|
828
|
+
if (this.hasNodeLinkSearchTypeModifier(identifier))
|
|
829
|
+
return true;
|
|
830
|
+
const normalizedIdentifier = identifier.toLowerCase();
|
|
831
|
+
return prefix === "sprec" && !normalizedIdentifier.startsWith("sprec:mix:");
|
|
832
|
+
}
|
|
833
|
+
requiresLavalinkSearchNode(identifier) {
|
|
834
|
+
return identifier.toLowerCase().startsWith("sprec:mix:");
|
|
835
|
+
}
|
|
836
|
+
getSearchNode(source, identifier, searchType) {
|
|
837
|
+
if (this.requiresLavalinkSearchNode(identifier)) {
|
|
838
|
+
return this.getPreferredNode((node) => !node.isNodeLink);
|
|
839
|
+
}
|
|
840
|
+
if (this.requiresNodeLinkSearchNode(source, identifier, searchType)) {
|
|
841
|
+
return this.getPreferredNode((node) => node.isNodeLink);
|
|
842
|
+
}
|
|
843
|
+
return this.useableNode ?? null;
|
|
844
|
+
}
|
|
845
|
+
getPreferredNode(predicate) {
|
|
846
|
+
const nodes = this.nodes.filter((node) => node.connected && !node.options.isBackup && predicate(node));
|
|
847
|
+
if (!nodes.size)
|
|
848
|
+
return null;
|
|
849
|
+
if (this.options.enablePriorityMode) {
|
|
850
|
+
const priorityNodes = nodes.filter((node) => node.options.nodePriority > 0);
|
|
851
|
+
return (priorityNodes.size ? priorityNodes : nodes).sort((a, b) => b.options.nodePriority - a.options.nodePriority).first() ?? null;
|
|
852
|
+
}
|
|
853
|
+
if (this.options.useNode === Enums_1.UseNodeOptions.LeastLoad) {
|
|
854
|
+
return nodes
|
|
855
|
+
.sort((a, b) => {
|
|
856
|
+
return getNodeLoad(a) - getNodeLoad(b);
|
|
857
|
+
})
|
|
858
|
+
.first();
|
|
859
|
+
}
|
|
860
|
+
return nodes.sort((a, b) => a.stats.players - b.stats.players).first();
|
|
861
|
+
}
|
|
720
862
|
/**
|
|
721
863
|
* Returns the node to use based on the configured `useNode` and `enablePriorityMode` options.
|
|
722
864
|
* If `enablePriorityMode` is true, the node is chosen based on priority, otherwise it is chosen based on the `useNode` option.
|
|
@@ -1097,10 +1239,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
1097
1239
|
return this.nodes
|
|
1098
1240
|
.filter((node) => node.connected && !node.options.isBackup)
|
|
1099
1241
|
.sort((a, b) => {
|
|
1100
|
-
|
|
1101
|
-
const bload = b.stats.cpu ? (b.stats.cpu.lavalinkLoad / b.stats.cpu.cores) * 100 : 0;
|
|
1102
|
-
// Sort the nodes by their load in ascending order
|
|
1103
|
-
return aload - bload;
|
|
1242
|
+
return getNodeLoad(a) - getNodeLoad(b);
|
|
1104
1243
|
});
|
|
1105
1244
|
}
|
|
1106
1245
|
/**
|
|
@@ -2,7 +2,7 @@ import { Manager } from "./Manager";
|
|
|
2
2
|
import { Player } from "./Player";
|
|
3
3
|
import { Rest } from "./Rest";
|
|
4
4
|
import WebSocket from "ws";
|
|
5
|
-
import { LavalinkInfo, Lyrics, NodeLinkGetLyrics, NodeOptions, NodeStats,
|
|
5
|
+
import { LavalinkInfo, Lyrics, NodeLinkGetLyrics, NodeLinkChapter, NodeLinkEvent, NodeLinkMix, NodeLinkMeaningResult, NodeLinkSponsorBlockSegment, NodeLinkSponsorBlockUpdate, NodeOptions, NodeStats, NodeLinkSponsorBlockState, PlayerEvent, Track, TrackEndEvent, TrackExceptionEvent, TrackStartEvent, TrackStuckEvent, WebSocketClosedEvent } from "./Types";
|
|
6
6
|
import { SponsorBlockSegment } from "./Enums";
|
|
7
7
|
export declare class Node {
|
|
8
8
|
manager: Manager;
|
|
@@ -151,13 +151,18 @@ export declare class Node {
|
|
|
151
151
|
* @private
|
|
152
152
|
*/
|
|
153
153
|
protected message(messagePayload: Buffer | string): Promise<void>;
|
|
154
|
+
private normalizeStats;
|
|
155
|
+
private handlePlayerUpdate;
|
|
154
156
|
/**
|
|
155
157
|
* Handles an event emitted from the Lavalink node.
|
|
156
158
|
* @param {PlayerEvent & PlayerEvents} payload The event emitted from the node.
|
|
157
159
|
* @returns {Promise<void>} A promise that resolves when the event has been handled.
|
|
158
160
|
* @private
|
|
159
161
|
*/
|
|
160
|
-
protected handleEvent(payload:
|
|
162
|
+
protected handleEvent(payload: NodeLinkEvent | PlayerEvent): Promise<void>;
|
|
163
|
+
private markAsNodeLink;
|
|
164
|
+
private resolveEventTrack;
|
|
165
|
+
private handleNodeLinkEvent;
|
|
161
166
|
/**
|
|
162
167
|
* Emitted when a new track starts playing.
|
|
163
168
|
* @param {Player} player The player that started playing the track.
|
|
@@ -247,6 +252,20 @@ export declare class Node {
|
|
|
247
252
|
* @returns {Promise<Lyrics | NodeLinkGetLyrics>} A promise that resolves with the lyrics data.
|
|
248
253
|
*/
|
|
249
254
|
getLyrics(track: Track, skipTrackSource?: boolean, language?: string): Promise<Lyrics | NodeLinkGetLyrics>;
|
|
255
|
+
/**
|
|
256
|
+
* Loads chapters for a track using NodeLink.
|
|
257
|
+
* @param {Track} track - The track to load chapters for.
|
|
258
|
+
* @returns {Promise<NodeLinkChapter[]>} A promise that resolves with the chapter list.
|
|
259
|
+
*/
|
|
260
|
+
getChapters(track: Track): Promise<NodeLinkChapter[]>;
|
|
261
|
+
/**
|
|
262
|
+
* Loads chapters for a track using NodeLink.
|
|
263
|
+
* @param {Track} track - The track to load chapters for.
|
|
264
|
+
* @returns {Promise<NodeLinkChapter[]>} A promise that resolves with the chapter list.
|
|
265
|
+
*/
|
|
266
|
+
getNodeLinkChapters(track: Track): Promise<NodeLinkChapter[]>;
|
|
267
|
+
/** Loads NodeLink meaning/background information for a track. */
|
|
268
|
+
getNodeLinkMeaning(track: Track, language?: string): Promise<NodeLinkMeaningResult>;
|
|
250
269
|
/**
|
|
251
270
|
* Subscribes to lyrics for a player.
|
|
252
271
|
* @param {string} guildId - The ID of the guild to subscribe to lyrics for.
|
|
@@ -359,6 +378,74 @@ export declare class Node {
|
|
|
359
378
|
* @throws {RangeError} If the sponsorblock-plugin is not available in the Lavalink node.
|
|
360
379
|
*/
|
|
361
380
|
getSponsorBlock(player: Player): Promise<SponsorBlockSegment[]>;
|
|
381
|
+
/** Returns the complete NodeLink SponsorBlock state for a player. */
|
|
382
|
+
getNodeLinkSponsorBlockState(player: Player): Promise<NodeLinkSponsorBlockState>;
|
|
383
|
+
/** Updates NodeLink SponsorBlock behavior for a player. */
|
|
384
|
+
updateNodeLinkSponsorBlock(player: Player, update: NodeLinkSponsorBlockUpdate): Promise<NodeLinkSponsorBlockState>;
|
|
385
|
+
/** Replaces the NodeLink SponsorBlock segment list for a player. */
|
|
386
|
+
setNodeLinkSponsorBlockSegments(player: Player, segments: NodeLinkSponsorBlockSegment[]): Promise<NodeLinkSponsorBlockState>;
|
|
387
|
+
/**
|
|
388
|
+
* Adds a NodeLink audio mix layer to the player.
|
|
389
|
+
* @param {Player} player - The player to add the mix to.
|
|
390
|
+
* @param {Track} track - The track to mix over the current playback.
|
|
391
|
+
* @param {number} [volume] - The mix volume in the 0-1 range.
|
|
392
|
+
* @returns {Promise<NodeLinkMix>} The created mix layer.
|
|
393
|
+
*/
|
|
394
|
+
addMix(player: Player, track: Track, volume?: number): Promise<NodeLinkMix>;
|
|
395
|
+
/**
|
|
396
|
+
* Adds a NodeLink audio mix layer to the player.
|
|
397
|
+
* @param {Player} player - The player to add the mix to.
|
|
398
|
+
* @param {Track} track - The track to mix over the current playback.
|
|
399
|
+
* @param {number} [volume] - The mix volume in the 0-1 range.
|
|
400
|
+
* @returns {Promise<NodeLinkMix>} The created mix layer.
|
|
401
|
+
*/
|
|
402
|
+
addNodeLinkMix(player: Player, track: Track, volume?: number): Promise<NodeLinkMix>;
|
|
403
|
+
/**
|
|
404
|
+
* Gets the active NodeLink audio mix layers for the player.
|
|
405
|
+
* @param {Player} player - The player to fetch mixes for.
|
|
406
|
+
* @returns {Promise<NodeLinkMix[]>} The active mix layers.
|
|
407
|
+
*/
|
|
408
|
+
getMixes(player: Player): Promise<NodeLinkMix[]>;
|
|
409
|
+
/**
|
|
410
|
+
* Gets the active NodeLink audio mix layers for the player.
|
|
411
|
+
* @param {Player} player - The player to fetch mixes for.
|
|
412
|
+
* @returns {Promise<NodeLinkMix[]>} The active mix layers.
|
|
413
|
+
*/
|
|
414
|
+
getNodeLinkMixes(player: Player): Promise<NodeLinkMix[]>;
|
|
415
|
+
/**
|
|
416
|
+
* Updates a NodeLink audio mix layer volume.
|
|
417
|
+
* @param {Player} player - The player that owns the mix.
|
|
418
|
+
* @param {string} mixId - The mix layer id.
|
|
419
|
+
* @param {number} volume - The mix volume in the 0-1 range.
|
|
420
|
+
* @returns {Promise<void>}
|
|
421
|
+
*/
|
|
422
|
+
updateMix(player: Player, mixId: string, volume: number): Promise<void>;
|
|
423
|
+
/**
|
|
424
|
+
* Updates a NodeLink audio mix layer volume.
|
|
425
|
+
* @param {Player} player - The player that owns the mix.
|
|
426
|
+
* @param {string} mixId - The mix layer id.
|
|
427
|
+
* @param {number} volume - The mix volume in the 0-1 range.
|
|
428
|
+
* @returns {Promise<void>}
|
|
429
|
+
*/
|
|
430
|
+
updateNodeLinkMix(player: Player, mixId: string, volume: number): Promise<void>;
|
|
431
|
+
/**
|
|
432
|
+
* Removes a NodeLink audio mix layer.
|
|
433
|
+
* @param {Player} player - The player that owns the mix.
|
|
434
|
+
* @param {string} mixId - The mix layer id.
|
|
435
|
+
* @returns {Promise<void>}
|
|
436
|
+
*/
|
|
437
|
+
removeMix(player: Player, mixId: string): Promise<void>;
|
|
438
|
+
/**
|
|
439
|
+
* Removes a NodeLink audio mix layer.
|
|
440
|
+
* @param {Player} player - The player that owns the mix.
|
|
441
|
+
* @param {string} mixId - The mix layer id.
|
|
442
|
+
* @returns {Promise<void>}
|
|
443
|
+
*/
|
|
444
|
+
removeNodeLinkMix(player: Player, mixId: string): Promise<void>;
|
|
445
|
+
private assertNodeLinkFeature;
|
|
446
|
+
private assertMixVolume;
|
|
447
|
+
private assertNodeLinkSponsorBlockUpdate;
|
|
448
|
+
private isValidNodeLinkSponsorBlockSegment;
|
|
362
449
|
/**
|
|
363
450
|
* Sets the sponsorblock segments for a player.
|
|
364
451
|
* @param {Player} player - The player to set the sponsor blocks for.
|