From d1d13f5c85d89d3c3507a25887673d7655410543 Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 17 Apr 2016 19:12:29 +0100 Subject: [PATCH] Added VoiceStateUpdate handler and DataStore for VoiceChannels. Also added toString methods to Guilds, DMChannels, ServerChannels and Users. --- .../packets/WebSocketPacketManager.js | 1 + .../packets/handlers/VoiceStateUpdate.js | 43 +++++++++++++++++++ src/structures/DMChannel.js | 4 ++ src/structures/Guild.js | 18 ++++++++ src/structures/GuildMember.js | 20 ++++++++- src/structures/ServerChannel.js | 4 ++ src/structures/User.js | 4 ++ src/structures/VoiceChannel.js | 2 + .../datastore/VoiceChannelDataStore.js | 12 ++++++ src/util/Constants.js | 1 + test/random.js | 4 ++ 11 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 src/client/websocket/packets/handlers/VoiceStateUpdate.js create mode 100644 src/structures/datastore/VoiceChannelDataStore.js diff --git a/src/client/websocket/packets/WebSocketPacketManager.js b/src/client/websocket/packets/WebSocketPacketManager.js index bb9ef601e..e23eabf8b 100644 --- a/src/client/websocket/packets/WebSocketPacketManager.js +++ b/src/client/websocket/packets/WebSocketPacketManager.js @@ -34,6 +34,7 @@ class WebSocketPacketManager { this.register(Constants.WSEvents.CHANNEL_UPDATE, 'ChannelUpdate'); this.register(Constants.WSEvents.PRESENCE_UPDATE, 'PresenceUpdate'); this.register(Constants.WSEvents.USER_UPDATE, 'UserUpdate'); + this.register(Constants.WSEvents.VOICE_STATE_UPDATE, 'VoiceStateUpdate'); } get client() { diff --git a/src/client/websocket/packets/handlers/VoiceStateUpdate.js b/src/client/websocket/packets/handlers/VoiceStateUpdate.js new file mode 100644 index 000000000..3838b7007 --- /dev/null +++ b/src/client/websocket/packets/handlers/VoiceStateUpdate.js @@ -0,0 +1,43 @@ +'use strict'; + +const AbstractHandler = require('./AbstractHandler'); +const Structure = name => require(`../../../../structures/${name}`); +const Constants = require('../../../../util/Constants'); +const CloneObject = require('../../../../util/CloneObject'); + +const Role = Structure('User'); + +class VoiceStateUpdateHandler extends AbstractHandler { + + constructor(packetManager) { + super(packetManager); + } + + handle(packet) { + let data = packet.d; + let client = this.packetManager.client; + let guild = client.store.get('guilds', data.guild_id); + + if (guild) { + let member = guild.store.get('members', data.user_id); + let channel = guild.store.get('channels', data.channel_id); + if (member) { + let oldVoiceChannelMember = CloneObject(member); + if (member.voiceChannel && member.voiceChannel.id !== data.channel_id) { + member.voiceChannel.store.remove('members', oldVoiceChannelMember); + } + + member.serverMute = data.mute; + member.serverDeaf = data.deaf; + member.selfMute = data.self_mute; + member.selfDeaf = data.self_deaf; + member.voiceSessionID = data.session_id; + member.voiceChannelID = data.channel_id; + client.emit(Constants.Events.VOICE_STATE_UPDATE, oldVoiceChannelMember, member); + } + } + } + +}; + +module.exports = VoiceStateUpdateHandler; diff --git a/src/structures/DMChannel.js b/src/structures/DMChannel.js index 0db181e96..7333ac8e7 100644 --- a/src/structures/DMChannel.js +++ b/src/structures/DMChannel.js @@ -12,6 +12,10 @@ class DMChannel extends Channel{ this.recipient = this.client.store.add('users', new User(this.client, data.recipient)); this.lastMessageID = data.last_message_id; } + + toString() { + return this.recipient.toString(); + } } module.exports = DMChannel; diff --git a/src/structures/Guild.js b/src/structures/Guild.js index 94b5d82b0..f6fb90a00 100644 --- a/src/structures/Guild.js +++ b/src/structures/Guild.js @@ -56,6 +56,10 @@ class Guild { } } + toString() { + return this.name; + } + setup(data) { this.id = data.id; this.available = !data.unavailable; @@ -106,6 +110,20 @@ class Guild { } } } + + if (data.voice_states) { + for (let voiceState of data.voice_states) { + let member = this.store.get('members', voiceState.user_id); + if (member) { + member.serverMute = voiceState.mute; + member.serverDeaf = voiceState.deaf; + member.selfMute = voiceState.self_mute; + member.selfDeaf = voiceState.self_deaf; + member.voiceSessionID = voiceState.session_id; + member.voiceChannelID = voiceState.channel_id; + } + } + } } } diff --git a/src/structures/GuildMember.js b/src/structures/GuildMember.js index 560787840..e8b531db0 100644 --- a/src/structures/GuildMember.js +++ b/src/structures/GuildMember.js @@ -13,8 +13,12 @@ class GuildMember { setup(data) { this.user = data.user; - this.deaf = data.deaf; - this.mute = data.mute; + this.serverDeaf = data.deaf; + this.serverMute = data.mute; + this.selfMute = data.self_mute; + this.selfDeaf = data.self_deaf; + this.voiceSessionID = data.session_id; + this.voiceChannelID = data.channel_id; this.joinDate = new Date(data.joined_at); this._roles = data.roles; } @@ -31,6 +35,18 @@ class GuildMember { return list; } + get mute() { + return this.selfMute || this.serverMute; + } + + get deaf() { + return this.selfDeaf || this.serverDeaf; + } + + get voiceChannel() { + return this.guild.store.get('channels', this.voiceChannelID); + } + get id() { return this.user.id; } diff --git a/src/structures/ServerChannel.js b/src/structures/ServerChannel.js index 32294b0ab..58053250a 100644 --- a/src/structures/ServerChannel.js +++ b/src/structures/ServerChannel.js @@ -17,6 +17,10 @@ class ServerChannel extends Channel{ this.name = data.name; this.lastMessageID = data.last_message_id; } + + toString() { + return this.name; + } } module.exports = ServerChannel; diff --git a/src/structures/User.js b/src/structures/User.js index dcab3f561..6cae4518b 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -17,6 +17,10 @@ class User { this.status = data.status || 'offline'; this.game = data.game; } + + toString() { + return `<@${this.id}>`; + } } module.exports = User; diff --git a/src/structures/VoiceChannel.js b/src/structures/VoiceChannel.js index 7a69e2b19..fb54df361 100644 --- a/src/structures/VoiceChannel.js +++ b/src/structures/VoiceChannel.js @@ -1,10 +1,12 @@ 'use strict'; const ServerChannel = require('./ServerChannel'); +const VoiceChannelDataStore = require('./datastore/VoiceChannelDataStore'); class VoiceChannel extends ServerChannel { constructor(guild, data) { super(guild, data); + this.store = new VoiceChannelDataStore(); } setup(data) { diff --git a/src/structures/datastore/VoiceChannelDataStore.js b/src/structures/datastore/VoiceChannelDataStore.js new file mode 100644 index 000000000..88b9da7bb --- /dev/null +++ b/src/structures/datastore/VoiceChannelDataStore.js @@ -0,0 +1,12 @@ +'use strict'; + +const AbstractDataStore = require('./AbstractDataStore'); + +class VoiceChannelDataStore extends AbstractDataStore{ + constructor() { + super(); + this.register('members'); + } +} + +module.exports = VoiceChannelDataStore; diff --git a/src/util/Constants.js b/src/util/Constants.js index 81511b072..86fe01556 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -93,6 +93,7 @@ const Events = exports.Events = { CHANNEL_UPDATE: 'channelUpdate', PRESENCE_UPDATE: 'presenceUpdate', USER_UPDATE: 'userUpdate', + VOICE_STATE_UPDATE: 'voiceStateUpdate', WARN: 'warn', }; diff --git a/test/random.js b/test/random.js index fd54e734b..ec4003d72 100644 --- a/test/random.js +++ b/test/random.js @@ -52,3 +52,7 @@ client.on('guildRoleUpdate', (guild, old, newRole) => { client.on('presenceUpdate', (oldUser, newUser) => { // console.log('presence from', oldUser.username, 'to', newUser.username); }); + +client.on('voiceStateUpdate', (oldMember, newMember) => { + console.log('voiceState', oldMember.user.username, oldMember.voiceChannel + '', newMember.voiceChannel + ''); +});