muthera 1.0.4 → 1.0.5

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/package.json CHANGED
@@ -1,31 +1,31 @@
1
- {
2
- "name": "muthera",
3
- "version": "1.0.4",
4
- "description": "A simple Lavalink wrapper for Discord music bot. Forked from Niizuki.",
5
- "main": "src/index.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "author": "urfavteddybear",
10
- "license": "ISC",
11
- "dependencies": {
12
- "@discordjs/collection": "^2.1.1",
13
- "jsdom": "^26.1.0",
14
- "ws": "^8.18.3"
15
- },
16
- "repository": {
17
- "type": "git",
18
- "url": "git+https://github.com/urfavteddybear/muthera.git"
19
- },
20
- "bugs": {
21
- "url": "https://github.com/urfavteddybear/muthera/issues"
22
- },
23
- "homepage": "https://github.com/urfavteddybear/muthera#readme",
24
- "keywords": [
25
- "wrapper",
26
- "discord",
27
- "lavalink-v4",
28
- "lavalink",
29
- "music-bot"
30
- ]
31
- }
1
+ {
2
+ "name": "muthera",
3
+ "version": "1.0.5",
4
+ "description": "A simple Lavalink wrapper for Discord music bot. Forked from Niizuki.",
5
+ "main": "src/index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "author": "urfavteddybear",
10
+ "license": "ISC",
11
+ "dependencies": {
12
+ "@discordjs/collection": "^2.1.1",
13
+ "jsdom": "^26.1.0",
14
+ "ws": "^8.18.3"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/urfavteddybear/muthera.git"
19
+ },
20
+ "bugs": {
21
+ "url": "https://github.com/urfavteddybear/muthera/issues"
22
+ },
23
+ "homepage": "https://github.com/urfavteddybear/muthera#readme",
24
+ "keywords": [
25
+ "wrapper",
26
+ "discord",
27
+ "lavalink-v4",
28
+ "lavalink",
29
+ "music-bot"
30
+ ]
31
+ }
package/src/index.d.ts CHANGED
@@ -381,7 +381,11 @@ export type Voice = {
381
381
  /**
382
382
  * The voice endpoint
383
383
  */
384
- endpoint: String
384
+ endpoint: String,
385
+ /**
386
+ * The voice channel id
387
+ */
388
+ channelId: String
385
389
  }
386
390
 
