lavalink-client 2.6.7 → 2.7.0
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 +4 -1
- package/dist/index.d.mts +136 -160
- package/dist/index.d.ts +136 -160
- package/dist/index.js +49 -27
- package/dist/index.mjs +49 -27
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -108,13 +108,15 @@ pnpm add tomato6966/lavalink-client
|
|
|
108
108
|
## 💖 Used In
|
|
109
109
|
This client powers various Discord bots:
|
|
110
110
|
- **[Mivator](https://discord.gg/5dUb7M2qCj)** (Public Bot by @Tomato6966)
|
|
111
|
-
- **[Betty](https://betty.
|
|
111
|
+
- **[Betty](https://betty.bot/?utm_source=lavalink-client)** (Public Bot by @fb_sean)
|
|
112
|
+
- **[Nero](https://betty.bot/?utm_source=lavalink-client)** (Public Bot by @fb_sean)
|
|
112
113
|
- **Bots by Contributors:**
|
|
113
114
|
- [Mintone](https://mintone.tech/) (@appujet)
|
|
114
115
|
- [Stelle](https://github.com/Ganyu-Studios/stelle-music) (@EvilG-MC)
|
|
115
116
|
- [Panais](https://panais.xyz/) (@LucasB25)
|
|
116
117
|
- [Akyn](https://akynbot.vercel.app/) (@notdeltaxd)
|
|
117
118
|
- [ARINO](https://site.arinoapp.qzz.io/) (@ryanwtf88)
|
|
119
|
+
- [iHorizon](https://github.com/ihrz/ihrz) (@iHorizon)
|
|
118
120
|
- **Bots Community (Users):**
|
|
119
121
|
- [Soundy](https://github.com/idMJA/Soundy) (@idMJA)
|
|
120
122
|
- [BeatBot ](https://getbeatbot.vercel.app/) (@zenitsujs)
|
|
@@ -461,3 +463,4 @@ if (response.tracks.length > 0) {
|
|
|
461
463
|
</div>
|
|
462
464
|
|
|
463
465
|
|
|
466
|
+
|
package/dist/index.d.mts
CHANGED
|
@@ -210,6 +210,7 @@ declare enum DebugEvents {
|
|
|
210
210
|
PlayerUpdateSuccess = "PlayerUpdateSuccess",
|
|
211
211
|
HeartBeatTriggered = "HeartBeatTriggered",
|
|
212
212
|
NoSocketOnDestroy = "NoSocketOnDestroy",
|
|
213
|
+
SocketCleanupError = "SocketCleanupError",
|
|
213
214
|
SocketTerminateHeartBeatTimeout = "SocketTerminateHeartBeatTimeout",
|
|
214
215
|
TryingConnectWhileConnected = "TryingConnectWhileConnected",
|
|
215
216
|
LavaSearchNothingFound = "LavaSearchNothingFound",
|
|
@@ -704,138 +705,6 @@ declare class FilterManager {
|
|
|
704
705
|
clearEQ(): Promise<this>;
|
|
705
706
|
}
|
|
706
707
|
|
|
707
|
-
/** Sourcenames provided by lavalink server */
|
|
708
|
-
type LavalinkSourceNames = "youtube" | "youtubemusic" | "soundcloud" | "bandcamp" | "twitch";
|
|
709
|
-
/** Source Names provided by lava src plugin */
|
|
710
|
-
type LavalinkPlugin_LavaSrc_SourceNames = "deezer" | "spotify" | "applemusic" | "yandexmusic" | "flowery-tts" | "vkmusic" | "tidal" | "qobuz" | "pandora";
|
|
711
|
-
/** Source Names provided by jiosaavan plugin */
|
|
712
|
-
type LavalinkPlugin_JioSaavn_SourceNames = "jiosaavn";
|
|
713
|
-
/** The SourceNames provided by lavalink */
|
|
714
|
-
type SourceNames = LavalinkSourceNames | LavalinkPlugin_LavaSrc_SourceNames | LavalinkPlugin_JioSaavn_SourceNames;
|
|
715
|
-
interface LavalinkTrackInfo {
|
|
716
|
-
/** The Identifier of the Track */
|
|
717
|
-
identifier: string;
|
|
718
|
-
/** The Track Title / Name */
|
|
719
|
-
title: string;
|
|
720
|
-
/** The Name of the Author */
|
|
721
|
-
author: string;
|
|
722
|
-
/** The duration of the Track */
|
|
723
|
-
length: number;
|
|
724
|
-
/** The URL of the artwork if available */
|
|
725
|
-
artworkUrl: string | null;
|
|
726
|
-
/** The URL (aka Link) of the Track called URI */
|
|
727
|
-
uri: string;
|
|
728
|
-
/** The Source name of the Track, e.g. soundcloud, youtube, spotify */
|
|
729
|
-
sourceName: SourceNames;
|
|
730
|
-
/** Wether the audio is seekable */
|
|
731
|
-
isSeekable: boolean;
|
|
732
|
-
/** Wether the audio is of a live stream */
|
|
733
|
-
isStream: boolean;
|
|
734
|
-
/** If isrc code is available, it's provided */
|
|
735
|
-
isrc: string | null;
|
|
736
|
-
}
|
|
737
|
-
interface TrackInfo {
|
|
738
|
-
/** The Identifier of the Track */
|
|
739
|
-
identifier: string;
|
|
740
|
-
/** The Track Title / Name */
|
|
741
|
-
title: string;
|
|
742
|
-
/** The Name of the Author */
|
|
743
|
-
author: string;
|
|
744
|
-
/** The duration of the Track */
|
|
745
|
-
duration: number;
|
|
746
|
-
/** The URL of the artwork if available */
|
|
747
|
-
artworkUrl: string | null;
|
|
748
|
-
/** The URL (aka Link) of the Track called URI */
|
|
749
|
-
uri: string;
|
|
750
|
-
/** The Source name of the Track, e.g. soundcloud, youtube, spotify */
|
|
751
|
-
sourceName: SourceNames;
|
|
752
|
-
/** Wether the audio is seekable */
|
|
753
|
-
isSeekable: boolean;
|
|
754
|
-
/** Wether the audio is of a live stream */
|
|
755
|
-
isStream: boolean;
|
|
756
|
-
/** If isrc code is available, it's provided */
|
|
757
|
-
isrc: string | null;
|
|
758
|
-
}
|
|
759
|
-
interface PluginInfo {
|
|
760
|
-
/** The Type provided by a plugin */
|
|
761
|
-
type?: "album" | "playlist" | "artist" | "recommendations" | string;
|
|
762
|
-
/** The Identifier provided by a plugin */
|
|
763
|
-
albumName?: string;
|
|
764
|
-
/** The url of the album */
|
|
765
|
-
albumUrl?: string;
|
|
766
|
-
/** The url of the album art */
|
|
767
|
-
albumArtUrl?: string;
|
|
768
|
-
/** The url of the artist */
|
|
769
|
-
artistUrl?: string;
|
|
770
|
-
/** The url of the artist artwork */
|
|
771
|
-
artistArtworkUrl?: string;
|
|
772
|
-
/** The url of the preview */
|
|
773
|
-
previewUrl?: string;
|
|
774
|
-
/** Whether the track is a preview */
|
|
775
|
-
isPreview?: boolean;
|
|
776
|
-
/** The total number of tracks in the playlist */
|
|
777
|
-
totalTracks?: number;
|
|
778
|
-
/** The Identifier provided by a plugin */
|
|
779
|
-
identifier?: string;
|
|
780
|
-
/** The ArtworkUrl provided by a plugin */
|
|
781
|
-
artworkUrl?: string;
|
|
782
|
-
/** The Author Information provided by a plugin */
|
|
783
|
-
author?: string;
|
|
784
|
-
/** The Url provided by a Plugin */
|
|
785
|
-
url?: string;
|
|
786
|
-
/** The Url provided by a Plugin */
|
|
787
|
-
uri?: string;
|
|
788
|
-
/** You can put specific track information here, to transform the tracks... */
|
|
789
|
-
clientData?: {
|
|
790
|
-
previousTrack?: boolean;
|
|
791
|
-
[key: string]: any;
|
|
792
|
-
};
|
|
793
|
-
}
|
|
794
|
-
interface LavalinkTrack {
|
|
795
|
-
/** The Base 64 encoded String */
|
|
796
|
-
encoded?: Base64;
|
|
797
|
-
/** Track Information */
|
|
798
|
-
info: LavalinkTrackInfo;
|
|
799
|
-
/** Plugin Information from Lavalink */
|
|
800
|
-
pluginInfo: Partial<PluginInfo>;
|
|
801
|
-
/** The userData Object from when you provide to the lavalink request */
|
|
802
|
-
userData?: anyObject;
|
|
803
|
-
}
|
|
804
|
-
interface Track {
|
|
805
|
-
/** The Base 64 encoded String */
|
|
806
|
-
encoded?: Base64;
|
|
807
|
-
/** Track Information */
|
|
808
|
-
info: TrackInfo;
|
|
809
|
-
/** Plugin Information from Lavalink */
|
|
810
|
-
pluginInfo: Partial<PluginInfo>;
|
|
811
|
-
/** The Track's Requester */
|
|
812
|
-
requester?: unknown;
|
|
813
|
-
/** The userData Object from when you provide to the lavalink request */
|
|
814
|
-
userData?: anyObject;
|
|
815
|
-
}
|
|
816
|
-
interface UnresolvedTrackInfo extends Partial<TrackInfo> {
|
|
817
|
-
/** Required */
|
|
818
|
-
title: string;
|
|
819
|
-
}
|
|
820
|
-
interface UnresolvedQuery extends UnresolvedTrackInfo {
|
|
821
|
-
/** The base64 of the unresolved track to "encode" */
|
|
822
|
-
encoded?: Base64;
|
|
823
|
-
}
|
|
824
|
-
interface UnresolvedTrack {
|
|
825
|
-
/** Required */
|
|
826
|
-
resolve: (player: Player) => Promise<void>;
|
|
827
|
-
/** The Base 64 encoded String */
|
|
828
|
-
encoded?: Base64;
|
|
829
|
-
/** Track Information */
|
|
830
|
-
info: UnresolvedTrackInfo;
|
|
831
|
-
/** Plugin Information from Lavalink */
|
|
832
|
-
pluginInfo: Partial<PluginInfo>;
|
|
833
|
-
/** The userData Object from when you provide to the lavalink request */
|
|
834
|
-
userData?: anyObject;
|
|
835
|
-
/** The Track's Requester */
|
|
836
|
-
requester?: unknown;
|
|
837
|
-
}
|
|
838
|
-
|
|
839
708
|
declare class QueueSaver {
|
|
840
709
|
/**
|
|
841
710
|
* The queue store manager
|
|
@@ -977,6 +846,7 @@ declare class Queue {
|
|
|
977
846
|
* - single Track | UnresolvedTrack
|
|
978
847
|
* - multiple Track | UnresovedTrack
|
|
979
848
|
* - at the index or multiple indexes
|
|
849
|
+
* - Since v2.7 the removed tracks get unshifted into the previous queue state instead of pushed (indexed at the start instead of end - as it should)
|
|
980
850
|
* @param removeQueryTrack
|
|
981
851
|
* @returns null (if nothing was removed) / { removed } where removed is an array with all removed elements
|
|
982
852
|
*
|
|
@@ -1249,6 +1119,138 @@ declare class Player {
|
|
|
1249
1119
|
toJSON(): PlayerJson;
|
|
1250
1120
|
}
|
|
1251
1121
|
|
|
1122
|
+
/** Sourcenames provided by lavalink server */
|
|
1123
|
+
type LavalinkSourceNames = "youtube" | "youtubemusic" | "soundcloud" | "bandcamp" | "twitch";
|
|
1124
|
+
/** Source Names provided by lava src plugin */
|
|
1125
|
+
type LavalinkPlugin_LavaSrc_SourceNames = "deezer" | "spotify" | "applemusic" | "yandexmusic" | "flowery-tts" | "vkmusic" | "tidal" | "qobuz" | "pandora";
|
|
1126
|
+
/** Source Names provided by jiosaavan plugin */
|
|
1127
|
+
type LavalinkPlugin_JioSaavn_SourceNames = "jiosaavn";
|
|
1128
|
+
/** The SourceNames provided by lavalink */
|
|
1129
|
+
type SourceNames = LavalinkSourceNames | LavalinkPlugin_LavaSrc_SourceNames | LavalinkPlugin_JioSaavn_SourceNames;
|
|
1130
|
+
interface LavalinkTrackInfo {
|
|
1131
|
+
/** The Identifier of the Track */
|
|
1132
|
+
identifier: string;
|
|
1133
|
+
/** The Track Title / Name */
|
|
1134
|
+
title: string;
|
|
1135
|
+
/** The Name of the Author */
|
|
1136
|
+
author: string;
|
|
1137
|
+
/** The duration of the Track */
|
|
1138
|
+
length: number;
|
|
1139
|
+
/** The URL of the artwork if available */
|
|
1140
|
+
artworkUrl: string | null;
|
|
1141
|
+
/** The URL (aka Link) of the Track called URI */
|
|
1142
|
+
uri: string;
|
|
1143
|
+
/** The Source name of the Track, e.g. soundcloud, youtube, spotify */
|
|
1144
|
+
sourceName: SourceNames;
|
|
1145
|
+
/** Wether the audio is seekable */
|
|
1146
|
+
isSeekable: boolean;
|
|
1147
|
+
/** Wether the audio is of a live stream */
|
|
1148
|
+
isStream: boolean;
|
|
1149
|
+
/** If isrc code is available, it's provided */
|
|
1150
|
+
isrc: string | null;
|
|
1151
|
+
}
|
|
1152
|
+
interface TrackInfo {
|
|
1153
|
+
/** The Identifier of the Track */
|
|
1154
|
+
identifier: string;
|
|
1155
|
+
/** The Track Title / Name */
|
|
1156
|
+
title: string;
|
|
1157
|
+
/** The Name of the Author */
|
|
1158
|
+
author: string;
|
|
1159
|
+
/** The duration of the Track */
|
|
1160
|
+
duration: number;
|
|
1161
|
+
/** The URL of the artwork if available */
|
|
1162
|
+
artworkUrl: string | null;
|
|
1163
|
+
/** The URL (aka Link) of the Track called URI */
|
|
1164
|
+
uri: string;
|
|
1165
|
+
/** The Source name of the Track, e.g. soundcloud, youtube, spotify */
|
|
1166
|
+
sourceName: SourceNames;
|
|
1167
|
+
/** Wether the audio is seekable */
|
|
1168
|
+
isSeekable: boolean;
|
|
1169
|
+
/** Wether the audio is of a live stream */
|
|
1170
|
+
isStream: boolean;
|
|
1171
|
+
/** If isrc code is available, it's provided */
|
|
1172
|
+
isrc: string | null;
|
|
1173
|
+
}
|
|
1174
|
+
interface PluginInfo {
|
|
1175
|
+
/** The Type provided by a plugin */
|
|
1176
|
+
type?: "album" | "playlist" | "artist" | "recommendations" | string;
|
|
1177
|
+
/** The Identifier provided by a plugin */
|
|
1178
|
+
albumName?: string;
|
|
1179
|
+
/** The url of the album */
|
|
1180
|
+
albumUrl?: string;
|
|
1181
|
+
/** The url of the album art */
|
|
1182
|
+
albumArtUrl?: string;
|
|
1183
|
+
/** The url of the artist */
|
|
1184
|
+
artistUrl?: string;
|
|
1185
|
+
/** The url of the artist artwork */
|
|
1186
|
+
artistArtworkUrl?: string;
|
|
1187
|
+
/** The url of the preview */
|
|
1188
|
+
previewUrl?: string;
|
|
1189
|
+
/** Whether the track is a preview */
|
|
1190
|
+
isPreview?: boolean;
|
|
1191
|
+
/** The total number of tracks in the playlist */
|
|
1192
|
+
totalTracks?: number;
|
|
1193
|
+
/** The Identifier provided by a plugin */
|
|
1194
|
+
identifier?: string;
|
|
1195
|
+
/** The ArtworkUrl provided by a plugin */
|
|
1196
|
+
artworkUrl?: string;
|
|
1197
|
+
/** The Author Information provided by a plugin */
|
|
1198
|
+
author?: string;
|
|
1199
|
+
/** The Url provided by a Plugin */
|
|
1200
|
+
url?: string;
|
|
1201
|
+
/** The Url provided by a Plugin */
|
|
1202
|
+
uri?: string;
|
|
1203
|
+
/** You can put specific track information here, to transform the tracks... */
|
|
1204
|
+
clientData?: {
|
|
1205
|
+
previousTrack?: boolean;
|
|
1206
|
+
[key: string]: any;
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
interface LavalinkTrack {
|
|
1210
|
+
/** The Base 64 encoded String */
|
|
1211
|
+
encoded?: Base64;
|
|
1212
|
+
/** Track Information */
|
|
1213
|
+
info: LavalinkTrackInfo;
|
|
1214
|
+
/** Plugin Information from Lavalink */
|
|
1215
|
+
pluginInfo: Partial<PluginInfo>;
|
|
1216
|
+
/** The userData Object from when you provide to the lavalink request */
|
|
1217
|
+
userData?: anyObject;
|
|
1218
|
+
}
|
|
1219
|
+
interface Track {
|
|
1220
|
+
/** The Base 64 encoded String */
|
|
1221
|
+
encoded?: Base64;
|
|
1222
|
+
/** Track Information */
|
|
1223
|
+
info: TrackInfo;
|
|
1224
|
+
/** Plugin Information from Lavalink */
|
|
1225
|
+
pluginInfo: Partial<PluginInfo>;
|
|
1226
|
+
/** The Track's Requester */
|
|
1227
|
+
requester?: unknown;
|
|
1228
|
+
/** The userData Object from when you provide to the lavalink request */
|
|
1229
|
+
userData?: anyObject;
|
|
1230
|
+
}
|
|
1231
|
+
interface UnresolvedTrackInfo extends Partial<TrackInfo> {
|
|
1232
|
+
/** Required */
|
|
1233
|
+
title: string;
|
|
1234
|
+
}
|
|
1235
|
+
interface UnresolvedQuery extends UnresolvedTrackInfo {
|
|
1236
|
+
/** The base64 of the unresolved track to "encode" */
|
|
1237
|
+
encoded?: Base64;
|
|
1238
|
+
}
|
|
1239
|
+
interface UnresolvedTrack {
|
|
1240
|
+
/** Required */
|
|
1241
|
+
resolve: (player: Player) => Promise<void>;
|
|
1242
|
+
/** The Base 64 encoded String */
|
|
1243
|
+
encoded?: Base64;
|
|
1244
|
+
/** Track Information */
|
|
1245
|
+
info: UnresolvedTrackInfo;
|
|
1246
|
+
/** Plugin Information from Lavalink */
|
|
1247
|
+
pluginInfo: Partial<PluginInfo>;
|
|
1248
|
+
/** The userData Object from when you provide to the lavalink request */
|
|
1249
|
+
userData?: anyObject;
|
|
1250
|
+
/** The Track's Requester */
|
|
1251
|
+
requester?: unknown;
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1252
1254
|
interface StoredQueue {
|
|
1253
1255
|
current: Track | null;
|
|
1254
1256
|
previous: Track[];
|
|
@@ -1266,7 +1268,7 @@ interface QueueStoreManager {
|
|
|
1266
1268
|
/** @async Parse the saved value back to the Queue (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */
|
|
1267
1269
|
parse: (value: StoredQueue | string) => Awaitable<Partial<StoredQueue>>;
|
|
1268
1270
|
}
|
|
1269
|
-
interface ManagerQueueOptions
|
|
1271
|
+
interface ManagerQueueOptions {
|
|
1270
1272
|
/** Maximum Amount of tracks for the queue.previous array. Set to 0 to not save previous songs. Defaults to 25 Tracks */
|
|
1271
1273
|
maxPreviousTracks?: number;
|
|
1272
1274
|
/** Custom Queue Store option */
|
|
@@ -1916,38 +1918,12 @@ interface LyricsFoundEvent extends PlayerEvent {
|
|
|
1916
1918
|
/** The lyrics */
|
|
1917
1919
|
lyrics: LyricsResult;
|
|
1918
1920
|
}
|
|
1919
|
-
interface LyricsFoundEvent extends PlayerEvent {
|
|
1920
|
-
/** The lyricsfound event */
|
|
1921
|
-
type: "LyricsFoundEvent";
|
|
1922
|
-
/** The guildId */
|
|
1923
|
-
guildId: string;
|
|
1924
|
-
/** The lyrics */
|
|
1925
|
-
lyrics: LyricsResult;
|
|
1926
|
-
}
|
|
1927
1921
|
interface LyricsNotFoundEvent extends PlayerEvent {
|
|
1928
1922
|
/**The lyricsnotfound event*/
|
|
1929
1923
|
type: "LyricsNotFoundEvent";
|
|
1930
1924
|
/**The guildId*/
|
|
1931
1925
|
guildId: string;
|
|
1932
1926
|
}
|
|
1933
|
-
interface LyricsNotFoundEvent extends PlayerEvent {
|
|
1934
|
-
/**The lyricsnotfound event*/
|
|
1935
|
-
type: "LyricsNotFoundEvent";
|
|
1936
|
-
/**The guildId*/
|
|
1937
|
-
guildId: string;
|
|
1938
|
-
}
|
|
1939
|
-
interface LyricsLineEvent extends PlayerEvent {
|
|
1940
|
-
/**The lyricsline event*/
|
|
1941
|
-
type: "LyricsLineEvent";
|
|
1942
|
-
/** The guildId */
|
|
1943
|
-
guildId: string;
|
|
1944
|
-
/** The line number */
|
|
1945
|
-
lineIndex: number;
|
|
1946
|
-
/** The line */
|
|
1947
|
-
line: LyricsLine;
|
|
1948
|
-
/**skipped is true if the line was skipped */
|
|
1949
|
-
skipped: boolean;
|
|
1950
|
-
}
|
|
1951
1927
|
interface LyricsLineEvent extends PlayerEvent {
|
|
1952
1928
|
/**The lyricsline event*/
|
|
1953
1929
|
type: "LyricsLineEvent";
|
|
@@ -3040,7 +3016,7 @@ interface ManagerOptions<CustomPlayerT extends Player = Player> {
|
|
|
3040
3016
|
/** The Bot Client's Data for Authorization */
|
|
3041
3017
|
client?: BotClientOptions;
|
|
3042
3018
|
/** QueueOptions for all Queues */
|
|
3043
|
-
queueOptions?: ManagerQueueOptions
|
|
3019
|
+
queueOptions?: ManagerQueueOptions;
|
|
3044
3020
|
/** PlayerOptions for all Players */
|
|
3045
3021
|
playerOptions?: ManagerPlayerOptions<CustomPlayerT>;
|
|
3046
3022
|
/** The player class you want to use when creating a player. (can be extendable) */
|
package/dist/index.d.ts
CHANGED
|
@@ -210,6 +210,7 @@ declare enum DebugEvents {
|
|
|
210
210
|
PlayerUpdateSuccess = "PlayerUpdateSuccess",
|
|
211
211
|
HeartBeatTriggered = "HeartBeatTriggered",
|
|
212
212
|
NoSocketOnDestroy = "NoSocketOnDestroy",
|
|
213
|
+
SocketCleanupError = "SocketCleanupError",
|
|
213
214
|
SocketTerminateHeartBeatTimeout = "SocketTerminateHeartBeatTimeout",
|
|
214
215
|
TryingConnectWhileConnected = "TryingConnectWhileConnected",
|
|
215
216
|
LavaSearchNothingFound = "LavaSearchNothingFound",
|
|
@@ -704,138 +705,6 @@ declare class FilterManager {
|
|
|
704
705
|
clearEQ(): Promise<this>;
|
|
705
706
|
}
|
|
706
707
|
|
|
707
|
-
/** Sourcenames provided by lavalink server */
|
|
708
|
-
type LavalinkSourceNames = "youtube" | "youtubemusic" | "soundcloud" | "bandcamp" | "twitch";
|
|
709
|
-
/** Source Names provided by lava src plugin */
|
|
710
|
-
type LavalinkPlugin_LavaSrc_SourceNames = "deezer" | "spotify" | "applemusic" | "yandexmusic" | "flowery-tts" | "vkmusic" | "tidal" | "qobuz" | "pandora";
|
|
711
|
-
/** Source Names provided by jiosaavan plugin */
|
|
712
|
-
type LavalinkPlugin_JioSaavn_SourceNames = "jiosaavn";
|
|
713
|
-
/** The SourceNames provided by lavalink */
|
|
714
|
-
type SourceNames = LavalinkSourceNames | LavalinkPlugin_LavaSrc_SourceNames | LavalinkPlugin_JioSaavn_SourceNames;
|
|
715
|
-
interface LavalinkTrackInfo {
|
|
716
|
-
/** The Identifier of the Track */
|
|
717
|
-
identifier: string;
|
|
718
|
-
/** The Track Title / Name */
|
|
719
|
-
title: string;
|
|
720
|
-
/** The Name of the Author */
|
|
721
|
-
author: string;
|
|
722
|
-
/** The duration of the Track */
|
|
723
|
-
length: number;
|
|
724
|
-
/** The URL of the artwork if available */
|
|
725
|
-
artworkUrl: string | null;
|
|
726
|
-
/** The URL (aka Link) of the Track called URI */
|
|
727
|
-
uri: string;
|
|
728
|
-
/** The Source name of the Track, e.g. soundcloud, youtube, spotify */
|
|
729
|
-
sourceName: SourceNames;
|
|
730
|
-
/** Wether the audio is seekable */
|
|
731
|
-
isSeekable: boolean;
|
|
732
|
-
/** Wether the audio is of a live stream */
|
|
733
|
-
isStream: boolean;
|
|
734
|
-
/** If isrc code is available, it's provided */
|
|
735
|
-
isrc: string | null;
|
|
736
|
-
}
|
|
737
|
-
interface TrackInfo {
|
|
738
|
-
/** The Identifier of the Track */
|
|
739
|
-
identifier: string;
|
|
740
|
-
/** The Track Title / Name */
|
|
741
|
-
title: string;
|
|
742
|
-
/** The Name of the Author */
|
|
743
|
-
author: string;
|
|
744
|
-
/** The duration of the Track */
|
|
745
|
-
duration: number;
|
|
746
|
-
/** The URL of the artwork if available */
|
|
747
|
-
artworkUrl: string | null;
|
|
748
|
-
/** The URL (aka Link) of the Track called URI */
|
|
749
|
-
uri: string;
|
|
750
|
-
/** The Source name of the Track, e.g. soundcloud, youtube, spotify */
|
|
751
|
-
sourceName: SourceNames;
|
|
752
|
-
/** Wether the audio is seekable */
|
|
753
|
-
isSeekable: boolean;
|
|
754
|
-
/** Wether the audio is of a live stream */
|
|
755
|
-
isStream: boolean;
|
|
756
|
-
/** If isrc code is available, it's provided */
|
|
757
|
-
isrc: string | null;
|
|
758
|
-
}
|
|
759
|
-
interface PluginInfo {
|
|
760
|
-
/** The Type provided by a plugin */
|
|
761
|
-
type?: "album" | "playlist" | "artist" | "recommendations" | string;
|
|
762
|
-
/** The Identifier provided by a plugin */
|
|
763
|
-
albumName?: string;
|
|
764
|
-
/** The url of the album */
|
|
765
|
-
albumUrl?: string;
|
|
766
|
-
/** The url of the album art */
|
|
767
|
-
albumArtUrl?: string;
|
|
768
|
-
/** The url of the artist */
|
|
769
|
-
artistUrl?: string;
|
|
770
|
-
/** The url of the artist artwork */
|
|
771
|
-
artistArtworkUrl?: string;
|
|
772
|
-
/** The url of the preview */
|
|
773
|
-
previewUrl?: string;
|
|
774
|
-
/** Whether the track is a preview */
|
|
775
|
-
isPreview?: boolean;
|
|
776
|
-
/** The total number of tracks in the playlist */
|
|
777
|
-
totalTracks?: number;
|
|
778
|
-
/** The Identifier provided by a plugin */
|
|
779
|
-
identifier?: string;
|
|
780
|
-
/** The ArtworkUrl provided by a plugin */
|
|
781
|
-
artworkUrl?: string;
|
|
782
|
-
/** The Author Information provided by a plugin */
|
|
783
|
-
author?: string;
|
|
784
|
-
/** The Url provided by a Plugin */
|
|
785
|
-
url?: string;
|
|
786
|
-
/** The Url provided by a Plugin */
|
|
787
|
-
uri?: string;
|
|
788
|
-
/** You can put specific track information here, to transform the tracks... */
|
|
789
|
-
clientData?: {
|
|
790
|
-
previousTrack?: boolean;
|
|
791
|
-
[key: string]: any;
|
|
792
|
-
};
|
|
793
|
-
}
|
|
794
|
-
interface LavalinkTrack {
|
|
795
|
-
/** The Base 64 encoded String */
|
|
796
|
-
encoded?: Base64;
|
|
797
|
-
/** Track Information */
|
|
798
|
-
info: LavalinkTrackInfo;
|
|
799
|
-
/** Plugin Information from Lavalink */
|
|
800
|
-
pluginInfo: Partial<PluginInfo>;
|
|
801
|
-
/** The userData Object from when you provide to the lavalink request */
|
|
802
|
-
userData?: anyObject;
|
|
803
|
-
}
|
|
804
|
-
interface Track {
|
|
805
|
-
/** The Base 64 encoded String */
|
|
806
|
-
encoded?: Base64;
|
|
807
|
-
/** Track Information */
|
|
808
|
-
info: TrackInfo;
|
|
809
|
-
/** Plugin Information from Lavalink */
|
|
810
|
-
pluginInfo: Partial<PluginInfo>;
|
|
811
|
-
/** The Track's Requester */
|
|
812
|
-
requester?: unknown;
|
|
813
|
-
/** The userData Object from when you provide to the lavalink request */
|
|
814
|
-
userData?: anyObject;
|
|
815
|
-
}
|
|
816
|
-
interface UnresolvedTrackInfo extends Partial<TrackInfo> {
|
|
817
|
-
/** Required */
|
|
818
|
-
title: string;
|
|
819
|
-
}
|
|
820
|
-
interface UnresolvedQuery extends UnresolvedTrackInfo {
|
|
821
|
-
/** The base64 of the unresolved track to "encode" */
|
|
822
|
-
encoded?: Base64;
|
|
823
|
-
}
|
|
824
|
-
interface UnresolvedTrack {
|
|
825
|
-
/** Required */
|
|
826
|
-
resolve: (player: Player) => Promise<void>;
|
|
827
|
-
/** The Base 64 encoded String */
|
|
828
|
-
encoded?: Base64;
|
|
829
|
-
/** Track Information */
|
|
830
|
-
info: UnresolvedTrackInfo;
|
|
831
|
-
/** Plugin Information from Lavalink */
|
|
832
|
-
pluginInfo: Partial<PluginInfo>;
|
|
833
|
-
/** The userData Object from when you provide to the lavalink request */
|
|
834
|
-
userData?: anyObject;
|
|
835
|
-
/** The Track's Requester */
|
|
836
|
-
requester?: unknown;
|
|
837
|
-
}
|
|
838
|
-
|
|
839
708
|
declare class QueueSaver {
|
|
840
709
|
/**
|
|
841
710
|
* The queue store manager
|
|
@@ -977,6 +846,7 @@ declare class Queue {
|
|
|
977
846
|
* - single Track | UnresolvedTrack
|
|
978
847
|
* - multiple Track | UnresovedTrack
|
|
979
848
|
* - at the index or multiple indexes
|
|
849
|
+
* - Since v2.7 the removed tracks get unshifted into the previous queue state instead of pushed (indexed at the start instead of end - as it should)
|
|
980
850
|
* @param removeQueryTrack
|
|
981
851
|
* @returns null (if nothing was removed) / { removed } where removed is an array with all removed elements
|
|
982
852
|
*
|
|
@@ -1249,6 +1119,138 @@ declare class Player {
|
|
|
1249
1119
|
toJSON(): PlayerJson;
|
|
1250
1120
|
}
|
|
1251
1121
|
|
|
1122
|
+
/** Sourcenames provided by lavalink server */
|
|
1123
|
+
type LavalinkSourceNames = "youtube" | "youtubemusic" | "soundcloud" | "bandcamp" | "twitch";
|
|
1124
|
+
/** Source Names provided by lava src plugin */
|
|
1125
|
+
type LavalinkPlugin_LavaSrc_SourceNames = "deezer" | "spotify" | "applemusic" | "yandexmusic" | "flowery-tts" | "vkmusic" | "tidal" | "qobuz" | "pandora";
|
|
1126
|
+
/** Source Names provided by jiosaavan plugin */
|
|
1127
|
+
type LavalinkPlugin_JioSaavn_SourceNames = "jiosaavn";
|
|
1128
|
+
/** The SourceNames provided by lavalink */
|
|
1129
|
+
type SourceNames = LavalinkSourceNames | LavalinkPlugin_LavaSrc_SourceNames | LavalinkPlugin_JioSaavn_SourceNames;
|
|
1130
|
+
interface LavalinkTrackInfo {
|
|
1131
|
+
/** The Identifier of the Track */
|
|
1132
|
+
identifier: string;
|
|
1133
|
+
/** The Track Title / Name */
|
|
1134
|
+
title: string;
|
|
1135
|
+
/** The Name of the Author */
|
|
1136
|
+
author: string;
|
|
1137
|
+
/** The duration of the Track */
|
|
1138
|
+
length: number;
|
|
1139
|
+
/** The URL of the artwork if available */
|
|
1140
|
+
artworkUrl: string | null;
|
|
1141
|
+
/** The URL (aka Link) of the Track called URI */
|
|
1142
|
+
uri: string;
|
|
1143
|
+
/** The Source name of the Track, e.g. soundcloud, youtube, spotify */
|
|
1144
|
+
sourceName: SourceNames;
|
|
1145
|
+
/** Wether the audio is seekable */
|
|
1146
|
+
isSeekable: boolean;
|
|
1147
|
+
/** Wether the audio is of a live stream */
|
|
1148
|
+
isStream: boolean;
|
|
1149
|
+
/** If isrc code is available, it's provided */
|
|
1150
|
+
isrc: string | null;
|
|
1151
|
+
}
|
|
1152
|
+
interface TrackInfo {
|
|
1153
|
+
/** The Identifier of the Track */
|
|
1154
|
+
identifier: string;
|
|
1155
|
+
/** The Track Title / Name */
|
|
1156
|
+
title: string;
|
|
1157
|
+
/** The Name of the Author */
|
|
1158
|
+
author: string;
|
|
1159
|
+
/** The duration of the Track */
|
|
1160
|
+
duration: number;
|
|
1161
|
+
/** The URL of the artwork if available */
|
|
1162
|
+
artworkUrl: string | null;
|
|
1163
|
+
/** The URL (aka Link) of the Track called URI */
|
|
1164
|
+
uri: string;
|
|
1165
|
+
/** The Source name of the Track, e.g. soundcloud, youtube, spotify */
|
|
1166
|
+
sourceName: SourceNames;
|
|
1167
|
+
/** Wether the audio is seekable */
|
|
1168
|
+
isSeekable: boolean;
|
|
1169
|
+
/** Wether the audio is of a live stream */
|
|
1170
|
+
isStream: boolean;
|
|
1171
|
+
/** If isrc code is available, it's provided */
|
|
1172
|
+
isrc: string | null;
|
|
1173
|
+
}
|
|
1174
|
+
interface PluginInfo {
|
|
1175
|
+
/** The Type provided by a plugin */
|
|
1176
|
+
type?: "album" | "playlist" | "artist" | "recommendations" | string;
|
|
1177
|
+
/** The Identifier provided by a plugin */
|
|
1178
|
+
albumName?: string;
|
|
1179
|
+
/** The url of the album */
|
|
1180
|
+
albumUrl?: string;
|
|
1181
|
+
/** The url of the album art */
|
|
1182
|
+
albumArtUrl?: string;
|
|
1183
|
+
/** The url of the artist */
|
|
1184
|
+
artistUrl?: string;
|
|
1185
|
+
/** The url of the artist artwork */
|
|
1186
|
+
artistArtworkUrl?: string;
|
|
1187
|
+
/** The url of the preview */
|
|
1188
|
+
previewUrl?: string;
|
|
1189
|
+
/** Whether the track is a preview */
|
|
1190
|
+
isPreview?: boolean;
|
|
1191
|
+
/** The total number of tracks in the playlist */
|
|
1192
|
+
totalTracks?: number;
|
|
1193
|
+
/** The Identifier provided by a plugin */
|
|
1194
|
+
identifier?: string;
|
|
1195
|
+
/** The ArtworkUrl provided by a plugin */
|
|
1196
|
+
artworkUrl?: string;
|
|
1197
|
+
/** The Author Information provided by a plugin */
|
|
1198
|
+
author?: string;
|
|
1199
|
+
/** The Url provided by a Plugin */
|
|
1200
|
+
url?: string;
|
|
1201
|
+
/** The Url provided by a Plugin */
|
|
1202
|
+
uri?: string;
|
|
1203
|
+
/** You can put specific track information here, to transform the tracks... */
|
|
1204
|
+
clientData?: {
|
|
1205
|
+
previousTrack?: boolean;
|
|
1206
|
+
[key: string]: any;
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
interface LavalinkTrack {
|
|
1210
|
+
/** The Base 64 encoded String */
|
|
1211
|
+
encoded?: Base64;
|
|
1212
|
+
/** Track Information */
|
|
1213
|
+
info: LavalinkTrackInfo;
|
|
1214
|
+
/** Plugin Information from Lavalink */
|
|
1215
|
+
pluginInfo: Partial<PluginInfo>;
|
|
1216
|
+
/** The userData Object from when you provide to the lavalink request */
|
|
1217
|
+
userData?: anyObject;
|
|
1218
|
+
}
|
|
1219
|
+
interface Track {
|
|
1220
|
+
/** The Base 64 encoded String */
|
|
1221
|
+
encoded?: Base64;
|
|
1222
|
+
/** Track Information */
|
|
1223
|
+
info: TrackInfo;
|
|
1224
|
+
/** Plugin Information from Lavalink */
|
|
1225
|
+
pluginInfo: Partial<PluginInfo>;
|
|
1226
|
+
/** The Track's Requester */
|
|
1227
|
+
requester?: unknown;
|
|
1228
|
+
/** The userData Object from when you provide to the lavalink request */
|
|
1229
|
+
userData?: anyObject;
|
|
1230
|
+
}
|
|
1231
|
+
interface UnresolvedTrackInfo extends Partial<TrackInfo> {
|
|
1232
|
+
/** Required */
|
|
1233
|
+
title: string;
|
|
1234
|
+
}
|
|
1235
|
+
interface UnresolvedQuery extends UnresolvedTrackInfo {
|
|
1236
|
+
/** The base64 of the unresolved track to "encode" */
|
|
1237
|
+
encoded?: Base64;
|
|
1238
|
+
}
|
|
1239
|
+
interface UnresolvedTrack {
|
|
1240
|
+
/** Required */
|
|
1241
|
+
resolve: (player: Player) => Promise<void>;
|
|
1242
|
+
/** The Base 64 encoded String */
|
|
1243
|
+
encoded?: Base64;
|
|
1244
|
+
/** Track Information */
|
|
1245
|
+
info: UnresolvedTrackInfo;
|
|
1246
|
+
/** Plugin Information from Lavalink */
|
|
1247
|
+
pluginInfo: Partial<PluginInfo>;
|
|
1248
|
+
/** The userData Object from when you provide to the lavalink request */
|
|
1249
|
+
userData?: anyObject;
|
|
1250
|
+
/** The Track's Requester */
|
|
1251
|
+
requester?: unknown;
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1252
1254
|
interface StoredQueue {
|
|
1253
1255
|
current: Track | null;
|
|
1254
1256
|
previous: Track[];
|
|
@@ -1266,7 +1268,7 @@ interface QueueStoreManager {
|
|
|
1266
1268
|
/** @async Parse the saved value back to the Queue (IF YOU DON'T NEED PARSING/STRINGIFY, then just return the value) */
|
|
1267
1269
|
parse: (value: StoredQueue | string) => Awaitable<Partial<StoredQueue>>;
|
|
1268
1270
|
}
|
|
1269
|
-
interface ManagerQueueOptions
|
|
1271
|
+
interface ManagerQueueOptions {
|
|
1270
1272
|
/** Maximum Amount of tracks for the queue.previous array. Set to 0 to not save previous songs. Defaults to 25 Tracks */
|
|
1271
1273
|
maxPreviousTracks?: number;
|
|
1272
1274
|
/** Custom Queue Store option */
|
|
@@ -1916,38 +1918,12 @@ interface LyricsFoundEvent extends PlayerEvent {
|
|
|
1916
1918
|
/** The lyrics */
|
|
1917
1919
|
lyrics: LyricsResult;
|
|
1918
1920
|
}
|
|
1919
|
-
interface LyricsFoundEvent extends PlayerEvent {
|
|
1920
|
-
/** The lyricsfound event */
|
|
1921
|
-
type: "LyricsFoundEvent";
|
|
1922
|
-
/** The guildId */
|
|
1923
|
-
guildId: string;
|
|
1924
|
-
/** The lyrics */
|
|
1925
|
-
lyrics: LyricsResult;
|
|
1926
|
-
}
|
|
1927
1921
|
interface LyricsNotFoundEvent extends PlayerEvent {
|
|
1928
1922
|
/**The lyricsnotfound event*/
|
|
1929
1923
|
type: "LyricsNotFoundEvent";
|
|
1930
1924
|
/**The guildId*/
|
|
1931
1925
|
guildId: string;
|
|
1932
1926
|
}
|
|
1933
|
-
interface LyricsNotFoundEvent extends PlayerEvent {
|
|
1934
|
-
/**The lyricsnotfound event*/
|
|
1935
|
-
type: "LyricsNotFoundEvent";
|
|
1936
|
-
/**The guildId*/
|
|
1937
|
-
guildId: string;
|
|
1938
|
-
}
|
|
1939
|
-
interface LyricsLineEvent extends PlayerEvent {
|
|
1940
|
-
/**The lyricsline event*/
|
|
1941
|
-
type: "LyricsLineEvent";
|
|
1942
|
-
/** The guildId */
|
|
1943
|
-
guildId: string;
|
|
1944
|
-
/** The line number */
|
|
1945
|
-
lineIndex: number;
|
|
1946
|
-
/** The line */
|
|
1947
|
-
line: LyricsLine;
|
|
1948
|
-
/**skipped is true if the line was skipped */
|
|
1949
|
-
skipped: boolean;
|
|
1950
|
-
}
|
|
1951
1927
|
interface LyricsLineEvent extends PlayerEvent {
|
|
1952
1928
|
/**The lyricsline event*/
|
|
1953
1929
|
type: "LyricsLineEvent";
|
|
@@ -3040,7 +3016,7 @@ interface ManagerOptions<CustomPlayerT extends Player = Player> {
|
|
|
3040
3016
|
/** The Bot Client's Data for Authorization */
|
|
3041
3017
|
client?: BotClientOptions;
|
|
3042
3018
|
/** QueueOptions for all Queues */
|
|
3043
|
-
queueOptions?: ManagerQueueOptions
|
|
3019
|
+
queueOptions?: ManagerQueueOptions;
|
|
3044
3020
|
/** PlayerOptions for all Players */
|
|
3045
3021
|
playerOptions?: ManagerPlayerOptions<CustomPlayerT>;
|
|
3046
3022
|
/** The player class you want to use when creating a player. (can be extendable) */
|
package/dist/index.js
CHANGED
|
@@ -79,6 +79,7 @@ var DebugEvents = /* @__PURE__ */ ((DebugEvents2) => {
|
|
|
79
79
|
DebugEvents2["PlayerUpdateSuccess"] = "PlayerUpdateSuccess";
|
|
80
80
|
DebugEvents2["HeartBeatTriggered"] = "HeartBeatTriggered";
|
|
81
81
|
DebugEvents2["NoSocketOnDestroy"] = "NoSocketOnDestroy";
|
|
82
|
+
DebugEvents2["SocketCleanupError"] = "SocketCleanupError";
|
|
82
83
|
DebugEvents2["SocketTerminateHeartBeatTimeout"] = "SocketTerminateHeartBeatTimeout";
|
|
83
84
|
DebugEvents2["TryingConnectWhileConnected"] = "TryingConnectWhileConnected";
|
|
84
85
|
DebugEvents2["LavaSearchNothingFound"] = "LavaSearchNothingFound";
|
|
@@ -481,7 +482,7 @@ var SourceLinksRegexes = {
|
|
|
481
482
|
/** DEFAULT SUPPORTED BY LAVALINK */
|
|
482
483
|
YoutubeRegex: /https?:\/\/?(?:www\.)?(?:(m|www)\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|shorts|playlist\?|watch\?v=|watch\?.+(?:&|&);v=))([a-zA-Z0-9\-_]{11})?(?:(?:\?|&|&)index=((?:\d){1,3}))?(?:(?:\?|&|&)?list=([a-zA-Z\-_0-9]{34}))?(?:\S+)?/,
|
|
483
484
|
YoutubeMusicRegex: /https?:\/\/?(?:www\.)?(?:(music|m|www)\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|shorts|playlist\?|watch\?v=|watch\?.+(?:&|&);v=))([a-zA-Z0-9\-_]{11})?(?:(?:\?|&|&)index=((?:\d){1,3}))?(?:(?:\?|&|&)?list=([a-zA-Z\-_0-9]{34}))?(?:\S+)?/,
|
|
484
|
-
SoundCloudRegex: /https
|
|
485
|
+
SoundCloudRegex: /https?:\/\/(?:on\.)?soundcloud\.com\//,
|
|
485
486
|
SoundCloudMobileRegex: /https?:\/\/(soundcloud\.app\.goo\.gl)\/(\S+)/,
|
|
486
487
|
bandcamp: /https?:\/\/?(?:www\.)?([\d|\w]+)\.bandcamp\.com\/(\S+)/,
|
|
487
488
|
TwitchTv: /https?:\/\/?(?:www\.)?twitch\.tv\/\w+/,
|
|
@@ -1001,9 +1002,15 @@ async function getClosestTrack(data, player) {
|
|
|
1001
1002
|
source: sourceName !== "twitch" && sourceName !== "flowery-tts" ? sourceName : player.LavalinkManager.options?.playerOptions?.defaultSearchPlatform
|
|
1002
1003
|
}, data.requester).then((res) => {
|
|
1003
1004
|
let trackToUse = null;
|
|
1004
|
-
if (
|
|
1005
|
-
|
|
1006
|
-
|
|
1005
|
+
if ((data.info?.title || data.info?.author) && !trackToUse) trackToUse = res.tracks.find(
|
|
1006
|
+
(track) => (
|
|
1007
|
+
// find via author name (i ... case insensitve)
|
|
1008
|
+
[data.info?.author || "", `${data.info?.author} - Topic`].some((name) => new RegExp(`^${escapeRegExp(name)}$`, "i").test(track.info?.author)) || // find via title (i ... case insensitve)
|
|
1009
|
+
new RegExp(`^${escapeRegExp(data.info?.title)}$`, "i").test(track.info?.title)
|
|
1010
|
+
)
|
|
1011
|
+
);
|
|
1012
|
+
if (data.info?.isrc && !trackToUse) trackToUse = res.tracks.find((track) => track.info?.isrc === data.info?.isrc);
|
|
1013
|
+
if (data.info?.duration && !trackToUse) trackToUse = res.tracks.find((track) => track.info?.duration >= data.info?.duration - 1500 && track?.info.duration <= data.info?.duration + 1500);
|
|
1007
1014
|
return applyUnresolvedData(trackToUse || res.tracks[0], data, player.LavalinkManager.utils);
|
|
1008
1015
|
});
|
|
1009
1016
|
}
|
|
@@ -1440,8 +1447,8 @@ var LavalinkNode = class {
|
|
|
1440
1447
|
}
|
|
1441
1448
|
};
|
|
1442
1449
|
handlePlayerOperations().finally(() => {
|
|
1443
|
-
this.socket
|
|
1444
|
-
this.socket
|
|
1450
|
+
this.socket?.close(1e3, "Node-Destroy");
|
|
1451
|
+
this.socket?.removeAllListeners();
|
|
1445
1452
|
this.socket = null;
|
|
1446
1453
|
this.reconnectAttempts = 1;
|
|
1447
1454
|
clearTimeout(this.reconnectTimeout);
|
|
@@ -1455,8 +1462,8 @@ var LavalinkNode = class {
|
|
|
1455
1462
|
}
|
|
1456
1463
|
});
|
|
1457
1464
|
} else {
|
|
1458
|
-
this.socket
|
|
1459
|
-
this.socket
|
|
1465
|
+
this.socket?.close(1e3, "Node-Destroy");
|
|
1466
|
+
this.socket?.removeAllListeners();
|
|
1460
1467
|
this.socket = null;
|
|
1461
1468
|
this.reconnectAttempts = 1;
|
|
1462
1469
|
clearTimeout(this.reconnectTimeout);
|
|
@@ -1485,8 +1492,8 @@ var LavalinkNode = class {
|
|
|
1485
1492
|
*/
|
|
1486
1493
|
disconnect(disconnectReason) {
|
|
1487
1494
|
if (!this.connected) return;
|
|
1488
|
-
this.socket
|
|
1489
|
-
this.socket
|
|
1495
|
+
this.socket?.close(1e3, "Node-Disconnect");
|
|
1496
|
+
this.socket?.removeAllListeners();
|
|
1490
1497
|
this.socket = null;
|
|
1491
1498
|
this.reconnectAttempts = 1;
|
|
1492
1499
|
clearTimeout(this.reconnectTimeout);
|
|
@@ -1877,8 +1884,6 @@ var LavalinkNode = class {
|
|
|
1877
1884
|
this.NodeManager.emit("error", this, error);
|
|
1878
1885
|
return this.destroy("NodeReconnectFail" /* NodeReconnectFail */);
|
|
1879
1886
|
}
|
|
1880
|
-
this.socket.removeAllListeners();
|
|
1881
|
-
this.socket = null;
|
|
1882
1887
|
this.NodeManager.emit("reconnecting", this);
|
|
1883
1888
|
this.connect();
|
|
1884
1889
|
this.reconnectAttempts++;
|
|
@@ -1891,8 +1896,6 @@ var LavalinkNode = class {
|
|
|
1891
1896
|
this.NodeManager.emit("error", this, error);
|
|
1892
1897
|
return this.destroy("NodeReconnectFail" /* NodeReconnectFail */);
|
|
1893
1898
|
}
|
|
1894
|
-
this.socket.removeAllListeners();
|
|
1895
|
-
this.socket = null;
|
|
1896
1899
|
this.NodeManager.emit("reconnecting", this);
|
|
1897
1900
|
this.connect();
|
|
1898
1901
|
this.reconnectAttempts++;
|
|
@@ -1901,6 +1904,8 @@ var LavalinkNode = class {
|
|
|
1901
1904
|
/** @private util function for handling opening events from websocket */
|
|
1902
1905
|
async open() {
|
|
1903
1906
|
this.isAlive = true;
|
|
1907
|
+
this.reconnectAttempts = 1;
|
|
1908
|
+
if (this.reconnectTimeout) clearTimeout(this.reconnectTimeout);
|
|
1904
1909
|
if (this.options.enablePingOnStatsCheck) this.heartBeat();
|
|
1905
1910
|
if (this.heartBeatInterval) clearInterval(this.heartBeatInterval);
|
|
1906
1911
|
if (this.options.heartBeatInterval > 0) {
|
|
@@ -1916,8 +1921,6 @@ var LavalinkNode = class {
|
|
|
1916
1921
|
this.socket.ping();
|
|
1917
1922
|
}, this.options.heartBeatInterval || 3e4);
|
|
1918
1923
|
}
|
|
1919
|
-
if (this.reconnectTimeout) clearTimeout(this.reconnectTimeout);
|
|
1920
|
-
this.reconnectAttempts = 1;
|
|
1921
1924
|
this.info = await this.fetchInfo().catch((e) => (console.error(e, "ON-OPEN-FETCH"), null));
|
|
1922
1925
|
if (!this.info && ["v3", "v4"].includes(this.version)) {
|
|
1923
1926
|
const errorString = `Lavalink Node (${this.restAddress}) does not provide any /${this.version}/info`;
|
|
@@ -1928,6 +1931,21 @@ var LavalinkNode = class {
|
|
|
1928
1931
|
/** @private util function for handling closing events from websocket */
|
|
1929
1932
|
close(code, reason) {
|
|
1930
1933
|
if (this.pingTimeout) clearTimeout(this.pingTimeout);
|
|
1934
|
+
try {
|
|
1935
|
+
if (this.socket) {
|
|
1936
|
+
this.socket.removeAllListeners();
|
|
1937
|
+
this.socket = null;
|
|
1938
|
+
}
|
|
1939
|
+
} catch (e) {
|
|
1940
|
+
if (this.NodeManager?.LavalinkManager?.options?.advancedOptions?.enableDebugEvents) {
|
|
1941
|
+
this.NodeManager.LavalinkManager.emit("debug", "SocketCleanupError" /* SocketCleanupError */, {
|
|
1942
|
+
state: "warn",
|
|
1943
|
+
message: `An error occurred during socket cleanup in close() (likely a race condition): ${e.message}`,
|
|
1944
|
+
functionLayer: "LavalinkNode > close()"
|
|
1945
|
+
});
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
this.isAlive = false;
|
|
1931
1949
|
if (this.heartBeatInterval) clearInterval(this.heartBeatInterval);
|
|
1932
1950
|
if (code === 1006 && !reason) reason = "Socket got terminated due to no ping connection";
|
|
1933
1951
|
if (code === 1e3 && reason === "Node-Disconnect") return;
|
|
@@ -2697,7 +2715,7 @@ var bandCampSearch = async (player, query, requestUser) => {
|
|
|
2697
2715
|
artworkUrl: item.img,
|
|
2698
2716
|
author: item.band_name,
|
|
2699
2717
|
title: item.name,
|
|
2700
|
-
identifier: item.id ? `${item.id}` : item.url?.split("/")
|
|
2718
|
+
identifier: item.id ? `${item.id}` : item.url?.split("/")?.reverse()[0]
|
|
2701
2719
|
}, requestUser));
|
|
2702
2720
|
} catch (e) {
|
|
2703
2721
|
error = e;
|
|
@@ -3741,6 +3759,7 @@ var Queue = class {
|
|
|
3741
3759
|
* - single Track | UnresolvedTrack
|
|
3742
3760
|
* - multiple Track | UnresovedTrack
|
|
3743
3761
|
* - at the index or multiple indexes
|
|
3762
|
+
* - Since v2.7 the removed tracks get unshifted into the previous queue state instead of pushed (indexed at the start instead of end - as it should)
|
|
3744
3763
|
* @param removeQueryTrack
|
|
3745
3764
|
* @returns null (if nothing was removed) / { removed } where removed is an array with all removed elements
|
|
3746
3765
|
*
|
|
@@ -3786,9 +3805,10 @@ var Queue = class {
|
|
|
3786
3805
|
if (Array.isArray(removeQueryTrack)) {
|
|
3787
3806
|
if (removeQueryTrack.every((v) => typeof v === "number")) {
|
|
3788
3807
|
const removed3 = [];
|
|
3789
|
-
|
|
3808
|
+
const sortedIndexes = removeQueryTrack.sort((a, b) => b - a);
|
|
3809
|
+
for (const i of sortedIndexes) {
|
|
3790
3810
|
if (this.tracks[i]) {
|
|
3791
|
-
removed3.
|
|
3811
|
+
removed3.unshift(...this.tracks.splice(i, 1));
|
|
3792
3812
|
}
|
|
3793
3813
|
}
|
|
3794
3814
|
if (!removed3.length) return null;
|
|
@@ -3804,9 +3824,10 @@ var Queue = class {
|
|
|
3804
3824
|
));
|
|
3805
3825
|
if (!tracksToRemove.length) return null;
|
|
3806
3826
|
const removed2 = [];
|
|
3827
|
+
tracksToRemove.sort((a, b) => b.i - a.i);
|
|
3807
3828
|
for (const { i } of tracksToRemove) {
|
|
3808
3829
|
if (this.tracks[i]) {
|
|
3809
|
-
removed2.
|
|
3830
|
+
removed2.unshift(...this.tracks.splice(i, 1));
|
|
3810
3831
|
}
|
|
3811
3832
|
}
|
|
3812
3833
|
if (typeof this.queueChanges?.tracksRemoved === "function") try {
|
|
@@ -4029,7 +4050,7 @@ var Player = class {
|
|
|
4029
4050
|
this.queue.current = options.clientTrack || null;
|
|
4030
4051
|
this.queue.utils.save();
|
|
4031
4052
|
if (typeof options?.volume === "number" && !isNaN(options?.volume)) {
|
|
4032
|
-
this.volume = Math.max(Math.min(options?.volume,
|
|
4053
|
+
this.volume = Math.max(Math.min(options?.volume, 1e3), 0);
|
|
4033
4054
|
let vol = Number(this.volume);
|
|
4034
4055
|
if (this.LavalinkManager.options.playerOptions.volumeDecrementer) vol *= this.LavalinkManager.options.playerOptions.volumeDecrementer;
|
|
4035
4056
|
this.lavalinkVolume = Math.round(vol);
|
|
@@ -4099,7 +4120,7 @@ var Player = class {
|
|
|
4099
4120
|
}
|
|
4100
4121
|
if (!this.queue.current) throw new Error(`There is no Track in the Queue, nor provided in the PlayOptions`);
|
|
4101
4122
|
if (typeof options?.volume === "number" && !isNaN(options?.volume)) {
|
|
4102
|
-
this.volume = Math.max(Math.min(options?.volume,
|
|
4123
|
+
this.volume = Math.max(Math.min(options?.volume, 1e3), 0);
|
|
4103
4124
|
let vol = Number(this.volume);
|
|
4104
4125
|
if (this.LavalinkManager.options.playerOptions.volumeDecrementer) vol *= this.LavalinkManager.options.playerOptions.volumeDecrementer;
|
|
4105
4126
|
this.lavalinkVolume = Math.round(vol);
|
|
@@ -4122,9 +4143,9 @@ var Player = class {
|
|
|
4122
4143
|
paused: options?.paused ?? void 0,
|
|
4123
4144
|
voice: options?.voice ?? void 0
|
|
4124
4145
|
}).filter((v) => typeof v[1] !== "undefined"));
|
|
4125
|
-
if (typeof finalOptions.position !== "undefined" && isNaN(finalOptions.position) || typeof finalOptions.position === "number" &&
|
|
4146
|
+
if (typeof finalOptions.position !== "undefined" && isNaN(finalOptions.position) || typeof finalOptions.position === "number" && finalOptions.position < 0 || typeof finalOptions.position === "number" && this.queue.current.info.duration > 0 && finalOptions.position >= this.queue.current.info.duration) throw new Error("PlayerOption#position must be a positive number, less than track's duration");
|
|
4126
4147
|
if (typeof finalOptions.volume !== "undefined" && isNaN(finalOptions.volume) || typeof finalOptions.volume === "number" && finalOptions.volume < 0) throw new Error("PlayerOption#volume must be a positive number");
|
|
4127
|
-
if (typeof finalOptions.endTime !== "undefined" && isNaN(finalOptions.endTime) || typeof finalOptions.endTime === "number" &&
|
|
4148
|
+
if (typeof finalOptions.endTime !== "undefined" && isNaN(finalOptions.endTime) || typeof finalOptions.endTime === "number" && finalOptions.endTime < 0 || typeof finalOptions.endTime === "number" && this.queue.current.info.duration > 0 && finalOptions.endTime >= this.queue.current.info.duration) throw new Error("PlayerOption#endTime must be a positive number, less than track's duration");
|
|
4128
4149
|
if (typeof finalOptions.position === "number" && typeof finalOptions.endTime === "number" && finalOptions.endTime < finalOptions.position) throw new Error("PlayerOption#endTime must be bigger than PlayerOption#position");
|
|
4129
4150
|
const now = performance.now();
|
|
4130
4151
|
await this.node.updatePlayer({
|
|
@@ -4199,7 +4220,7 @@ var Player = class {
|
|
|
4199
4220
|
*/
|
|
4200
4221
|
async search(query, requestUser, throwOnEmpty = false) {
|
|
4201
4222
|
const Query = this.LavalinkManager.utils.transformQuery(query);
|
|
4202
|
-
if (["bcsearch", "bandcamp"].includes(Query.source) && !this.node.info
|
|
4223
|
+
if (["bcsearch", "bandcamp"].includes(Query.source) && !this.node.info?.sourceManagers.includes("bandcamp")) {
|
|
4203
4224
|
if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
|
|
4204
4225
|
this.LavalinkManager.emit("debug", "BandcampSearchLokalEngine" /* BandcampSearchLokalEngine */, {
|
|
4205
4226
|
state: "log",
|
|
@@ -4454,7 +4475,7 @@ var Player = class {
|
|
|
4454
4475
|
if (this.queue.current || this.queue.tracks.length) {
|
|
4455
4476
|
const trackSources = new Set([this.queue.current, ...this.queue.tracks].map((track) => track.info.sourceName));
|
|
4456
4477
|
const missingSources = [...trackSources].filter(
|
|
4457
|
-
(source) => !updateNode.info
|
|
4478
|
+
(source) => !updateNode.info?.sourceManagers.includes(source)
|
|
4458
4479
|
);
|
|
4459
4480
|
if (missingSources.length)
|
|
4460
4481
|
throw new RangeError(`Sources missing for Node ${updateNode.id}: ${missingSources.join(", ")}`);
|
|
@@ -4876,7 +4897,7 @@ var LavalinkManager = class extends import_events2.EventEmitter {
|
|
|
4876
4897
|
deletePlayer(guildId) {
|
|
4877
4898
|
const oldPlayer = this.getPlayer(guildId);
|
|
4878
4899
|
if (!oldPlayer) return;
|
|
4879
|
-
if (oldPlayer.voiceChannelId === "string" && oldPlayer.connected && !oldPlayer.get("internal_destroywithoutdisconnect")) {
|
|
4900
|
+
if (typeof oldPlayer.voiceChannelId === "string" && oldPlayer.connected && !oldPlayer.get("internal_destroywithoutdisconnect")) {
|
|
4880
4901
|
if (!this.options?.advancedOptions?.debugOptions?.playerDestroy?.dontThrowError) throw new Error(`Use Player#destroy() not LavalinkManager#deletePlayer() to stop the Player ${safeStringify(oldPlayer.toJSON?.())}`);
|
|
4881
4902
|
else if (this.options?.advancedOptions?.enableDebugEvents) {
|
|
4882
4903
|
this.emit("debug", "PlayerDeleteInsteadOfDestroy" /* PlayerDeleteInsteadOfDestroy */, {
|
|
@@ -5139,6 +5160,7 @@ var LavalinkManager = class extends import_events2.EventEmitter {
|
|
|
5139
5160
|
message: `Auto reconnected, but nothing to play`,
|
|
5140
5161
|
functionLayer: "LavalinkManager > sendRawData()"
|
|
5141
5162
|
});
|
|
5163
|
+
return;
|
|
5142
5164
|
} catch (e) {
|
|
5143
5165
|
console.error(e);
|
|
5144
5166
|
return void await player.destroy("PlayerReconnectFail" /* PlayerReconnectFail */);
|
package/dist/index.mjs
CHANGED
|
@@ -19,6 +19,7 @@ var DebugEvents = /* @__PURE__ */ ((DebugEvents2) => {
|
|
|
19
19
|
DebugEvents2["PlayerUpdateSuccess"] = "PlayerUpdateSuccess";
|
|
20
20
|
DebugEvents2["HeartBeatTriggered"] = "HeartBeatTriggered";
|
|
21
21
|
DebugEvents2["NoSocketOnDestroy"] = "NoSocketOnDestroy";
|
|
22
|
+
DebugEvents2["SocketCleanupError"] = "SocketCleanupError";
|
|
22
23
|
DebugEvents2["SocketTerminateHeartBeatTimeout"] = "SocketTerminateHeartBeatTimeout";
|
|
23
24
|
DebugEvents2["TryingConnectWhileConnected"] = "TryingConnectWhileConnected";
|
|
24
25
|
DebugEvents2["LavaSearchNothingFound"] = "LavaSearchNothingFound";
|
|
@@ -421,7 +422,7 @@ var SourceLinksRegexes = {
|
|
|
421
422
|
/** DEFAULT SUPPORTED BY LAVALINK */
|
|
422
423
|
YoutubeRegex: /https?:\/\/?(?:www\.)?(?:(m|www)\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|shorts|playlist\?|watch\?v=|watch\?.+(?:&|&);v=))([a-zA-Z0-9\-_]{11})?(?:(?:\?|&|&)index=((?:\d){1,3}))?(?:(?:\?|&|&)?list=([a-zA-Z\-_0-9]{34}))?(?:\S+)?/,
|
|
423
424
|
YoutubeMusicRegex: /https?:\/\/?(?:www\.)?(?:(music|m|www)\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|shorts|playlist\?|watch\?v=|watch\?.+(?:&|&);v=))([a-zA-Z0-9\-_]{11})?(?:(?:\?|&|&)index=((?:\d){1,3}))?(?:(?:\?|&|&)?list=([a-zA-Z\-_0-9]{34}))?(?:\S+)?/,
|
|
424
|
-
SoundCloudRegex: /https
|
|
425
|
+
SoundCloudRegex: /https?:\/\/(?:on\.)?soundcloud\.com\//,
|
|
425
426
|
SoundCloudMobileRegex: /https?:\/\/(soundcloud\.app\.goo\.gl)\/(\S+)/,
|
|
426
427
|
bandcamp: /https?:\/\/?(?:www\.)?([\d|\w]+)\.bandcamp\.com\/(\S+)/,
|
|
427
428
|
TwitchTv: /https?:\/\/?(?:www\.)?twitch\.tv\/\w+/,
|
|
@@ -941,9 +942,15 @@ async function getClosestTrack(data, player) {
|
|
|
941
942
|
source: sourceName !== "twitch" && sourceName !== "flowery-tts" ? sourceName : player.LavalinkManager.options?.playerOptions?.defaultSearchPlatform
|
|
942
943
|
}, data.requester).then((res) => {
|
|
943
944
|
let trackToUse = null;
|
|
944
|
-
if (
|
|
945
|
-
|
|
946
|
-
|
|
945
|
+
if ((data.info?.title || data.info?.author) && !trackToUse) trackToUse = res.tracks.find(
|
|
946
|
+
(track) => (
|
|
947
|
+
// find via author name (i ... case insensitve)
|
|
948
|
+
[data.info?.author || "", `${data.info?.author} - Topic`].some((name) => new RegExp(`^${escapeRegExp(name)}$`, "i").test(track.info?.author)) || // find via title (i ... case insensitve)
|
|
949
|
+
new RegExp(`^${escapeRegExp(data.info?.title)}$`, "i").test(track.info?.title)
|
|
950
|
+
)
|
|
951
|
+
);
|
|
952
|
+
if (data.info?.isrc && !trackToUse) trackToUse = res.tracks.find((track) => track.info?.isrc === data.info?.isrc);
|
|
953
|
+
if (data.info?.duration && !trackToUse) trackToUse = res.tracks.find((track) => track.info?.duration >= data.info?.duration - 1500 && track?.info.duration <= data.info?.duration + 1500);
|
|
947
954
|
return applyUnresolvedData(trackToUse || res.tracks[0], data, player.LavalinkManager.utils);
|
|
948
955
|
});
|
|
949
956
|
}
|
|
@@ -1380,8 +1387,8 @@ var LavalinkNode = class {
|
|
|
1380
1387
|
}
|
|
1381
1388
|
};
|
|
1382
1389
|
handlePlayerOperations().finally(() => {
|
|
1383
|
-
this.socket
|
|
1384
|
-
this.socket
|
|
1390
|
+
this.socket?.close(1e3, "Node-Destroy");
|
|
1391
|
+
this.socket?.removeAllListeners();
|
|
1385
1392
|
this.socket = null;
|
|
1386
1393
|
this.reconnectAttempts = 1;
|
|
1387
1394
|
clearTimeout(this.reconnectTimeout);
|
|
@@ -1395,8 +1402,8 @@ var LavalinkNode = class {
|
|
|
1395
1402
|
}
|
|
1396
1403
|
});
|
|
1397
1404
|
} else {
|
|
1398
|
-
this.socket
|
|
1399
|
-
this.socket
|
|
1405
|
+
this.socket?.close(1e3, "Node-Destroy");
|
|
1406
|
+
this.socket?.removeAllListeners();
|
|
1400
1407
|
this.socket = null;
|
|
1401
1408
|
this.reconnectAttempts = 1;
|
|
1402
1409
|
clearTimeout(this.reconnectTimeout);
|
|
@@ -1425,8 +1432,8 @@ var LavalinkNode = class {
|
|
|
1425
1432
|
*/
|
|
1426
1433
|
disconnect(disconnectReason) {
|
|
1427
1434
|
if (!this.connected) return;
|
|
1428
|
-
this.socket
|
|
1429
|
-
this.socket
|
|
1435
|
+
this.socket?.close(1e3, "Node-Disconnect");
|
|
1436
|
+
this.socket?.removeAllListeners();
|
|
1430
1437
|
this.socket = null;
|
|
1431
1438
|
this.reconnectAttempts = 1;
|
|
1432
1439
|
clearTimeout(this.reconnectTimeout);
|
|
@@ -1817,8 +1824,6 @@ var LavalinkNode = class {
|
|
|
1817
1824
|
this.NodeManager.emit("error", this, error);
|
|
1818
1825
|
return this.destroy("NodeReconnectFail" /* NodeReconnectFail */);
|
|
1819
1826
|
}
|
|
1820
|
-
this.socket.removeAllListeners();
|
|
1821
|
-
this.socket = null;
|
|
1822
1827
|
this.NodeManager.emit("reconnecting", this);
|
|
1823
1828
|
this.connect();
|
|
1824
1829
|
this.reconnectAttempts++;
|
|
@@ -1831,8 +1836,6 @@ var LavalinkNode = class {
|
|
|
1831
1836
|
this.NodeManager.emit("error", this, error);
|
|
1832
1837
|
return this.destroy("NodeReconnectFail" /* NodeReconnectFail */);
|
|
1833
1838
|
}
|
|
1834
|
-
this.socket.removeAllListeners();
|
|
1835
|
-
this.socket = null;
|
|
1836
1839
|
this.NodeManager.emit("reconnecting", this);
|
|
1837
1840
|
this.connect();
|
|
1838
1841
|
this.reconnectAttempts++;
|
|
@@ -1841,6 +1844,8 @@ var LavalinkNode = class {
|
|
|
1841
1844
|
/** @private util function for handling opening events from websocket */
|
|
1842
1845
|
async open() {
|
|
1843
1846
|
this.isAlive = true;
|
|
1847
|
+
this.reconnectAttempts = 1;
|
|
1848
|
+
if (this.reconnectTimeout) clearTimeout(this.reconnectTimeout);
|
|
1844
1849
|
if (this.options.enablePingOnStatsCheck) this.heartBeat();
|
|
1845
1850
|
if (this.heartBeatInterval) clearInterval(this.heartBeatInterval);
|
|
1846
1851
|
if (this.options.heartBeatInterval > 0) {
|
|
@@ -1856,8 +1861,6 @@ var LavalinkNode = class {
|
|
|
1856
1861
|
this.socket.ping();
|
|
1857
1862
|
}, this.options.heartBeatInterval || 3e4);
|
|
1858
1863
|
}
|
|
1859
|
-
if (this.reconnectTimeout) clearTimeout(this.reconnectTimeout);
|
|
1860
|
-
this.reconnectAttempts = 1;
|
|
1861
1864
|
this.info = await this.fetchInfo().catch((e) => (console.error(e, "ON-OPEN-FETCH"), null));
|
|
1862
1865
|
if (!this.info && ["v3", "v4"].includes(this.version)) {
|
|
1863
1866
|
const errorString = `Lavalink Node (${this.restAddress}) does not provide any /${this.version}/info`;
|
|
@@ -1868,6 +1871,21 @@ var LavalinkNode = class {
|
|
|
1868
1871
|
/** @private util function for handling closing events from websocket */
|
|
1869
1872
|
close(code, reason) {
|
|
1870
1873
|
if (this.pingTimeout) clearTimeout(this.pingTimeout);
|
|
1874
|
+
try {
|
|
1875
|
+
if (this.socket) {
|
|
1876
|
+
this.socket.removeAllListeners();
|
|
1877
|
+
this.socket = null;
|
|
1878
|
+
}
|
|
1879
|
+
} catch (e) {
|
|
1880
|
+
if (this.NodeManager?.LavalinkManager?.options?.advancedOptions?.enableDebugEvents) {
|
|
1881
|
+
this.NodeManager.LavalinkManager.emit("debug", "SocketCleanupError" /* SocketCleanupError */, {
|
|
1882
|
+
state: "warn",
|
|
1883
|
+
message: `An error occurred during socket cleanup in close() (likely a race condition): ${e.message}`,
|
|
1884
|
+
functionLayer: "LavalinkNode > close()"
|
|
1885
|
+
});
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
this.isAlive = false;
|
|
1871
1889
|
if (this.heartBeatInterval) clearInterval(this.heartBeatInterval);
|
|
1872
1890
|
if (code === 1006 && !reason) reason = "Socket got terminated due to no ping connection";
|
|
1873
1891
|
if (code === 1e3 && reason === "Node-Disconnect") return;
|
|
@@ -2637,7 +2655,7 @@ var bandCampSearch = async (player, query, requestUser) => {
|
|
|
2637
2655
|
artworkUrl: item.img,
|
|
2638
2656
|
author: item.band_name,
|
|
2639
2657
|
title: item.name,
|
|
2640
|
-
identifier: item.id ? `${item.id}` : item.url?.split("/")
|
|
2658
|
+
identifier: item.id ? `${item.id}` : item.url?.split("/")?.reverse()[0]
|
|
2641
2659
|
}, requestUser));
|
|
2642
2660
|
} catch (e) {
|
|
2643
2661
|
error = e;
|
|
@@ -3681,6 +3699,7 @@ var Queue = class {
|
|
|
3681
3699
|
* - single Track | UnresolvedTrack
|
|
3682
3700
|
* - multiple Track | UnresovedTrack
|
|
3683
3701
|
* - at the index or multiple indexes
|
|
3702
|
+
* - Since v2.7 the removed tracks get unshifted into the previous queue state instead of pushed (indexed at the start instead of end - as it should)
|
|
3684
3703
|
* @param removeQueryTrack
|
|
3685
3704
|
* @returns null (if nothing was removed) / { removed } where removed is an array with all removed elements
|
|
3686
3705
|
*
|
|
@@ -3726,9 +3745,10 @@ var Queue = class {
|
|
|
3726
3745
|
if (Array.isArray(removeQueryTrack)) {
|
|
3727
3746
|
if (removeQueryTrack.every((v) => typeof v === "number")) {
|
|
3728
3747
|
const removed3 = [];
|
|
3729
|
-
|
|
3748
|
+
const sortedIndexes = removeQueryTrack.sort((a, b) => b - a);
|
|
3749
|
+
for (const i of sortedIndexes) {
|
|
3730
3750
|
if (this.tracks[i]) {
|
|
3731
|
-
removed3.
|
|
3751
|
+
removed3.unshift(...this.tracks.splice(i, 1));
|
|
3732
3752
|
}
|
|
3733
3753
|
}
|
|
3734
3754
|
if (!removed3.length) return null;
|
|
@@ -3744,9 +3764,10 @@ var Queue = class {
|
|
|
3744
3764
|
));
|
|
3745
3765
|
if (!tracksToRemove.length) return null;
|
|
3746
3766
|
const removed2 = [];
|
|
3767
|
+
tracksToRemove.sort((a, b) => b.i - a.i);
|
|
3747
3768
|
for (const { i } of tracksToRemove) {
|
|
3748
3769
|
if (this.tracks[i]) {
|
|
3749
|
-
removed2.
|
|
3770
|
+
removed2.unshift(...this.tracks.splice(i, 1));
|
|
3750
3771
|
}
|
|
3751
3772
|
}
|
|
3752
3773
|
if (typeof this.queueChanges?.tracksRemoved === "function") try {
|
|
@@ -3969,7 +3990,7 @@ var Player = class {
|
|
|
3969
3990
|
this.queue.current = options.clientTrack || null;
|
|
3970
3991
|
this.queue.utils.save();
|
|
3971
3992
|
if (typeof options?.volume === "number" && !isNaN(options?.volume)) {
|
|
3972
|
-
this.volume = Math.max(Math.min(options?.volume,
|
|
3993
|
+
this.volume = Math.max(Math.min(options?.volume, 1e3), 0);
|
|
3973
3994
|
let vol = Number(this.volume);
|
|
3974
3995
|
if (this.LavalinkManager.options.playerOptions.volumeDecrementer) vol *= this.LavalinkManager.options.playerOptions.volumeDecrementer;
|
|
3975
3996
|
this.lavalinkVolume = Math.round(vol);
|
|
@@ -4039,7 +4060,7 @@ var Player = class {
|
|
|
4039
4060
|
}
|
|
4040
4061
|
if (!this.queue.current) throw new Error(`There is no Track in the Queue, nor provided in the PlayOptions`);
|
|
4041
4062
|
if (typeof options?.volume === "number" && !isNaN(options?.volume)) {
|
|
4042
|
-
this.volume = Math.max(Math.min(options?.volume,
|
|
4063
|
+
this.volume = Math.max(Math.min(options?.volume, 1e3), 0);
|
|
4043
4064
|
let vol = Number(this.volume);
|
|
4044
4065
|
if (this.LavalinkManager.options.playerOptions.volumeDecrementer) vol *= this.LavalinkManager.options.playerOptions.volumeDecrementer;
|
|
4045
4066
|
this.lavalinkVolume = Math.round(vol);
|
|
@@ -4062,9 +4083,9 @@ var Player = class {
|
|
|
4062
4083
|
paused: options?.paused ?? void 0,
|
|
4063
4084
|
voice: options?.voice ?? void 0
|
|
4064
4085
|
}).filter((v) => typeof v[1] !== "undefined"));
|
|
4065
|
-
if (typeof finalOptions.position !== "undefined" && isNaN(finalOptions.position) || typeof finalOptions.position === "number" &&
|
|
4086
|
+
if (typeof finalOptions.position !== "undefined" && isNaN(finalOptions.position) || typeof finalOptions.position === "number" && finalOptions.position < 0 || typeof finalOptions.position === "number" && this.queue.current.info.duration > 0 && finalOptions.position >= this.queue.current.info.duration) throw new Error("PlayerOption#position must be a positive number, less than track's duration");
|
|
4066
4087
|
if (typeof finalOptions.volume !== "undefined" && isNaN(finalOptions.volume) || typeof finalOptions.volume === "number" && finalOptions.volume < 0) throw new Error("PlayerOption#volume must be a positive number");
|
|
4067
|
-
if (typeof finalOptions.endTime !== "undefined" && isNaN(finalOptions.endTime) || typeof finalOptions.endTime === "number" &&
|
|
4088
|
+
if (typeof finalOptions.endTime !== "undefined" && isNaN(finalOptions.endTime) || typeof finalOptions.endTime === "number" && finalOptions.endTime < 0 || typeof finalOptions.endTime === "number" && this.queue.current.info.duration > 0 && finalOptions.endTime >= this.queue.current.info.duration) throw new Error("PlayerOption#endTime must be a positive number, less than track's duration");
|
|
4068
4089
|
if (typeof finalOptions.position === "number" && typeof finalOptions.endTime === "number" && finalOptions.endTime < finalOptions.position) throw new Error("PlayerOption#endTime must be bigger than PlayerOption#position");
|
|
4069
4090
|
const now = performance.now();
|
|
4070
4091
|
await this.node.updatePlayer({
|
|
@@ -4139,7 +4160,7 @@ var Player = class {
|
|
|
4139
4160
|
*/
|
|
4140
4161
|
async search(query, requestUser, throwOnEmpty = false) {
|
|
4141
4162
|
const Query = this.LavalinkManager.utils.transformQuery(query);
|
|
4142
|
-
if (["bcsearch", "bandcamp"].includes(Query.source) && !this.node.info
|
|
4163
|
+
if (["bcsearch", "bandcamp"].includes(Query.source) && !this.node.info?.sourceManagers.includes("bandcamp")) {
|
|
4143
4164
|
if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
|
|
4144
4165
|
this.LavalinkManager.emit("debug", "BandcampSearchLokalEngine" /* BandcampSearchLokalEngine */, {
|
|
4145
4166
|
state: "log",
|
|
@@ -4394,7 +4415,7 @@ var Player = class {
|
|
|
4394
4415
|
if (this.queue.current || this.queue.tracks.length) {
|
|
4395
4416
|
const trackSources = new Set([this.queue.current, ...this.queue.tracks].map((track) => track.info.sourceName));
|
|
4396
4417
|
const missingSources = [...trackSources].filter(
|
|
4397
|
-
(source) => !updateNode.info
|
|
4418
|
+
(source) => !updateNode.info?.sourceManagers.includes(source)
|
|
4398
4419
|
);
|
|
4399
4420
|
if (missingSources.length)
|
|
4400
4421
|
throw new RangeError(`Sources missing for Node ${updateNode.id}: ${missingSources.join(", ")}`);
|
|
@@ -4816,7 +4837,7 @@ var LavalinkManager = class extends EventEmitter2 {
|
|
|
4816
4837
|
deletePlayer(guildId) {
|
|
4817
4838
|
const oldPlayer = this.getPlayer(guildId);
|
|
4818
4839
|
if (!oldPlayer) return;
|
|
4819
|
-
if (oldPlayer.voiceChannelId === "string" && oldPlayer.connected && !oldPlayer.get("internal_destroywithoutdisconnect")) {
|
|
4840
|
+
if (typeof oldPlayer.voiceChannelId === "string" && oldPlayer.connected && !oldPlayer.get("internal_destroywithoutdisconnect")) {
|
|
4820
4841
|
if (!this.options?.advancedOptions?.debugOptions?.playerDestroy?.dontThrowError) throw new Error(`Use Player#destroy() not LavalinkManager#deletePlayer() to stop the Player ${safeStringify(oldPlayer.toJSON?.())}`);
|
|
4821
4842
|
else if (this.options?.advancedOptions?.enableDebugEvents) {
|
|
4822
4843
|
this.emit("debug", "PlayerDeleteInsteadOfDestroy" /* PlayerDeleteInsteadOfDestroy */, {
|
|
@@ -5079,6 +5100,7 @@ var LavalinkManager = class extends EventEmitter2 {
|
|
|
5079
5100
|
message: `Auto reconnected, but nothing to play`,
|
|
5080
5101
|
functionLayer: "LavalinkManager > sendRawData()"
|
|
5081
5102
|
});
|
|
5103
|
+
return;
|
|
5082
5104
|
} catch (e) {
|
|
5083
5105
|
console.error(e);
|
|
5084
5106
|
return void await player.destroy("PlayerReconnectFail" /* PlayerReconnectFail */);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lavalink-client",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "Easy, flexible and feature-rich lavalink@v4 Client. Both for Beginners and Proficients.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -57,12 +57,12 @@
|
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@eslint/eslintrc": "^3.3.1",
|
|
59
59
|
"@eslint/js": "^9.39.1",
|
|
60
|
-
"@types/node": "^24.10.
|
|
60
|
+
"@types/node": "^24.10.1",
|
|
61
61
|
"@types/ws": "^8.18.1",
|
|
62
|
-
"@typescript-eslint/eslint-plugin": "^8.46.
|
|
63
|
-
"@typescript-eslint/parser": "^8.46.
|
|
62
|
+
"@typescript-eslint/eslint-plugin": "^8.46.4",
|
|
63
|
+
"@typescript-eslint/parser": "^8.46.4",
|
|
64
64
|
"eslint": "^9.39.1",
|
|
65
|
-
"tsup": "^8.5.
|
|
65
|
+
"tsup": "^8.5.1",
|
|
66
66
|
"typescript": "^5.9.3"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|