magmastream 2.9.3-dev.23 → 2.9.3-dev.24
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 +6 -0
- package/dist/structures/Manager.js +61 -78
- package/dist/structures/Node.js +2 -1
- package/dist/wrappers/discordeno.js +4 -0
- package/package.json +105 -105
package/dist/index.d.ts
CHANGED
|
@@ -915,6 +915,10 @@ interface ManagerOptions {
|
|
|
915
915
|
* @default UseNodeOptions.LeastPlayers
|
|
916
916
|
*/
|
|
917
917
|
useNode?: UseNodeOptions.LeastLoad | UseNodeOptions.LeastPlayers;
|
|
918
|
+
/** Whether the manager should listen to SIGINT and SIGTERM events.
|
|
919
|
+
* @default true
|
|
920
|
+
*/
|
|
921
|
+
listenToSIGEvents?: boolean;
|
|
918
922
|
/**
|
|
919
923
|
* Function to send data to the websocket.
|
|
920
924
|
* @param id The ID of the node to send the data to.
|
|
@@ -3151,6 +3155,7 @@ declare class Manager extends EventEmitter {
|
|
|
3151
3155
|
private get priorityNode();
|
|
3152
3156
|
protected send(packet: GatewayVoiceStateUpdate): unknown;
|
|
3153
3157
|
protected getUserFromCache(id: string): AnyUser | undefined;
|
|
3158
|
+
protected getGuildFromCache(id: string): AnyGuild | undefined;
|
|
3154
3159
|
sendPacket(packet: GatewayVoiceStateUpdate): unknown;
|
|
3155
3160
|
/**
|
|
3156
3161
|
* Resolves a PortableUser or ID to a real user object.
|
|
@@ -3703,6 +3708,7 @@ declare class DiscordenoManager extends Manager {
|
|
|
3703
3708
|
* Uses user-provided cache getter if available, otherwise falls back to minimal info.
|
|
3704
3709
|
*/
|
|
3705
3710
|
resolveUser(user: AnyUser | string): Promise<User$2 | AnyUser>;
|
|
3711
|
+
resolveGuild(guildId: string): AnyGuild;
|
|
3706
3712
|
}
|
|
3707
3713
|
|
|
3708
3714
|
/**
|
|
@@ -95,6 +95,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
95
95
|
deleteDestroyedPlayers: options.stateStorage?.deleteDestroyedPlayers ?? true,
|
|
96
96
|
},
|
|
97
97
|
autoPlaySearchPlatforms: options.autoPlaySearchPlatforms ?? [Enums_1.AutoPlayPlatform.YouTube],
|
|
98
|
+
listenToSIGEvents: options.listenToSIGEvents ?? true,
|
|
98
99
|
send: this._send,
|
|
99
100
|
};
|
|
100
101
|
Utils_1.AutoPlayUtils.init(this);
|
|
@@ -102,49 +103,51 @@ class Manager extends events_1.EventEmitter {
|
|
|
102
103
|
for (const nodeOptions of this.options.nodes)
|
|
103
104
|
new Node_1.Node(this, nodeOptions);
|
|
104
105
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
if (this.options.listenToSIGEvents) {
|
|
107
|
+
process.on("SIGINT", async () => {
|
|
108
|
+
console.warn("\x1b[33mSIGINT received! Graceful shutdown initiated...\x1b[0m");
|
|
109
|
+
try {
|
|
110
|
+
await this.handleShutdown();
|
|
111
|
+
console.warn("\x1b[32mShutdown complete. Waiting for Node.js event loop to empty...\x1b[0m");
|
|
112
|
+
// Prevent forced exit by Windows
|
|
113
|
+
setTimeout(() => {
|
|
114
|
+
process.exit(0);
|
|
115
|
+
}, 2000);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
119
|
+
? err
|
|
120
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
121
|
+
code: Enums_1.MagmaStreamErrorCode.MANAGER_SHUTDOWN_FAILED,
|
|
122
|
+
message: "An unknown error occurred.",
|
|
123
|
+
cause: err,
|
|
124
|
+
context: { stage: "SIGINT" },
|
|
125
|
+
});
|
|
126
|
+
console.error(error);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
process.on("SIGTERM", async () => {
|
|
131
|
+
console.warn("\x1b[33mSIGTERM received! Graceful shutdown initiated...\x1b[0m");
|
|
132
|
+
try {
|
|
133
|
+
await this.handleShutdown();
|
|
134
|
+
console.warn("\x1b[32mShutdown complete. Exiting now...\x1b[0m");
|
|
112
135
|
process.exit(0);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
process.on("SIGTERM", async () => {
|
|
129
|
-
console.warn("\x1b[33mSIGTERM received! Graceful shutdown initiated...\x1b[0m");
|
|
130
|
-
try {
|
|
131
|
-
await this.handleShutdown();
|
|
132
|
-
console.warn("\x1b[32mShutdown complete. Exiting now...\x1b[0m");
|
|
133
|
-
process.exit(0);
|
|
134
|
-
}
|
|
135
|
-
catch (err) {
|
|
136
|
-
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
137
|
-
? err
|
|
138
|
-
: new MagmastreamError_1.MagmaStreamError({
|
|
139
|
-
code: Enums_1.MagmaStreamErrorCode.MANAGER_SHUTDOWN_FAILED,
|
|
140
|
-
message: "An unknown error occurred.",
|
|
141
|
-
cause: err,
|
|
142
|
-
context: { stage: "SIGTERM" },
|
|
143
|
-
});
|
|
144
|
-
console.error(error);
|
|
145
|
-
process.exit(1);
|
|
146
|
-
}
|
|
147
|
-
});
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
139
|
+
? err
|
|
140
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
141
|
+
code: Enums_1.MagmaStreamErrorCode.MANAGER_SHUTDOWN_FAILED,
|
|
142
|
+
message: "An unknown error occurred.",
|
|
143
|
+
cause: err,
|
|
144
|
+
context: { stage: "SIGTERM" },
|
|
145
|
+
});
|
|
146
|
+
console.error(error);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
148
151
|
}
|
|
149
152
|
/**
|
|
150
153
|
* Initiates the Manager.
|
|
@@ -527,10 +530,10 @@ class Manager extends events_1.EventEmitter {
|
|
|
527
530
|
});
|
|
528
531
|
// Read guild directories inside players base dir
|
|
529
532
|
const guildDirs = await promises_1.default.readdir(playersBaseDir, { withFileTypes: true });
|
|
530
|
-
for (const
|
|
531
|
-
if (!
|
|
533
|
+
for (const file of guildDirs) {
|
|
534
|
+
if (!file.isDirectory())
|
|
532
535
|
continue;
|
|
533
|
-
const guildId =
|
|
536
|
+
const guildId = file.name;
|
|
534
537
|
const stateFilePath = Utils_1.PlayerUtils.getPlayerStatePath(guildId);
|
|
535
538
|
try {
|
|
536
539
|
await promises_1.default.access(stateFilePath);
|
|
@@ -556,23 +559,9 @@ class Manager extends events_1.EventEmitter {
|
|
|
556
559
|
applyVolumeAsFilter: state.options.applyVolumeAsFilter,
|
|
557
560
|
pauseOnDisconnect: state.options.pauseOnDisconnect,
|
|
558
561
|
};
|
|
559
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${state.guildId} from saved file: ${Utils_1.JSONUtils.safe(state.options, 2)}`);
|
|
560
562
|
const player = this.create(playerOptions);
|
|
563
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${state.guildId} from saved file: ${Utils_1.JSONUtils.safe(state.options, 2)}`);
|
|
561
564
|
player.connect();
|
|
562
|
-
await player.node.rest.updatePlayer({
|
|
563
|
-
guildId: state.options.guildId,
|
|
564
|
-
data: {
|
|
565
|
-
voice: {
|
|
566
|
-
token: state.voiceState.event.token,
|
|
567
|
-
endpoint: state.voiceState.event.endpoint,
|
|
568
|
-
sessionId: state.voiceState.sessionId,
|
|
569
|
-
channelId: state.voiceState.channelId,
|
|
570
|
-
},
|
|
571
|
-
},
|
|
572
|
-
});
|
|
573
|
-
const tracks = [];
|
|
574
|
-
const currentTrack = state.queue.current;
|
|
575
|
-
const queueTracks = state.queue.tracks;
|
|
576
565
|
if (state.isAutoplay) {
|
|
577
566
|
const savedUser = state.data.clientUser;
|
|
578
567
|
if (savedUser) {
|
|
@@ -584,6 +573,9 @@ class Manager extends events_1.EventEmitter {
|
|
|
584
573
|
if (savedNowPlayingMessage) {
|
|
585
574
|
player.setNowPlayingMessage(savedNowPlayingMessage);
|
|
586
575
|
}
|
|
576
|
+
const tracks = [];
|
|
577
|
+
const currentTrack = state.queue.current;
|
|
578
|
+
const queueTracks = state.queue.tracks;
|
|
587
579
|
if (lavaPlayer.track) {
|
|
588
580
|
await player.queue.clear();
|
|
589
581
|
if (currentTrack) {
|
|
@@ -732,9 +724,8 @@ class Manager extends events_1.EventEmitter {
|
|
|
732
724
|
if (!hasGuild)
|
|
733
725
|
continue;
|
|
734
726
|
const lavaPlayer = await node.rest.getPlayer(state.guildId);
|
|
735
|
-
if (!lavaPlayer)
|
|
727
|
+
if (!lavaPlayer)
|
|
736
728
|
await this.destroy(guildId);
|
|
737
|
-
}
|
|
738
729
|
const playerOptions = {
|
|
739
730
|
guildId: state.options.guildId,
|
|
740
731
|
textChannelId: state.options.textChannelId,
|
|
@@ -745,24 +736,9 @@ class Manager extends events_1.EventEmitter {
|
|
|
745
736
|
applyVolumeAsFilter: state.options.applyVolumeAsFilter,
|
|
746
737
|
pauseOnDisconnect: state.options.pauseOnDisconnect,
|
|
747
738
|
};
|
|
748
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${guildId} from Redis`);
|
|
749
739
|
const player = this.create(playerOptions);
|
|
740
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${guildId} from Redis`);
|
|
750
741
|
player.connect();
|
|
751
|
-
await player.node.rest.updatePlayer({
|
|
752
|
-
guildId: state.options.guildId,
|
|
753
|
-
data: {
|
|
754
|
-
voice: {
|
|
755
|
-
token: state.voiceState.event.token,
|
|
756
|
-
endpoint: state.voiceState.event.endpoint,
|
|
757
|
-
sessionId: state.voiceState.sessionId,
|
|
758
|
-
channelId: state.voiceState.channelId,
|
|
759
|
-
},
|
|
760
|
-
},
|
|
761
|
-
});
|
|
762
|
-
// Rest of the player state restoration code (tracks, filters, etc.)
|
|
763
|
-
const tracks = [];
|
|
764
|
-
const currentTrack = state.queue.current;
|
|
765
|
-
const queueTracks = state.queue.tracks;
|
|
766
742
|
if (state.isAutoplay) {
|
|
767
743
|
const savedUser = state.data.clientUser;
|
|
768
744
|
if (savedUser) {
|
|
@@ -774,6 +750,10 @@ class Manager extends events_1.EventEmitter {
|
|
|
774
750
|
if (savedNowPlayingMessage) {
|
|
775
751
|
player.setNowPlayingMessage(savedNowPlayingMessage);
|
|
776
752
|
}
|
|
753
|
+
// Rest of the player state restoration code (tracks, filters, etc.)
|
|
754
|
+
const tracks = [];
|
|
755
|
+
const currentTrack = state.queue.current;
|
|
756
|
+
const queueTracks = state.queue.tracks;
|
|
777
757
|
if (lavaPlayer.track) {
|
|
778
758
|
await player.queue.clear();
|
|
779
759
|
if (currentTrack) {
|
|
@@ -1352,6 +1332,9 @@ class Manager extends events_1.EventEmitter {
|
|
|
1352
1332
|
getUserFromCache(id) {
|
|
1353
1333
|
return this._getUser?.(id);
|
|
1354
1334
|
}
|
|
1335
|
+
getGuildFromCache(id) {
|
|
1336
|
+
return this._getGuild?.(id);
|
|
1337
|
+
}
|
|
1355
1338
|
sendPacket(packet) {
|
|
1356
1339
|
return this.send(packet);
|
|
1357
1340
|
}
|
package/dist/structures/Node.js
CHANGED
|
@@ -127,7 +127,8 @@ class Node {
|
|
|
127
127
|
}
|
|
128
128
|
getNodeSessionPath() {
|
|
129
129
|
const safeId = String(this.options.identifier).replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
130
|
-
|
|
130
|
+
const clusterId = String(this.manager.options.clusterId ?? 0);
|
|
131
|
+
return path_1.default.join(this.getNodeSessionsDir(), `${safeId}__${clusterId}.txt`);
|
|
131
132
|
}
|
|
132
133
|
/**
|
|
133
134
|
* Loads session IDs from the sessionIds.json file if it exists.
|
|
@@ -69,5 +69,9 @@ class DiscordenoManager extends Manager_1.Manager {
|
|
|
69
69
|
username: typeof user === "string" ? undefined : user.username,
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
|
+
resolveGuild(guildId) {
|
|
73
|
+
// Try user-provided cache getter
|
|
74
|
+
return this.getGuildFromCache(guildId);
|
|
75
|
+
}
|
|
72
76
|
}
|
|
73
77
|
exports.DiscordenoManager = DiscordenoManager;
|
package/package.json
CHANGED
|
@@ -1,107 +1,107 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
2
|
+
"name": "magmastream",
|
|
3
|
+
"version": "2.9.3-dev.24",
|
|
4
|
+
"description": "A user-friendly Lavalink client designed for NodeJS.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"types": "rtb --dist dist",
|
|
13
|
+
"format": "prettier --write .",
|
|
14
|
+
"format:check": "prettier --check .",
|
|
15
|
+
"lint": "eslint \"src/**/*.{ts,js}\"",
|
|
16
|
+
"lint:fix": "eslint --fix \"src/**/*.{ts,js}\"",
|
|
17
|
+
"ci": "run-s format:check lint build types",
|
|
18
|
+
"release:dev": "npm run format && npm run lint:fix && npm run ci && npm version prerelease --preid=dev && git push && npm publish --tag dev"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@favware/rollup-type-bundler": "^4.0.0",
|
|
22
|
+
"@types/jsdom": "^28.0.0",
|
|
23
|
+
"@types/lodash": "^4.17.24",
|
|
24
|
+
"@types/node": "^25.3.0",
|
|
25
|
+
"@types/ws": "^8.18.1",
|
|
26
|
+
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
27
|
+
"@typescript-eslint/parser": "^8.56.0",
|
|
28
|
+
"eslint": "^10.0.2",
|
|
29
|
+
"npm-run-all": "^4.1.5",
|
|
30
|
+
"prettier": "^3.8.1",
|
|
31
|
+
"typedoc": "^0.28.17",
|
|
32
|
+
"typedoc-plugin-no-inherit": "^1.6.1",
|
|
33
|
+
"typescript": "^5.9.3"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@discordjs/collection": "^2.1.1",
|
|
37
|
+
"axios": "^1.13.6",
|
|
38
|
+
"events": "^3.3.0",
|
|
39
|
+
"ioredis": "^5.10.0",
|
|
40
|
+
"jsdom": "^28.1.0",
|
|
41
|
+
"lodash": "^4.17.23",
|
|
42
|
+
"safe-stable-stringify": "^2.5.0",
|
|
43
|
+
"tslib": "^2.8.1",
|
|
44
|
+
"ws": "^8.19.0"
|
|
45
|
+
},
|
|
46
|
+
"optionalDependencies": {
|
|
47
|
+
"discord.js": "14.x",
|
|
48
|
+
"discordeno": "21.x",
|
|
49
|
+
"eris": "0.18.x",
|
|
50
|
+
"oceanic.js": "1.13.x",
|
|
51
|
+
"seyfert": "4.x"
|
|
52
|
+
},
|
|
53
|
+
"overrides": {
|
|
54
|
+
"undici": "^7.0.0"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=20.19.0"
|
|
58
|
+
},
|
|
59
|
+
"eslintConfig": {
|
|
60
|
+
"root": true,
|
|
61
|
+
"parser": "@typescript-eslint/parser",
|
|
62
|
+
"plugins": [
|
|
63
|
+
"@typescript-eslint"
|
|
64
|
+
],
|
|
65
|
+
"rules": {
|
|
66
|
+
"object-curly-spacing": [
|
|
67
|
+
"error",
|
|
68
|
+
"always"
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
"extends": [
|
|
72
|
+
"eslint:recommended",
|
|
73
|
+
"plugin:@typescript-eslint/recommended"
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
"keywords": [
|
|
77
|
+
"lavalink client",
|
|
78
|
+
"wrapper",
|
|
79
|
+
"typescript",
|
|
80
|
+
"discord.js",
|
|
81
|
+
"node.js",
|
|
82
|
+
"java",
|
|
83
|
+
"javascript",
|
|
84
|
+
"audio streaming",
|
|
85
|
+
"music bot",
|
|
86
|
+
"voice chat",
|
|
87
|
+
"discord integration",
|
|
88
|
+
"high performance",
|
|
89
|
+
"scalable",
|
|
90
|
+
"easy-to-use",
|
|
91
|
+
"feature-rich",
|
|
92
|
+
"cross-platform",
|
|
93
|
+
"seamless integration",
|
|
94
|
+
"community support",
|
|
95
|
+
"documentation",
|
|
96
|
+
"open-source",
|
|
97
|
+
"lavalink",
|
|
98
|
+
"magmastream"
|
|
99
|
+
],
|
|
100
|
+
"repository": {
|
|
101
|
+
"type": "git",
|
|
102
|
+
"url": "git+https://gitryx.com/MagmaStream/magmastream.git#main"
|
|
103
|
+
},
|
|
104
|
+
"homepage": "https://docs.magmastream.com",
|
|
105
|
+
"author": "Abel Purnwasy",
|
|
106
|
+
"license": "Apache-2.0"
|
|
107
107
|
}
|