mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-16 11:33:30 +01:00
Added voice disconnect
This commit is contained in:
@@ -243,6 +243,7 @@ class ClientVoiceManager {
|
|||||||
this.connections.set(channel.guild.id, voiceConnection);
|
this.connections.set(channel.guild.id, voiceConnection);
|
||||||
voiceConnection.once('ready', () => resolve(voiceConnection));
|
voiceConnection.once('ready', () => resolve(voiceConnection));
|
||||||
voiceConnection.once('error', reject);
|
voiceConnection.once('error', reject);
|
||||||
|
voiceConnection.once('disconnected', () => this.connections.delete(channel.guild.id));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ class VoiceConnection extends EventEmitter {
|
|||||||
|
|
||||||
this.player.on('error', e => {
|
this.player.on('error', e => {
|
||||||
this.emit('warn', e);
|
this.emit('warn', e);
|
||||||
console.log('so yeah uh' + e);
|
|
||||||
this.player.cleanup();
|
this.player.cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -63,9 +62,26 @@ class VoiceConnection extends EventEmitter {
|
|||||||
speaking: true,
|
speaking: true,
|
||||||
delay: 0,
|
delay: 0,
|
||||||
},
|
},
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
this.emit('debug', e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disconnect() {
|
||||||
|
this.emit('closing');
|
||||||
|
this.voiceManager.client.ws.send({
|
||||||
|
op: Constants.OPCodes.VOICE_STATE_UPDATE,
|
||||||
|
d: {
|
||||||
|
guild_id: this.channel.guild.id,
|
||||||
|
channel_id: null,
|
||||||
|
self_mute: false,
|
||||||
|
self_deaf: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.emit('disconnected');
|
||||||
|
}
|
||||||
|
|
||||||
connect() {
|
connect() {
|
||||||
if (this.sockets.ws) {
|
if (this.sockets.ws) {
|
||||||
throw new Error('There is already an existing WebSocket connection!');
|
throw new Error('There is already an existing WebSocket connection!');
|
||||||
|
|||||||
@@ -49,6 +49,17 @@ class VoiceConnectionUDPClient extends EventEmitter {
|
|||||||
* @type {?string}
|
* @type {?string}
|
||||||
*/
|
*/
|
||||||
this.localPort = null;
|
this.localPort = null;
|
||||||
|
this.voiceConnection.on('closing', this.shutdown.bind(this));
|
||||||
|
}
|
||||||
|
shutdown() {
|
||||||
|
if (this.socket) {
|
||||||
|
try {
|
||||||
|
this.socket.close();
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.socket = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* The port of the discord voice server
|
* The port of the discord voice server
|
||||||
@@ -57,7 +68,6 @@ class VoiceConnectionUDPClient extends EventEmitter {
|
|||||||
get discordPort() {
|
get discordPort() {
|
||||||
return this.voiceConnection.authentication.port;
|
return this.voiceConnection.authentication.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to resolve the voice server endpoint to an address
|
* Tries to resolve the voice server endpoint to an address
|
||||||
* @returns {Promise<string>}
|
* @returns {Promise<string>}
|
||||||
|
|||||||
@@ -22,6 +22,15 @@ class VoiceWebSocket extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
this.attempts = 0;
|
this.attempts = 0;
|
||||||
this.connect();
|
this.connect();
|
||||||
|
|
||||||
|
this.dead = false;
|
||||||
|
|
||||||
|
this.voiceConnection.on('closing', this.shutdown.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
shutdown() {
|
||||||
|
this.dead = true;
|
||||||
|
this.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,6 +59,9 @@ class VoiceWebSocket extends EventEmitter {
|
|||||||
* Starts connecting to the Voice WebSocket Server.
|
* Starts connecting to the Voice WebSocket Server.
|
||||||
*/
|
*/
|
||||||
connect() {
|
connect() {
|
||||||
|
if (this.dead) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this.ws) {
|
if (this.ws) {
|
||||||
this.reset();
|
this.reset();
|
||||||
}
|
}
|
||||||
@@ -76,7 +88,7 @@ class VoiceWebSocket extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
send(data) {
|
send(data) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (this.ws.readyState === WebSocket.OPEN) {
|
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
||||||
this.ws.send(data, null, error => {
|
this.ws.send(data, null, error => {
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
@@ -85,7 +97,7 @@ class VoiceWebSocket extends EventEmitter {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
reject(new Error('websocket not open'));
|
reject(new Error('websocket not open for ' + data));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -140,7 +152,7 @@ class VoiceWebSocket extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
onClose(event) {
|
onClose(event) {
|
||||||
// #todo see if the connection is open before reconnecting
|
// #todo see if the connection is open before reconnecting
|
||||||
this.client.setTimeout(this.connect.bind(this), this.attempts * 1000);
|
if (!this.dead) this.client.setTimeout(this.connect.bind(this), this.attempts * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -134,7 +134,10 @@ class StreamDispatcher extends EventEmitter {
|
|||||||
_sendBuffer(buffer, sequence, timestamp) {
|
_sendBuffer(buffer, sequence, timestamp) {
|
||||||
let repeats = this.passes;
|
let repeats = this.passes;
|
||||||
const packet = this._createPacket(sequence, timestamp, this.player.opusEncoder.encode(buffer));
|
const packet = this._createPacket(sequence, timestamp, this.player.opusEncoder.encode(buffer));
|
||||||
while (repeats--) this.player.voiceConnection.sockets.udp.send(packet).catch(e => console.log('so uhhh', e));
|
while (repeats--) {
|
||||||
|
this.player.voiceConnection.sockets.udp.send(packet)
|
||||||
|
.catch(e => this.emit('debug', `failed to send a packet ${e}`));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_createPacket(sequence, timestamp, buffer) {
|
_createPacket(sequence, timestamp, buffer) {
|
||||||
|
|||||||
@@ -20,12 +20,13 @@ class AudioPlayer extends EventEmitter {
|
|||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
pausedTime: 0,
|
pausedTime: 0,
|
||||||
};
|
};
|
||||||
|
this.voiceConnection.on('closing', () => this.cleanup(null, 'voice connection is closing'));
|
||||||
}
|
}
|
||||||
|
|
||||||
playUnknownStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) {
|
playUnknownStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) {
|
||||||
const options = { seek, volume, passes };
|
const options = { seek, volume, passes };
|
||||||
stream.on('end', () => {
|
stream.on('end', () => {
|
||||||
console.log(Date.now(), 'real input stream ended');
|
this.emit('debug', 'input stream to converter has ended');
|
||||||
});
|
});
|
||||||
stream.on('error', e => this.emit('error', e));
|
stream.on('error', e => this.emit('error', e));
|
||||||
const conversionProcess = this.audioToPCM.createConvertStream(options.seek);
|
const conversionProcess = this.audioToPCM.createConvertStream(options.seek);
|
||||||
@@ -36,7 +37,7 @@ class AudioPlayer extends EventEmitter {
|
|||||||
|
|
||||||
cleanup(checkStream, reason) {
|
cleanup(checkStream, reason) {
|
||||||
// cleanup is a lot less aggressive than v9 because it doesn't try to kill every single stream it is aware of
|
// cleanup is a lot less aggressive than v9 because it doesn't try to kill every single stream it is aware of
|
||||||
console.log(Date.now(), 'clean up triggered due to', reason);
|
this.emit('debug', `clean up triggered due to ${reason}`);
|
||||||
const filter = checkStream && this.currentDispatcher && this.currentDispatcher.stream === checkStream;
|
const filter = checkStream && this.currentDispatcher && this.currentDispatcher.stream === checkStream;
|
||||||
if (this.currentConverter && (checkStream ? filter : true)) {
|
if (this.currentConverter && (checkStream ? filter : true)) {
|
||||||
this.currentConverter.destroy();
|
this.currentConverter.destroy();
|
||||||
@@ -46,9 +47,7 @@ class AudioPlayer extends EventEmitter {
|
|||||||
|
|
||||||
playPCMStream(stream, converter, { seek = 0, volume = 1, passes = 1 } = {}) {
|
playPCMStream(stream, converter, { seek = 0, volume = 1, passes = 1 } = {}) {
|
||||||
const options = { seek, volume, passes };
|
const options = { seek, volume, passes };
|
||||||
stream.on('end', () => {
|
stream.on('end', () => this.emit('debug', 'pcm input stream ended'));
|
||||||
console.log(Date.now(), 'pcm input stream ended');
|
|
||||||
});
|
|
||||||
this.cleanup(null, 'outstanding play stream');
|
this.cleanup(null, 'outstanding play stream');
|
||||||
this.currentConverter = converter;
|
this.currentConverter = converter;
|
||||||
if (this.currentDispatcher) {
|
if (this.currentDispatcher) {
|
||||||
|
|||||||
@@ -101,6 +101,9 @@ class VoiceConnectionPlayer extends EventEmitter {
|
|||||||
speaking: true,
|
speaking: true,
|
||||||
delay: 0,
|
delay: 0,
|
||||||
},
|
},
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
this.emit('debug', e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ let disp, con;
|
|||||||
|
|
||||||
client.on('message', msg => {
|
client.on('message', msg => {
|
||||||
if (msg.content.startsWith('/play')) {
|
if (msg.content.startsWith('/play')) {
|
||||||
|
console.log('I am now going to play', msg.content);
|
||||||
const chan = msg.content.split(' ').slice(1).join(' ');
|
const chan = msg.content.split(' ').slice(1).join(' ');
|
||||||
con.playStream(ytdl(chan, {filter : 'audioonly'}), { passes : 4 });
|
con.playStream(ytdl(chan, {filter : 'audioonly'}), { passes : 4 });
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user