UNPKG

magmastream

Version:

A user-friendly Lavalink client designed for NodeJS.

1,765 lines (1,758 loc) 142 kB
import { Collection } from '@discordjs/collection'; import { GatewayVoiceStateUpdate } from 'discord-api-types/v10'; import { EventEmitter } from 'events'; import { User, ClientUser, Guild, Message, Client as Client$1 } from 'discord.js'; import { User as User$1, Guild as Guild$1, Message as Message$1, Client as Client$3 } from 'oceanic.js'; import { User as User$2, Guild as Guild$2, Message as Message$2, Bot } from '@discordeno/bot'; import { User as User$3, Guild as Guild$3, Message as Message$3, Client as Client$2 } from 'eris'; import { User as User$4, ClientUser as ClientUser$1, Guild as Guild$4, Message as Message$4, Client as Client$4, WorkerClient } from 'seyfert'; import { RedisOptions, Redis } from 'ioredis'; import WebSocket$1, { WebSocket } from 'ws'; import { Client } from 'cloudstorm'; /** Represents an equalizer band. */ interface Band { /** The index of the equalizer band (0-12). */ band: number; /** The gain value of the equalizer band (in decibels). */ gain: number; } /** * State Storage Enum */ declare enum StateStorageType { Memory = "memory", Redis = "redis", JSON = "json" } /** * AutoPlay Platform Enum */ declare enum AutoPlayPlatform { Spotify = "spotify", Deezer = "deezer", SoundCloud = "soundcloud", Tidal = "tidal", VKMusic = "vkmusic", Qobuz = "qobuz", Yandex = "yandex", YouTube = "youtube" } /** * State Types Enum */ declare enum StateTypes { Connected = "CONNECTED", Connecting = "CONNECTING", Disconnected = "DISCONNECTED", Disconnecting = "DISCONNECTING", Destroying = "DESTROYING" } /** * Load Types Enum */ declare enum LoadTypes { Track = "track", Playlist = "playlist", Search = "search", Empty = "empty", Error = "error", /** Nodelink */ Album = "album", /** Nodelink */ Artist = "artist", /** Nodelink */ Station = "station", /** Nodelink */ Podcast = "podcast", /** Nodelink */ Show = "show", /** Nodelink */ Short = "short" } /** * Search Platform Enum */ declare enum SearchPlatform { AppleMusic = "amsearch", Yandex = "ymsearch", Audius = "audsearch", Bandcamp = "bcsearch", Deezer = "dzsearch", Jiosaavn = "jssearch", Qobuz = "qbsearch", SoundCloud = "scsearch", Spotify = "spsearch", Tidal = "tdsearch", TTS = "speak", VKMusic = "vksearch", YouTube = "ytsearch", YouTubeMusic = "ytmsearch" } /** * Player State Event Types Enum */ declare enum PlayerStateEventTypes { AutoPlayChange = "playerAutoplay", ConnectionChange = "playerConnection", RepeatChange = "playerRepeat", PauseChange = "playerPause", QueueChange = "queueChange", TrackChange = "trackChange", VolumeChange = "volumeChange", ChannelChange = "channelChange", PlayerCreate = "playerCreate", PlayerDestroy = "playerDestroy", FilterChange = "filterChange" } /** * Track Source Types Enum */ declare enum TrackSourceTypes { AppleMusic = "AppleMusic", Audius = "Audius", Bandcamp = "Bandcamp", Deezer = "Deezer", Jiosaavn = "Jiosaavn", Qobuz = "Qobuz", SoundCloud = "SoundCloud", Spotify = "Spotify", Tidal = "Tidal", VKMusic = "VKMusic", YouTube = "YouTube", Pornhub = "Pornub", TikTok = "TikTok", Flowertts = "Flowertts", Ocremix = "Ocremix", Yandex = "Yandex", Mixcloud = "Mixcloud", Soundgasm = "Soundgasm", Reddit = "Reddit", Clypit = "Clypit", Http = "Http", Tts = "Tts" } /** * Use Node Options Enum */ declare enum UseNodeOptions { LeastLoad = "leastLoad", LeastPlayers = "leastPlayers" } /** * Track Partial Enum */ declare enum TrackPartial { /** The base64 encoded string of the track */ Track = "track", /** The title of the track */ Title = "title", /** The track identifier */ Identifier = "identifier", /** The author of the track */ Author = "author", /** The length of the track in milliseconds */ Duration = "duration", /** The ISRC of the track */ Isrc = "isrc", /** Whether the track is seekable */ IsSeekable = "isSeekable", /** Whether the track is a stream */ IsStream = "isStream", /** The URI of the track */ Uri = "uri", /** The artwork URL of the track */ ArtworkUrl = "artworkUrl", /** The source name of the track */ SourceName = "sourceName", /** The thumbnail of the track */ ThumbNail = "thumbnail", /** The requester of the track */ Requester = "requester", /** The plugin info of the track */ PluginInfo = "pluginInfo", /** The custom data of the track */ CustomData = "customData", /** Whether the track got autoplayed */ IsAutoPlay = "isAutoplay" } /** * Manager Event Types Enum */ declare enum ManagerEventTypes { ChapterStarted = "chapterStarted", ChaptersLoaded = "chaptersLoaded", Debug = "debug", LyricsFound = "lyricsFound", LyricsLine = "lyricsLine", LyricsNotFound = "lyricsNotFound", NodeConnect = "nodeConnect", NodeCreate = "nodeCreate", NodeDestroy = "nodeDestroy", NodeDisconnect = "nodeDisconnect", NodeError = "nodeError", NodeRaw = "nodeRaw", NodeReconnect = "nodeReconnect", PlayerCreate = "playerCreate", PlayerDestroy = "playerDestroy", PlayerDisconnect = "playerDisconnect", PlayerMove = "playerMove", PlayerRestored = "playerRestored", PlayerStateUpdate = "playerStateUpdate", QueueEnd = "queueEnd", RestoreComplete = "restoreComplete", SegmentSkipped = "segmentSkipped", SegmentsLoaded = "segmentsLoaded", SocketClosed = "socketClosed", TrackEnd = "trackEnd", TrackError = "trackError", TrackStart = "trackStart", TrackStuck = "trackStuck", /** Nodelink */ VoiceReceiverDisconnect = "voiceReceiverDisconnect", /** Nodelink */ VoiceReceiverConnect = "voiceReceiverConnect", /** Nodelink */ VoiceReceiverError = "voiceReceiverError", /** Nodelink */ VoiceReceiverStartSpeaking = "voiceReceiverStartSpeaking", /** Nodelink */ VoiceReceiverEndSpeaking = "voiceReceiverEndSpeaking" } /** * Track End Reason Enum */ declare enum TrackEndReasonTypes { Finished = "finished", LoadFailed = "loadFailed", Stopped = "stopped", Replaced = "replaced", Cleanup = "cleanup" } /** * Severity Types Enum */ declare enum SeverityTypes { Common = "common", Suspicious = "suspicious", Fault = "fault" } /** * SponsorBlock Segment Enum */ declare enum SponsorBlockSegment { Filler = "filler", Interaction = "interaction", Intro = "intro", MusicOfftopic = "music_offtopic", Outro = "outro", Preview = "preview", SelfPromo = "selfpromo", Sponsor = "sponsor" } /** * Available Filters Enum */ declare enum AvailableFilters { BassBoost = "bassboost", China = "china", Chipmunk = "chipmunk", Darthvader = "darthvader", Daycore = "daycore", Demon = "demon", Distort = "distort", Doubletime = "doubletime", Earrape = "earrape", EightD = "eightD", Electronic = "electronic", Nightcore = "nightcore", Party = "party", Pop = "pop", Radio = "radio", SetDistortion = "setDistortion", SetKaraoke = "setKaraoke", SetRotation = "setRotation", SetTimescale = "setTimescale", Slowmo = "slowmo", Soft = "soft", TrebleBass = "trebleBass", Tremolo = "tremolo", TV = "tv", Vaporwave = "vaporwave", Vibrato = "vibrato" } /** * MagmaStream Error Codes Enum */ declare enum MagmaStreamErrorCode { GENERAL_UNKNOWN = "MS_GENERAL_UNKNOWN", GENERAL_TIMEOUT = "MS_GENERAL_TIMEOUT", GENERAL_INVALID_MANAGER = "MS_GENERAL_INVALID_MANAGER", INTENT_MISSING = "MS_INTENT_MISSING", MANAGER_INIT_FAILED = "MS_MANAGER_INIT_FAILED", MANAGER_INVALID_CONFIG = "MS_MANAGER_INVALID_CONFIG", MANAGER_SHUTDOWN_FAILED = "MS_MANAGER_SHUTDOWN_FAILED", MANAGER_NO_NODES = "MS_MANAGER_NO_NODES", MANAGER_NODE_NOT_FOUND = "MS_MANAGER_NODE_NOT_FOUND", MANAGER_SEARCH_FAILED = "MS_MANAGER_SEARCH_FAILED", MANAGER_CLEANUP_INACTIVE_PLAYERS_FAILED = "MS_MANAGER_CLEANUP_INACTIVE_PLAYERS_FAILED", NODE_INVALID_CONFIG = "MS_NODE_INVALID_CONFIG", NODE_CONNECT_FAILED = "MS_NODE_CONNECT_FAILED", NODE_RECONNECT_FAILED = "MS_NODE_RECONNECT_FAILED", NODE_DISCONNECTED = "MS_NODE_DISCONNECTED", NODE_PROTOCOL_ERROR = "MS_NODE_PROTOCOL_ERROR", NODE_SESSION_IDS_LOAD_FAILED = "MS_NODE_SESSION_IDS_LOAD_FAILED", NODE_SESSION_IDS_UPDATE_FAILED = "MS_NODE_SESSION_IDS_UPDATE_FAILED", NODE_PLUGIN_ERROR = "MS_NODE_PLUGIN_ERROR", PLAYER_INVALID_CONFIG = "MS_PLAYER_INVALID_CONFIG", PLAYER_STATE_INVALID = "MS_PLAYER_STATE_INVALID", PLAYER_QUEUE_EMPTY = "MS_PLAYER_QUEUE_EMPTY", PLAYER_PREVIOUS_EMPTY = "MS_PLAYER_PREVIOUS_EMPTY", PLAYER_INVALID_NOW_PLAYING_MESSAGE = "MS_PLAYER_INVALID_NOW_PLAYING_MESSAGE", PLAYER_INVALID_AUTOPLAY = "MS_PLAYER_INVALID_AUTOPLAY", PLAYER_INVALID_VOLUME = "MS_PLAYER_INVALID_VOLUME", PLAYER_INVALID_REPEAT = "MS_PLAYER_INVALID_REPEAT", PLAYER_INVALID_PAUSE = "MS_PLAYER_INVALID_PAUSE", PLAYER_INVALID_SEEK = "MS_PLAYER_INVALID_SEEK", PLAYER_MOVE_FAILED = "MS_PLAYER_MOVE_FAILED", PLAYER_VOICE_RECEIVER_ERROR = "MS_PLAYER_VOICE_RECEIVER_ERROR", QUEUE_REDIS_ERROR = "MS_QUEUE_REDIS_ERROR", QUEUE_JSON_ERROR = "MS_QUEUE_JSON_ERROR", QUEUE_MEMORY_ERROR = "MS_QUEUE_MEMORY_ERROR", FILTER_APPLY_FAILED = "MS_FILTER_APPLY_FAILED", REST_REQUEST_FAILED = "MS_REST_REQUEST_FAILED", REST_UNAUTHORIZED = "MS_REST_UNAUTHORIZED", UTILS_TRACK_PARTIAL_INVALID = "MS_UTILS_TRACK_PARTIAL_INVALID", UTILS_TRACK_BUILD_FAILED = "MS_UTILS_TRACK_BUILD_FAILED", UTILS_AUTOPLAY_BUILD_FAILED = "MS_UTILS_AUTOPLAY_BUILD_FAILED", UTILS_PLAYER_SERIALIZE_FAILED = "MS_UTILS_PLAYER_SERIALIZE_FAILED", PLUGIN_LOAD_FAILED = "MS_PLUGIN_LOAD_FAILED", PLUGIN_RUNTIME_ERROR = "MS_PLUGIN_RUNTIME_ERROR" } declare const MagmaStreamErrorNumbers: Record<MagmaStreamErrorCode, number>; /** * The player's queue, the `current` property is the currently playing track, think of the rest as the up-coming tracks. */ declare class JsonQueue implements IQueue { readonly guildId: string; readonly manager: Manager; /** * The base path for the queue files. */ private basePath; /** * Whether the queue has been destroyed. */ private destroyed; /** * @param guildId The guild ID. * @param manager The manager. */ constructor(guildId: string, manager: Manager); /** * @param track The track or tracks to add. Can be a single `Track` or an array of `Track`s. * @param [offset=null] The position to add the track(s) at. If not provided, the track(s) will be added at the end of the queue. */ add(track: Track | Track[], offset?: number): Promise<void>; /** * @param track The track to add. */ addPrevious(track: Track | Track[]): Promise<void>; /** * Clears the queue. */ clear(): Promise<void>; /** * Clears the previous tracks. */ clearPrevious(): Promise<void>; /** * Removes the first track from the queue. */ dequeue(): Promise<Track | undefined>; /** * Destroys the queue and releases all resources. * After calling this method, the queue must not be used again. */ destroy(): Promise<void>; /** * @returns The total duration of the queue. */ duration(): Promise<number>; /** * Adds a track to the front of the queue. */ enqueueFront(track: Track | Track[]): Promise<void>; /** * Tests whether all elements in the queue pass the test implemented by the provided function. */ everyAsync(callback: (track: Track, index: number, array: Track[]) => boolean): Promise<boolean>; /** * Filters the queue. */ filterAsync(callback: (track: Track, index: number, array: Track[]) => boolean): Promise<Track[]>; /** * Finds the first track in the queue that satisfies the provided testing function. */ findAsync(callback: (track: Track, index: number, array: Track[]) => boolean): Promise<Track | undefined>; /** * @returns The current track. */ getCurrent(): Promise<Track | null>; /** * @returns The previous tracks. */ getPrevious(): Promise<Track[]>; /** * @returns The tracks in the queue from start to end. */ getSlice(start?: number, end?: number): Promise<Track[]>; /** * @returns The tracks in the queue. */ getTracks(): Promise<Track[]>; /** * Maps the queue to a new array. */ mapAsync<T>(callback: (track: Track, index: number, array: Track[]) => T): Promise<T[]>; /** * Modifies the queue at the specified index. */ modifyAt(start: number, deleteCount?: number, ...items: Track[]): Promise<Track[]>; /** * @returns The newest track. */ popPrevious(): Promise<Track | null>; /** * Removes a track from the queue. * @param position The position to remove the track at. * @param end The end position to remove the track at. */ remove(position?: number): Promise<Track[]>; remove(start: number, end: number): Promise<Track[]>; /** * Shuffles the queue by round-robin. */ roundRobinShuffle(): Promise<void>; /** * @param track The track to set. */ setCurrent(track: Track | null): Promise<void>; /** * @param track The track to set. */ setPrevious(track: Track | Track[]): Promise<void>; /** * Shuffles the queue. */ shuffle(): Promise<void>; /** * @returns The size of the queue. */ size(): Promise<number>; /** * Tests whether at least one element in the queue passes the test implemented by the provided function. */ someAsync(callback: (track: Track, index: number, array: Track[]) => boolean): Promise<boolean>; /** * @returns The total size of the queue. */ totalSize(): Promise<number>; /** * Shuffles the queue by user. */ userBlockShuffle(): Promise<void>; /** * @returns The current path. */ private get currentPath(); /** * @param filePath The file path. */ private deleteFile; /** * Ensures the directory exists. */ private ensureDir; /** * @returns The queue. */ private getQueue; /** * @returns The previous path. */ private get previousPath(); /** * @returns The queue path. */ private get queuePath(); /** * @param filePath The file path. * @returns The JSON data. */ private readJSON; /** * @param queue The queue. */ private setQueue; /** * @param filePath The file path. * @param data The data to write. */ private writeJSON; } /** * The player's queue, the `current` property is the currently playing track, think of the rest as the up-coming tracks. */ declare class MemoryQueue extends Array<Track> implements IQueue { /** The current track */ current: Track | null; /** The previous tracks */ previous: Track[]; /** The Manager instance. */ manager: Manager; /** The guild ID property. */ guildId: string; /** * Whether the queue has been destroyed. */ private destroyed; /** * Constructs a new Queue. * @param guildId The guild ID. * @param manager The Manager instance. */ constructor(guildId: string, manager: Manager); /** * Adds a track to the queue. * @param track The track or tracks to add. Can be a single `Track` or an array of `Track`s. * @param [offset=null] The position to add the track(s) at. If not provided, the track(s) will be added at the end of the queue. */ add(track: Track | Track[], offset?: number): void; /** * Adds a track to the previous tracks. * @param track The track or tracks to add. Can be a single `Track` or an array of `Track`s. */ addPrevious(track: Track | Track[]): void; /** * Clears the queue. * This will remove all tracks from the queue and emit a state update event. */ clear(): void; /** * Clears the previous tracks. */ clearPrevious(): void; /** * Removes the first element from the queue. */ dequeue(): Track | undefined; /** * Destroys the queue and releases all resources. * After calling this method, the queue must not be used again. */ destroy(): void; /** * The total duration of the queue in milliseconds. * This includes the duration of the currently playing track. */ duration(): number; /** * Adds the specified track or tracks to the front of the queue. * @param track The track or tracks to add. */ enqueueFront(track: Track | Track[]): void; /** * @returns Whether all elements in the queue satisfy the provided testing function. */ everyAsync(callback: (track: Track, index: number, array: Track[]) => boolean): boolean; /** * @returns A new array with all elements that pass the test implemented by the provided function. */ filterAsync(callback: (track: Track, index: number, array: Track[]) => boolean): Track[]; /** * @returns The first element in the queue that satisfies the provided testing function. */ findAsync(callback: (track: Track, index: number, array: Track[]) => boolean): Track | undefined; /** * @returns The current track. */ getCurrent(): Track | null; /** * @returns The previous tracks. */ getPrevious(): Track[]; /** * @returns The tracks in the queue from start to end. */ getSlice(start?: number, end?: number): Track[]; /** * @returns The tracks in the queue. */ getTracks(): Track[]; /** * @returns A new array with the results of calling a provided function on every element in the queue. */ mapAsync<T>(callback: (track: Track, index: number, array: Track[]) => T): T[]; /** * Modifies the queue at the specified index. * @param start The index at which to start modifying the queue. * @param deleteCount The number of elements to remove from the queue. * @param items The elements to add to the queue. * @returns The modified queue. */ modifyAt(start: number, deleteCount?: number, ...items: Track[]): Track[]; /** * @returns The newest track. */ popPrevious(): Track | null; /** * Removes track(s) from the queue. * @param startOrPosition If a single number is provided, it will be treated as the position of the track to remove. * If two numbers are provided, they will be used as the start and end of a range of tracks to remove. * @param end Optional, end of the range of tracks to remove. * @returns The removed track(s). */ remove(position?: number): Track[]; remove(start: number, end: number): Track[]; /** * Shuffles the queue to play tracks requested by each user one by one. */ roundRobinShuffle(): void; /** * @param track The track to set. */ setCurrent(track: Track | null): void; /** * @param tracks The tracks to set. */ setPrevious(tracks: Track[]): void; /** * Shuffles the queue. * This will randomize the order of the tracks in the queue and emit a state update event. */ shuffle(): void; /** * The size of tracks in the queue. * This does not include the currently playing track. * @returns The size of tracks in the queue. */ size(): number; /** * @returns Whether at least one element in the queue satisfies the provided testing function. */ someAsync(callback: (track: Track, index: number, array: Track[]) => boolean): boolean; /** * The total size of tracks in the queue including the current track. * This includes the current track if it is not null. * @returns The total size of tracks in the queue including the current track. */ totalSize(): number; /** * Shuffles the queue to play tracks requested by each user one block at a time. */ userBlockShuffle(): void; } /** * The player's queue, the `current` property is the currently playing track, think of the rest as the up-coming tracks. */ declare class RedisQueue implements IQueue { readonly guildId: string; readonly manager: Manager; /** * The prefix for the Redis keys. */ redisPrefix: string; /** * The Redis instance. */ private redis; /** * Whether the queue has been destroyed. */ private destroyed; /** * Constructs a new RedisQueue. * @param guildId The guild ID. * @param manager The Manager instance. */ constructor(guildId: string, manager: Manager); /** * Adds a track or tracks to the queue. * @param track The track or tracks to add. Can be a single `Track` or an array of `Track`s. * @param [offset=null] The position to add the track(s) at. If not provided, the track(s) will be added at the end of the queue. */ add(track: Track | Track[], offset?: number): Promise<void>; /** * Adds a track or tracks to the previous tracks. * @param track The track or tracks to add. */ addPrevious(track: Track | Track[]): Promise<void>; /** * Clears the queue. */ clear(): Promise<void>; /** * Clears the previous tracks. */ clearPrevious(): Promise<void>; /** * Removes the first track from the queue. */ dequeue(): Promise<Track | undefined>; /** * Destroys the queue and releases all resources. * After calling this method, the queue must not be used again. */ destroy(): Promise<void>; /** * @returns The total duration of the queue in milliseconds. * This includes the duration of the currently playing track. */ duration(): Promise<number>; /** * Adds a track to the front of the queue. * @param track The track or tracks to add. */ enqueueFront(track: Track | Track[]): Promise<void>; /** * Whether all tracks in the queue match the specified condition. * @param callback The condition to match. * @returns Whether all tracks in the queue match the specified condition. */ everyAsync(callback: (track: Track, index: number, array: Track[]) => boolean): Promise<boolean>; /** * Filters the tracks in the queue. * @param callback The condition to match. * @returns The tracks that match the condition. */ filterAsync(callback: (track: Track, index: number, array: Track[]) => boolean): Promise<Track[]>; /** * Finds the first track in the queue that matches the specified condition. * @param callback The condition to match. * @returns The first track that matches the condition. */ findAsync(callback: (track: Track, index: number, array: Track[]) => boolean): Promise<Track | undefined>; /** * @returns The current track. */ getCurrent(): Promise<Track | null>; /** * @returns The previous tracks. */ getPrevious(): Promise<Track[]>; /** * @returns The tracks in the queue from the start to the end. */ getSlice(start?: number, end?: number): Promise<Track[]>; /** * @returns The tracks in the queue. */ getTracks(): Promise<Track[]>; /** * Maps the tracks in the queue. * @returns The tracks in the queue after the specified index. */ mapAsync<T>(callback: (track: Track, index: number, array: Track[]) => T): Promise<T[]>; /** * Modifies the queue at the specified index. * @param start The start index. * @param deleteCount The number of tracks to delete. * @param items The tracks to insert. * @returns The removed tracks. */ modifyAt(start: number, deleteCount?: number, ...items: Track[]): Promise<Track[]>; /** * Removes the newest track. * @returns The newest track. */ popPrevious(): Promise<Track | null>; /** * Removes the track at the specified index. * @param position The position to remove the track at. * @param end The end position to remove the track at. */ remove(position?: number): Promise<Track[]>; remove(start: number, end: number): Promise<Track[]>; /** * Shuffles the queue round-robin style. */ roundRobinShuffle(): Promise<void>; /** * Sets the current track. * @param track The track to set. */ setCurrent(track: Track | null): Promise<void>; /** * Sets the previous track(s). * @param track The track to set. */ setPrevious(track: Track | Track[]): Promise<void>; /** * Shuffles the queue. */ shuffle(): Promise<void>; /** * @returns The size of the queue. */ size(): Promise<number>; /** * @returns Whether any tracks in the queue match the specified condition. */ someAsync(callback: (track: Track, index: number, array: Track[]) => boolean): Promise<boolean>; /** * @returns The total size of tracks in the queue including the current track. */ totalSize(): Promise<number>; /** * Shuffles the queue, but keeps the tracks of the same user together. */ userBlockShuffle(): Promise<void>; /** * @returns The current key. */ private get currentKey(); /** * Deserializes a track from a string. */ private deserialize; /** * @returns The previous key. */ private get previousKey(); /** * @returns The queue key. */ private get queueKey(); /** * Helper to serialize/deserialize Track */ private serialize; } /** * Base abstract class for all plugins. * Users must extend this and implement load and unload methods. */ declare abstract class Plugin { readonly name: string; /** * @param name The name of the plugin */ constructor(name: string); /** * Load the plugin. * @param manager The MagmaStream Manager instance */ abstract load(manager: Manager): void; /** * Unload the plugin. * Called on shutdown to gracefully cleanup resources or detach listeners. * @param manager The MagmaStream Manager instance */ abstract unload(manager: Manager): void; } /** * Manager Options */ interface ManagerOptions { /** The state storage options. * * @default { type: StateStorageType.Collection, deleteDestroyedPlayers: true } */ stateStorage?: StateStorageOptions; /** Enable priority mode over least player count or load balancing? * @default false */ enablePriorityMode?: boolean; /** Automatically play the next track when the current one ends. * @default true */ playNextOnEnd?: boolean; /** An array of search platforms to use for autoplay. First to last matters * Use enum `AutoPlayPlatform`. * @default [AutoPlayPlatform.YouTube] */ autoPlaySearchPlatforms?: AutoPlayPlatform[]; /** The client ID to use. */ clientId?: string; /** Value to use for the `Client-Name` header. * @default "Magmastream" * * For NodeLink, leave it empty. */ clientName?: string; /** The array of shard IDs connected to this manager instance. * @default 0 */ clusterId?: number; /** List of plugins to load. */ enabledPlugins?: Plugin[]; /** The default search platform to use. * Use enum `SearchPlatform`. * @default SearchPlatform.YouTube */ defaultSearchPlatform?: SearchPlatform; /** The last.fm API key. * If you need to create one go here: https://www.last.fm/api/account/create. * If you already have one, get it from here: https://www.last.fm/api/accounts. */ lastFmApiKey?: string; /** The maximum number of previous tracks to store. * @default 20 */ maxPreviousTracks?: number; /** The array of nodes to connect to. */ nodes?: NodeOptions[]; /** Whether the YouTube video titles should be replaced if the Author does not exactly match. * @default false */ normalizeYouTubeTitles?: boolean; /** An array of track properties to keep. `track` will always be present. */ trackPartial?: TrackPartial[]; /** Use the least amount of players or least load? * Use enum `UseNodeOptions`. * @default UseNodeOptions.LeastPlayers */ useNode?: UseNodeOptions.LeastLoad | UseNodeOptions.LeastPlayers; /** Whether the manager should listen to SIGINT and SIGTERM events. * @default true */ listenToSIGEvents?: boolean; /** * Function to send data to the websocket. * @param id The ID of the node to send the data to. * @param payload The payload to send. */ send?: (packet: DiscordPacket) => unknown; /** * User cache getter. Required when using `new Manager(...)` directly, optional for built-in wrappers. * When resolving a user from a partial ID, this function will be called first. * Should return the full user object if cached, or undefined if not. * @param id The ID of the user to get. * @returns The user object if cached, or undefined if not. */ getUser?: (id: string) => AnyUser | undefined; /** * Guild cache getter. Required when using `new Manager(...)` directly, optional for built-in wrappers. * When resolving a guild from a partial ID, this function will be called first. * Should return the full guild object if cached, or undefined if not. * @param id The ID of the guild to get. * @returns The guild object if cached, or undefined if not. */ getGuild?: (id: string) => AnyGuild | undefined; } /** * Manager options for direct `new Manager(...)` usage. * Built-in wrappers provide these cache hooks automatically, so they only require {@link ManagerOptions}. */ interface StandaloneManagerOptions extends ManagerOptions { getUser: (id: string) => AnyUser | undefined; getGuild: (id: string) => AnyGuild | undefined; } /** * State Storage Options */ interface StateStorageOptions { type: StateStorageType; redisConfig?: RedisConfig; jsonConfig?: JsonConfig; deleteDestroyedPlayers?: boolean; } /** * Node Options */ interface NodeOptions { /** The host for the node. */ host: string; /** The port for the node. * @default 2333 */ port?: number; /** The password for the node. * @default "youshallnotpass" */ password?: string; /** Whether the host uses SSL. * @default false */ useSSL?: boolean; /** The identifier for the node. * @default host */ identifier?: string; /** The maxRetryAttempts for the node. * @default 30 */ maxRetryAttempts?: number; /** The retryDelayMs for the node. * @default 60000 */ retryDelayMs?: number; /** Whether to resume the previous session. * @default false */ enableSessionResumeOption?: boolean; /** The time in seconds the lavalink server will wait before it removes the player. * @default 60 */ sessionTimeoutSeconds?: number; /** The timeout used for api calls. * @default 10000 */ apiRequestTimeoutMs?: number; /** Priority of the node. * @default 0 */ nodePriority?: number; /** Whether the node is a NodeLink. * @default false */ isNodeLink?: boolean; /** Whether the node is a backup node. * @default false */ isBackup?: boolean; } /** * Portable User */ interface PortableUser { id: string; username?: string; } /** * Any user */ type AnyUser = PortableUser | User | ClientUser | User$1 | User$2 | User$3 | User$4 | ClientUser$1; /** * Portable Message */ interface PortableMessage { id: string; } /** * Any message */ type AnyMessage = PortableMessage | Message | Message$1 | Message$2 | Message$3 | Message$4; /** * Any guild */ type AnyGuild = Guild | Guild$1 | Guild$2 | Guild$3 | Guild$4<"cached">; /** * Discord Packet */ interface DiscordPacket { /** * The opcode for the payload */ op: number; /** * Event data */ d: any; /** * Sequence number, used for resuming sessions and heartbeats */ s?: number; /** * The event name for this payload */ t?: string; } /** * Player Update Voice State */ interface PlayerUpdateVoiceState { /** * The session id of the voice connection */ sessionId: string; /** * Event data */ event: VoiceServerUpdate; } /** * Voice Server Update */ interface VoiceServerUpdate { /** * The token for the session */ token: string; /** * Guild if of the voice connection */ guild_id: string; /** * The endpoint lavalink will connect to */ endpoint: string; } /** * Redis Configuration */ interface RedisConfig extends RedisOptions { prefix?: string; } /** * JSON Configuration */ interface JsonConfig { path: string; } /** * Player State Update Event */ type PlayerStateUpdateEvent = { changeType: PlayerStateEventTypes.TrackChange; details: TrackChangeEvent; } | { changeType: PlayerStateEventTypes.PauseChange; details: PauseChangeEvent; } | { changeType: PlayerStateEventTypes.QueueChange; details: QueueChangeEvent; } | { changeType: PlayerStateEventTypes.ConnectionChange; details: ConnectionChangeEvent; } | { changeType: PlayerStateEventTypes.AutoPlayChange; details: AutoplayChangeEvent; } | { changeType: PlayerStateEventTypes.ChannelChange; details: ChannelChangeEvent; } | { changeType: PlayerStateEventTypes.VolumeChange; details: VolumeChangeEvent; } | { changeType: PlayerStateEventTypes.RepeatChange; details: RepeatChangeEvent; } | { changeType: PlayerStateEventTypes.FilterChange; details: FilterChangeEvent; }; /** * Autoplay Change Event */ interface AutoplayChangeEvent { type: "autoplay"; action: "toggle"; previousAutoplay: boolean | null; currentAutoplay: boolean | null; } /** * Connection Change Event */ interface ConnectionChangeEvent { type: "connection"; action: "connect" | "disconnect"; previousConnection: boolean | null; currentConnection: boolean | null; } interface FilterChangeEvent { type: "filter"; action: "change"; } /** * Repeat Change Event */ interface RepeatChangeEvent { type: "repeat"; action: "dynamic" | "track" | "queue" | "none"; previousRepeat: "dynamic" | "track" | "queue" | null; currentRepeat: "dynamic" | "track" | "queue" | null; } /** * Pause Change Event */ interface PauseChangeEvent { type: "pause"; action: "pause" | "resume" | "toggle"; previousPause: boolean | null; currentPause: boolean | null; } /** * Queue Change Event */ interface QueueChangeEvent { type: "queue"; action: "add" | "remove" | "clear" | "shuffle" | "roundRobin" | "userBlock" | "autoPlayAdd"; previousQueueLength: number | null; currentQueueLength: number | null; tracks?: Track[]; } /** * Track Change Event */ interface TrackChangeEvent { type: "track"; action: "start" | "end" | "previous" | "timeUpdate" | "autoPlay"; track: Track; previousTime?: number | null; currentTime?: number | null; } /** * Volume Change Event */ interface VolumeChangeEvent { type: "volume"; action: "adjust"; previousVolume: number | null; currentVolume: number | null; } /** * Channel Change Event */ interface ChannelChangeEvent { type: "channel"; action: "text" | "voice"; previousChannel: string | null; currentChannel: string | null; } /** * Track */ interface Track { /** The base64 encoded track. */ readonly track: string; /** The artwork url of the track. */ readonly artworkUrl: string | null; /** The track source name. */ readonly sourceName: TrackSourceName; /** The title of the track. */ title: string; /** The identifier of the track. */ readonly identifier: string; /** The author of the track. */ author: string; /** The duration of the track. */ readonly duration: number; /** The ISRC of the track. */ readonly isrc: string; /** If the track is seekable. */ readonly isSeekable: boolean; /** If the track is a stream.. */ readonly isStream: boolean; /** The uri of the track. */ readonly uri: string; /** The thumbnail of the track or null if it's a unsupported source. */ readonly thumbnail: string | null; /** The user that requested the track. */ requester: AnyUser; /** Displays the track thumbnail with optional size or null if it's a unsupported source. */ displayThumbnail(size?: Sizes): string | null; /** Additional track info provided by plugins. */ pluginInfo: TrackPluginInfo; /** Add your own data to the track. */ customData: Record<string, unknown>; /** If the track got added by autoplay. */ readonly isAutoplay: boolean; } /** * Track Plugin Info */ interface TrackPluginInfo { albumName?: string; albumUrl?: string; artistArtworkUrl?: string; artistUrl?: string; isPreview?: string; previewUrl?: string; } /** * Search Query */ interface SearchQuery { /** The source to search from. */ source?: SearchPlatform; /** The query to search for. */ query: string; } /** * Lavalink Response */ interface LavalinkResponse { loadType: LoadTypes; data: TrackData[] | PlaylistRawData; } /** * Track Data */ interface TrackData { /** The track information. */ encoded: string; /** The detailed information of the track. */ info: TrackDataInfo; /** Additional track info provided by plugins. */ pluginInfo: Record<string, string>; } /** * Playlist Raw Data */ interface PlaylistRawData { info: { /** The playlist name. */ name: string; }; /** Addition info provided by plugins. */ pluginInfo: object; /** The tracks of the playlist */ tracks: TrackData[]; } /** * Track Data Info */ interface TrackDataInfo { identifier: string; isSeekable: boolean; author: string; length: number; isrc?: string; isStream: boolean; title: string; uri?: string; artworkUrl?: string; sourceName?: TrackSourceName; } /** * LavaPlayer */ interface LavaPlayer { guildId: string; track: TrackData; volume: number; paused: boolean; state: { time: number; position: number; connected: boolean; ping: number; }; voice: LavalinkVoiceStateResponse; filters: Record<string, unknown>; } /** * Error or Empty Search Result */ interface ErrorOrEmptySearchResult { /** The load type of the result. */ loadType: LoadTypes.Empty | LoadTypes.Error; } /** * Track Search Result */ interface TrackSearchResult { /** The load type is always 'track' */ loadType: LoadTypes.Track; /** The track obtained */ tracks: [Track]; } /** * Search Result */ interface SearchSearchResult { /** The load type is always 'search' */ loadType: LoadTypes.Search; /** The tracks of the search result */ tracks: Track[]; } /** * Playlist Search Result */ interface PlaylistSearchResult { /** The playlist load type */ loadType: LoadTypes.Playlist; /** The tracks of the playlist */ tracks: Track[]; /** The playlist info */ playlist: PlaylistData; } /** * Album Search Result */ interface AlbumSearchResult { loadType: LoadTypes.Album; tracks: Track[]; playlist: PlaylistData; } /** * Artist Search Result */ interface ArtistSearchResult { loadType: LoadTypes.Artist; tracks: Track[]; playlist: PlaylistData; } /** * Station Search Result */ interface StationSearchResult { loadType: LoadTypes.Station; tracks: Track[]; playlist: PlaylistData; } /** * Podcast Search Result */ interface PodcastSearchResult { loadType: LoadTypes.Podcast; tracks: Track[]; playlist: PlaylistData; } /** * Show Search Result */ interface ShowSearchResult { loadType: LoadTypes.Show; tracks: Track[]; playlist: PlaylistData; } /** * Short Search Result */ interface ShortSearchResult { loadType: LoadTypes.Short; tracks: [Track]; } /** * Playlist Data */ interface PlaylistData { /** The playlist name. */ name: string; /** Requester of playlist. */ requester: AnyUser; /** More playlist information. */ playlistInfo: PlaylistInfoData[]; /** The length of the playlist. */ duration: number; /** The songs of the playlist. */ tracks: Track[]; } /** * Playlist Info Data */ interface PlaylistInfoData { /** Url to playlist. */ url: string; /** Type is always playlist in that case. */ type: string; /** ArtworkUrl of playlist */ artworkUrl: string; /** Number of total tracks in playlist */ totalTracks: number; /** Author of playlist */ author: string; } /** * Manager Events */ interface ManagerEvents { [ManagerEventTypes.ChapterStarted]: [player: Player, track: Track, payload: SponsorBlockChapterStarted]; [ManagerEventTypes.ChaptersLoaded]: [player: Player, track: Track, payload: SponsorBlockChaptersLoaded]; [ManagerEventTypes.Debug]: [info: string]; [ManagerEventTypes.LyricsFound]: [player: Player, track: Track, payload: LyricsFoundEvent]; [ManagerEventTypes.LyricsLine]: [player: Player, track: Track, payload: LyricsLineEvent]; [ManagerEventTypes.LyricsNotFound]: [player: Player, track: Track, payload: LyricsNotFoundEvent]; [ManagerEventTypes.NodeConnect]: [node: Node]; [ManagerEventTypes.NodeCreate]: [node: Node]; [ManagerEventTypes.NodeDestroy]: [node: Node]; [ManagerEventTypes.NodeDisconnect]: [node: Node, reason: { code?: number; reason?: string; }]; [ManagerEventTypes.NodeError]: [node: Node, error: Error]; [ManagerEventTypes.NodeRaw]: [payload: unknown]; [ManagerEventTypes.NodeReconnect]: [node: Node]; [ManagerEventTypes.PlayerCreate]: [player: Player]; [ManagerEventTypes.PlayerDestroy]: [player: Player]; [ManagerEventTypes.PlayerDisconnect]: [player: Player, oldChannel: string]; [ManagerEventTypes.PlayerMove]: [player: Player, oldChannel: string, newChannel: string]; [ManagerEventTypes.PlayerRestored]: [player: Player, node: Node]; [ManagerEventTypes.PlayerStateUpdate]: [oldPlayer: Player, newPlayer: Player, changeType: PlayerStateUpdateEvent]; [ManagerEventTypes.QueueEnd]: [player: Player, track: Track, payload: TrackEndEvent]; [ManagerEventTypes.RestoreComplete]: [node: Node]; [ManagerEventTypes.SegmentSkipped]: [player: Player, track: Track, payload: SponsorBlockSegmentSkipped]; [ManagerEventTypes.SegmentsLoaded]: [player: Player, track: Track, payload: SponsorBlockSegmentsLoaded]; [ManagerEventTypes.SocketClosed]: [player: Player, payload: WebSocketClosedEvent]; [ManagerEventTypes.TrackEnd]: [player: Player, track: Track, payload: TrackEndEvent]; [ManagerEventTypes.TrackError]: [player: Player, track: Track, payload: TrackExceptionEvent]; [ManagerEventTypes.TrackStart]: [player: Player, track: Track, payload: TrackStartEvent]; [ManagerEventTypes.TrackStuck]: [player: Player, track: Track, payload: TrackStuckEvent]; [ManagerEventTypes.VoiceReceiverDisconnect]: [player: Player]; [ManagerEventTypes.VoiceReceiverConnect]: [player: Player]; [ManagerEventTypes.VoiceReceiverError]: [player: Player, error: Error]; [ManagerEventTypes.VoiceReceiverStartSpeaking]: [player: Player, data: unknown]; [ManagerEventTypes.VoiceReceiverEndSpeaking]: [player: Player, data: unknown]; } /** * Voice Packet */ interface VoicePacket { t?: "VOICE_SERVER_UPDATE" | "VOICE_STATE_UPDATE"; d: DiscordVoiceState | VoiceServer; } /** * Voice Server */ interface VoiceServer { token: string; guild_id: string; endpoint: string; } interface Extendable { Player: typeof Player; Queue: typeof MemoryQueue | typeof RedisQueue | typeof JsonQueue; Node: typeof Node; } /** * Voice State */ interface PlayerVoiceState { op: "voiceUpdate"; guildId: string; event: VoiceServer; sessionId?: string; channelId?: string; } /** * Voice State */ interface DiscordVoiceState { guild_id: string; user_id: string; session_id: string; channel_id: string; } /** @deprecated Use DiscordVoiceState or PlayerVoiceState instead */ type VoiceState = DiscordVoiceState | PlayerVoiceState; /** * Node Message */ interface NodeMessage extends NodeStats { type: PlayerEventType; op: "stats" | "playerUpdate" | "event"; guildId: string; } /** * PlayerEvent interface */ interface PlayerEvent { op: "event"; type: PlayerEventType; guildId: string; } /** * Exception interface */ interface Exception { message: string; severity: SeverityTypes; cause: string; } /** * TrackStartEvent interface */ interface TrackStartEvent extends PlayerEvent { type: "TrackStartEvent"; track: TrackData; } /** * TrackEndEvent interface */ interface TrackEndEvent extends PlayerEvent { type: "TrackEndEvent"; track: TrackData; reason: TrackEndReasonTypes; } /** * TrackExceptionEvent interface */ interface TrackExceptionEvent extends PlayerEvent { exception?: Exception; guildId: string; type: "TrackExceptionEvent"; } /** * TrackStuckEvent interface */ interface TrackStuckEvent extends PlayerEvent { type: "TrackStuckEvent"; thresholdMs: number; } /** * WebSocketClosedEvent interface */ interface WebSocketClosedEvent extends PlayerEvent { type: "WebSocketClosedEvent"; code: number; reason: string; byRemote: boolean; } /** * SponsorBlockSegmentsLoaded interface */ interface SponsorBlockSegmentsLoaded extends PlayerEvent { type: "SegmentsLoaded"; segments: { category: string; start: number; end: number; }[]; } /** * SponsorBlockSegmentSkipped interface */ interface SponsorBlockSegmentSkipped extends PlayerEvent { type: "SegmentSkipped"; segment: { category: string; start: number; end: number; }; } /** * SponsorBlockChapterStarted interface */ interface SponsorBlockChapterStarted extends PlayerEvent { type: "ChapterStarted"; /** The chapter which started */ chapter: { /** The name of the chapter */ name: string; start: number; end: number; duration: number; }; } /** * SponsorBlockChaptersLoaded interface */ interface SponsorBlockChaptersLoaded extends PlayerEvent { type: "ChaptersLoaded"; /** All chapters loaded */ chapters: { /** The name of the chapter */ name: string; start: number; end: number; duration: number; }[]; } /** * NodeStats interface */ interface NodeStats { /** The amount of players on the node. */ players: number; /** The amount of playing players on the node. */ playingPlayers: number; /** The uptime for the node. */ uptime: number; /** The memory stats for the node. */ memory: MemoryStats; /** The cpu stats for the node. */ cpu: CPUStats; /** The frame stats for the node. */ frameStats: FrameStats; } /** * NodeStats interface */ interface NodeStats { /** The amount of players on the node. */ players: number; /** The amount of playing players on the node. */ playingPlayers: number; /** The uptime for the node. */ uptime: number; /** The memory stats for the node. */ memory: MemoryStats; /** The cpu stats for the node. */ cpu: CPUStats; /** The frame stats for the node. */ frameStats: FrameStats; } /** * MemoryStats interface */ interface MemoryStats { /** The free memory of the allocated amount. */ free: number; /** The used memory of the allocated amount. */ used: number; /** The total allocated memory. */ allocated: number; /** The reservable memory. */ reservable: number; } /** * CPUStats interface */ interface CPUStats { /** The core amount the host machine has. */ cores: number; /** The system load. */ systemLoad: number; /** The lavalink load. */ lavalinkLoad: number; } /** * FrameStats interface */ interface FrameStats { /** The amount of sent frames. */ sent?: number; /** The amount of nulled frames. */ nulled?: number; /** The amount of deficit frames. */ deficit?: number; } /** * LavalinkInfo interface */ interface LavalinkInfo { version: { semver: string; major: number; minor: number; patch: number; preRelease: string; }; buildTime: number; git: { branch: string; commit: string; commitTime: number; }; jvm: string; lavaplayer: string; sourceManagers: string[]; filters: string[]; plugins: { name: string; version: string; }[]; } /** * LyricsLine interface */ interface LyricsLine { timestamp: number; duration: number; line: string; plugin: object; } /** * Lyrics interface */ interface Lyrics { source: string; provider: string; text?: string; lines: LyricsLine[]; plugin: object[]; } /** * LyricsFoundEvent interface */ inter