From ebfc2169d54dc7722b6fdaed0c8843160fae0abf Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sun, 1 May 2016 21:12:42 +0100 Subject: [PATCH] Added ClientUser modification support --- src/client/Client.js | 4 ++ src/client/ClientDataResolver.js | 7 +++ src/client/actions/ActionsManager.js | 1 + src/client/actions/UserUpdate.js | 44 +++++++++++++++++++ src/client/rest/RESTMethods.js | 22 +++++++++- .../websocket/packets/handlers/UserUpdate.js | 18 +------- src/structures/ClientUser.js | 20 +++++++++ src/structures/User.js | 26 ++++++++++- src/structures/datastore/ClientDataStore.js | 2 + test/random.js | 18 ++++++++ 10 files changed, 143 insertions(+), 19 deletions(-) create mode 100644 src/client/actions/UserUpdate.js diff --git a/src/client/Client.js b/src/client/Client.js index d48f6c2a8..b51ac03e6 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -33,6 +33,10 @@ class Client extends EventEmitter{ } } + get user() { + return this.store.user; + } + } module.exports = Client; diff --git a/src/client/ClientDataResolver.js b/src/client/ClientDataResolver.js index 47ee3f9fc..8f8cd6d22 100644 --- a/src/client/ClientDataResolver.js +++ b/src/client/ClientDataResolver.js @@ -54,6 +54,13 @@ class ClientDataResolver { return guild.store.get('members', user.id); } + + ResolveBase64(data) { + if (data instanceof Buffer) { + return 'data:image/jpg;base64,' + data.toString('base64'); + } + return data; + } } module.exports = ClientDataResolver; diff --git a/src/client/actions/ActionsManager.js b/src/client/actions/ActionsManager.js index ed711b5fa..9b1ed9256 100644 --- a/src/client/actions/ActionsManager.js +++ b/src/client/actions/ActionsManager.js @@ -13,6 +13,7 @@ class ActionsManager { this.register('ChannelDelete'); this.register('ChannelUpdate'); this.register('GuildDelete'); + this.register('UserUpdate'); } register(name) { diff --git a/src/client/actions/UserUpdate.js b/src/client/actions/UserUpdate.js new file mode 100644 index 000000000..ec3a42cb6 --- /dev/null +++ b/src/client/actions/UserUpdate.js @@ -0,0 +1,44 @@ +'use strict'; + +const Action = require('./Action'); +const Constants = require('../../util/Constants'); +const CloneObject = require('../../util/CloneObject'); +const Message = require('../../structures/Message'); + +class UserUpdateAction extends Action { + + constructor(client) { + super(client); + } + + handle(data) { + + let client = this.client; + + if (client.store.user) { + if (client.store.user.equals(data)) { + return { + old: client.store.user, + updated: client.store.user, + }; + } + + let oldUser = CloneObject(client.store.user); + client.store.user.setup(data); + + client.emit(Constants.Events.USER_UPDATE, oldUser, client.store.user); + + return { + old: oldUser, + updated: client.store.user, + }; + } + + return { + old: null, + updated: null, + }; + } +}; + +module.exports = UserUpdateAction; diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index d175dcf67..2a3a54176 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -12,7 +12,8 @@ class RESTMethods{ LoginEmailPassword(email, password) { return new Promise((resolve, reject) => { - + this.rest.client.store.email = email; + this.rest.client.store.password = password; this.rest.makeRequest('post', Constants.Endpoints.LOGIN, false, { email, password }) .then(data => { this.rest.client.manager.connectToWebSocket(data.token, resolve, reject); @@ -132,6 +133,25 @@ class RESTMethods{ .catch(reject); }); } + + UpdateCurrentUser(_data) { + return new Promise((resolve, reject) => { + let user = this.rest.client.store.user; + let data = {}; + + data.username = _data.username || user.username; + data.avatar = this.rest.client.resolver.ResolveBase64(_data.avatar) || user.avatar; + if (!user.bot) { + data.password = this.rest.client.store.password; + data.email = _data.email || this.rest.client.store.email; + data.new_password = _data.newPassword; + } + + this.rest.makeRequest('patch', Constants.Endpoints.ME, true, data) + .then(data => resolve(this.rest.client.actions.UserUpdate.handle(data).updated)) + .catch(reject); + }); + } } module.exports = RESTMethods; diff --git a/src/client/websocket/packets/handlers/UserUpdate.js b/src/client/websocket/packets/handlers/UserUpdate.js index d8bc1f7cc..8cefe8fcd 100644 --- a/src/client/websocket/packets/handlers/UserUpdate.js +++ b/src/client/websocket/packets/handlers/UserUpdate.js @@ -3,6 +3,7 @@ const AbstractHandler = require('./AbstractHandler'); const Structure = name => require(`../../../../structures/${name}`); const CloneObject = name => require(`../../../../util/CloneObject`); +const Constants = require(`../../../../util/Constants`); const ClientUser = Structure('ClientUser'); const Guild = Structure('Guild'); @@ -18,22 +19,7 @@ class UserUpdateHandler extends AbstractHandler { let data = packet.d; let client = this.packetManager.client; - let user = client.store.user; - - if (!user) { - return; - } - - let oldUser = CloneObject(user); - - user.username = data.username || user.username; - user.id = data.id || user.id; - user.avatar = data.avatar || user.avatar; - user.discriminator = data.discriminator || user.discriminator; - user.email = data.email || user.email; - user.verified = data.verified || user.verified; - - client.emit(Constants.Events.USER_UPDATE, oldUser, user); + let response = client.actions.UserUpdate.handle(data); } diff --git a/src/structures/ClientUser.js b/src/structures/ClientUser.js index 19b84d5b8..923c571dd 100644 --- a/src/structures/ClientUser.js +++ b/src/structures/ClientUser.js @@ -12,6 +12,26 @@ class ClientUser extends User { this.verified = data.verified; this.email = data.email; } + + setUsername(username) { + return this.client.rest.methods.UpdateCurrentUser({ username, }); + } + + setEmail(email) { + return this.client.rest.methods.UpdateCurrentUser({ email, }); + } + + setPassword(password) { + return this.client.rest.methods.UpdateCurrentUser({ password, }); + } + + setAvatar(avatar) { + return this.client.rest.methods.UpdateCurrentUser({ avatar, }); + } + + edit(data) { + return this.client.rest.methods.UpdateCurrentUser(data); + } } module.exports = ClientUser; diff --git a/src/structures/User.js b/src/structures/User.js index 6cae4518b..4d48aed5a 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -14,13 +14,35 @@ class User { this.discriminator = data.discriminator; this.avatar = data.avatar; this.bot = Boolean(data.bot); - this.status = data.status || 'offline'; - this.game = data.game; + this.status = data.status || this.status || 'offline'; + this.game = data.game || this.game; } toString() { return `<@${this.id}>`; } + + equals(user) { + let base = ( + this.username === user.username && + this.id === user.id && + this.discriminator === user.discriminator && + this.avatar === user.avatar && + this.bot === Boolean(user.bot) + ); + + if (base) { + if (user.status) { + base = this.status === user.status; + } + + if (user.game) { + base = this.game === user.game; + } + } + + return base; + } } module.exports = User; diff --git a/src/structures/datastore/ClientDataStore.js b/src/structures/datastore/ClientDataStore.js index cdcbdc2e3..a7b39c19d 100644 --- a/src/structures/datastore/ClientDataStore.js +++ b/src/structures/datastore/ClientDataStore.js @@ -18,6 +18,8 @@ class ClientDataStore extends AbstractDataStore{ this.token = null; this.session = null; this.user = null; + this.email = null; + this.password = null; this.register('users'); this.register('guilds'); diff --git a/test/random.js b/test/random.js index 9f4b6879d..194fe13da 100644 --- a/test/random.js +++ b/test/random.js @@ -1,6 +1,7 @@ 'use strict'; const Discord = require('../'); +const request = require('superagent'); let client = new Discord.Client(); @@ -84,12 +85,29 @@ client.on('message', message => { message.channel.setName(message.content.substr(8)).then(chanLoop).catch(console.log); } + if (message.content.startsWith('botname')) { + client.user.setUsername(message.content.substr(8)).then(nameLoop).catch(console.log); + } + + if (message.content.startsWith('botavatar')) { + request + .get('url') + .end((err, res) => { + client.user.setAvatar(res.body).catch(console.log) + .then(user => message.channel.sendMessage('Done!')); + }); + } + if (message.content === 'leave') { message.guild.leave().then(guild => console.log('left guild', guild.name)).catch(console.log); } } }); +function nameLoop(user) { + user.setUsername(user.username + 'a').then(nameLoop).catch(console.log); +} + function chanLoop(channel) { channel.setName(channel.name + 'a').then(chanLoop).catch(console.log); }