mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-18 20:43:30 +01:00
Merge pull request #220 from qeled/indev
Implement voice encryption support 0.0
This commit is contained in:
@@ -51,6 +51,9 @@ var _unpipe = require("unpipe");
|
|||||||
|
|
||||||
var _unpipe2 = _interopRequireDefault(_unpipe);
|
var _unpipe2 = _interopRequireDefault(_unpipe);
|
||||||
|
|
||||||
|
var MODE_xsalsa20_poly1305 = "xsalsa20_poly1305";
|
||||||
|
var MODE_plain = "plain";
|
||||||
|
|
||||||
var VoiceConnection = (function (_EventEmitter) {
|
var VoiceConnection = (function (_EventEmitter) {
|
||||||
_inherits(VoiceConnection, _EventEmitter);
|
_inherits(VoiceConnection, _EventEmitter);
|
||||||
|
|
||||||
@@ -77,6 +80,10 @@ var VoiceConnection = (function (_EventEmitter) {
|
|||||||
this.KAI = null;
|
this.KAI = null;
|
||||||
this.timestamp = 0;
|
this.timestamp = 0;
|
||||||
this.sequence = 0;
|
this.sequence = 0;
|
||||||
|
|
||||||
|
this.mode = null;
|
||||||
|
this.secret = null;
|
||||||
|
|
||||||
this.volume = new _VolumeTransformer2["default"]();
|
this.volume = new _VolumeTransformer2["default"]();
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
@@ -232,7 +239,7 @@ var VoiceConnection = (function (_EventEmitter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var buffer = self.encoder.opusBuffer(rawbuffer);
|
var buffer = self.encoder.opusBuffer(rawbuffer);
|
||||||
var packet = new _VoicePacket2["default"](buffer, sequence, timestamp, self.vWSData.ssrc);
|
var packet = new _VoicePacket2["default"](buffer, sequence, timestamp, self.vWSData.ssrc, self.secret);
|
||||||
return self.sendPacket(packet, callback);
|
return self.sendPacket(packet, callback);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
self.playing = false;
|
self.playing = false;
|
||||||
@@ -361,6 +368,13 @@ var VoiceConnection = (function (_EventEmitter) {
|
|||||||
}
|
}
|
||||||
discordPort = msg.readUIntLE(msg.length - 2, 2).toString(10);
|
discordPort = msg.readUIntLE(msg.length - 2, 2).toString(10);
|
||||||
|
|
||||||
|
var modes = self.vWSData.modes;
|
||||||
|
var mode = MODE_xsalsa20_poly1305;
|
||||||
|
if (modes.indexOf(MODE_xsalsa20_poly1305) < 0) {
|
||||||
|
mode = MODE_plain;
|
||||||
|
self.client.emit("debug", "Encrypted mode not reported as supported by the server, using 'plain'");
|
||||||
|
}
|
||||||
|
|
||||||
vWS.send(JSON.stringify({
|
vWS.send(JSON.stringify({
|
||||||
"op": 1,
|
"op": 1,
|
||||||
"d": {
|
"d": {
|
||||||
@@ -368,7 +382,7 @@ var VoiceConnection = (function (_EventEmitter) {
|
|||||||
"data": {
|
"data": {
|
||||||
"address": discordIP,
|
"address": discordIP,
|
||||||
"port": Number(discordPort),
|
"port": Number(discordPort),
|
||||||
"mode": self.vWSData.modes[0] //Plain
|
"mode": mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@@ -410,6 +424,13 @@ var VoiceConnection = (function (_EventEmitter) {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
if (data.d.secret_key && data.d.secret_key.length > 0) {
|
||||||
|
var buffer = new ArrayBuffer(data.d.secret_key.length);
|
||||||
|
self.secret = new Uint8Array(buffer);
|
||||||
|
for (var i = 0; i < _this4.secret.length; i++) {
|
||||||
|
self.secret[i] = data.d.secret_key[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.ready = true;
|
self.ready = true;
|
||||||
self.mode = data.d.mode;
|
self.mode = data.d.mode;
|
||||||
|
|||||||
@@ -2,27 +2,45 @@
|
|||||||
|
|
||||||
exports.__esModule = true;
|
exports.__esModule = true;
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
|
||||||
var VoicePacket = function VoicePacket(data, sequence, time, ssrc) {
|
var _tweetnacl = require("tweetnacl");
|
||||||
_classCallCheck(this, VoicePacket);
|
|
||||||
|
|
||||||
var audioBuffer = data,
|
var _tweetnacl2 = _interopRequireDefault(_tweetnacl);
|
||||||
returnBuffer = new Buffer(audioBuffer.length + 12);
|
|
||||||
|
|
||||||
returnBuffer.fill(0);
|
var nonce = new Buffer(24);
|
||||||
returnBuffer[0] = 0x80;
|
nonce.fill(0);
|
||||||
returnBuffer[1] = 0x78;
|
|
||||||
|
|
||||||
returnBuffer.writeUIntBE(sequence, 2, 2);
|
var VoicePacket = function VoicePacket(data, sequence, time, ssrc, secret) {
|
||||||
returnBuffer.writeUIntBE(time, 4, 4);
|
_classCallCheck(this, VoicePacket);
|
||||||
returnBuffer.writeUIntBE(ssrc, 8, 4);
|
|
||||||
|
|
||||||
for (var i = 0; i < audioBuffer.length; i++) {
|
var mac = secret ? 16 : 0;
|
||||||
returnBuffer[i + 12] = audioBuffer[i];
|
var packetLength = data.length + 12 + mac;
|
||||||
}
|
|
||||||
|
|
||||||
return returnBuffer;
|
var audioBuffer = data;
|
||||||
|
var returnBuffer = new Buffer(packetLength);
|
||||||
|
|
||||||
|
returnBuffer.fill(0);
|
||||||
|
returnBuffer[0] = 0x80;
|
||||||
|
returnBuffer[1] = 0x78;
|
||||||
|
|
||||||
|
returnBuffer.writeUIntBE(sequence, 2, 2);
|
||||||
|
returnBuffer.writeUIntBE(time, 4, 4);
|
||||||
|
returnBuffer.writeUIntBE(ssrc, 8, 4);
|
||||||
|
|
||||||
|
if (secret) {
|
||||||
|
// copy first 12 bytes
|
||||||
|
returnBuffer.copy(nonce, 0, 0, 12);
|
||||||
|
audioBuffer = _tweetnacl2["default"].secretbox(data, nonce, secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < audioBuffer.length; i++) {
|
||||||
|
returnBuffer[i + 12] = audioBuffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports["default"] = VoicePacket;
|
exports["default"] = VoicePacket;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"homepage": "https://github.com/hydrabolt/discord.js#readme",
|
"homepage": "https://github.com/hydrabolt/discord.js#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"superagent": "^1.8.0",
|
"superagent": "^1.8.0",
|
||||||
|
"tweetnacl": "^0.14.1",
|
||||||
"unpipe": "^1.0.0",
|
"unpipe": "^1.0.0",
|
||||||
"ws": "^1.0.1"
|
"ws": "^1.0.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ import StreamIntent from "./StreamIntent";
|
|||||||
import EventEmitter from "events";
|
import EventEmitter from "events";
|
||||||
import unpipe from "unpipe";
|
import unpipe from "unpipe";
|
||||||
|
|
||||||
|
const MODE_xsalsa20_poly1305 = "xsalsa20_poly1305";
|
||||||
|
const MODE_plain = "plain";
|
||||||
|
|
||||||
export default class VoiceConnection extends EventEmitter {
|
export default class VoiceConnection extends EventEmitter {
|
||||||
constructor(channel, client, session, token, server, endpoint) {
|
constructor(channel, client, session, token, server, endpoint) {
|
||||||
super();
|
super();
|
||||||
@@ -39,6 +42,10 @@ export default class VoiceConnection extends EventEmitter {
|
|||||||
this.KAI = null;
|
this.KAI = null;
|
||||||
this.timestamp = 0;
|
this.timestamp = 0;
|
||||||
this.sequence = 0;
|
this.sequence = 0;
|
||||||
|
|
||||||
|
this.mode = null;
|
||||||
|
this.secret = null;
|
||||||
|
|
||||||
this.volume = new VolumeTransformer();
|
this.volume = new VolumeTransformer();
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
@@ -196,7 +203,7 @@ export default class VoiceConnection extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var buffer = self.encoder.opusBuffer(rawbuffer);
|
var buffer = self.encoder.opusBuffer(rawbuffer);
|
||||||
var packet = new VoicePacket(buffer, sequence, timestamp, self.vWSData.ssrc);
|
var packet = new VoicePacket(buffer, sequence, timestamp, self.vWSData.ssrc, self.secret);
|
||||||
return self.sendPacket(packet, callback);
|
return self.sendPacket(packet, callback);
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -314,6 +321,13 @@ export default class VoiceConnection extends EventEmitter {
|
|||||||
}
|
}
|
||||||
discordPort = msg.readUIntLE(msg.length - 2, 2).toString(10);
|
discordPort = msg.readUIntLE(msg.length - 2, 2).toString(10);
|
||||||
|
|
||||||
|
var modes = self.vWSData.modes;
|
||||||
|
var mode = MODE_xsalsa20_poly1305;
|
||||||
|
if (modes.indexOf(MODE_xsalsa20_poly1305) < 0) {
|
||||||
|
mode = MODE_plain;
|
||||||
|
self.client.emit("debug", "Encrypted mode not reported as supported by the server, using 'plain'");
|
||||||
|
}
|
||||||
|
|
||||||
vWS.send(JSON.stringify({
|
vWS.send(JSON.stringify({
|
||||||
"op": 1,
|
"op": 1,
|
||||||
"d": {
|
"d": {
|
||||||
@@ -321,7 +335,7 @@ export default class VoiceConnection extends EventEmitter {
|
|||||||
"data": {
|
"data": {
|
||||||
"address": discordIP,
|
"address": discordIP,
|
||||||
"port": Number(discordPort),
|
"port": Number(discordPort),
|
||||||
"mode": self.vWSData.modes[0] //Plain
|
"mode": mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@@ -365,6 +379,13 @@ export default class VoiceConnection extends EventEmitter {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
if (data.d.secret_key && data.d.secret_key.length > 0) {
|
||||||
|
const buffer = new ArrayBuffer(data.d.secret_key.length);
|
||||||
|
self.secret = new Uint8Array(buffer);
|
||||||
|
for (let i = 0; i < this.secret.length; i++) {
|
||||||
|
self.secret[i] = data.d.secret_key[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.ready = true;
|
self.ready = true;
|
||||||
self.mode = data.d.mode;
|
self.mode = data.d.mode;
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
export default class VoicePacket {
|
import nacl from "tweetnacl";
|
||||||
constructor(data, sequence, time, ssrc){
|
|
||||||
|
|
||||||
var audioBuffer = data,
|
const nonce = new Buffer(24);
|
||||||
returnBuffer = new Buffer(audioBuffer.length + 12);
|
nonce.fill(0);
|
||||||
|
|
||||||
|
export default class VoicePacket {
|
||||||
|
constructor(data, sequence, time, ssrc, secret){
|
||||||
|
var mac = secret ? 16 : 0;
|
||||||
|
var packetLength = data.length + 12 + mac;
|
||||||
|
|
||||||
|
var audioBuffer = data;
|
||||||
|
var returnBuffer = new Buffer(packetLength);
|
||||||
|
|
||||||
returnBuffer.fill(0);
|
returnBuffer.fill(0);
|
||||||
returnBuffer[0] = 0x80;
|
returnBuffer[0] = 0x80;
|
||||||
@@ -14,7 +21,13 @@ export default class VoicePacket {
|
|||||||
returnBuffer.writeUIntBE(time, 4, 4);
|
returnBuffer.writeUIntBE(time, 4, 4);
|
||||||
returnBuffer.writeUIntBE(ssrc, 8, 4);
|
returnBuffer.writeUIntBE(ssrc, 8, 4);
|
||||||
|
|
||||||
for (var i=0; i<audioBuffer.length; i++) {
|
if (secret) {
|
||||||
|
// copy first 12 bytes
|
||||||
|
returnBuffer.copy(nonce, 0, 0, 12);
|
||||||
|
audioBuffer = nacl.secretbox(data, nonce, secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < audioBuffer.length; i++) {
|
||||||
returnBuffer[i + 12] = audioBuffer[i];
|
returnBuffer[i + 12] = audioBuffer[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user