From 2518a0f7e256b6419c85b690bc5462b7e361f6a9 Mon Sep 17 00:00:00 2001 From: Zack Campbell Date: Wed, 8 Feb 2017 11:38:57 -0600 Subject: [PATCH] Fix for incorrect oldMember in guildMemberUpdate event after addRole (#1129) * Fix for incorrect oldMember in guildMemberUpdate event after addRole `addRole` would modify the cached GuildMember rather than letting it be handled internally when a guild member update packet is received from Discord, leading to the `oldMember` and `newMember` being identical following a call to `addRole` This is currently how `addRoles` does it, and a correct oldMember is passed to the `guildMemberUpdate` event following a call to `addRoles` * Return cloned member with added/removed role So we can return a member object with the added/removed role without affecting the member object sent to `guildMemberUpdate` * Wait for guildMemberUpdate and return updated GuildMember * Fix linter errors * Remove listeners after 10 seconds --- src/client/rest/RESTMethods.js | 46 ++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index 7b7528688..ce257b210 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -406,22 +406,42 @@ class RESTMethods { } addMemberRole(member, role) { - return this.rest.makeRequest('put', Constants.Endpoints.guildMemberRole(member.guild.id, member.id, role.id), true) - .then(() => { - if (!member._roles.includes(role.id)) member._roles.push(role.id); - return member; - }); + return new Promise(resolve => { + const listener = (oldMember, newMember) => { + if (!oldMember._roles.includes(role.id) && newMember._roles.includes(role.id)) { + this.client.removeListener('guildMemberUpdate', listener); + resolve(newMember); + } + }; + + this.client.on('guildMemberUpdate', listener); + this.client.setTimeout(() => this.client.removeListener('guildMemberUpdate', listener), 10e3); + + this.rest.makeRequest( + 'put', + Constants.Endpoints.guildMemberRole(member.guild.id, member.id, role.id), + true + ); + }); } removeMemberRole(member, role) { - return this.rest.makeRequest( - 'delete', - Constants.Endpoints.guildMemberRole(member.guild.id, member.id, role.id), - true - ).then(() => { - const index = member._roles.indexOf(role.id); - if (index >= 0) member._roles.splice(index, 1); - return member; + return new Promise(resolve => { + const listener = (oldMember, newMember) => { + if (oldMember._roles.includes(role.id) && !newMember._roles.includes(role.id)) { + this.client.removeListener('guildMemberUpdate', listener); + resolve(newMember); + } + }; + + this.client.on('guildMemberUpdate', listener); + this.client.setTimeout(() => this.client.removeListener('guildMemberUpdate', listener), 10e3); + + this.rest.makeRequest( + 'delete', + Constants.Endpoints.guildMemberRole(member.guild.id, member.id, role.id), + true + ); }); }