diff --git a/src/client/websocket/packets/WebSocketPacketManager.js b/src/client/websocket/packets/WebSocketPacketManager.js index 43d6b1249..d3c2d0ca6 100644 --- a/src/client/websocket/packets/WebSocketPacketManager.js +++ b/src/client/websocket/packets/WebSocketPacketManager.js @@ -37,6 +37,7 @@ class WebSocketPacketManager { this.register(Constants.WSEvents.USER_UPDATE, 'UserUpdate'); this.register(Constants.WSEvents.VOICE_STATE_UPDATE, 'VoiceStateUpdate'); this.register(Constants.WSEvents.TYPING_START, 'TypingStart'); + this.register(Constants.WSEvents.MESSAGE_CREATE, 'MessageCreate'); } get client() { diff --git a/src/client/websocket/packets/handlers/MessageCreate.js b/src/client/websocket/packets/handlers/MessageCreate.js new file mode 100644 index 000000000..f6e2cf35e --- /dev/null +++ b/src/client/websocket/packets/handlers/MessageCreate.js @@ -0,0 +1,31 @@ +'use strict'; + +const AbstractHandler = require('./AbstractHandler'); +const Structure = name => require(`../../../../structures/${name}`); +const Constants = require('../../../../util/Constants'); + +const Message = Structure('Message'); +const Guild = Structure('Guild'); + +class MessageCreateHandler extends AbstractHandler { + + constructor(packetManager) { + super(packetManager); + } + + handle(packet) { + let data = packet.d; + let client = this.packetManager.client; + let channel = client.store.get('channels', data.channel_id); + + if (channel) { + let message = new Message(channel, data); + channel._cacheMessage(message); + client.emit(Constants.Events.MESSAGE_CREATE, message); + } + + } + +}; + +module.exports = MessageCreateHandler; diff --git a/src/structures/DMChannel.js b/src/structures/DMChannel.js index 7333ac8e7..b1bdd92c7 100644 --- a/src/structures/DMChannel.js +++ b/src/structures/DMChannel.js @@ -2,10 +2,26 @@ const Channel = require('./Channel'); const User = require('./User'); +const TextChannelDataStore = require('./datastore/TextChannelDataStore'); class DMChannel extends Channel{ constructor(client, data) { super(client, data); + this.store = new TextChannelDataStore(); + } + + _cacheMessage(message) { + let maxSize = this.client.options.max_message_cache; + if (maxSize === 0) { + // saves on performance + return; + } + + let storeKeys = Object.keys(this.store); + if (storeKeys.length >= maxSize) { + this.store.remove(storeKeys[0]); + this.store.add('messages', message); + } } setup(data) { diff --git a/src/structures/Message.js b/src/structures/Message.js index 30d7fc4ac..1da8cf9bc 100644 --- a/src/structures/Message.js +++ b/src/structures/Message.js @@ -1,8 +1,31 @@ 'use strict'; class Message { - constructor() { + constructor(serverChannel, data) { + this.channel = serverChannel; + this.guild = serverChannel.guild; + if (data) { + this.setup(data); + } + } + setup(data) { + this.author = this.guild.client.store.get('users', data.author.id); + this.content = data.content; + this.timestamp = new Date(data.timestamp); + this.editedTimestamp = data.edited_timestamp ? new Date(data.edited_timestamp) : null; + this.tts = data.tts; + this.mentionEveryone = data.mention_everyone; + this.nonce = data.nonce; + this.embeds = data.embeds; + this.attachments = data.attachments; + this.mentions = []; + for (let mention of data.mentions) { + let user = this.guild.client.store.get('users', mention.id); + if (user) { + this.mentions.push(user); + } + } } } diff --git a/src/structures/TextChannel.js b/src/structures/TextChannel.js index e8b2b6acc..c9ae55f06 100644 --- a/src/structures/TextChannel.js +++ b/src/structures/TextChannel.js @@ -4,10 +4,25 @@ const ServerChannel = require('./ServerChannel'); const TextChannelDataStore = require('./datastore/TextChannelDataStore'); class TextChannel extends ServerChannel { + constructor(guild, data) { super(guild, data); this.store = new TextChannelDataStore(); } + + _cacheMessage(message) { + let maxSize = this.client.options.max_message_cache; + if (maxSize === 0) { + // saves on performance + return; + } + + let storeKeys = Object.keys(this.store); + if (storeKeys.length >= maxSize) { + this.store.remove(storeKeys[0]); + this.store.add('messages', message); + } + } } module.exports = TextChannel; diff --git a/src/util/Constants.js b/src/util/Constants.js index 74666d589..abbf2c6a2 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -11,6 +11,7 @@ const DefaultOptions = exports.DefaultOptions = { }, }, protocol_version: 4, + max_message_cache: 20, }; const Package = exports.Package = require('../../package.json'); @@ -98,6 +99,7 @@ const Events = exports.Events = { TYPING_STOP: 'typingStop', WARN: 'warn', GUILD_MEMBERS_CHUNK: 'guildMembersChunk', + MESSAGE_CREATE: 'message', }; const WSEvents = exports.WSEvents = { diff --git a/test/random.js b/test/random.js index 22a216aa4..f8df05a74 100644 --- a/test/random.js +++ b/test/random.js @@ -66,3 +66,7 @@ client.on('typingStop.', (channel, user, data) => { if (user.username === 'hydrabolt') console.log(user.username, 'stopped typing in', channel.name, 'after', data.elapsedTime + 'ms'); }); + +client.on('message', message => { + console.log(message.author.username, 'said', message.content, 'in', message.channel.name); +});