From 9a1bdbb3a02b0abd0fee4437f8e769bb4159b8d4 Mon Sep 17 00:00:00 2001 From: jamesbt365 Date: Sun, 28 Apr 2024 21:21:28 +0100 Subject: [PATCH] Provide old presence data from the cache on presence update (#2852) --- examples/e10_gateway_intents/src/main.rs | 7 ++++++- src/cache/event.rs | 10 +++++++--- src/client/dispatch.rs | 3 ++- src/client/event_handler.rs | 5 +++-- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/examples/e10_gateway_intents/src/main.rs b/examples/e10_gateway_intents/src/main.rs index 50b22a5e030..ea1ffeca732 100644 --- a/examples/e10_gateway_intents/src/main.rs +++ b/examples/e10_gateway_intents/src/main.rs @@ -16,7 +16,12 @@ impl EventHandler for Handler { // As the intents set in this example, this event shall never be dispatched. // Try it by changing your status. - async fn presence_update(&self, _ctx: Context, _new_data: Presence) { + async fn presence_update( + &self, + _ctx: Context, + _old_data: Option, + _new_data: Presence, + ) { println!("Presence Update"); } diff --git a/src/cache/event.rs b/src/cache/event.rs index a6f9e8f266e..62675f0a8f1 100644 --- a/src/cache/event.rs +++ b/src/cache/event.rs @@ -32,7 +32,7 @@ use crate::model::event::{ VoiceChannelStatusUpdateEvent, VoiceStateUpdateEvent, }; -use crate::model::gateway::ShardInfo; +use crate::model::gateway::{Presence, ShardInfo}; use crate::model::guild::{Guild, GuildMemberFlags, Member, MemberGeneratedFlags, Role}; use crate::model::id::ShardId; use crate::model::user::{CurrentUser, OnlineStatus}; @@ -394,11 +394,13 @@ impl CacheUpdate for MessageUpdateEvent { } impl CacheUpdate for PresenceUpdateEvent { - type Output = (); + type Output = Presence; - fn update(&mut self, cache: &Cache) -> Option<()> { + fn update(&mut self, cache: &Cache) -> Option { if let Some(guild_id) = self.presence.guild_id { if let Some(mut guild) = cache.guilds.get_mut(&guild_id) { + let old = guild.presences.get(&self.presence.user.id).cloned(); + // If the member went offline, remove them from the presence list. if self.presence.status == OnlineStatus::Offline { guild.presences.remove(&self.presence.user.id); @@ -425,6 +427,8 @@ impl CacheUpdate for PresenceUpdateEvent { }); } } + + return old; } } diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs index d881aa7fc54..88d655c7049 100644 --- a/src/client/dispatch.rs +++ b/src/client/dispatch.rs @@ -319,9 +319,10 @@ fn update_cache_with_event( presences: event.presences.into_vec(), }, Event::PresenceUpdate(mut event) => { - update_cache!(cache, event); + let old_data = if_cache!(event.update(cache)); FullEvent::PresenceUpdate { + old_data, new_data: event.presence, } }, diff --git a/src/client/event_handler.rs b/src/client/event_handler.rs index 64d20cf0385..d43e4c9233b 100644 --- a/src/client/event_handler.rs +++ b/src/client/event_handler.rs @@ -315,11 +315,12 @@ event_handler! { /// Dispatched when a user's presence is updated (e.g off -> on). /// - /// Provides the presence's new data. + /// Provides the presence's new data, as well as the old presence data if the + /// cache feature is enabled and the data is available. /// /// Note: This event will not trigger unless the "guild presences" privileged intent is enabled /// on the bot application page. - PresenceUpdate { new_data: Presence } => async fn presence_update(&self, ctx: Context); + PresenceUpdate { old_data: Option, new_data: Presence } => async fn presence_update(&self, ctx: Context); /// Dispatched upon startup. ///