magmastream 2.9.0-dev.40 → 2.9.0-dev.41
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 +7 -3
- package/dist/structures/Manager.js +13 -15
- package/dist/structures/Node.js +14 -2
- package/dist/utils/nodeCheck.js +5 -5
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -965,10 +965,10 @@ interface NodeOptions {
|
|
|
965
965
|
* @default false
|
|
966
966
|
*/
|
|
967
967
|
enableSessionResumeOption?: boolean;
|
|
968
|
-
/** The time the lavalink server will wait before it removes the player.
|
|
969
|
-
* @default
|
|
968
|
+
/** The time in seconds the lavalink server will wait before it removes the player.
|
|
969
|
+
* @default 60
|
|
970
970
|
*/
|
|
971
|
-
|
|
971
|
+
sessionTimeoutSeconds?: number;
|
|
972
972
|
/** The timeout used for api calls.
|
|
973
973
|
* @default 10000
|
|
974
974
|
*/
|
|
@@ -981,6 +981,10 @@ interface NodeOptions {
|
|
|
981
981
|
* @default false
|
|
982
982
|
*/
|
|
983
983
|
isNodeLink?: boolean;
|
|
984
|
+
/** Whether the node is a backup node.
|
|
985
|
+
* @default false
|
|
986
|
+
*/
|
|
987
|
+
isBackup?: boolean;
|
|
984
988
|
}
|
|
985
989
|
/**
|
|
986
990
|
* Discord Packet
|
|
@@ -70,7 +70,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
70
70
|
password: "Try BlackForHosting",
|
|
71
71
|
useSSL: true,
|
|
72
72
|
enableSessionResumeOption: false,
|
|
73
|
-
|
|
73
|
+
sessionTimeoutSeconds: 1000,
|
|
74
74
|
nodePriority: 69,
|
|
75
75
|
},
|
|
76
76
|
],
|
|
@@ -1127,30 +1127,30 @@ class Manager extends events_1.EventEmitter {
|
|
|
1127
1127
|
switch (this.options.stateStorage.type) {
|
|
1128
1128
|
case Enums_1.StateStorageType.JSON:
|
|
1129
1129
|
{
|
|
1130
|
-
const
|
|
1131
|
-
const
|
|
1130
|
+
const playerStoreDir = path_1.default.join(process.cwd(), "magmastream", "dist", "sessionData", "playerStore");
|
|
1131
|
+
const playerDataDir = this.options.stateStorage?.jsonConfig?.path ?? path_1.default.join(process.cwd(), "magmastream", "dist", "sessionData", "players");
|
|
1132
1132
|
try {
|
|
1133
|
-
await promises_1.default.mkdir(
|
|
1134
|
-
await promises_1.default.mkdir(
|
|
1133
|
+
await promises_1.default.mkdir(playerStoreDir, { recursive: true });
|
|
1134
|
+
await promises_1.default.mkdir(playerDataDir, { recursive: true });
|
|
1135
1135
|
const activeGuildIds = new Set(this.players.keys());
|
|
1136
|
-
// Clean up
|
|
1137
|
-
const playerStateFiles = await promises_1.default.readdir(
|
|
1136
|
+
// Clean up playerStore/*.json
|
|
1137
|
+
const playerStateFiles = await promises_1.default.readdir(playerStoreDir);
|
|
1138
1138
|
for (const file of playerStateFiles) {
|
|
1139
1139
|
const guildId = path_1.default.basename(file, ".json");
|
|
1140
1140
|
if (!activeGuildIds.has(guildId)) {
|
|
1141
|
-
const filePath = path_1.default.join(
|
|
1141
|
+
const filePath = path_1.default.join(playerStoreDir, file);
|
|
1142
1142
|
await promises_1.default.unlink(filePath);
|
|
1143
1143
|
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Deleted inactive player state: ${guildId}`);
|
|
1144
1144
|
}
|
|
1145
1145
|
}
|
|
1146
1146
|
// Clean up players/<guildId>/ folders
|
|
1147
|
-
const guildDirs = await promises_1.default.readdir(
|
|
1147
|
+
const guildDirs = await promises_1.default.readdir(playerDataDir, { withFileTypes: true });
|
|
1148
1148
|
for (const dirent of guildDirs) {
|
|
1149
1149
|
if (!dirent.isDirectory())
|
|
1150
1150
|
continue;
|
|
1151
1151
|
const guildId = dirent.name;
|
|
1152
1152
|
if (!activeGuildIds.has(guildId)) {
|
|
1153
|
-
const guildPath = path_1.default.join(
|
|
1153
|
+
const guildPath = path_1.default.join(playerDataDir, guildId);
|
|
1154
1154
|
await promises_1.default.rm(guildPath, { recursive: true, force: true });
|
|
1155
1155
|
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Deleted inactive player data folder: ${guildId}`);
|
|
1156
1156
|
}
|
|
@@ -1202,7 +1202,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
1202
1202
|
switch (this.options.stateStorage.type) {
|
|
1203
1203
|
case Enums_1.StateStorageType.JSON:
|
|
1204
1204
|
{
|
|
1205
|
-
const playersStoreDir = path_1.default.join(process.cwd(), "magmastream", "dist", "sessionData", "
|
|
1205
|
+
const playersStoreDir = path_1.default.join(process.cwd(), "magmastream", "dist", "sessionData", "playerStore");
|
|
1206
1206
|
const playersDataDir = this.options.stateStorage?.jsonConfig?.path ?? path_1.default.join(process.cwd(), "magmastream", "dist", "sessionData", "players");
|
|
1207
1207
|
try {
|
|
1208
1208
|
if (!this.players.has(guildId)) {
|
|
@@ -1344,7 +1344,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
1344
1344
|
*/
|
|
1345
1345
|
get leastLoadNode() {
|
|
1346
1346
|
return this.nodes
|
|
1347
|
-
.filter((node) => node.connected)
|
|
1347
|
+
.filter((node) => node.connected && !node.options.isBackup)
|
|
1348
1348
|
.sort((a, b) => {
|
|
1349
1349
|
const aload = a.stats.cpu ? (a.stats.cpu.lavalinkLoad / a.stats.cpu.cores) * 100 : 0;
|
|
1350
1350
|
const bload = b.stats.cpu ? (b.stats.cpu.lavalinkLoad / b.stats.cpu.cores) * 100 : 0;
|
|
@@ -1359,9 +1359,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
1359
1359
|
* @returns {Collection<string, Node>} A collection of nodes sorted by player count.
|
|
1360
1360
|
*/
|
|
1361
1361
|
get leastPlayersNode() {
|
|
1362
|
-
return this.nodes
|
|
1363
|
-
.filter((node) => node.connected) // Filter out nodes that are not connected
|
|
1364
|
-
.sort((a, b) => a.stats.players - b.stats.players); // Sort by the number of players
|
|
1362
|
+
return this.nodes.filter((node) => node.connected && !node.options.isBackup).sort((a, b) => a.stats.players - b.stats.players);
|
|
1365
1363
|
}
|
|
1366
1364
|
/**
|
|
1367
1365
|
* Returns a node based on priority.
|
package/dist/structures/Node.js
CHANGED
|
@@ -56,10 +56,11 @@ class Node {
|
|
|
56
56
|
maxRetryAttempts: options.maxRetryAttempts ?? 30,
|
|
57
57
|
retryDelayMs: options.retryDelayMs ?? 60000,
|
|
58
58
|
enableSessionResumeOption: options.enableSessionResumeOption ?? false,
|
|
59
|
-
|
|
59
|
+
sessionTimeoutSeconds: options.sessionTimeoutSeconds ?? 60,
|
|
60
60
|
apiRequestTimeoutMs: options.apiRequestTimeoutMs ?? 10000,
|
|
61
61
|
nodePriority: options.nodePriority ?? 0,
|
|
62
62
|
isNodeLink: options.isNodeLink ?? false,
|
|
63
|
+
isBackup: options.isBackup ?? false,
|
|
63
64
|
};
|
|
64
65
|
if (this.options.useSSL) {
|
|
65
66
|
this.options.port = 443;
|
|
@@ -373,6 +374,10 @@ class Node {
|
|
|
373
374
|
};
|
|
374
375
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Connected node: ${JSON.stringify(debugInfo)}`);
|
|
375
376
|
this.manager.emit(Enums_1.ManagerEventTypes.NodeConnect, this);
|
|
377
|
+
const playersOnBackupNode = this.manager.players.filter((p) => p.node.options.isBackup);
|
|
378
|
+
if (playersOnBackupNode.size) {
|
|
379
|
+
Promise.all(Array.from(playersOnBackupNode.values(), (player) => player.moveNode(this.options.identifier)));
|
|
380
|
+
}
|
|
376
381
|
}
|
|
377
382
|
/**
|
|
378
383
|
* Handles the "close" event emitted by the WebSocket connection.
|
|
@@ -401,6 +406,13 @@ class Node {
|
|
|
401
406
|
await Promise.all(Array.from(players.values(), (player) => player.autoMoveNode()));
|
|
402
407
|
}
|
|
403
408
|
}
|
|
409
|
+
else {
|
|
410
|
+
const backUpNodes = this.manager.nodes.filter((node) => node.options.isBackup && node.connected);
|
|
411
|
+
const backupNode = backUpNodes.first();
|
|
412
|
+
if (backupNode) {
|
|
413
|
+
await Promise.all(Array.from(this.manager.players.values(), (player) => player.moveNode(backupNode.options.identifier)));
|
|
414
|
+
}
|
|
415
|
+
}
|
|
404
416
|
if (code !== 1000 || reason !== "destroy")
|
|
405
417
|
await this.reconnect();
|
|
406
418
|
}
|
|
@@ -474,7 +486,7 @@ class Node {
|
|
|
474
486
|
if (this.options.enableSessionResumeOption) {
|
|
475
487
|
await this.rest.patch(`/v4/sessions/${this.sessionId}`, {
|
|
476
488
|
resuming: this.options.enableSessionResumeOption,
|
|
477
|
-
timeout: this.options.
|
|
489
|
+
timeout: this.options.sessionTimeoutSeconds,
|
|
478
490
|
});
|
|
479
491
|
}
|
|
480
492
|
break;
|
package/dist/utils/nodeCheck.js
CHANGED
|
@@ -12,7 +12,7 @@ function nodeCheck(options) {
|
|
|
12
12
|
throw new TypeError("NodeOptions must not be empty.");
|
|
13
13
|
// Validate the host option
|
|
14
14
|
// The host option must be present and be a non-empty string.
|
|
15
|
-
const { host, identifier, password, port, enableSessionResumeOption,
|
|
15
|
+
const { host, identifier, password, port, enableSessionResumeOption, sessionTimeoutSeconds, maxRetryAttempts, retryDelayMs, useSSL, nodePriority } = options;
|
|
16
16
|
if (typeof host !== "string" || !/.+/.test(host)) {
|
|
17
17
|
throw new TypeError('Node option "host" must be present and be a non-empty string.');
|
|
18
18
|
}
|
|
@@ -36,10 +36,10 @@ function nodeCheck(options) {
|
|
|
36
36
|
if (typeof enableSessionResumeOption !== "undefined" && typeof enableSessionResumeOption !== "boolean") {
|
|
37
37
|
throw new TypeError('Node option "enableSessionResumeOption" must be a boolean.');
|
|
38
38
|
}
|
|
39
|
-
// Validate the
|
|
40
|
-
// The
|
|
41
|
-
if (typeof
|
|
42
|
-
throw new TypeError('Node option "
|
|
39
|
+
// Validate the sessionTimeoutSeconds option
|
|
40
|
+
// The sessionTimeoutSeconds option must be a number or undefined.
|
|
41
|
+
if (typeof sessionTimeoutSeconds !== "undefined" && typeof sessionTimeoutSeconds !== "number") {
|
|
42
|
+
throw new TypeError('Node option "sessionTimeoutSeconds" must be a number.');
|
|
43
43
|
}
|
|
44
44
|
// Validate the maxRetryAttempts option
|
|
45
45
|
// The maxRetryAttempts option must be a number or undefined.
|