387
391
  export declare class Connection {
@@ -1,191 +1,191 @@
1
- const { EventEmitter } = require("events");
2
- const { Node } = require("./mutheraNode");
3
- const { Player } = require("./mutheraPlayer");
4
- const { Track } = require("./mutheraTrack");
5
- const { Collection } = require("@discordjs/collection");
6
-
7
- class Muthera extends EventEmitter {
8
- constructor(client, nodes, options) {
9
- super();
10
- if (!client)
11
- throw new Error("Client option must be present to initialize muthera.");
12
- if (!nodes)
13
- throw new Error("Node option must be present to initialize muthera.");
14
- if (!options.send)
15
- throw new Error("Send function must be present to initialize muthera.");
16
-
17
- this.client = client;
18
- this.nodes = nodes;
19
- this.nodeMap = new Collection();
20
- this.players = new Collection();
21
- this.options = options;
22
- this.clientId = null;
23
- this.initiated = false;
24
- this.send = options.send || null;
25
- this.defaultSearchPlatform = options.defaultSearchPlatform || "ytsearch";
26
- this.tracks = [];
27
- this.loadType = null;
28
- this.playlistInfo = null;
29
- }
30
-
31
- get leastUsedNodes() {
32
- return [...this.nodeMap.values()]
33
- .filter((node) => node.connected)
34
- .sort((a, b) => b.rest.calls - a.rest.calls);
35
- }
36
-
37
- init(clientId) {
38
- if (this.initiated) return this;
39
- this.clientId = clientId;
40
- this.nodes.forEach((node) => this.createNode(node));
41
- this.initiated = true;
42
- }
43
-
44
- createNode(options) {
45
- const node = new Node(this, options, this.options);
46
- this.nodeMap.set(options.name || options.host, node);
47
- node.connect();
48
-
49
- this.emit("nodeCreate", node);
50
- return node;
51
- }
52
-
53
- destroyNode(identifier) {
54
- const node = this.nodeMap.get(identifier);
55
- if (!node) return;
56
- node.disconnect();
57
- this.nodeMap.delete(identifier);
58
- this.emit("nodeDestroy", node);
59
- }
60
-
61
- updateVoiceState(packet) {
62
- if (!["VOICE_STATE_UPDATE", "VOICE_SERVER_UPDATE"].includes(packet.t))
63
- return;
64
- const player = this.players.get(packet.d.guild_id);
65
- if (!player) return;
66
-
67
- if (packet.t === "VOICE_SERVER_UPDATE") {
68
- player.connection.setServerUpdate(packet.d);
69
- } else if (packet.t === "VOICE_STATE_UPDATE") {
70
- if (packet.d.user_id !== this.clientId) return;
71
- player.connection.setStateUpdate(packet.d);
72
- }
73
- }
74
-
75
- fetchRegion(region) {
76
- const nodesByRegion = [...this.nodeMap.values()]
77
- .filter(
78
- (node) =>
79
- node.connected && node.regions?.includes(region?.toLowerCase())
80
- )
81
- .sort((a, b) => {
82
- const aLoad = a.stats.cpu
83
- ? (a.stats.cpu.systemLoad / a.stats.cpu.cores) * 100
84
- : 0;
85
- const bLoad = b.stats.cpu
86
- ? (b.stats.cpu.systemLoad / b.stats.cpu.cores) * 100
87
- : 0;
88
- return aLoad - bLoad;
89
- });
90
-
91
- return nodesByRegion;
92
- }
93
-
94
- createConnection(options) {
95
- if (!this.initiated)
96
- throw new Error("You have to initialize muthera in your event.");
97
-
98
- const player = this.players.get(options.guildId);
99
- if (player) return player;
100
-
101
- if (this.leastUsedNodes.length === 0)
102
- throw new Error("No nodes are available.");
103
-
104
- let node;
105
- if (options.node) {
106
- node = this.nodeMap.get(options.node);
107
- } else {
108
- node = this.nodeMap.get(this.leastUsedNodes[0].name);
109
- }
110
-
111
- if (!node) throw new Error("No nodes are available.");
112
-
113
- return this.createPlayer(node, options);
114
- }
115
-
116
- createPlayer(node, options) {
117
- const player = new Player(this, node, options);
118
- this.players.set(options.guildId, player);
119
-
120
- player.connect(options);
121
-
122
- this.emit("playerCreate", player);
123
- return player;
124
- }
125
-
126
- destroyPlayer(guildId) {
127
- const player = this.players.get(guildId);
128
- if (!player) return;
129
- player.destroy();
130
- this.players.delete(guildId);
131
-
132
- this.emit("playerDestroy", player);
133
- }
134
-
135
- removeConnection(guildId) {
136
- this.players.get(guildId)?.destroy();
137
- this.players.delete(guildId);
138
- }
139
-
140
- async resolve({ query, source, requester }) {
141
- try {
142
- if (!this.initiated)
143
- throw new Error("You have to initialize muthera in your event.");
144
-
145
- const sources = source || this.defaultSearchPlatform;
146
-
147
- const node = this.leastUsedNodes[0];
148
- if (!node) throw new Error("No nodes are available.");
149
-
150
- const regex = /^https?:\/\//;
151
- const identifier = regex.test(query) ? query : `${sources}:${query}`;
152
-
153
- let response = await node.rest.makeRequest(
154
- `GET`,
155
- `/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`
156
- );
157
-
158
- if (response.loadType === "track") {
159
- this.tracks = [new Track(response.data, requester, node)];
160
- } else if (response.loadType === "playlist") {
161
- this.tracks = response.data.tracks.map(
162
- (track) => new Track(track, requester, node)
163
- );
164
- } else if (
165
- response.loadType === "error" ||
166
- response.loadType === "empty"
167
- ) {
168
- this.tracks = null;
169
- } else {
170
- this.tracks = response.data.map(
171
- (track) => new Track(track, requester, node)
172
- );
173
- }
174
-
175
- this.playlistInfo = response.data.info ?? null;
176
- this.loadType = response.loadType ?? null;
177
- return this;
178
- } catch (error) {
179
- throw new Error(error);
180
- }
181
- }
182
-
183
- get(guildId) {
184
- const player = this.players.get(guildId);
185
- if (!player)
186
- throw new Error(`No player were found for guildId: ${guildId}.`);
187
- return player;
188
- }
189
- }
190
-
191
- module.exports = { Muthera };
1
+ const { EventEmitter } = require("events");
2
+ const { Node } = require("./mutheraNode");
3
+ const { Player } = require("./mutheraPlayer");
4
+ const { Track } = require("./mutheraTrack");
5
+ const { Collection } = require("@discordjs/collection");
6
+
7
+ class Muthera extends EventEmitter {
8
+ constructor(client, nodes, options) {
9
+ super();
10
+ if (!client)
11
+ throw new Error("Client option must be present to initialize muthera.");
12
+ if (!nodes)
13
+ throw new Error("Node option must be present to initialize muthera.");
14
+ if (!options.send)
15
+ throw new Error("Send function must be present to initialize muthera.");
16
+
17
+ this.client = client;
18
+ this.nodes = nodes;
19
+ this.nodeMap = new Collection();
20
+ this.players = new Collection();
21
+ this.options = options;
22
+ this.clientId = null;
23
+ this.initiated = false;
24
+ this.send = options.send || null;
25
+ this.defaultSearchPlatform = options.defaultSearchPlatform || "ytsearch";
26
+ this.tracks = [];
27
+ this.loadType = null;
28
+ this.playlistInfo = null;
29
+ }
30
+
31
+ get leastUsedNodes() {
32
+ return [...this.nodeMap.values()]
33
+ .filter((node) => node.connected)
34
+ .sort((a, b) => b.rest.calls - a.rest.calls);
35
+ }
36
+
37
+ init(clientId) {
38
+ if (this.initiated) return this;
39
+ this.clientId = clientId;
40
+ this.nodes.forEach((node) => this.createNode(node));
41
+ this.initiated = true;
42
+ }
43
+
44
+ createNode(options) {
45
+ const node = new Node(this, options, this.options);
46
+ this.nodeMap.set(options.name || options.host, node);
47
+ node.connect();
48
+
49
+ this.emit("nodeCreate", node);
50
+ return node;
51
+ }
52
+
53
+ destroyNode(identifier) {
54
+ const node = this.nodeMap.get(identifier);
55
+ if (!node) return;
56
+ node.disconnect();
57
+ this.nodeMap.delete(identifier);
58
+ this.emit("nodeDestroy", node);
59
+ }
60
+
61
+ updateVoiceState(packet) {
62
+ if (!["VOICE_STATE_UPDATE", "VOICE_SERVER_UPDATE"].includes(packet.t))
63
+ return;
64
+ const player = this.players.get(packet.d.guild_id);
65
+ if (!player) return;
66
+
67
+ if (packet.t === "VOICE_SERVER_UPDATE") {
68
+ player.connection.setServerUpdate(packet.d);
69
+ } else if (packet.t === "VOICE_STATE_UPDATE") {
70
+ if (packet.d.user_id !== this.clientId) return;
71
+ player.connection.setStateUpdate(packet.d);
72
+ }
73
+ }
74
+
75
+ fetchRegion(region) {
76
+ const nodesByRegion = [...this.nodeMap.values()]
77
+ .filter(
78
+ (node) =>
79
+ node.connected && node.regions?.includes(region?.toLowerCase())
80
+ )
81
+ .sort((a, b) => {
82
+ const aLoad = a.stats.cpu
83
+ ? (a.stats.cpu.systemLoad / a.stats.cpu.cores) * 100
84
+ : 0;
85
+ const bLoad = b.stats.cpu
86
+ ? (b.stats.cpu.systemLoad / b.stats.cpu.cores) * 100
87
+ : 0;
88
+ return aLoad - bLoad;
89
+ });
90
+
91
+ return nodesByRegion;
92
+ }
93
+
94
+ createConnection(options) {
95
+ if (!this.initiated)
96
+ throw new Error("You have to initialize muthera in your event.");
97
+
98
+ const player = this.players.get(options.guildId);
99
+ if (player) return player;
100
+
101
+ if (this.leastUsedNodes.length === 0)
102
+ throw new Error("No nodes are available.");
103
+
104
+ let node;
105
+ if (options.node) {
106
+ node = this.nodeMap.get(options.node);
107
+ } else {
108
+ node = this.nodeMap.get(this.leastUsedNodes[0].name);
109
+ }
110
+
111
+ if (!node) throw new Error("No nodes are available.");
112
+
113
+ return this.createPlayer(node, options);
114
+ }
115
+
116
+ createPlayer(node, options) {
117
+ const player = new Player(this, node, options);
118
+ this.players.set(options.guildId, player);
119
+
120
+ player.connect(options);
121
+
122
+ this.emit("playerCreate", player);
123
+ return player;
124
+ }
125
+
126
+ destroyPlayer(guildId) {
127
+ const player = this.players.get(guildId);
128
+ if (!player) return;
129
+ player.destroy();
130
+ this.players.delete(guildId);
131
+
132
+ this.emit("playerDestroy", player);
133
+ }
134
+
135
+ removeConnection(guildId) {
136
+ this.players.get(guildId)?.destroy();
137
+ this.players.delete(guildId);
138
+ }
139
+
140
+ async resolve({ query, source, requester }) {
141
+ try {
142
+ if (!this.initiated)
143
+ throw new Error("You have to initialize muthera in your event.");
144
+
145
+ const sources = source || this.defaultSearchPlatform;
146
+
147
+ const node = this.leastUsedNodes[0];
148
+ if (!node) throw new Error("No nodes are available.");
149
+
150
+ const regex = /^https?:\/\//;
151
+ const identifier = regex.test(query) ? query : `${sources}:${query}`;
152
+
153
+ let response = await node.rest.makeRequest(
154
+ `GET`,
155
+ `/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`
156
+ );
157
+
158
+ if (response.loadType === "track") {
159
+ this.tracks = [new Track(response.data, requester, node)];
160
+ } else if (response.loadType === "playlist") {
161
+ this.tracks = response.data.tracks.map(
162
+ (track) => new Track(track, requester, node)
163
+ );
164
+ } else if (
165
+ response.loadType === "error" ||
166
+ response.loadType === "empty"
167
+ ) {
168
+ this.tracks = null;
169
+ } else {
170
+ this.tracks = response.data.map(
171
+ (track) => new Track(track, requester, node)
172
+ );
173
+ }
174
+
175
+ this.playlistInfo = response.data.info ?? null;
176
+ this.loadType = response.loadType ?? null;
177
+ return this;
178
+ } catch (error) {
179
+ throw new Error(error);
180
+ }
181
+ }
182
+
183
+ get(guildId) {
184
+ const player = this.players.get(guildId);
185
+ if (!player)
186
+ throw new Error(`No player were found for guildId: ${guildId}.`);
187
+ return player;
188
+ }
189
+ }
190
+
191
+ module.exports = { Muthera };
@@ -9,6 +9,7 @@ class Connection {
9
9
  event: null,
10
10
  endpoint: null,
11
11
  sessionId: null,
12
+ channelId: null,
12
13
  };
13
14
  this.self_deaf = false;
14
15
  this.self_mute = false;
@@ -48,6 +49,7 @@ class Connection {
48
49
  this.self_deaf = self_deaf;
49
50
  this.self_mute = self_mute;
50
51
  this.voice.sessionId = session_id || null;
52
+ this.voice.channelId = channel_id || null;
51
53
  }
52
54
 
53
55
  updatePlayerVoiceData() {