diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 6b732ed6d..21863b262 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -660,3 +660,13 @@ userUnbanned ~~~~~~~~~~ Emitted when a user is unbanned from a server. Supplies two parameters, a User_ object and a Server_ object. + +voiceJoin +~~~~~~~~ + +Emitted when a user joins a voice channel, supplies a User_ and a VoiceChannel_ + +voiceLeave +~~~~~~~~~~ + +Emitted when a user leaves a voice channel, supplies a User_ and a VoiceChannel_ \ No newline at end of file diff --git a/docs/docs_voicechannel.rst b/docs/docs_voicechannel.rst index 1ba5b9250..22e905734 100644 --- a/docs/docs_voicechannel.rst +++ b/docs/docs_voicechannel.rst @@ -8,3 +8,12 @@ VoiceChannel A voice channel of a server. Currently, the voice channel class has no differences to the ServerChannel class. -------- + + +Attributes +---------- + +speaking +~~~~~~~~ + +A Cache_ of User_s that are speaking in the voice channel \ No newline at end of file diff --git a/lib/Client/InternalClient.js b/lib/Client/InternalClient.js index 9069c0399..90745be1d 100644 --- a/lib/Client/InternalClient.js +++ b/lib/Client/InternalClient.js @@ -1592,6 +1592,30 @@ var InternalClient = (function () { } else { client.emit("warn", "user unbanned but user/server not in cache."); } + break; + case _Constants.PacketType.VOICE_STATE_UPDATE: + + var user = self.users.get("id", data.user_id); + var server = self.servers.get("id", data.guild_id); + + if (user && server) { + + if (data.channel_id) { + // speaking + var channel = self.channels.get("id", data.channel_id); + if (channel) { + if (server.eventStartSpeaking(user, channel)) client.emit("voiceJoin", user, channel);else client.emit("warn", "voice state error occurred in adding"); + } else { + client.emit("warn", "voice state channel not in cache"); + } + } else { + // not speaking + client.emit("voiceLeave", user, server.eventStopSpeaking(user)); + } + } else { + client.emit("warn", "voice state update but user or server not in cache"); + } + break; default: client.emit("unknown", packet); diff --git a/lib/Constants.js b/lib/Constants.js index 13b465ae1..d6773a65a 100644 --- a/lib/Constants.js +++ b/lib/Constants.js @@ -125,6 +125,7 @@ var PacketType = { PRESENCE_UPDATE: "PRESENCE_UPDATE", TYPING: "TYPING_START", SERVER_BAN_ADD: "GUILD_BAN_ADD", - SERVER_BAN_REMOVE: "GUILD_BAN_REMOVE" + SERVER_BAN_REMOVE: "GUILD_BAN_REMOVE", + VOICE_STATE_UPDATE: "VOICE_STATE_UPDATE" }; exports.PacketType = PacketType; diff --git a/lib/Structures/Server.js b/lib/Structures/Server.js index 1332da1ba..2eafa75ea 100644 --- a/lib/Structures/Server.js +++ b/lib/Structures/Server.js @@ -148,21 +148,60 @@ var Server = (function (_Equality) { return this.name; }; + Server.prototype.eventStartSpeaking = function eventStartSpeaking(user, channel) { + channel = this.channels.get("id", channel.id); + if (channel) { + // good + + // removes from other speaking channels first + this.eventStopSpeaking(user); + + channel.speaking.add(user); + return true; + } else { + // bad + return false; + } + }; + + Server.prototype.eventStopSpeaking = function eventStopSpeaking(user) { + for (var _iterator2 = this.channels.getAll("type", "voice"), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref2; + + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref2 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref2 = _i2.value; + } + + var chan = _ref2; + + if (chan.speaking.has(user)) { + chan.speaking.remove(user); + return chan; + } + } + return this; + }; + Server.prototype.equalsStrict = function equalsStrict(obj) { if (obj instanceof Server) { - for (var _iterator2 = strictKeys, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref2; + for (var _iterator3 = strictKeys, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { + var _ref3; - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref2 = _iterator2[_i2++]; + if (_isArray3) { + if (_i3 >= _iterator3.length) break; + _ref3 = _iterator3[_i3++]; } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref2 = _i2.value; + _i3 = _iterator3.next(); + if (_i3.done) break; + _ref3 = _i3.value; } - var key = _ref2; + var key = _ref3; if (obj[key] !== this[key]) { return false; diff --git a/src/Client/InternalClient.js b/src/Client/InternalClient.js index 727620f37..d20cdb49c 100644 --- a/src/Client/InternalClient.js +++ b/src/Client/InternalClient.js @@ -1417,6 +1417,34 @@ export default class InternalClient { } else { client.emit("warn", "user unbanned but user/server not in cache."); } + break; + case PacketType.VOICE_STATE_UPDATE: + + var user = self.users.get("id", data.user_id); + var server = self.servers.get("id", data.guild_id); + + if(user && server){ + + if(data.channel_id){ + // speaking + var channel = self.channels.get("id", data.channel_id); + if(channel){ + if(server.eventStartSpeaking(user, channel)) + client.emit("voiceJoin", user, channel); + else + client.emit("warn", "voice state error occurred in adding"); + }else{ + client.emit("warn", "voice state channel not in cache"); + } + }else{ + // not speaking + client.emit("voiceLeave", user, server.eventStopSpeaking(user)); + } + + }else{ + client.emit("warn", "voice state update but user or server not in cache"); + } + break; default: client.emit("unknown", packet); diff --git a/src/Constants.js b/src/Constants.js index 90ef95f8d..4e5b31f8f 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -83,5 +83,6 @@ export const PacketType = { PRESENCE_UPDATE : "PRESENCE_UPDATE", TYPING : "TYPING_START", SERVER_BAN_ADD : "GUILD_BAN_ADD", - SERVER_BAN_REMOVE : "GUILD_BAN_REMOVE" + SERVER_BAN_REMOVE: "GUILD_BAN_REMOVE", + VOICE_STATE_UPDATE : "VOICE_STATE_UPDATE" }; diff --git a/src/Structures/Server.js b/src/Structures/Server.js index df8157d02..9025db755 100644 --- a/src/Structures/Server.js +++ b/src/Structures/Server.js @@ -129,6 +129,32 @@ export default class Server extends Equality { return this.name; } + eventStartSpeaking(user, channel){ + channel = this.channels.get("id", channel.id); + if(channel){ + // good + + // removes from other speaking channels first + this.eventStopSpeaking(user); + + channel.speaking.add(user); + return true; + }else{ + // bad + return false; + } + } + + eventStopSpeaking(user){ + for(let chan of this.channels.getAll("type", "voice")){ + if(chan.speaking.has(user)){ + chan.speaking.remove(user); + return chan; + } + } + return this; + } + equalsStrict(obj) { if (obj instanceof Server) { for (var key of strictKeys) { diff --git a/test/msgbot.js b/test/msgbot.js index 405446db4..67a1295ad 100644 --- a/test/msgbot.js +++ b/test/msgbot.js @@ -13,6 +13,14 @@ client.on("autoRevive", () => { console.log("auto revived"); }); +client.on("voiceJoin", (user, channel) => { + console.log(`VOICE ${user.username} joined ${channel}!`); +}); + +client.on("voiceLeave", (user, channel) => { + console.log(`VOICE ${user.username} left ${channel}!`); +}); + client.on("message", msg => { if(!msg.sender.equals(client.user))