magmastream 2.9.1-dev.2 → 2.9.1-dev.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +31 -11
- package/dist/statestorage/JsonQueue.js +4 -3
- package/dist/statestorage/MemoryQueue.js +5 -4
- package/dist/statestorage/RedisQueue.js +4 -3
- package/dist/structures/Manager.js +61 -53
- package/dist/structures/Node.js +17 -17
- package/dist/structures/Player.js +11 -14
- package/dist/structures/Rest.js +4 -3
- package/dist/structures/Utils.js +36 -35
- package/dist/wrappers/detritus.js +16 -0
- package/dist/wrappers/discord.js.js +13 -0
- package/dist/wrappers/eris.js +10 -0
- package/dist/wrappers/oceanic.js +10 -0
- package/dist/wrappers/seyfert.js +15 -3
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Collection } from '@discordjs/collection';
|
|
2
2
|
import { GatewayVoiceStateUpdate } from 'discord-api-types/v10';
|
|
3
3
|
import { EventEmitter } from 'events';
|
|
4
|
-
import { User, ClientUser,
|
|
4
|
+
import { Message, User, ClientUser, Client } from 'discord.js';
|
|
5
5
|
import WebSocket$1, { WebSocket } from 'ws';
|
|
6
6
|
import { Redis } from 'ioredis';
|
|
7
|
-
import { Client as Client$1 } from 'eris';
|
|
7
|
+
import { Client as Client$1, User as User$1 } from 'eris';
|
|
8
8
|
import { ClusterClient, ShardClient } from 'detritus-client';
|
|
9
|
-
import { Client as Client$2 } from 'oceanic.js';
|
|
10
|
-
import { Client as Client$3, WorkerClient } from 'seyfert';
|
|
9
|
+
import { Client as Client$2, User as User$2 } from 'oceanic.js';
|
|
10
|
+
import { Client as Client$3, WorkerClient, User as User$3 } from 'seyfert';
|
|
11
11
|
|
|
12
12
|
/** Represents an equalizer band. */
|
|
13
13
|
interface Band {
|
|
@@ -897,6 +897,13 @@ interface NodeOptions {
|
|
|
897
897
|
*/
|
|
898
898
|
isBackup?: boolean;
|
|
899
899
|
}
|
|
900
|
+
/**
|
|
901
|
+
* Portable User
|
|
902
|
+
*/
|
|
903
|
+
interface PortableUser {
|
|
904
|
+
id: string;
|
|
905
|
+
username?: string;
|
|
906
|
+
}
|
|
900
907
|
/**
|
|
901
908
|
* Discord Packet
|
|
902
909
|
*/
|
|
@@ -1102,7 +1109,7 @@ interface Track {
|
|
|
1102
1109
|
/** The thumbnail of the track or null if it's a unsupported source. */
|
|
1103
1110
|
readonly thumbnail: string | null;
|
|
1104
1111
|
/** The user that requested the track. */
|
|
1105
|
-
requester?:
|
|
1112
|
+
requester?: PortableUser;
|
|
1106
1113
|
/** Displays the track thumbnail with optional size or null if it's a unsupported source. */
|
|
1107
1114
|
displayThumbnail(size?: Sizes): string;
|
|
1108
1115
|
/** Additional track info provided by plugins. */
|
|
@@ -1287,7 +1294,7 @@ interface PlaylistData {
|
|
|
1287
1294
|
/** The playlist name. */
|
|
1288
1295
|
name: string;
|
|
1289
1296
|
/** Requester of playlist. */
|
|
1290
|
-
requester:
|
|
1297
|
+
requester: PortableUser;
|
|
1291
1298
|
/** More playlist information. */
|
|
1292
1299
|
playlistInfo: PlaylistInfoData[];
|
|
1293
1300
|
/** The length of the playlist. */
|
|
@@ -2103,12 +2110,12 @@ declare class Player {
|
|
|
2103
2110
|
* track when the current track ends.
|
|
2104
2111
|
*
|
|
2105
2112
|
* @param {boolean} autoplayState - Whether or not autoplay should be enabled.
|
|
2106
|
-
* @param {object}
|
|
2113
|
+
* @param {object} AutoplayUser - The user-object that should be used as the bot-user.
|
|
2107
2114
|
* @param {number} [tries=3] - The number of times the player should try to find a
|
|
2108
2115
|
* recommended track if the first one doesn't work.
|
|
2109
2116
|
* @returns {this} - The player instance.
|
|
2110
2117
|
*/
|
|
2111
|
-
setAutoplay<T = unknown>(autoplayState: boolean,
|
|
2118
|
+
setAutoplay<T = unknown>(autoplayState: boolean, AutoplayUser?: T, tries?: number): this;
|
|
2112
2119
|
/**
|
|
2113
2120
|
* Gets recommended tracks and returns an array of tracks.
|
|
2114
2121
|
* @param {Track} track - The track to find recommendations for.
|
|
@@ -2998,6 +3005,11 @@ declare class Manager extends EventEmitter {
|
|
|
2998
3005
|
private get priorityNode();
|
|
2999
3006
|
protected send(packet: GatewayVoiceStateUpdate): unknown;
|
|
3000
3007
|
sendPacket(packet: GatewayVoiceStateUpdate): unknown;
|
|
3008
|
+
/**
|
|
3009
|
+
* Resolves a PortableUser or ID to a real user object.
|
|
3010
|
+
* Can be overridden by wrapper managers to return wrapper-specific User classes.
|
|
3011
|
+
*/
|
|
3012
|
+
resolveUser(user: PortableUser | string): Promise<PortableUser>;
|
|
3001
3013
|
}
|
|
3002
3014
|
|
|
3003
3015
|
declare class Filters {
|
|
@@ -3376,7 +3388,7 @@ declare abstract class TrackUtils {
|
|
|
3376
3388
|
* @param requester The user who requested the track, if any.
|
|
3377
3389
|
* @returns The built Track.
|
|
3378
3390
|
*/
|
|
3379
|
-
static build<T = User | ClientUser>(data: TrackData, requester?: T): Track;
|
|
3391
|
+
static build<T = PortableUser | User | ClientUser>(data: TrackData, requester?: T): Track;
|
|
3380
3392
|
/**
|
|
3381
3393
|
* Validates a search result.
|
|
3382
3394
|
* @param result The search result to validate.
|
|
@@ -3487,6 +3499,9 @@ declare abstract class Structure {
|
|
|
3487
3499
|
*/
|
|
3488
3500
|
static get<K extends keyof Extendable>(name: K): Extendable[K];
|
|
3489
3501
|
}
|
|
3502
|
+
declare abstract class JSONUtils {
|
|
3503
|
+
static safe<T>(obj: T, space?: number): string;
|
|
3504
|
+
}
|
|
3490
3505
|
|
|
3491
3506
|
/**
|
|
3492
3507
|
* Discord.js wrapper for Magmastream.
|
|
@@ -3495,6 +3510,7 @@ declare class DiscordJSManager extends Manager {
|
|
|
3495
3510
|
readonly client: Client;
|
|
3496
3511
|
constructor(client: Client, options?: ManagerOptions);
|
|
3497
3512
|
protected send(packet: GatewayVoiceStateUpdate): void;
|
|
3513
|
+
resolveUser(user: PortableUser | string): Promise<User | PortableUser>;
|
|
3498
3514
|
}
|
|
3499
3515
|
|
|
3500
3516
|
/**
|
|
@@ -3504,6 +3520,7 @@ declare class ErisManager extends Manager {
|
|
|
3504
3520
|
readonly client: Client$1;
|
|
3505
3521
|
constructor(client: Client$1, options?: ManagerOptions);
|
|
3506
3522
|
protected send(packet: GatewayVoiceStateUpdate): void;
|
|
3523
|
+
resolveUser(user: PortableUser | string): Promise<User$1 | PortableUser>;
|
|
3507
3524
|
}
|
|
3508
3525
|
|
|
3509
3526
|
/**
|
|
@@ -3513,6 +3530,7 @@ declare class DetritusManager extends Manager {
|
|
|
3513
3530
|
readonly client: ClusterClient | ShardClient;
|
|
3514
3531
|
constructor(client: ClusterClient | ShardClient, options?: ManagerOptions);
|
|
3515
3532
|
protected send(packet: GatewayVoiceStateUpdate): void;
|
|
3533
|
+
resolveUser(user: PortableUser | string): Promise<PortableUser>;
|
|
3516
3534
|
}
|
|
3517
3535
|
|
|
3518
3536
|
/**
|
|
@@ -3522,6 +3540,7 @@ declare class OceanicManager extends Manager {
|
|
|
3522
3540
|
readonly client: Client$2;
|
|
3523
3541
|
constructor(client: Client$2, options?: ManagerOptions);
|
|
3524
3542
|
protected send(packet: GatewayVoiceStateUpdate): void;
|
|
3543
|
+
resolveUser(user: PortableUser | string): Promise<User$2 | PortableUser>;
|
|
3525
3544
|
}
|
|
3526
3545
|
|
|
3527
3546
|
/**
|
|
@@ -3553,7 +3572,8 @@ declare class SeyfertManager extends Manager {
|
|
|
3553
3572
|
readonly client: Client$3 | WorkerClient;
|
|
3554
3573
|
constructor(client: Client$3 | WorkerClient, options?: ManagerOptions);
|
|
3555
3574
|
protected send(packet: GatewayVoiceStateUpdate): void;
|
|
3575
|
+
resolveUser(user: PortableUser | string): Promise<User$3 | PortableUser>;
|
|
3556
3576
|
}
|
|
3557
3577
|
|
|
3558
|
-
export { AutoPlayPlatform, AutoPlayUtils, AvailableFilters, DetritusManager, DiscordJSManager, ErisManager, Filters, JsonQueue, LoadTypes, Manager, ManagerEventTypes, MemoryQueue, Node, OceanicManager, Player, PlayerStateEventTypes, PlayerUtils, Plugin, RedisQueue, Rest, SearchPlatform, SeverityTypes, SeyfertManager, SponsorBlockSegment, StateStorageType, StateTypes, Structure, TrackEndReasonTypes, TrackPartial, TrackSourceTypes, TrackUtils, UseNodeOptions };
|
|
3559
|
-
export type { AlbumSearchResult, ArtistSearchResult, CPUStats, DiscordPacket, DistortionOptions, EndSpeakingEventVoiceReceiver, EndSpeakingEventVoiceReceiverData, EqualizerBand, ErrorOrEmptySearchResult, Exception, Extendable, FrameStats, IQueue, JsonConfig, KaraokeOptions, LavaPlayer, LavalinkInfo, LavalinkResponse, LoadType, Lyrics, LyricsEvent, LyricsEventType, LyricsFoundEvent, LyricsLine, LyricsLineEvent, LyricsNotFoundEvent, ManagerEvents, ManagerInitOptions, ManagerOptions, MemoryStats, NodeLinkGetLyrics, NodeLinkGetLyricsEmpty, NodeLinkGetLyricsError, NodeLinkGetLyricsMultiple, NodeLinkGetLyricsSingle, NodeMessage, NodeOptions, NodeStats, PlayOptions, PlayerEvent, PlayerEventType, PlayerEvents, PlayerOptions, PlayerStateUpdateEvent, PlayerUpdateVoiceState, PlaylistData, PlaylistInfoData, PlaylistRawData, PlaylistSearchResult, PodcastSearchResult, RedisConfig, RestPlayOptions, ReverbOptions, RotationOptions, SearchQuery, SearchResult, SearchSearchResult, Severity, ShortSearchResult, ShowSearchResult, Sizes, SponsorBlockChapterStarted, SponsorBlockChaptersLoaded, SponsorBlockSegmentEventType, SponsorBlockSegmentEvents, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, StartSpeakingEventVoiceReceiver, StartSpeakingEventVoiceReceiverData, StateStorageOptions, StationSearchResult, TimescaleOptions, Track, TrackData, TrackDataInfo, TrackEndEvent, TrackEndReason, TrackExceptionEvent, TrackPluginInfo, TrackSearchResult, TrackSourceName, TrackStartEvent, TrackStuckEvent, UseNodeOption, VibratoOptions, VoicePacket, VoiceReceiverEvent, VoiceServer, VoiceServerUpdate, VoiceState, WebSocketClosedEvent };
|
|
3578
|
+
export { AutoPlayPlatform, AutoPlayUtils, AvailableFilters, DetritusManager, DiscordJSManager, ErisManager, Filters, JSONUtils, JsonQueue, LoadTypes, Manager, ManagerEventTypes, MemoryQueue, Node, OceanicManager, Player, PlayerStateEventTypes, PlayerUtils, Plugin, RedisQueue, Rest, SearchPlatform, SeverityTypes, SeyfertManager, SponsorBlockSegment, StateStorageType, StateTypes, Structure, TrackEndReasonTypes, TrackPartial, TrackSourceTypes, TrackUtils, UseNodeOptions };
|
|
3579
|
+
export type { AlbumSearchResult, ArtistSearchResult, CPUStats, DiscordPacket, DistortionOptions, EndSpeakingEventVoiceReceiver, EndSpeakingEventVoiceReceiverData, EqualizerBand, ErrorOrEmptySearchResult, Exception, Extendable, FrameStats, IQueue, JsonConfig, KaraokeOptions, LavaPlayer, LavalinkInfo, LavalinkResponse, LoadType, Lyrics, LyricsEvent, LyricsEventType, LyricsFoundEvent, LyricsLine, LyricsLineEvent, LyricsNotFoundEvent, ManagerEvents, ManagerInitOptions, ManagerOptions, MemoryStats, NodeLinkGetLyrics, NodeLinkGetLyricsEmpty, NodeLinkGetLyricsError, NodeLinkGetLyricsMultiple, NodeLinkGetLyricsSingle, NodeMessage, NodeOptions, NodeStats, PlayOptions, PlayerEvent, PlayerEventType, PlayerEvents, PlayerOptions, PlayerStateUpdateEvent, PlayerUpdateVoiceState, PlaylistData, PlaylistInfoData, PlaylistRawData, PlaylistSearchResult, PodcastSearchResult, PortableUser, RedisConfig, RestPlayOptions, ReverbOptions, RotationOptions, SearchQuery, SearchResult, SearchSearchResult, Severity, ShortSearchResult, ShowSearchResult, Sizes, SponsorBlockChapterStarted, SponsorBlockChaptersLoaded, SponsorBlockSegmentEventType, SponsorBlockSegmentEvents, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, StartSpeakingEventVoiceReceiver, StartSpeakingEventVoiceReceiverData, StateStorageOptions, StationSearchResult, TimescaleOptions, Track, TrackData, TrackDataInfo, TrackEndEvent, TrackEndReason, TrackExceptionEvent, TrackPluginInfo, TrackSearchResult, TrackSourceName, TrackStartEvent, TrackStuckEvent, UseNodeOption, VibratoOptions, VoicePacket, VoiceReceiverEvent, VoiceServer, VoiceServerUpdate, VoiceState, WebSocketClosedEvent };
|
|
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const Enums_1 = require("../structures/Enums");
|
|
6
6
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
7
7
|
const fs_1 = require("fs");
|
|
8
|
+
const Utils_1 = require("../structures/Utils");
|
|
8
9
|
/**
|
|
9
10
|
* The player's queue, the `current` property is the currently playing track, think of the rest as the up-coming tracks.
|
|
10
11
|
*/
|
|
@@ -53,8 +54,8 @@ class JsonQueue {
|
|
|
53
54
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[JSONQUEUE] Added ${tracks.length} track(s) to queue`);
|
|
54
55
|
if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
|
|
55
56
|
if (!isArray) {
|
|
56
|
-
const
|
|
57
|
-
if (
|
|
57
|
+
const AutoplayUser = (await this.manager.players.get(this.guildId).get("Internal_AutoplayUser"));
|
|
58
|
+
if (AutoplayUser && AutoplayUser.id === track.requester.id) {
|
|
58
59
|
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
59
60
|
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
60
61
|
details: {
|
|
@@ -437,7 +438,7 @@ class JsonQueue {
|
|
|
437
438
|
*/
|
|
438
439
|
async writeJSON(filePath, data) {
|
|
439
440
|
await this.ensureDir();
|
|
440
|
-
await fs_1.promises.writeFile(filePath,
|
|
441
|
+
await fs_1.promises.writeFile(filePath, Utils_1.JSONUtils.safe(data, 2), "utf-8");
|
|
441
442
|
}
|
|
442
443
|
}
|
|
443
444
|
exports.JsonQueue = JsonQueue;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MemoryQueue = void 0;
|
|
4
4
|
const Enums_1 = require("../structures/Enums");
|
|
5
|
+
const Utils_1 = require("../structures/Utils");
|
|
5
6
|
/**
|
|
6
7
|
* The player's queue, the `current` property is the currently playing track, think of the rest as the up-coming tracks.
|
|
7
8
|
*/
|
|
@@ -36,7 +37,7 @@ class MemoryQueue extends Array {
|
|
|
36
37
|
const isArray = Array.isArray(track);
|
|
37
38
|
const tracks = isArray ? [...track] : [track];
|
|
38
39
|
// Get the track info as a string
|
|
39
|
-
const trackInfo = isArray ? tracks.map((t) =>
|
|
40
|
+
const trackInfo = isArray ? tracks.map((t) => Utils_1.JSONUtils.safe(t, 2)).join(", ") : Utils_1.JSONUtils.safe(track, 2);
|
|
40
41
|
// Emit a debug message
|
|
41
42
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Added ${tracks.length} track(s) to queue: ${trackInfo}`);
|
|
42
43
|
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
@@ -81,8 +82,8 @@ class MemoryQueue extends Array {
|
|
|
81
82
|
}
|
|
82
83
|
if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
|
|
83
84
|
if (!isArray) {
|
|
84
|
-
const
|
|
85
|
-
if (
|
|
85
|
+
const AutoplayUser = this.manager.players.get(this.guildId).get("Internal_AutoplayUser");
|
|
86
|
+
if (AutoplayUser && AutoplayUser.id === track.requester.id) {
|
|
86
87
|
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
87
88
|
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
88
89
|
details: {
|
|
@@ -262,7 +263,7 @@ class MemoryQueue extends Array {
|
|
|
262
263
|
}
|
|
263
264
|
// Single item removal when no end specified
|
|
264
265
|
const removedTrack = this.splice(startOrPosition, 1);
|
|
265
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Removed 1 track from player: ${this.guildId} from position ${startOrPosition}: ${
|
|
266
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Removed 1 track from player: ${this.guildId} from position ${startOrPosition}: ${Utils_1.JSONUtils.safe(removedTrack[0], 2)}`);
|
|
266
267
|
// Ensure removedTrack is an array for consistency
|
|
267
268
|
const tracksToEmit = removedTrack.length > 0 ? removedTrack : [];
|
|
268
269
|
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RedisQueue = void 0;
|
|
4
4
|
const Enums_1 = require("../structures/Enums");
|
|
5
|
+
const Utils_1 = require("../structures/Utils");
|
|
5
6
|
/**
|
|
6
7
|
* The player's queue, the `current` property is the currently playing track, think of the rest as the up-coming tracks.
|
|
7
8
|
*/
|
|
@@ -61,8 +62,8 @@ class RedisQueue {
|
|
|
61
62
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Added ${tracks.length} track(s) to queue`);
|
|
62
63
|
if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
|
|
63
64
|
if (!Array.isArray(track)) {
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
65
|
+
const AutoplayUser = (await this.manager.players.get(this.guildId).get("Internal_AutoplayUser"));
|
|
66
|
+
if (AutoplayUser && AutoplayUser.id === track.requester.id) {
|
|
66
67
|
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
67
68
|
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
68
69
|
details: {
|
|
@@ -441,7 +442,7 @@ class RedisQueue {
|
|
|
441
442
|
* Helper to serialize/deserialize Track
|
|
442
443
|
*/
|
|
443
444
|
serialize(track) {
|
|
444
|
-
return
|
|
445
|
+
return Utils_1.JSONUtils.safe(track, 2);
|
|
445
446
|
}
|
|
446
447
|
}
|
|
447
448
|
exports.RedisQueue = RedisQueue;
|
|
@@ -180,22 +180,26 @@ class Manager extends events_1.EventEmitter {
|
|
|
180
180
|
throw new Error("No available nodes.");
|
|
181
181
|
const _query = typeof query === "string" ? { query } : query;
|
|
182
182
|
const _source = _query.source ?? this.options.defaultSearchPlatform;
|
|
183
|
-
|
|
184
|
-
|
|
183
|
+
const isUrl = /^https?:\/\//.test(_query.query);
|
|
184
|
+
const search = isUrl ? _query.query : `${_source}:${_query.query}`;
|
|
185
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, isUrl ? `[MANAGER] Performing search for: ${_query.query}` : `[MANAGER] Performing ${_source} search for: ${_query.query}`);
|
|
185
186
|
try {
|
|
186
187
|
const res = (await node.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(search)}`));
|
|
187
188
|
if (!res)
|
|
188
189
|
throw new Error("Query not found.");
|
|
189
|
-
let
|
|
190
|
-
let playlist = null;
|
|
190
|
+
let result;
|
|
191
191
|
switch (res.loadType) {
|
|
192
|
-
case Enums_1.LoadTypes.Search:
|
|
193
|
-
tracks = res.data.map((
|
|
192
|
+
case Enums_1.LoadTypes.Search: {
|
|
193
|
+
const tracks = res.data.map((t) => Utils_1.TrackUtils.build(t, requester));
|
|
194
|
+
result = { loadType: res.loadType, tracks };
|
|
194
195
|
break;
|
|
196
|
+
}
|
|
195
197
|
case Enums_1.LoadTypes.Short:
|
|
196
|
-
case Enums_1.LoadTypes.Track:
|
|
197
|
-
|
|
198
|
+
case Enums_1.LoadTypes.Track: {
|
|
199
|
+
const track = Utils_1.TrackUtils.build(res.data, requester);
|
|
200
|
+
result = { loadType: res.loadType, tracks: [track] };
|
|
198
201
|
break;
|
|
202
|
+
}
|
|
199
203
|
case Enums_1.LoadTypes.Album:
|
|
200
204
|
case Enums_1.LoadTypes.Artist:
|
|
201
205
|
case Enums_1.LoadTypes.Station:
|
|
@@ -203,18 +207,24 @@ class Manager extends events_1.EventEmitter {
|
|
|
203
207
|
case Enums_1.LoadTypes.Show:
|
|
204
208
|
case Enums_1.LoadTypes.Playlist: {
|
|
205
209
|
const playlistData = res.data;
|
|
206
|
-
tracks = playlistData.tracks.map((
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
playlistInfo: playlistData.pluginInfo,
|
|
210
|
-
requester: requester,
|
|
210
|
+
const tracks = playlistData.tracks.map((t) => Utils_1.TrackUtils.build(t, requester));
|
|
211
|
+
result = {
|
|
212
|
+
loadType: res.loadType,
|
|
211
213
|
tracks,
|
|
212
|
-
|
|
214
|
+
playlist: {
|
|
215
|
+
name: playlistData.info.name,
|
|
216
|
+
playlistInfo: playlistData.pluginInfo,
|
|
217
|
+
requester: requester,
|
|
218
|
+
tracks,
|
|
219
|
+
duration: tracks.reduce((acc, cur) => acc + (cur.duration || 0), 0),
|
|
220
|
+
},
|
|
213
221
|
};
|
|
214
222
|
break;
|
|
215
223
|
}
|
|
224
|
+
default:
|
|
225
|
+
result = { loadType: res.loadType };
|
|
216
226
|
}
|
|
217
|
-
if (this.options.normalizeYouTubeTitles) {
|
|
227
|
+
if (this.options.normalizeYouTubeTitles && "tracks" in result) {
|
|
218
228
|
const processTrack = (track) => {
|
|
219
229
|
if (!/(youtube\.com|youtu\.be)/.test(track.uri))
|
|
220
230
|
return track;
|
|
@@ -223,34 +233,15 @@ class Manager extends events_1.EventEmitter {
|
|
|
223
233
|
track.author = cleanAuthor;
|
|
224
234
|
return track;
|
|
225
235
|
};
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
else {
|
|
230
|
-
tracks = tracks.map(processTrack);
|
|
236
|
+
result.tracks = result.tracks.map(processTrack);
|
|
237
|
+
if ("playlist" in result && result.playlist) {
|
|
238
|
+
result.playlist.tracks = result.playlist.tracks.map(processTrack);
|
|
231
239
|
}
|
|
232
240
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
case Enums_1.LoadTypes.Station:
|
|
238
|
-
case Enums_1.LoadTypes.Podcast:
|
|
239
|
-
case Enums_1.LoadTypes.Show:
|
|
240
|
-
case Enums_1.LoadTypes.Playlist:
|
|
241
|
-
result = { loadType: res.loadType, tracks, playlist };
|
|
242
|
-
break;
|
|
243
|
-
case Enums_1.LoadTypes.Search:
|
|
244
|
-
result = { loadType: res.loadType, tracks };
|
|
245
|
-
break;
|
|
246
|
-
case Enums_1.LoadTypes.Short:
|
|
247
|
-
case Enums_1.LoadTypes.Track:
|
|
248
|
-
result = { loadType: res.loadType, tracks: [tracks[0]] };
|
|
249
|
-
break;
|
|
250
|
-
default:
|
|
251
|
-
return { loadType: res.loadType };
|
|
252
|
-
}
|
|
253
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Result ${_source} search for: ${_query.query}: ${JSON.stringify(result)}`);
|
|
241
|
+
const summary = "tracks" in result
|
|
242
|
+
? result.tracks.map((t) => Object.fromEntries(Object.entries(t).filter(([key]) => key !== "requester")))
|
|
243
|
+
: [];
|
|
244
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Result search for ${_query.query}: ${Utils_1.JSONUtils.safe(summary, 2)}`);
|
|
254
245
|
return result;
|
|
255
246
|
}
|
|
256
247
|
catch (err) {
|
|
@@ -275,7 +266,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
275
266
|
return this.players.get(options.guildId);
|
|
276
267
|
}
|
|
277
268
|
// Create a new player with the given options
|
|
278
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Creating new player with options: ${
|
|
269
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Creating new player with options: ${Utils_1.JSONUtils.safe(options, 2)}`);
|
|
279
270
|
return new (Utils_1.Structure.get("Player"))(options);
|
|
280
271
|
}
|
|
281
272
|
/**
|
|
@@ -306,7 +297,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
306
297
|
// Set the node in the manager's collection
|
|
307
298
|
this.nodes.set(key, node);
|
|
308
299
|
// Emit a debug event for node creation
|
|
309
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Creating new node with options: ${
|
|
300
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Creating new node with options: ${Utils_1.JSONUtils.safe(options, 2)}`);
|
|
310
301
|
// Return the created node
|
|
311
302
|
return node;
|
|
312
303
|
}
|
|
@@ -350,7 +341,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
350
341
|
const player = this.getPlayer(update.guild_id);
|
|
351
342
|
if (!player)
|
|
352
343
|
return;
|
|
353
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Updating voice state: ${
|
|
344
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Updating voice state: ${Utils_1.JSONUtils.safe(update, 2)}`);
|
|
354
345
|
if ("token" in update) {
|
|
355
346
|
return await this.handleVoiceServerUpdate(player, update);
|
|
356
347
|
}
|
|
@@ -366,12 +357,12 @@ class Manager extends events_1.EventEmitter {
|
|
|
366
357
|
* @throws Will throw an error if no nodes are available or if the API request fails.
|
|
367
358
|
*/
|
|
368
359
|
async decodeTracks(tracks) {
|
|
369
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Decoding tracks: ${
|
|
360
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Decoding tracks: ${Utils_1.JSONUtils.safe(tracks, 2)}`);
|
|
370
361
|
return new Promise(async (resolve, reject) => {
|
|
371
362
|
const node = this.nodes.first();
|
|
372
363
|
if (!node)
|
|
373
364
|
throw new Error("No available nodes.");
|
|
374
|
-
const res = (await node.rest.post("/v4/decodetracks",
|
|
365
|
+
const res = (await node.rest.post("/v4/decodetracks", Utils_1.JSONUtils.safe(tracks, 2)).catch((err) => reject(err)));
|
|
375
366
|
if (!res) {
|
|
376
367
|
return reject(new Error("No data returned from query."));
|
|
377
368
|
}
|
|
@@ -407,7 +398,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
407
398
|
}
|
|
408
399
|
const serializedPlayer = await Utils_1.PlayerUtils.serializePlayer(player);
|
|
409
400
|
await promises_1.default.mkdir(path_1.default.dirname(playerStateFilePath), { recursive: true });
|
|
410
|
-
await promises_1.default.writeFile(playerStateFilePath,
|
|
401
|
+
await promises_1.default.writeFile(playerStateFilePath, Utils_1.JSONUtils.safe(serializedPlayer, 2), "utf-8");
|
|
411
402
|
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Player state saved: ${guildId}`);
|
|
412
403
|
}
|
|
413
404
|
catch (error) {
|
|
@@ -427,7 +418,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
427
418
|
const redisKey = `${this.options.stateStorage.redisConfig.prefix?.endsWith(":")
|
|
428
419
|
? this.options.stateStorage.redisConfig.prefix
|
|
429
420
|
: this.options.stateStorage.redisConfig.prefix ?? "magmastream:"}playerstore:${guildId}`;
|
|
430
|
-
await this.redis.set(redisKey,
|
|
421
|
+
await this.redis.set(redisKey, Utils_1.JSONUtils.safe(serializedPlayer, 2));
|
|
431
422
|
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Player state saved to Redis: ${guildId}`);
|
|
432
423
|
}
|
|
433
424
|
catch (error) {
|
|
@@ -497,7 +488,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
497
488
|
volume: lavaPlayer.volume || state.options.volume,
|
|
498
489
|
nodeIdentifier: nodeId,
|
|
499
490
|
};
|
|
500
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${state.guildId} from saved file: ${
|
|
491
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${state.guildId} from saved file: ${Utils_1.JSONUtils.safe(state.options, 2)}`);
|
|
501
492
|
const player = this.create(playerOptions);
|
|
502
493
|
await player.node.rest.updatePlayer({
|
|
503
494
|
guildId: state.options.guildId,
|
|
@@ -514,8 +505,11 @@ class Manager extends events_1.EventEmitter {
|
|
|
514
505
|
const currentTrack = state.queue.current;
|
|
515
506
|
const queueTracks = state.queue.tracks;
|
|
516
507
|
if (state.isAutoplay) {
|
|
517
|
-
|
|
518
|
-
|
|
508
|
+
const savedUser = state.data.clientUser;
|
|
509
|
+
if (savedUser) {
|
|
510
|
+
const autoPlayUser = await player.manager.resolveUser(savedUser);
|
|
511
|
+
player.setAutoplay(true, autoPlayUser, state.autoplayTries);
|
|
512
|
+
}
|
|
519
513
|
}
|
|
520
514
|
if (lavaPlayer?.track) {
|
|
521
515
|
tracks.push(...queueTracks);
|
|
@@ -705,8 +699,11 @@ class Manager extends events_1.EventEmitter {
|
|
|
705
699
|
const currentTrack = state.queue.current;
|
|
706
700
|
const queueTracks = state.queue.tracks;
|
|
707
701
|
if (state.isAutoplay) {
|
|
708
|
-
|
|
709
|
-
|
|
702
|
+
const savedUser = state.data.clientUser;
|
|
703
|
+
if (savedUser) {
|
|
704
|
+
const autoPlayUser = await player.manager.resolveUser(savedUser);
|
|
705
|
+
player.setAutoplay(true, autoPlayUser, state.autoplayTries);
|
|
706
|
+
}
|
|
710
707
|
}
|
|
711
708
|
if (lavaPlayer?.track) {
|
|
712
709
|
// If lavaPlayer has a track, push all queue tracks
|
|
@@ -1310,5 +1307,16 @@ class Manager extends events_1.EventEmitter {
|
|
|
1310
1307
|
sendPacket(packet) {
|
|
1311
1308
|
return this.send(packet);
|
|
1312
1309
|
}
|
|
1310
|
+
/**
|
|
1311
|
+
* Resolves a PortableUser or ID to a real user object.
|
|
1312
|
+
* Can be overridden by wrapper managers to return wrapper-specific User classes.
|
|
1313
|
+
*/
|
|
1314
|
+
async resolveUser(user) {
|
|
1315
|
+
if (!user)
|
|
1316
|
+
return null;
|
|
1317
|
+
if (typeof user === "string")
|
|
1318
|
+
return { id: user }; // fallback by ID only
|
|
1319
|
+
return user; // default: just return the portable user
|
|
1320
|
+
}
|
|
1313
1321
|
}
|
|
1314
1322
|
exports.Manager = Manager;
|
package/dist/structures/Node.js
CHANGED
|
@@ -128,7 +128,7 @@ class Node {
|
|
|
128
128
|
createSessionIdsFile() {
|
|
129
129
|
if (!fs_1.default.existsSync(this.sessionIdsFilePath)) {
|
|
130
130
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Creating sessionId file at: ${this.sessionIdsFilePath}`);
|
|
131
|
-
fs_1.default.writeFileSync(this.sessionIdsFilePath,
|
|
131
|
+
fs_1.default.writeFileSync(this.sessionIdsFilePath, Utils_1.JSONUtils.safe({}), "utf-8");
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
/**
|
|
@@ -178,7 +178,7 @@ class Node {
|
|
|
178
178
|
}
|
|
179
179
|
else {
|
|
180
180
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] No sessionIds found in Redis — creating new key.`);
|
|
181
|
-
await this.manager.redis.set(key,
|
|
181
|
+
await this.manager.redis.set(key, Utils_1.JSONUtils.safe({}));
|
|
182
182
|
this.sessionIdsMap = new Map();
|
|
183
183
|
}
|
|
184
184
|
break;
|
|
@@ -219,7 +219,7 @@ class Node {
|
|
|
219
219
|
}
|
|
220
220
|
fileData[compositeKey] = this.sessionId;
|
|
221
221
|
const tmpPath = `${filePath}.tmp`;
|
|
222
|
-
fs_1.default.writeFileSync(tmpPath,
|
|
222
|
+
fs_1.default.writeFileSync(tmpPath, Utils_1.JSONUtils.safe(fileData, 2), "utf-8");
|
|
223
223
|
fs_1.default.renameSync(tmpPath, filePath);
|
|
224
224
|
this.sessionIdsMap = new Map(Object.entries(fileData));
|
|
225
225
|
updated = true;
|
|
@@ -259,7 +259,7 @@ class Node {
|
|
|
259
259
|
}
|
|
260
260
|
sessionIds[compositeKey] = this.sessionId;
|
|
261
261
|
this.sessionIdsMap = new Map(Object.entries(sessionIds));
|
|
262
|
-
await this.manager.redis.set(key,
|
|
262
|
+
await this.manager.redis.set(key, Utils_1.JSONUtils.safe(sessionIds));
|
|
263
263
|
break;
|
|
264
264
|
}
|
|
265
265
|
}
|
|
@@ -307,7 +307,7 @@ class Node {
|
|
|
307
307
|
identifier: this.options.identifier,
|
|
308
308
|
},
|
|
309
309
|
};
|
|
310
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Connecting ${
|
|
310
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Connecting ${Utils_1.JSONUtils.safe(debugInfo, 2)}`);
|
|
311
311
|
}
|
|
312
312
|
/**
|
|
313
313
|
* Destroys the node and cleans up associated resources.
|
|
@@ -329,7 +329,7 @@ class Node {
|
|
|
329
329
|
sessionId: this.sessionId,
|
|
330
330
|
playerCount: this.manager.players.filter((p) => p.node == this).size,
|
|
331
331
|
};
|
|
332
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Destroying node: ${
|
|
332
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Destroying node: ${Utils_1.JSONUtils.safe(debugInfo, 2)}`);
|
|
333
333
|
// Automove all players connected to that node
|
|
334
334
|
const players = this.manager.players.filter((p) => p.node == this);
|
|
335
335
|
if (players.size) {
|
|
@@ -368,7 +368,7 @@ class Node {
|
|
|
368
368
|
maxRetryAttempts: this.options.maxRetryAttempts,
|
|
369
369
|
retryDelayMs: this.options.retryDelayMs,
|
|
370
370
|
};
|
|
371
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Reconnecting node: ${
|
|
371
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Reconnecting node: ${Utils_1.JSONUtils.safe(debugInfo, 2)}`);
|
|
372
372
|
this.reconnectTimeout = setTimeout(async () => {
|
|
373
373
|
if (this.reconnectAttempts >= this.options.maxRetryAttempts) {
|
|
374
374
|
const error = new Error(`Unable to connect after ${this.options.maxRetryAttempts} attempts.`);
|
|
@@ -405,7 +405,7 @@ class Node {
|
|
|
405
405
|
identifier: this.options.identifier,
|
|
406
406
|
connected: this.connected,
|
|
407
407
|
};
|
|
408
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Connected node: ${
|
|
408
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Connected node: ${Utils_1.JSONUtils.safe(debugInfo, 2)}`);
|
|
409
409
|
this.manager.emit(Enums_1.ManagerEventTypes.NodeConnect, this);
|
|
410
410
|
const playersOnBackupNode = this.manager.players.filter((p) => p.node.options.isBackup);
|
|
411
411
|
if (playersOnBackupNode.size) {
|
|
@@ -432,7 +432,7 @@ class Node {
|
|
|
432
432
|
reason,
|
|
433
433
|
};
|
|
434
434
|
this.manager.emit(Enums_1.ManagerEventTypes.NodeDisconnect, this, { code, reason });
|
|
435
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Disconnected node: ${
|
|
435
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Disconnected node: ${Utils_1.JSONUtils.safe(debugInfo, 2)}`);
|
|
436
436
|
if (this.manager.useableNode) {
|
|
437
437
|
const players = this.manager.players.filter((p) => p.node.options.identifier == this.options.identifier);
|
|
438
438
|
if (players.size) {
|
|
@@ -464,7 +464,7 @@ class Node {
|
|
|
464
464
|
identifier: this.options.identifier,
|
|
465
465
|
error: error.message,
|
|
466
466
|
};
|
|
467
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Error on node: ${
|
|
467
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Error on node: ${Utils_1.JSONUtils.safe(debugInfo, 2)}`);
|
|
468
468
|
this.manager.emit(Enums_1.ManagerEventTypes.NodeError, this, error);
|
|
469
469
|
}
|
|
470
470
|
/**
|
|
@@ -504,11 +504,11 @@ class Node {
|
|
|
504
504
|
if (player && player.node.options.identifier !== this.options.identifier) {
|
|
505
505
|
return;
|
|
506
506
|
}
|
|
507
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Node message: ${
|
|
507
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Node message: ${Utils_1.JSONUtils.safe(payload, 2)}`);
|
|
508
508
|
await this.handleEvent(payload);
|
|
509
509
|
break;
|
|
510
510
|
case "ready":
|
|
511
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Node message: ${
|
|
511
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Node message: ${Utils_1.JSONUtils.safe(payload, 2)}`);
|
|
512
512
|
this.rest.setSessionId(payload.sessionId);
|
|
513
513
|
this.sessionId = payload.sessionId;
|
|
514
514
|
await this.updateSessionId();
|
|
@@ -601,8 +601,8 @@ class Node {
|
|
|
601
601
|
player.playing = true;
|
|
602
602
|
player.paused = false;
|
|
603
603
|
this.manager.emit(Enums_1.ManagerEventTypes.TrackStart, player, track, payload);
|
|
604
|
-
const
|
|
605
|
-
if (
|
|
604
|
+
const AutoplayUser = player.get("Internal_AutoplayUser");
|
|
605
|
+
if (AutoplayUser && AutoplayUser.id === track.requester.id) {
|
|
606
606
|
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, player, {
|
|
607
607
|
changeType: Enums_1.PlayerStateEventTypes.TrackChange,
|
|
608
608
|
details: {
|
|
@@ -702,7 +702,7 @@ class Node {
|
|
|
702
702
|
return false;
|
|
703
703
|
const PreviousQueue = await player.queue.getPrevious();
|
|
704
704
|
const lastTrack = PreviousQueue?.at(-1);
|
|
705
|
-
lastTrack.requester = player.get("
|
|
705
|
+
lastTrack.requester = player.get("Internal_AutoplayUser");
|
|
706
706
|
if (!lastTrack)
|
|
707
707
|
return false;
|
|
708
708
|
const tracks = await Utils_1.AutoPlayUtils.getRecommendedTracks(lastTrack);
|
|
@@ -934,7 +934,7 @@ class Node {
|
|
|
934
934
|
*/
|
|
935
935
|
socketClosed(player, payload) {
|
|
936
936
|
this.manager.emit(Enums_1.ManagerEventTypes.SocketClosed, player, payload);
|
|
937
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Websocket closed for player: ${player.guildId} with payload: ${
|
|
937
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Websocket closed for player: ${player.guildId} with payload: ${Utils_1.JSONUtils.safe(payload, 2)}`);
|
|
938
938
|
}
|
|
939
939
|
/**
|
|
940
940
|
* Emitted when the segments for a track are loaded.
|
|
@@ -1045,7 +1045,7 @@ class Node {
|
|
|
1045
1045
|
throw new RangeError("No Segments provided. Did you mean to use 'deleteSponsorBlock'?");
|
|
1046
1046
|
if (segments.some((v) => !validSponsorBlocks.includes(v.toLowerCase())))
|
|
1047
1047
|
throw new SyntaxError(`You provided a sponsorblock which isn't valid, valid ones are: ${validSponsorBlocks.map((v) => `'${v}'`).join(", ")}`);
|
|
1048
|
-
await this.rest.put(`/v4/sessions/${this.sessionId}/players/${player.guildId}/sponsorblock/categories`,
|
|
1048
|
+
await this.rest.put(`/v4/sessions/${this.sessionId}/players/${player.guildId}/sponsorblock/categories`, Utils_1.JSONUtils.safe(segments.map((v) => v.toLowerCase()), 2));
|
|
1049
1049
|
return;
|
|
1050
1050
|
}
|
|
1051
1051
|
/**
|
|
@@ -355,30 +355,27 @@ class Player {
|
|
|
355
355
|
* track when the current track ends.
|
|
356
356
|
*
|
|
357
357
|
* @param {boolean} autoplayState - Whether or not autoplay should be enabled.
|
|
358
|
-
* @param {object}
|
|
358
|
+
* @param {object} AutoplayUser - The user-object that should be used as the bot-user.
|
|
359
359
|
* @param {number} [tries=3] - The number of times the player should try to find a
|
|
360
360
|
* recommended track if the first one doesn't work.
|
|
361
361
|
* @returns {this} - The player instance.
|
|
362
362
|
*/
|
|
363
|
-
setAutoplay(autoplayState,
|
|
363
|
+
setAutoplay(autoplayState, AutoplayUser, tries) {
|
|
364
364
|
if (typeof autoplayState !== "boolean") {
|
|
365
365
|
throw new Error("autoplayState must be a boolean.");
|
|
366
366
|
}
|
|
367
367
|
if (autoplayState) {
|
|
368
|
-
if (!
|
|
369
|
-
throw new Error("
|
|
370
|
-
}
|
|
371
|
-
if (!["ClientUser", "User"].includes(botUser.constructor.name)) {
|
|
372
|
-
throw new Error("botUser must be a user-object.");
|
|
368
|
+
if (!AutoplayUser) {
|
|
369
|
+
throw new Error("AutoplayUser must be provided when enabling autoplay.");
|
|
373
370
|
}
|
|
374
371
|
this.autoplayTries = tries && typeof tries === "number" && tries > 0 ? tries : 3; // Default to 3 if invalid
|
|
375
372
|
this.isAutoplay = true;
|
|
376
|
-
this.set("
|
|
373
|
+
this.set("Internal_AutoplayUser", AutoplayUser);
|
|
377
374
|
}
|
|
378
375
|
else {
|
|
379
376
|
this.isAutoplay = false;
|
|
380
377
|
this.autoplayTries = null;
|
|
381
|
-
this.set("
|
|
378
|
+
this.set("Internal_AutoplayUser", null);
|
|
382
379
|
}
|
|
383
380
|
const oldPlayer = { ...this };
|
|
384
381
|
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this, {
|
|
@@ -852,7 +849,7 @@ class Player {
|
|
|
852
849
|
queueRepeat: this.queueRepeat,
|
|
853
850
|
dynamicRepeat: this.dynamicRepeat,
|
|
854
851
|
dynamicRepeatIntervalMs: this.dynamicRepeatIntervalMs,
|
|
855
|
-
ClientUser: this.get("
|
|
852
|
+
ClientUser: this.get("Internal_AutoplayUser"),
|
|
856
853
|
filters: this.filters,
|
|
857
854
|
nowPlayingMessage: this.nowPlayingMessage,
|
|
858
855
|
isAutoplay: this.isAutoplay,
|
|
@@ -889,7 +886,7 @@ class Player {
|
|
|
889
886
|
clonedPlayer.queueRepeat = oldPlayerProperties.queueRepeat;
|
|
890
887
|
clonedPlayer.dynamicRepeat = oldPlayerProperties.dynamicRepeat;
|
|
891
888
|
clonedPlayer.dynamicRepeatIntervalMs = oldPlayerProperties.dynamicRepeatIntervalMs;
|
|
892
|
-
clonedPlayer.set("
|
|
889
|
+
clonedPlayer.set("Internal_AutoplayUser", oldPlayerProperties.ClientUser);
|
|
893
890
|
clonedPlayer.paused = oldPlayerProperties.paused;
|
|
894
891
|
// Update filters for the cloned player
|
|
895
892
|
await clonedPlayer.filters.updateFilters();
|
|
@@ -906,7 +903,7 @@ class Player {
|
|
|
906
903
|
queueSize: clonedPlayer.queue.size,
|
|
907
904
|
},
|
|
908
905
|
};
|
|
909
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[PLAYER] Transferred player to a new server: ${
|
|
906
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[PLAYER] Transferred player to a new server: ${Utils_1.JSONUtils.safe(debugInfo, 2)}.`);
|
|
910
907
|
// Return the cloned player
|
|
911
908
|
return clonedPlayer;
|
|
912
909
|
}
|
|
@@ -1035,7 +1032,7 @@ class Player {
|
|
|
1035
1032
|
const packet = JSON.parse(payload);
|
|
1036
1033
|
if (!packet?.op)
|
|
1037
1034
|
return;
|
|
1038
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `VoiceReceiver recieved a payload: ${
|
|
1035
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `VoiceReceiver recieved a payload: ${Utils_1.JSONUtils.safe(payload, 2)}`);
|
|
1039
1036
|
switch (packet.type) {
|
|
1040
1037
|
case "startSpeakingEvent": {
|
|
1041
1038
|
this.manager.emit(Enums_1.ManagerEventTypes.VoiceReceiverStartSpeaking, this, packet.data);
|
|
@@ -1050,7 +1047,7 @@ class Player {
|
|
|
1050
1047
|
break;
|
|
1051
1048
|
}
|
|
1052
1049
|
default: {
|
|
1053
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `VoiceReceiver recieved an unknown payload: ${
|
|
1050
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `VoiceReceiver recieved an unknown payload: ${Utils_1.JSONUtils.safe(payload, 2)}`);
|
|
1054
1051
|
break;
|
|
1055
1052
|
}
|
|
1056
1053
|
}
|
package/dist/structures/Rest.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.Rest = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const axios_1 = tslib_1.__importDefault(require("axios"));
|
|
6
6
|
const Enums_1 = require("./Enums");
|
|
7
|
+
const Utils_1 = require("./Utils");
|
|
7
8
|
/** Handles the requests sent to the Lavalink REST API. */
|
|
8
9
|
class Rest {
|
|
9
10
|
/** The Node that this Rest instance is connected to. */
|
|
@@ -44,7 +45,7 @@ class Rest {
|
|
|
44
45
|
// Send a GET request to the Lavalink Node to retrieve all the players.
|
|
45
46
|
const result = await this.get(`/v4/sessions/${this.sessionId}/players`);
|
|
46
47
|
// Log the result of the request.
|
|
47
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Getting all players on node: ${this.node.options.identifier} : ${
|
|
48
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Getting all players on node: ${this.node.options.identifier} : ${Utils_1.JSONUtils.safe(result, 2)}`);
|
|
48
49
|
// Return the result of the request.
|
|
49
50
|
return result;
|
|
50
51
|
}
|
|
@@ -55,7 +56,7 @@ class Rest {
|
|
|
55
56
|
*/
|
|
56
57
|
async updatePlayer(options) {
|
|
57
58
|
// Log the request.
|
|
58
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Updating player: ${options.guildId}: ${
|
|
59
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Updating player: ${options.guildId}: ${Utils_1.JSONUtils.safe(options, 2)}`);
|
|
59
60
|
// Send the PATCH request.
|
|
60
61
|
return await this.patch(`/v4/sessions/${this.sessionId}/players/${options.guildId}?noReplace=false`, options.data);
|
|
61
62
|
}
|
|
@@ -92,7 +93,7 @@ class Rest {
|
|
|
92
93
|
* @returns {Promise<unknown>} The response data of the request.
|
|
93
94
|
*/
|
|
94
95
|
async request(method, endpoint, body) {
|
|
95
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] ${method} api call for endpoint: ${endpoint} with data: ${
|
|
96
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] ${method} api call for endpoint: ${endpoint} with data: ${Utils_1.JSONUtils.safe(body, 2)}`);
|
|
96
97
|
const config = {
|
|
97
98
|
method,
|
|
98
99
|
url: this.url + endpoint,
|
package/dist/structures/Utils.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Structure = exports.PlayerUtils = exports.AutoPlayUtils = exports.TrackUtils = void 0;
|
|
3
|
+
exports.JSONUtils = exports.Structure = exports.PlayerUtils = exports.AutoPlayUtils = exports.TrackUtils = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
6
6
|
const axios_1 = tslib_1.__importDefault(require("axios"));
|
|
7
7
|
const jsdom_1 = require("jsdom");
|
|
8
8
|
const Enums_1 = require("./Enums");
|
|
9
9
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
10
|
+
const safe_stable_stringify_1 = tslib_1.__importDefault(require("safe-stable-stringify"));
|
|
10
11
|
// import playwright from "playwright";
|
|
11
12
|
/** @hidden */
|
|
12
13
|
const SIZES = ["0", "1", "2", "3", "default", "mqdefault", "hqdefault", "maxresdefault"];
|
|
@@ -601,58 +602,52 @@ class PlayerUtils {
|
|
|
601
602
|
* @returns The serialized Player instance
|
|
602
603
|
*/
|
|
603
604
|
static async serializePlayer(player) {
|
|
604
|
-
const seen = new WeakSet();
|
|
605
|
-
// Fetch async queue data once before serializing
|
|
606
605
|
const current = await player.queue.getCurrent();
|
|
607
606
|
const tracks = Array.isArray(await player.queue.getTracks()) ? await player.queue.getTracks() : [];
|
|
608
607
|
const previous = Array.isArray(await player.queue.getPrevious()) ? await player.queue.getPrevious() : [];
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
const serialize = (obj) => {
|
|
615
|
-
if (obj && typeof obj === "object") {
|
|
616
|
-
if (seen.has(obj))
|
|
608
|
+
const seen = new WeakSet();
|
|
609
|
+
// The replacer function
|
|
610
|
+
const replacer = (key, value) => {
|
|
611
|
+
if (value && typeof value === "object") {
|
|
612
|
+
if (seen.has(value))
|
|
617
613
|
return;
|
|
618
|
-
seen.add(
|
|
614
|
+
seen.add(value);
|
|
619
615
|
}
|
|
620
|
-
|
|
621
|
-
};
|
|
622
|
-
return JSON.parse(JSON.stringify(player, (key, value) => {
|
|
623
|
-
if (key === "manager") {
|
|
616
|
+
if (key === "manager")
|
|
624
617
|
return null;
|
|
625
|
-
}
|
|
626
618
|
if (key === "filters") {
|
|
627
619
|
if (!value || typeof value !== "object")
|
|
628
620
|
return null;
|
|
621
|
+
const filters = value;
|
|
629
622
|
return {
|
|
630
|
-
distortion:
|
|
631
|
-
equalizer:
|
|
632
|
-
karaoke:
|
|
633
|
-
rotation:
|
|
634
|
-
timescale:
|
|
635
|
-
vibrato:
|
|
636
|
-
reverb:
|
|
637
|
-
volume:
|
|
638
|
-
bassBoostlevel:
|
|
639
|
-
filterStatus:
|
|
623
|
+
distortion: filters.distortion ?? null,
|
|
624
|
+
equalizer: filters.equalizer ?? [],
|
|
625
|
+
karaoke: filters.karaoke ?? null,
|
|
626
|
+
rotation: filters.rotation ?? null,
|
|
627
|
+
timescale: filters.timescale ?? null,
|
|
628
|
+
vibrato: filters.vibrato ?? null,
|
|
629
|
+
reverb: filters.reverb ?? null,
|
|
630
|
+
volume: filters.volume ?? 1.0,
|
|
631
|
+
bassBoostlevel: filters.bassBoostlevel ?? null,
|
|
632
|
+
filterStatus: filters.filtersStatus ? { ...filters.filtersStatus } : {},
|
|
640
633
|
};
|
|
641
634
|
}
|
|
642
635
|
if (key === "queue") {
|
|
643
|
-
return {
|
|
644
|
-
current,
|
|
645
|
-
tracks,
|
|
646
|
-
previous,
|
|
647
|
-
};
|
|
636
|
+
return { current, tracks, previous };
|
|
648
637
|
}
|
|
649
638
|
if (key === "data") {
|
|
639
|
+
const data = value;
|
|
640
|
+
const AutoplayUser = data?.Internal_AutoplayUser;
|
|
641
|
+
const serializedUser = AutoplayUser ? { id: AutoplayUser.id, username: AutoplayUser.username } : null;
|
|
650
642
|
return {
|
|
651
|
-
clientUser:
|
|
643
|
+
clientUser: serializedUser,
|
|
644
|
+
autoplayTries: data?.autoplayTries ?? null,
|
|
652
645
|
};
|
|
653
646
|
}
|
|
654
|
-
return
|
|
655
|
-
}
|
|
647
|
+
return value;
|
|
648
|
+
};
|
|
649
|
+
const jsonString = (0, safe_stable_stringify_1.default)(player, replacer, 2);
|
|
650
|
+
return JSON.parse(jsonString);
|
|
656
651
|
}
|
|
657
652
|
/**
|
|
658
653
|
* Gets the base directory for player data.
|
|
@@ -718,6 +713,12 @@ class Structure {
|
|
|
718
713
|
}
|
|
719
714
|
}
|
|
720
715
|
exports.Structure = Structure;
|
|
716
|
+
class JSONUtils {
|
|
717
|
+
static safe(obj, space) {
|
|
718
|
+
return (0, safe_stable_stringify_1.default)(obj, null, space);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
exports.JSONUtils = JSONUtils;
|
|
721
722
|
const structures = {
|
|
722
723
|
Player: require("./Player").Player,
|
|
723
724
|
Queue: require("../statestorage/MemoryQueue").MemoryQueue,
|
|
@@ -32,5 +32,21 @@ class DetritusManager extends Manager_1.Manager {
|
|
|
32
32
|
shard.gateway.send(packet.op, packet.d);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
async resolveUser(user) {
|
|
36
|
+
const id = typeof user === "string" ? user : user.id;
|
|
37
|
+
if (this.client instanceof detritus_client_1.ShardClient) {
|
|
38
|
+
const cached = this.client.users.get(id);
|
|
39
|
+
if (cached)
|
|
40
|
+
return { id: cached.id, username: cached.username };
|
|
41
|
+
}
|
|
42
|
+
else if (this.client instanceof detritus_client_1.ClusterClient) {
|
|
43
|
+
for (const [, shard] of this.client.shards) {
|
|
44
|
+
const cached = shard.users.get(id);
|
|
45
|
+
if (cached)
|
|
46
|
+
return { id: cached.id, username: cached.username };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return typeof user === "string" ? { id: user } : user;
|
|
50
|
+
}
|
|
35
51
|
}
|
|
36
52
|
exports.DetritusManager = DetritusManager;
|
|
@@ -38,5 +38,18 @@ class DiscordJSManager extends Manager_1.Manager {
|
|
|
38
38
|
if (guild)
|
|
39
39
|
guild.shard.send(packet);
|
|
40
40
|
}
|
|
41
|
+
async resolveUser(user) {
|
|
42
|
+
const id = typeof user === "string" ? user : user.id;
|
|
43
|
+
const cached = this.client.users.cache.get(id);
|
|
44
|
+
if (cached)
|
|
45
|
+
return cached;
|
|
46
|
+
try {
|
|
47
|
+
const fetched = await this.client.users.fetch(id);
|
|
48
|
+
return fetched;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return { id, username: typeof user === "string" ? undefined : user.username };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
41
54
|
}
|
|
42
55
|
exports.DiscordJSManager = DiscordJSManager;
|
package/dist/wrappers/eris.js
CHANGED
|
@@ -25,5 +25,15 @@ class ErisManager extends Manager_1.Manager {
|
|
|
25
25
|
if (guild)
|
|
26
26
|
guild.shard.sendWS(packet.op, packet.d);
|
|
27
27
|
}
|
|
28
|
+
async resolveUser(user) {
|
|
29
|
+
const id = typeof user === "string" ? user : user.id;
|
|
30
|
+
const cached = this.client.users.get(id);
|
|
31
|
+
if (cached)
|
|
32
|
+
return cached;
|
|
33
|
+
return {
|
|
34
|
+
id,
|
|
35
|
+
username: typeof user === "string" ? undefined : user.username,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
28
38
|
}
|
|
29
39
|
exports.ErisManager = ErisManager;
|
package/dist/wrappers/oceanic.js
CHANGED
|
@@ -25,5 +25,15 @@ class OceanicManager extends Manager_1.Manager {
|
|
|
25
25
|
if (guild)
|
|
26
26
|
guild.shard.send(packet.op, packet.d);
|
|
27
27
|
}
|
|
28
|
+
async resolveUser(user) {
|
|
29
|
+
const id = typeof user === "string" ? user : user.id;
|
|
30
|
+
const cached = this.client.users.get(id);
|
|
31
|
+
if (cached)
|
|
32
|
+
return cached;
|
|
33
|
+
return {
|
|
34
|
+
id,
|
|
35
|
+
username: typeof user === "string" ? undefined : user.username,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
28
38
|
}
|
|
29
39
|
exports.OceanicManager = OceanicManager;
|
package/dist/wrappers/seyfert.js
CHANGED
|
@@ -38,11 +38,23 @@ class SeyfertManager extends Manager_1.Manager {
|
|
|
38
38
|
this.client = client;
|
|
39
39
|
}
|
|
40
40
|
send(packet) {
|
|
41
|
-
if (this.client instanceof seyfert_1.
|
|
42
|
-
this.client.
|
|
41
|
+
if (this.client instanceof seyfert_1.Client) {
|
|
42
|
+
this.client.gateway.send((0, common_1.calculateShardId)(packet.d.guild_id), packet);
|
|
43
43
|
}
|
|
44
44
|
else {
|
|
45
|
-
this.client.
|
|
45
|
+
this.client.shards.get((0, common_1.calculateShardId)(packet.d.guild_id))?.send(true, packet);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async resolveUser(user) {
|
|
49
|
+
const id = typeof user === "string" ? user : user.id;
|
|
50
|
+
const cached = this.client.cache.users?.get(id);
|
|
51
|
+
if (cached)
|
|
52
|
+
return cached;
|
|
53
|
+
try {
|
|
54
|
+
return await this.client.users.fetch(id);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return { id, username: typeof user === "string" ? undefined : user.username };
|
|
46
58
|
}
|
|
47
59
|
}
|
|
48
60
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "magmastream",
|
|
3
|
-
"version": "2.9.1-dev.
|
|
3
|
+
"version": "2.9.1-dev.4",
|
|
4
4
|
"description": "A user-friendly Lavalink client designed for NodeJS.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"ioredis": "^5.6.1",
|
|
36
36
|
"jsdom": "^26.1.0",
|
|
37
37
|
"lodash": "^4.17.21",
|
|
38
|
+
"safe-stable-stringify": "^2.5.0",
|
|
38
39
|
"tslib": "^2.8.1",
|
|
39
40
|
"ws": "^8.18.3"
|
|
40
41
|
},
|