v5.0.0! Woo!

This commit is contained in:
hydrabolt
2015-11-20 22:12:02 +00:00
parent 294c002bde
commit 409635d50a
30 changed files with 16834 additions and 4378 deletions

View File

@@ -1,332 +1,11 @@
"use strict";
/*
"use strict"; /*
Major credit to izy521 who is the creator of
https://github.com/izy521/discord.io,
without his help voice chat in discord.js would not have
been possible!
*/
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var WebSocket = require("ws");
var dns = require("dns");
var udp = require("dgram");
var fs = require("fs");
var AudioEncoder = require("./AudioEncoder.js");
var VoicePacket = require("./VoicePacket.js");
var StreamIntent = require("./StreamIntent.js");
var EventEmitter = require("events");
var VoiceConnection = (function (_EventEmitter) {
_inherits(VoiceConnection, _EventEmitter);
function VoiceConnection(channel, client, session, token, server, endpoint) {
_classCallCheck(this, VoiceConnection);
_EventEmitter.call(this);
this.id = channel.id;
this.voiceChannel = channel;
this.client = client;
this.session = session;
this.token = token;
this.server = server;
this.endpoint = endpoint.replace(":80", "");
this.vWS = null; // vWS means voice websocket
this.ready = false;
this.vWSData = {};
this.encoder = new AudioEncoder();
this.udp = null;
this.playingIntent = null;
this.playing = false;
this.streamTime = 0;
this.streamProc = null;
this.KAI = null;
this.init();
}
VoiceConnection.prototype.destroy = function destroy() {
this.stopPlaying();
if (this.KAI) clearInterval(this.KAI);
this.vWS.close();
this.udp.close();
this.client.internal.sendWS({
op: 4,
d: {
guild_id: null,
channel_id: null,
self_mute: true,
self_deaf: false
}
});
};
VoiceConnection.prototype.stopPlaying = function stopPlaying() {
this.playing = false;
this.playingIntent = null;
if (this.instream) {
this.instream.end();
this.instream.destroy();
}
};
VoiceConnection.prototype.playStream = function playStream(stream) {
var self = this;
var startTime = Date.now();
var sequence = 0;
var time = 0;
var count = 0;
var length = 20;
if (self.playingIntent) {
self.stopPlaying();
}
self.playing = true;
var retStream = new StreamIntent();
var onWarning = false;
self.playingIntent = retStream;
function send() {
if (!self.playingIntent || !self.playing) {
self.setSpeaking(false);
retStream.emit("end");
self;
return;
}
try {
var buffer = stream.read(1920);
if (!buffer) {
setTimeout(send, length * 10); // give chance for some data in 200ms to appear
return;
}
if (buffer.length !== 1920) {
if (onWarning) {
retStream.emit("end");
stream.destroy();
self.setSpeaking(false);
return;
} else {
onWarning = true;
setTimeout(send, length * 10); // give chance for some data in 200ms to appear
return;
}
}
count++;
sequence + 10 < 65535 ? sequence += 1 : sequence = 0;
time + 9600 < 4294967295 ? time += 960 : time = 0;
self.sendBuffer(buffer, sequence, time, function (e) {});
var nextTime = startTime + count * length;
self.streamTime = count * length;
setTimeout(send, length + (nextTime - Date.now()));
if (!self.playing) self.setSpeaking(true);
retStream.emit("time", self.streamTime);
} catch (e) {
retStream.emit("error", e);
}
}
self.setSpeaking(true);
send();
return retStream;
};
VoiceConnection.prototype.setSpeaking = function setSpeaking(value) {
this.playing = value;
if (this.vWS.readyState === WebSocket.OPEN) this.vWS.send(JSON.stringify({
op: 5,
d: {
speaking: value,
delay: 0
}
}));
};
VoiceConnection.prototype.sendPacket = function sendPacket(packet) {
var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1];
var self = this;
self.playing = true;
try {
if (self.vWS.readyState === WebSocket.OPEN) self.udp.send(packet, 0, packet.length, self.vWSData.port, self.endpoint, callback);
} catch (e) {
self.playing = false;
callback(e);
return false;
}
};
VoiceConnection.prototype.sendBuffer = function sendBuffer(rawbuffer, sequence, timestamp, callback) {
var self = this;
self.playing = true;
try {
if (!self.encoder.opus) {
self.playing = false;
self.emit("error", "No Opus!");
self.client.emit("debug", "Tried to use node-opus, but opus not available - install it!");
return;
}
var buffer = self.encoder.opusBuffer(rawbuffer);
var packet = new VoicePacket(buffer, sequence, timestamp, self.vWSData.ssrc);
return self.sendPacket(packet, callback);
} catch (e) {
self.playing = false;
self.emit("error", e);
return false;
}
};
VoiceConnection.prototype.test = function test() {
this.playFile("C:/users/amish/desktop/audio.mp3").then(function (stream) {
stream.on("time", function (time) {
console.log("Time", time);
});
});
};
VoiceConnection.prototype.playFile = function playFile(stream) {
var _this = this;
var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err, str) {} : arguments[1];
var self = this;
return new Promise(function (resolve, reject) {
_this.encoder.encodeFile(stream)["catch"](error).then(function (data) {
self.streamProc = data.proc;
var intent = self.playStream(data.stream);
resolve(intent);
callback(null, intent);
});
function error() {
var e = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];
reject(e);
callback(e);
}
});
};
VoiceConnection.prototype.playRawStream = function playRawStream(stream) {
var _this2 = this;
var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err, str) {} : arguments[1];
var self = this;
return new Promise(function (resolve, reject) {
_this2.encoder.encodeStream(stream)["catch"](error).then(function (data) {
self.streamProc = data.proc;
self.instream = data.instream;
var intent = self.playStream(data.stream);
resolve(intent);
callback(null, intent);
});
function error() {
var e = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];
reject(e);
callback(e);
}
});
};
VoiceConnection.prototype.init = function init() {
var _this3 = this;
var self = this;
dns.lookup(this.endpoint, function (err, address, family) {
self.endpoint = address;
var vWS = self.vWS = new WebSocket("wss://" + _this3.endpoint, null, { rejectUnauthorized: false });
var udpClient = self.udp = udp.createSocket("udp4");
var firstPacket = true;
var discordIP = "",
discordPort = "";
udpClient.bind({ exclusive: true });
udpClient.on('message', function (msg, rinfo) {
var buffArr = JSON.parse(JSON.stringify(msg)).data;
if (firstPacket === true) {
for (var i = 4; i < buffArr.indexOf(0, i); i++) {
discordIP += String.fromCharCode(buffArr[i]);
}
discordPort = msg.readUIntLE(msg.length - 2, 2).toString(10);
var wsDiscPayload = {
"op": 1,
"d": {
"protocol": "udp",
"data": {
"address": discordIP,
"port": Number(discordPort),
"mode": self.vWSData.modes[0] //Plain
}
}
};
vWS.send(JSON.stringify(wsDiscPayload));
firstPacket = false;
}
});
vWS.on("open", function () {
vWS.send(JSON.stringify({
op: 0,
d: {
server_id: self.server.id,
user_id: self.client.internal.user.id,
session_id: self.session,
token: self.token
}
}));
});
var KAI;
vWS.on("message", function (msg) {
var data = JSON.parse(msg);
switch (data.op) {
case 2:
self.vWSData = data.d;
KAI = setInterval(function () {
if (vWS && vWS.readyState === WebSocket.OPEN) vWS.send(JSON.stringify({
op: 3,
d: null
}));
}, data.d.heartbeat_interval);
self.KAI = KAI;
var udpPacket = new Buffer(70);
udpPacket.writeUIntBE(data.d.ssrc, 0, 4);
udpClient.send(udpPacket, 0, udpPacket.length, data.d.port, self.endpoint, function (err) {
if (err) self.emit("error", err);
});
break;
case 4:
self.ready = true;
self.mode = data.d.mode;
self.emit("ready", self);
break;
}
});
});
};
return VoiceConnection;
})(EventEmitter);
module.exports = VoiceConnection;
*/function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _inherits(subClass,superClass){if(typeof superClass !== "function" && superClass !== null){throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);}subClass.prototype = Object.create(superClass && superClass.prototype,{constructor:{value:subClass,enumerable:false,writable:true,configurable:true}});if(superClass)Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__ = superClass;}var WebSocket=require("ws");var dns=require("dns");var udp=require("dgram");var fs=require("fs");var AudioEncoder=require("./AudioEncoder.js");var VoicePacket=require("./VoicePacket.js");var StreamIntent=require("./StreamIntent.js");var EventEmitter=require("events");var VoiceConnection=(function(_EventEmitter){_inherits(VoiceConnection,_EventEmitter);function VoiceConnection(channel,client,session,token,server,endpoint){_classCallCheck(this,VoiceConnection);_EventEmitter.call(this);this.id = channel.id;this.voiceChannel = channel;this.client = client;this.session = session;this.token = token;this.server = server;this.endpoint = endpoint.replace(":80","");this.vWS = null; // vWS means voice websocket
this.ready = false;this.vWSData = {};this.encoder = new AudioEncoder();this.udp = null;this.playingIntent = null;this.playing = false;this.streamTime = 0;this.streamProc = null;this.KAI = null;this.init();}VoiceConnection.prototype.destroy = function destroy(){this.stopPlaying();if(this.KAI)clearInterval(this.KAI);this.vWS.close();this.udp.close();this.client.internal.sendWS({op:4,d:{guild_id:null,channel_id:null,self_mute:true,self_deaf:false}});};VoiceConnection.prototype.stopPlaying = function stopPlaying(){this.playing = false;this.playingIntent = null;if(this.instream){this.instream.end();this.instream.destroy();}};VoiceConnection.prototype.playStream = function playStream(stream){var self=this;var startTime=Date.now();var sequence=0;var time=0;var count=0;var length=20;if(self.playingIntent){self.stopPlaying();}self.playing = true;var retStream=new StreamIntent();var onWarning=false;self.playingIntent = retStream;function send(){if(!self.playingIntent || !self.playing){self.setSpeaking(false);retStream.emit("end");self;return;}try{var buffer=stream.read(1920);if(!buffer){setTimeout(send,length * 10); // give chance for some data in 200ms to appear
return;}if(buffer.length !== 1920){if(onWarning){retStream.emit("end");stream.destroy();self.setSpeaking(false);return;}else {onWarning = true;setTimeout(send,length * 10); // give chance for some data in 200ms to appear
return;}}count++;sequence + 10 < 65535?sequence += 1:sequence = 0;time + 9600 < 4294967295?time += 960:time = 0;self.sendBuffer(buffer,sequence,time,function(e){});var nextTime=startTime + count * length;self.streamTime = count * length;setTimeout(send,length + (nextTime - Date.now()));if(!self.playing)self.setSpeaking(true);retStream.emit("time",self.streamTime);}catch(e) {retStream.emit("error",e);}}self.setSpeaking(true);send();return retStream;};VoiceConnection.prototype.setSpeaking = function setSpeaking(value){this.playing = value;if(this.vWS.readyState === WebSocket.OPEN)this.vWS.send(JSON.stringify({op:5,d:{speaking:value,delay:0}}));};VoiceConnection.prototype.sendPacket = function sendPacket(packet){var callback=arguments.length <= 1 || arguments[1] === undefined?function(err){}:arguments[1];var self=this;self.playing = true;try{if(self.vWS.readyState === WebSocket.OPEN)self.udp.send(packet,0,packet.length,self.vWSData.port,self.endpoint,callback);}catch(e) {self.playing = false;callback(e);return false;}};VoiceConnection.prototype.sendBuffer = function sendBuffer(rawbuffer,sequence,timestamp,callback){var self=this;self.playing = true;try{if(!self.encoder.opus){self.playing = false;self.emit("error","No Opus!");self.client.emit("debug","Tried to use node-opus, but opus not available - install it!");return;}var buffer=self.encoder.opusBuffer(rawbuffer);var packet=new VoicePacket(buffer,sequence,timestamp,self.vWSData.ssrc);return self.sendPacket(packet,callback);}catch(e) {self.playing = false;self.emit("error",e);return false;}};VoiceConnection.prototype.test = function test(){this.playFile("C:/users/amish/desktop/audio.mp3").then(function(stream){stream.on("time",function(time){console.log("Time",time);});});};VoiceConnection.prototype.playFile = function playFile(stream){var _this=this;var callback=arguments.length <= 1 || arguments[1] === undefined?function(err,str){}:arguments[1];var self=this;return new Promise(function(resolve,reject){_this.encoder.encodeFile(stream)["catch"](error).then(function(data){self.streamProc = data.proc;var intent=self.playStream(data.stream);resolve(intent);callback(null,intent);});function error(){var e=arguments.length <= 0 || arguments[0] === undefined?true:arguments[0];reject(e);callback(e);}});};VoiceConnection.prototype.playRawStream = function playRawStream(stream){var _this2=this;var callback=arguments.length <= 1 || arguments[1] === undefined?function(err,str){}:arguments[1];var self=this;return new Promise(function(resolve,reject){_this2.encoder.encodeStream(stream)["catch"](error).then(function(data){self.streamProc = data.proc;self.instream = data.instream;var intent=self.playStream(data.stream);resolve(intent);callback(null,intent);});function error(){var e=arguments.length <= 0 || arguments[0] === undefined?true:arguments[0];reject(e);callback(e);}});};VoiceConnection.prototype.init = function init(){var _this3=this;var self=this;dns.lookup(this.endpoint,function(err,address,family){self.endpoint = address;var vWS=self.vWS = new WebSocket("wss://" + _this3.endpoint,null,{rejectUnauthorized:false});var udpClient=self.udp = udp.createSocket("udp4");var firstPacket=true;var discordIP="",discordPort="";udpClient.bind({exclusive:true});udpClient.on('message',function(msg,rinfo){var buffArr=JSON.parse(JSON.stringify(msg)).data;if(firstPacket === true){for(var i=4;i < buffArr.indexOf(0,i);i++) {discordIP += String.fromCharCode(buffArr[i]);}discordPort = msg.readUIntLE(msg.length - 2,2).toString(10);var wsDiscPayload={"op":1,"d":{"protocol":"udp","data":{"address":discordIP,"port":Number(discordPort),"mode":self.vWSData.modes[0] //Plain
}}};vWS.send(JSON.stringify(wsDiscPayload));firstPacket = false;}});vWS.on("open",function(){vWS.send(JSON.stringify({op:0,d:{server_id:self.server.id,user_id:self.client.internal.user.id,session_id:self.session,token:self.token}}));});var KAI;vWS.on("message",function(msg){var data=JSON.parse(msg);switch(data.op){case 2:self.vWSData = data.d;KAI = setInterval(function(){if(vWS && vWS.readyState === WebSocket.OPEN)vWS.send(JSON.stringify({op:3,d:null}));},data.d.heartbeat_interval);self.KAI = KAI;var udpPacket=new Buffer(70);udpPacket.writeUIntBE(data.d.ssrc,0,4);udpClient.send(udpPacket,0,udpPacket.length,data.d.port,self.endpoint,function(err){if(err)self.emit("error",err);});break;case 4:self.ready = true;self.mode = data.d.mode;self.emit("ready",self);break;}});});};return VoiceConnection;})(EventEmitter);module.exports = VoiceConnection;