Presence tracking

This commit is contained in:
hydrabolt
2016-04-17 18:20:57 +01:00
parent 71a4cd6a93
commit abc3f9e2fa
8 changed files with 130 additions and 4 deletions

View File

@@ -71,6 +71,7 @@ class WebSocketManager {
if (unavailableCount === 0) {
this.client.emit(Constants.Events.READY);
this.emittedReady = true;
this.packetManager.handleQueue();
}
}
}

View File

@@ -2,11 +2,18 @@
const Constants = require('../../../util/Constants');
const BeforeReadyWhitelist = [
Constants.WSEvents.READY,
Constants.WSEvents.GUILD_CREATE,
Constants.WSEvents.GUILD_DELETE,
];
class WebSocketPacketManager {
constructor(websocketManager) {
this.ws = websocketManager;
this.handlers = {};
this.queue = [];
this.register(Constants.WSEvents.READY, 'Ready');
this.register(Constants.WSEvents.GUILD_CREATE, 'GuildCreate');
@@ -23,6 +30,7 @@ class WebSocketPacketManager {
this.register(Constants.WSEvents.CHANNEL_CREATE, 'ChannelCreate');
this.register(Constants.WSEvents.CHANNEL_DELETE, 'ChannelDelete');
this.register(Constants.WSEvents.CHANNEL_UPDATE, 'ChannelUpdate');
this.register(Constants.WSEvents.PRESENCE_UPDATE, 'PresenceUpdate');
}
get client() {
@@ -34,7 +42,22 @@ class WebSocketPacketManager {
this.handlers[event] = new Handler(this);
}
handleQueue() {
for (let packetIndex in this.queue) {
this.handle(this.queue[packetIndex]);
this.queue.splice(packetIndex, 1);
}
}
handle(packet) {
if (!this.ws.emittedReady) {
if (BeforeReadyWhitelist.indexOf(packet.t) === -1) {
this.queue.push(packet);
return;
}
}
if (this.handlers[packet.t]) {
return this.handlers[packet.t].handle(packet);
}

View File

@@ -28,6 +28,7 @@ class GuildDeleteHandler extends AbstractHandler {
} else {
// delete guild
client.store.KillGuild(guild);
this.packetManager.ws.checkIfReady();
}
} else {
// it's not there! :(

View File

@@ -0,0 +1,77 @@
'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 PresenceUpdateHandler extends AbstractHandler {
constructor(packetManager) {
super(packetManager);
}
handle(packet) {
let data = packet.d;
let client = this.packetManager.client;
let user = client.store.get('users', data.user.id);
let guild = client.store.get('guilds', data.guild_id);
function makeUser(user) {
return client.store.NewUser(user);
}
// step 1
if (!user) {
if (data.user.username) {
user = makeUser(data.user);
}else {
return;
}
}
if (guild) {
let memberInGuild = guild.store.get('members', user.id);
if (!memberInGuild) {
let member = guild._addMember({
user,
roles: data.roles,
deaf: false,
mute: false,
}, true);
client.emit(Constants.Events.GUILD_MEMBER_AVAILABLE, guild, member);
}
}
data.user.username = data.user.username || user.username;
data.user.id = data.user.id || user.id;
data.user.discriminator = data.user.discriminator || user.discriminator;
data.user.avatar = data.user.avatar || user.avatar;
data.user.status = data.status || user.status;
data.user.game = data.game;
let same = (
data.user.username === user.username &&
data.user.id === user.id &&
data.user.discriminator === user.discriminator &&
data.user.avatar === user.avatar &&
data.user.status === user.status &&
!(
(data.user.game && !user.game) ||
(!data.user.game && user.game) ||
(data.user.game && user.game && data.user.game.name !== user.game.name)
)
);
if (!same) {
let oldUser = CloneObject(user);
user.setup(data.user);
client.emit(Constants.Events.PRESENCE_UPDATE, oldUser, user);
}
}
};
module.exports = PresenceUpdateHandler;

View File

@@ -26,12 +26,18 @@ class Guild {
}
}
_addMember(guildUser) {
guildUser.user = this.client.store.NewUser(guildUser.user);
_addMember(guildUser, noEvent) {
if (!(guildUser.user instanceof User)) {
guildUser.user = this.client.store.NewUser(guildUser.user);
}
guildUser.joined_at = guildUser.joined_at || 0;
let member = this.store.add('members', new GuildMember(this, guildUser));
if (this.client.ws.emittedReady) {
if (this.client.ws.emittedReady && !noEvent) {
this.client.emit(Constants.Events.GUILD_MEMBER_ADD, this, member);
}
return member;
}
_updateMember(member, data) {
@@ -89,7 +95,17 @@ class Guild {
for (let role of data.roles) {
this.store.add('roles', new Role(this, role));
}
};
}
if (data.presences) {
for (let presence of data.presences) {
let user = this.client.store.get('users', presence.user.id);
if (user) {
user.status = presence.status;
user.game = presence.game;
}
}
}
}
}

View File

@@ -14,6 +14,8 @@ class User {
this.discriminator = data.discriminator;
this.avatar = data.avatar;
this.bot = Boolean(data.bot);
this.status = data.status || 'offline';
this.game = data.game;
}
}

View File

@@ -87,9 +87,11 @@ const Events = exports.Events = {
GUILD_ROLE_CREATE: 'guildRoleCreate',
GUILD_ROLE_DELETE: 'guildRoleDelete',
GUILD_ROLE_UPDATE: 'guildRoleUpdate',
GUILD_MEMBER_AVAILABLE: 'guildMemberAvailable',
CHANNEL_CREATE: 'channelCreate',
CHANNEL_DELETE: 'channelDelete',
CHANNEL_UPDATE: 'channelUpdate',
PRESENCE_UPDATE: 'presenceUpdate',
WARN: 'warn',
};

View File

@@ -48,3 +48,7 @@ client.on('guildRoleDelete', (guild, role) => {
client.on('guildRoleUpdate', (guild, old, newRole) => {
console.log('updated role', old.name, 'to', newRole.name, 'in', guild.name);
});
client.on('presenceUpdate', (oldUser, newUser) => {
console.log('presence from', oldUser.username, 'to', newUser.username);
});