mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-18 04:23:31 +01:00
Complete voice connection
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1,17 +1,23 @@
|
|||||||
const VoiceConnectionWebSocket = require('./VoiceConnectionWebSocket');
|
const VoiceConnectionWebSocket = require('./VoiceConnectionWebSocket');
|
||||||
|
const VoiceConnectionUDPClient = require('./VoiceConnectionUDPClient');
|
||||||
const EventEmitter = require('events').EventEmitter;
|
const EventEmitter = require('events').EventEmitter;
|
||||||
|
|
||||||
class VoiceConnection extends EventEmitter {
|
class VoiceConnection extends EventEmitter {
|
||||||
constructor(manager, serverID, token, sessionID, endpoint) {
|
constructor(manager, serverID, token, sessionID, endpoint) {
|
||||||
super();
|
super();
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
|
this.endpoint = endpoint;
|
||||||
this.websocket = new VoiceConnectionWebSocket(this, serverID, token, sessionID, endpoint);
|
this.websocket = new VoiceConnectionWebSocket(this, serverID, token, sessionID, endpoint);
|
||||||
|
this.ready = false;
|
||||||
this.bindListeners();
|
this.bindListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
bindListeners() {
|
bindListeners() {
|
||||||
this.websocket.on('ready-for-udp', data => {
|
this.websocket.on('ready-for-udp', data => {
|
||||||
console.log(data);
|
this.udp = new VoiceConnectionUDPClient(this, data);
|
||||||
|
});
|
||||||
|
this.websocket.on('ready', () => {
|
||||||
|
this.ready = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,73 @@
|
|||||||
class VoiceConnectionUDPClient {
|
const udp = require('dgram');
|
||||||
|
const dns = require('dns');
|
||||||
|
const Constants = require('../../util/Constants');
|
||||||
|
const EventEmitter = require('events').EventEmitter;
|
||||||
|
|
||||||
|
class VoiceConnectionUDPClient extends EventEmitter {
|
||||||
|
|
||||||
|
constructor(voiceConnection, data) {
|
||||||
|
super();
|
||||||
|
this.voiceConnection = voiceConnection;
|
||||||
|
this.count = 0;
|
||||||
|
this.data = data;
|
||||||
|
this.dnsLookup();
|
||||||
|
}
|
||||||
|
|
||||||
|
dnsLookup() {
|
||||||
|
dns.lookup(this.voiceConnection.endpoint, (err, address) => {
|
||||||
|
if (err) {
|
||||||
|
return this.emit('error', err);
|
||||||
|
}
|
||||||
|
this.connectUDP(address);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
send(packet) {
|
||||||
|
if (this.udpSocket) {
|
||||||
|
try {
|
||||||
|
this.udpSocket.send(packet, 0, packet.length, this.data.port, this.udpIP);
|
||||||
|
} catch (err) {
|
||||||
|
return this.emit('error', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connectUDP(address) {
|
||||||
|
this.udpIP = address;
|
||||||
|
this.udpSocket = udp.createSocket('udp4');
|
||||||
|
|
||||||
|
// finding local IP
|
||||||
|
// https://discordapp.com/developers/docs/topics/voice-connections#ip-discovery
|
||||||
|
this.udpSocket.once('message', message => {
|
||||||
|
const packet = new Buffer(message);
|
||||||
|
this.localIP = '';
|
||||||
|
for (let i = 4; i < packet.indexOf(0, i); i++) {
|
||||||
|
this.localIP += String.fromCharCode(packet[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.localPort = parseInt(packet.readUIntLE(packet.length - 2, 2).toString(10), 10);
|
||||||
|
|
||||||
|
this.voiceConnection.websocket.send({
|
||||||
|
op: Constants.VoiceOPCodes.SELECT_PROTOCOL,
|
||||||
|
d: {
|
||||||
|
protocol: 'udp',
|
||||||
|
data: {
|
||||||
|
address: this.localIP,
|
||||||
|
port: this.localPort,
|
||||||
|
mode: 'xsalsa20_poly1305',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.udpSocket.on('error', (error, message) => {
|
||||||
|
this.emit('error', { error, message });
|
||||||
|
});
|
||||||
|
|
||||||
|
const blankMessage = new Buffer(70);
|
||||||
|
blankMessage.writeUIntBE(this.data.ssrc, 0, 4);
|
||||||
|
this.send(blankMessage);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,10 +45,19 @@ class VoiceConnectionWebSocket extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (packet.op) {
|
switch (packet.op) {
|
||||||
case 2:
|
case Constants.VoiceOPCodes.READY:
|
||||||
this.emit('ready-for-udp', packet.d);
|
this.emit('ready-for-udp', packet.d);
|
||||||
break;
|
break;
|
||||||
|
case Constants.VoiceOPCodes.SESSION_DESCRIPTION:
|
||||||
|
this.encryptionMode = packet.d.mode;
|
||||||
|
this.secretKey = new Uint8Array(new ArrayBuffer(packet.d.secret_key.length));
|
||||||
|
for (const index in packet.d.secret_key) {
|
||||||
|
this.secretKey[index] = packet.d.secret_key[index];
|
||||||
|
}
|
||||||
|
this.emit('ready');
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
this.emit('unknown', packet);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,15 @@ exports.OPCodes = {
|
|||||||
INVALID_SESSION: 9,
|
INVALID_SESSION: 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.VoiceOPCodes = {
|
||||||
|
IDENTIFY: 0,
|
||||||
|
SELECT_PROTOCOL: 1,
|
||||||
|
READY: 2,
|
||||||
|
HEARTBEAT: 3,
|
||||||
|
SESSION_DESCRIPTION: 4,
|
||||||
|
SPEAKING: 5,
|
||||||
|
};
|
||||||
|
|
||||||
exports.Events = {
|
exports.Events = {
|
||||||
READY: 'ready',
|
READY: 'ready',
|
||||||
GUILD_CREATE: 'guildCreate',
|
GUILD_CREATE: 'guildCreate',
|
||||||
|
|||||||
Reference in New Issue
Block a user