poru 1.0.1 → 1.0.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/README.md +66 -4
- package/package.json +1 -1
- package/src/Node.js +19 -3
- package/src/Player.js +71 -69
- package/src/Poru.js +8 -0
package/README.md
CHANGED
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
|
|
20
20
|
## Table of contents
|
|
21
21
|
|
|
22
|
-
- [Documentation](https://
|
|
22
|
+
- [Documentation](https://poru.parasdocs.tech)
|
|
23
23
|
- [Installation](#installation)
|
|
24
24
|
- [About](#about)
|
|
25
|
-
- [Example](
|
|
25
|
+
- [Example](https://github.com/parasop/poru-example)
|
|
26
26
|
|
|
27
27
|
# Installation
|
|
28
28
|
```
|
|
@@ -42,10 +42,72 @@ To use you need a configured [Lavalink](https://github.com/Frederikam/Lavalink)
|
|
|
42
42
|
- 100% Customizable
|
|
43
43
|
- Easy to setup
|
|
44
44
|
|
|
45
|
+
## Implementation
|
|
46
|
+
[Poru Music](https://github.com/parasop/poru-example) **Example bot as guide for beginning.**
|
|
47
|
+
|
|
48
|
+
|
|
45
49
|
## Example usage basic bot
|
|
46
50
|
```javascript
|
|
47
|
-
//
|
|
51
|
+
// main file
|
|
52
|
+
// Require both libraries
|
|
53
|
+
const { Client } = require("discord.js");
|
|
54
|
+
const { Poru } = require("poru");
|
|
55
|
+
|
|
56
|
+
// Initiate both main classes
|
|
57
|
+
const client = new Client();
|
|
58
|
+
|
|
59
|
+
// Define some options for the node
|
|
60
|
+
const nodes = [
|
|
61
|
+
{
|
|
62
|
+
host: "localhost",
|
|
63
|
+
password: "youshallnotpass",
|
|
64
|
+
port: 2333,
|
|
65
|
+
secure:false
|
|
66
|
+
}
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
// Assign Manager to the client variable
|
|
70
|
+
client.poru = new Poru(client,nodes);
|
|
71
|
+
|
|
72
|
+
// Emitted whenever a node connects
|
|
73
|
+
client.poru.on("nodeConnect", node => {
|
|
74
|
+
console.log(`Node "${node.name}" connected.`)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
// Emitted whenever a node encountered an error
|
|
78
|
+
client.poru.on("nodeError", (node, error) => {
|
|
79
|
+
console.log(`Node "${node.name}" encountered an error`)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
// Listen for when the client becomes ready
|
|
83
|
+
client.once("ready", () => {
|
|
84
|
+
client.poru.init(client;
|
|
85
|
+
console.log(`Logged in as ${client.user.tag}`);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// THIS IS REQUIRED. Send raw events to Erela.js
|
|
89
|
+
client.on("raw",async d => await client.poru.packetUpdate(d));
|
|
90
|
+
|
|
91
|
+
// Finally login at the END of your code
|
|
92
|
+
client.login("your bot token here");
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
// creating player
|
|
100
|
+
const player = await client.poru.createConnection({
|
|
101
|
+
guild: message.guild.id,
|
|
102
|
+
voiceChannel: message.member.voice.channel.id,
|
|
103
|
+
textChannel: message.channel,
|
|
104
|
+
selfDeaf: true,
|
|
105
|
+
selfMute: false,
|
|
106
|
+
})
|
|
107
|
+
// Getting tracks
|
|
108
|
+
const resolve = await client.poru.resolve('Ignite',"yt");
|
|
48
109
|
```
|
|
49
110
|
|
|
50
111
|
## Need Help?
|
|
51
|
-
|
|
112
|
+
Feel free to join our [discord server](https://discord.gg/Zmmc47Nrh8), Give us suggestions and advice about errors and new features.
|
|
113
|
+
with ❤️ by [Paras](https://github.com/parasop) .
|
package/package.json
CHANGED
package/src/Node.js
CHANGED
|
@@ -106,13 +106,29 @@ message(payload) {
|
|
|
106
106
|
* Fire up when node return an error
|
|
107
107
|
* @event nodeError
|
|
108
108
|
*/
|
|
109
|
-
this.manager.emit("nodeError",
|
|
109
|
+
this.manager.emit("nodeError", this, event);
|
|
110
110
|
return this.reconnect();
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
destroy(){
|
|
114
|
+
if(!this.isConnected) return;
|
|
115
|
+
|
|
116
|
+
const players = this.manager.players.filter(p => p.node == this);
|
|
117
|
+
if (players.size) players.forEach(p => p.destroy());
|
|
118
|
+
this.ws.close(1000, "destroy");
|
|
119
|
+
this.ws.removeAllListeners();
|
|
120
|
+
this.ws = null;
|
|
121
|
+
this.reconnect = 1;
|
|
122
|
+
this.manager.nodes.delete(this.host)
|
|
123
|
+
this.manager.emit("nodeDestroy", this);
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
}
|
|
127
|
+
|
|
113
128
|
reconnect() {
|
|
114
|
-
this.reconnect
|
|
115
|
-
|
|
129
|
+
this.reconnect++;
|
|
130
|
+
setTimeout(() => {
|
|
131
|
+
this.isConnected = false;
|
|
116
132
|
this.ws.removeAllListeners();
|
|
117
133
|
this.ws = null;
|
|
118
134
|
this.manager.emit("nodeReconnect", this);
|
package/src/Player.js
CHANGED
|
@@ -6,11 +6,14 @@ class Player extends EventEmitter {
|
|
|
6
6
|
super();
|
|
7
7
|
|
|
8
8
|
this.manager = manager;
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
this.queue = new Queue();
|
|
11
|
+
|
|
10
12
|
this.node = node;
|
|
11
|
-
this.filters = new Filters(this,this.node)
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
this.filters = new Filters(this, this.node)
|
|
15
|
+
|
|
16
|
+
|
|
14
17
|
this.guild = options.guild.id || options.guild;
|
|
15
18
|
|
|
16
19
|
this.voiceChannel = options.voiceChannel.id || options.voiceChannel;
|
|
@@ -32,40 +35,38 @@ class Player extends EventEmitter {
|
|
|
32
35
|
|
|
33
36
|
this.timestamp = Date.now();
|
|
34
37
|
|
|
38
|
+
this.pause = false;
|
|
35
39
|
this.position = 0;
|
|
36
40
|
|
|
37
|
-
this.isPaused = false
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
|
|
41
43
|
this.currentTrack = {};
|
|
42
44
|
|
|
43
45
|
this.previousTrack = {};
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
this.voiceUpdateState = null;
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
this.voiceUpdateState = null;
|
|
49
49
|
|
|
50
|
-
|
|
51
50
|
|
|
52
51
|
|
|
53
52
|
this.on("event", (data) => (this.lavalinkEvent(data).bind(this))());
|
|
54
|
-
this.on("event",(data)=> this.manager.emit("debug",data))
|
|
53
|
+
this.on("event", (data) => this.manager.emit("debug", data))
|
|
55
54
|
this.on("playerUpdate", (packet) => {
|
|
56
55
|
this.isConnectd = packet.state.connected,
|
|
57
|
-
|
|
56
|
+
this.position = packet.state.position
|
|
58
57
|
this.state = {
|
|
59
58
|
volume: this.state.volume,
|
|
60
59
|
equalizer: this.state.equalizer,
|
|
61
60
|
...packet.state,
|
|
61
|
+
|
|
62
62
|
};
|
|
63
|
+
this.manager.emit("playerUpdate", this, data);
|
|
63
64
|
});
|
|
64
65
|
}
|
|
65
66
|
async play() {
|
|
66
|
-
|
|
67
|
-
if(!this.queue.length){
|
|
68
|
-
|
|
67
|
+
|
|
68
|
+
if (!this.queue.length) {
|
|
69
|
+
return nulll;
|
|
69
70
|
}
|
|
70
71
|
this.currentTrack = this.queue.shift();
|
|
71
72
|
this.playing = true;
|
|
@@ -76,7 +77,7 @@ class Player extends EventEmitter {
|
|
|
76
77
|
track: this.currentTrack.track,
|
|
77
78
|
volume: this.volume || 100,
|
|
78
79
|
});
|
|
79
|
-
this.position =0;
|
|
80
|
+
this.position = 0;
|
|
80
81
|
return this;
|
|
81
82
|
}
|
|
82
83
|
|
|
@@ -85,7 +86,7 @@ class Player extends EventEmitter {
|
|
|
85
86
|
|
|
86
87
|
this.position = 0;
|
|
87
88
|
this.isConnectd = false
|
|
88
|
-
this.playing =false;
|
|
89
|
+
this.playing = false;
|
|
89
90
|
this.node.send({
|
|
90
91
|
op: "stop",
|
|
91
92
|
guildId: this.guild
|
|
@@ -95,14 +96,15 @@ class Player extends EventEmitter {
|
|
|
95
96
|
|
|
96
97
|
pause(pause = true) {
|
|
97
98
|
if (typeof pause !== "boolean") throw new RangeError("Pause function must be pass with boolean value.");
|
|
98
|
-
|
|
99
|
-
this.playing = !pause;
|
|
100
|
-
this.paused = pause;
|
|
99
|
+
|
|
101
100
|
this.node.send({
|
|
102
101
|
op: "pause",
|
|
103
102
|
guildId: this.guild,
|
|
104
103
|
pause,
|
|
105
104
|
});
|
|
105
|
+
this.playing = !pause;
|
|
106
|
+
this.paused = pause;
|
|
107
|
+
|
|
106
108
|
return this;
|
|
107
109
|
}
|
|
108
110
|
|
|
@@ -139,32 +141,32 @@ class Player extends EventEmitter {
|
|
|
139
141
|
async QueueRepeat() {
|
|
140
142
|
this.loop = 2;
|
|
141
143
|
this.queueRepeat = true;
|
|
142
|
-
this.trackRepeat= false;
|
|
144
|
+
this.trackRepeat = false;
|
|
143
145
|
return this;
|
|
144
146
|
}
|
|
145
147
|
|
|
146
148
|
async DisableRepeat() {
|
|
147
149
|
this.loop = 0;
|
|
148
|
-
this.trackRepeat =false;
|
|
150
|
+
this.trackRepeat = false;
|
|
149
151
|
this.queueRepeat = false;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
+
|
|
153
|
+
|
|
152
154
|
return this;
|
|
153
155
|
}
|
|
154
156
|
|
|
155
|
-
|
|
157
|
+
async setTextChannel(channel) {
|
|
156
158
|
if (typeof channel !== "string") throw new RangeError("Channel must be a string.");
|
|
157
159
|
this.textChannel = channel;
|
|
158
160
|
return this;
|
|
159
161
|
}
|
|
160
162
|
|
|
161
|
-
|
|
163
|
+
async setVoiceChannel(channel) {
|
|
162
164
|
if (typeof channel !== "string") throw new RangeError("Channel must be a string.");
|
|
163
165
|
this.voiceChannel = channel;
|
|
164
166
|
return this;
|
|
165
167
|
}
|
|
166
168
|
|
|
167
|
-
|
|
169
|
+
async connect(data) {
|
|
168
170
|
this.voiceUpdateState = data;
|
|
169
171
|
this.node.send({
|
|
170
172
|
op: "voiceUpdate",
|
|
@@ -188,10 +190,10 @@ class Player extends EventEmitter {
|
|
|
188
190
|
return this;
|
|
189
191
|
}
|
|
190
192
|
|
|
191
|
-
|
|
192
193
|
|
|
193
194
|
|
|
194
|
-
|
|
195
|
+
|
|
196
|
+
async disconnect() {
|
|
195
197
|
if (this.voiceChannel === null) return null;
|
|
196
198
|
this.pause(true);
|
|
197
199
|
this.isConnectd = false;
|
|
@@ -218,26 +220,26 @@ class Player extends EventEmitter {
|
|
|
218
220
|
this.manager.players.delete(this.guild);
|
|
219
221
|
}
|
|
220
222
|
|
|
221
|
-
|
|
223
|
+
async autoplay(toggle = false) {
|
|
222
224
|
|
|
223
|
-
|
|
224
|
-
try{
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
if (!toggle) return null;
|
|
226
|
+
try {
|
|
227
|
+
if (!this.previousTrack) return this.stop();
|
|
228
|
+
let data = `https://www.youtube.com/watch?v=${this.previousTrack.identifier}&list=RD${this.previousTrack.identifier}`;
|
|
227
229
|
|
|
228
|
-
|
|
230
|
+
let response = await this.manager.search(data);
|
|
229
231
|
|
|
230
|
-
|
|
232
|
+
if (!response || !response.tracks || ["LOAD_FAILED", "NO_MATCHES"].includes(response.type)) return this.stop();
|
|
231
233
|
|
|
232
|
-
|
|
234
|
+
let track = response.tracks[Math.floor(Math.random() * Math.floor(response.tracks.length))];
|
|
233
235
|
|
|
234
|
-
|
|
236
|
+
this.queue.push(track);
|
|
235
237
|
|
|
236
|
-
|
|
238
|
+
this.play();
|
|
237
239
|
|
|
238
|
-
|
|
240
|
+
return this;
|
|
239
241
|
|
|
240
|
-
}catch(e){
|
|
242
|
+
} catch (e) {
|
|
241
243
|
console.log(`[Poru Autoplay] error : ${e}`)
|
|
242
244
|
return this.stop();
|
|
243
245
|
}
|
|
@@ -248,46 +250,46 @@ class Player extends EventEmitter {
|
|
|
248
250
|
lavalinkEvent(data) {
|
|
249
251
|
const events = {
|
|
250
252
|
TrackStartEvent() {
|
|
251
|
-
this.playing =true;
|
|
252
|
-
this.paused =false;
|
|
253
|
-
this.manager.emit("trackStart", this, this.currentTrack);
|
|
253
|
+
this.playing = true;
|
|
254
|
+
this.paused = false;
|
|
255
|
+
this.manager.emit("trackStart", this, this.currentTrack, data);
|
|
254
256
|
},
|
|
255
257
|
// eslint-disable-next-line consistent-return
|
|
256
258
|
TrackEndEvent() {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
259
|
+
|
|
260
|
+
this.previousTrack = this.currentTrack;
|
|
261
|
+
|
|
260
262
|
if (this.currentTrack && this.loop === 1) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
263
|
+
|
|
264
|
+
this.queue.unshift(this.previousTrack)
|
|
265
|
+
return this.play();
|
|
264
266
|
} else if (this.currentTrack && this.loop === 2) {
|
|
265
|
-
|
|
267
|
+
|
|
266
268
|
this.queue.push(this.previousTrack)
|
|
267
269
|
return this.play();
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if(this.queue.length ===0){
|
|
271
|
-
return this.manager.emit("queueEnd", this, this.track,data);
|
|
272
|
-
// this.destroy();
|
|
273
|
-
} else if (this.queue.length>0) {
|
|
274
|
-
|
|
275
|
-
return this.play();
|
|
276
270
|
}
|
|
277
|
-
|
|
278
|
-
|
|
271
|
+
|
|
272
|
+
if (this.queue.length === 0) {
|
|
273
|
+
return this.manager.emit("queueEnd", this, this.track, data);
|
|
274
|
+
// this.destroy();
|
|
275
|
+
} else if (this.queue.length > 0) {
|
|
276
|
+
|
|
277
|
+
return this.play();
|
|
278
|
+
}
|
|
279
|
+
this.manager.emit("queueEnd", this, this.track, data);
|
|
280
|
+
|
|
279
281
|
},
|
|
280
282
|
TrackStuckEvent() {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
+
this.queue.shift();
|
|
284
|
+
this.manager.emit("trackError", this, this.track, data);
|
|
283
285
|
},
|
|
284
286
|
TrackExceptionEvent() {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
287
|
+
this.queue.shift();
|
|
288
|
+
/**
|
|
289
|
+
* Fire up when there's an error while playing the track
|
|
290
|
+
* @event trackError
|
|
291
|
+
*/
|
|
292
|
+
this.manager.emit("trackError", this, this.track, data);
|
|
291
293
|
},
|
|
292
294
|
WebSocketClosedEvent() {
|
|
293
295
|
if ([4015, 4009].includes(data.code)) {
|
package/src/Poru.js
CHANGED
|
@@ -38,6 +38,12 @@ class Poru extends EventEmitter {
|
|
|
38
38
|
return node;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
deleteNode(identifier){
|
|
42
|
+
const node = this.nodes.get(identifier);
|
|
43
|
+
if (!node) return;
|
|
44
|
+
node.destroy();
|
|
45
|
+
this.nodes.delete(identifier)
|
|
46
|
+
}
|
|
41
47
|
//create connection with discord voice channel
|
|
42
48
|
createConnection(data = {}, options = {}) {
|
|
43
49
|
const player = this.players.get(data.guild.id || data.guild);
|
|
@@ -56,6 +62,8 @@ class Poru extends EventEmitter {
|
|
|
56
62
|
return this.Player(data);
|
|
57
63
|
}
|
|
58
64
|
|
|
65
|
+
|
|
66
|
+
|
|
59
67
|
init(client) {
|
|
60
68
|
|
|
61
69
|
this.user =client.user.id;
|