From 36f4f68b0cad8060218f52284f064912d1d0e551 Mon Sep 17 00:00:00 2001 From: pk5ls20 Date: Wed, 12 Feb 2025 07:50:35 +0800 Subject: [PATCH] feat: parse group increase & decrease event & caching_logic --- README.MD | 46 +++++------ mania/src/core/business/caching_logic.rs | 57 ++++++++++++++ mania/src/core/business/messaging_logic.rs | 67 +++++++++++++++- mania/src/core/entity.rs | 1 + mania/src/core/entity/group_sys_enum.rs | 21 +++++ mania/src/core/event/message/push_msg.rs | 78 ++++++++++++++++++- .../core/event/notify/group_sys_decrease.rs | 10 +++ .../core/event/notify/group_sys_increase.rs | 10 +++ mania/src/core/event/notify/mod.rs | 2 + mania/src/core/operation/cache_op.rs | 15 +++- .../src/event/group/group_member_decrease.rs | 11 +-- .../src/event/group/group_member_increase.rs | 9 +-- 12 files changed, 284 insertions(+), 43 deletions(-) create mode 100644 mania/src/core/entity/group_sys_enum.rs create mode 100644 mania/src/core/event/notify/group_sys_decrease.rs create mode 100644 mania/src/core/event/notify/group_sys_increase.rs diff --git a/README.MD b/README.MD index 850495b..102061b 100644 --- a/README.MD +++ b/README.MD @@ -20,29 +20,29 @@ ## Features List -| Protocol | Support | Login | Support | Messages | Support | Operations | Support | Events | Support | -|----------|:-------:|--------------------------------|:-------:|:--------------|:-------:|:------------------|:-------:|:--------------------|:-------:| -| Windows | 🔴 | QrCode | 🟢 | BounceFace | 🔴 | Poke | 🔴 | ~~Captcha~~ | 🔴 | -| macOS | 🔴 | ~~Password~~ | 🔴 | Face | 🟡 [^1] | Recall | 🔴 | BotOnline | 🟢 | -| Linux | 🟢 | EasyLogin | 🟡 | File | 🟡[^1] | Leave Group | 🔴 | BotOffline | 🟢 | -| | | ~~UnusualDevice
Password~~ | 🔴 | Forward | 🟢 | Set Special Title | 🔴 | Message | 🟢 | -| | | ~~UnusualDevice
Easy~~ | 🔴 | ~~GreyTip~~ | 🔴 | Kick Member | 🔴 | Poke | 🟢 | -| | | ~~NewDeviceVerify~~ | 🔴 | GroupReaction | 🟡[^1] | Mute Member | 🔴 | MessageRecall | 🟢 | -| | | | | Image | 🟢 | Set Admin | 🔴 | GroupMemberDecrease | 🔴 | -| | | | | Json | 🟢 | Friend Request | 🔴 | GroupMemberIncrease | 🔴 | -| | | | | KeyBoard | 🔴 | Group Request | 🔴 | GroupPromoteAdmin | 🔴 | -| | | | | LightApp | 🟢 | ~~Voice Call~~ | 🔴 | GroupInvite | 🔴 | -| | | | | LongMsg | 🟡[^1] | Client Key | 🔴 | GroupRequestJoin | 🟢 | -| | | | | Markdown | 🔴 | Cookies | 🔴 | FriendRequest | 🔴 | -| | | | | MarketFace | 🟡[^1] | Send Message | 🔴 | ~~FriendTyping~~ | 🔴 | -| | | | | Mention | 🟢 | | | ~~FriendVoiceCall~~ | 🔴 | -| | | | | MultiMsg | 🟡[^1] | | | | | -| | | | | Poke | 🔴 | | | | | -| | | | | Record | 🟢 | | | | | -| | | | | SpecialPoke | 🔴 | | | | | -| | | | | Text | 🟢 | | | | | -| | | | | Video | 🟢 | | | | | -| | | | | Xml | 🟢 | | | | | +| Protocol | Support | Login | Support | Messages | Support | Operations | Support | Events | Support | +|----------|:-------:|--------------------------------|:-------:|:--------------|:-------:|:------------------|:-------:|:----------------------|:-------:| +| Windows | 🔴 | QrCode | 🟢 | BounceFace | 🔴 | Poke | 🔴 | ~~Captcha~~ | 🔴 | +| macOS | 🔴 | ~~Password~~ | 🔴 | Face | 🟡 [^1] | Recall | 🔴 | BotOnline | 🟢 | +| Linux | 🟢 | EasyLogin | 🟡 | File | 🟡[^1] | Leave Group | 🔴 | BotOffline | 🟢 | +| | | ~~UnusualDevice
Password~~ | 🔴 | Forward | 🟢 | Set Special Title | 🔴 | Message | 🟢 | +| | | ~~UnusualDevice
Easy~~ | 🔴 | ~~GreyTip~~ | 🔴 | Kick Member | 🔴 | Poke | 🟢 | +| | | ~~NewDeviceVerify~~ | 🔴 | GroupReaction | 🟡[^1] | Mute Member | 🔴 | MessageRecall | 🟢 | +| | | | | Image | 🟢 | Set Admin | 🔴 | GroupMemberDecrease | 🟢 | +| | | | | Json | 🟢 | Friend Request | 🔴 | GroupMemberIncrease | 🟢 | +| | | | | KeyBoard | 🔴 | Group Request | 🔴 | ~~GroupPromoteAdmin~~ | 🔴 | +| | | | | LightApp | 🟢 | ~~Voice Call~~ | 🔴 | GroupInvite | 🔴 | +| | | | | LongMsg | 🟡[^1] | Client Key | 🔴 | GroupRequestJoin | 🟢 | +| | | | | Markdown | 🔴 | Cookies | 🔴 | FriendRequest | 🔴 | +| | | | | MarketFace | 🟡[^1] | Send Message | 🔴 | ~~FriendTyping~~ | 🔴 | +| | | | | Mention | 🟢 | | | ~~FriendVoiceCall~~ | 🔴 | +| | | | | MultiMsg | 🟡[^1] | | | | | +| | | | | Poke | 🔴 | | | | | +| | | | | Record | 🟢 | | | | | +| | | | | SpecialPoke | 🔴 | | | | | +| | | | | Text | 🟢 | | | | | +| | | | | Video | 🟢 | | | | | +| | | | | Xml | 🟢 | | | | | [^1]: Only implemented event parsing diff --git a/mania/src/core/business/caching_logic.rs b/mania/src/core/business/caching_logic.rs index 8b13789..cf46b98 100644 --- a/mania/src/core/business/caching_logic.rs +++ b/mania/src/core/business/caching_logic.rs @@ -1 +1,58 @@ +use crate::core::business::LogicRegistry; +use crate::core::business::{BusinessHandle, LogicFlow}; +use crate::core::event::notify::group_sys_decrease::GroupSysDecreaseEvent; +use crate::core::event::notify::group_sys_increase::GroupSysIncreaseEvent; +use crate::core::event::prelude::*; +use mania_macros::handle_event; +use std::sync::Arc; +#[handle_event(GroupSysIncreaseEvent, GroupSysDecreaseEvent)] +async fn caching_logic( + event: &mut dyn ServerEvent, + handle: Arc, + flow: LogicFlow, +) -> &dyn ServerEvent { + match flow { + LogicFlow::InComing => caching_logic_incoming(event, handle).await, + LogicFlow::OutGoing => event, + } +} + +async fn caching_logic_incoming( + event: &mut dyn ServerEvent, + handle: Arc, +) -> &dyn ServerEvent { + match event { + _ if let Some(increase) = event.as_any_mut().downcast_mut::() => { + tracing::info!( + "caching_logic_incoming GroupSysIncreaseEvent: {:?}", + increase + ); + if let Err(e) = handle.refresh_group_members_cache(increase.group_uin).await { + tracing::error!("refresh_group_members_cache failed: {:?}", e); + } + } + _ if let Some(decrease) = event.as_any_mut().downcast_mut::() => { + tracing::info!( + "caching_logic_incoming GroupSysDecreaseEvent: {:?}", + decrease + ); + let self_uid = handle + .context + .key_store + .uid + .load() + .as_ref() + .expect("Missing self_uid") + .as_ref() + .clone(); + if decrease.member_uid != self_uid + && let Err(e) = handle.refresh_group_members_cache(decrease.group_uin).await + { + tracing::error!("refresh_group_members_cache failed: {:?}", e); + } + } + _ => {} + } + event +} diff --git a/mania/src/core/business/messaging_logic.rs b/mania/src/core/business/messaging_logic.rs index 50cc660..9b49d21 100644 --- a/mania/src/core/business/messaging_logic.rs +++ b/mania/src/core/business/messaging_logic.rs @@ -3,6 +3,8 @@ use crate::core::business::{BusinessHandle, LogicFlow}; use crate::core::event::message::push_msg::PushMessageEvent; use crate::core::event::notify::friend_sys_poke::FriendSysPokeEvent; use crate::core::event::notify::friend_sys_recall::FriendSysRecallEvent; +use crate::core::event::notify::group_sys_decrease::GroupSysDecreaseEvent; +use crate::core::event::notify::group_sys_increase::GroupSysIncreaseEvent; use crate::core::event::notify::group_sys_poke::GroupSysPokeEvent; use crate::core::event::notify::group_sys_reaction::GroupSysReactionEvent; use crate::core::event::notify::group_sys_recall::GroupSysRecallEvent; @@ -13,7 +15,9 @@ use crate::event::friend::{FriendEvent, friend_message, friend_recall}; use crate::event::group::group_poke::GroupPokeEvent; use crate::event::group::group_reaction::GroupReactionEvent; use crate::event::group::group_recall::GroupRecallEvent; -use crate::event::group::{GroupEvent, group_join_request, group_message}; +use crate::event::group::{ + GroupEvent, group_join_request, group_member_decrease, group_member_increase, group_message, +}; use crate::event::system::{SystemEvent, temp_message}; use crate::message::chain::{MessageChain, MessageType}; use crate::message::entity::Entity; @@ -27,6 +31,8 @@ use std::sync::Arc; GroupSysPokeEvent, GroupSysReactionEvent, GroupSysRecallEvent, + GroupSysIncreaseEvent, + GroupSysDecreaseEvent, FriendSysRecallEvent, FriendSysPokeEvent )] @@ -42,6 +48,7 @@ async fn messaging_logic( } } +// FIXME: avoid take things from event async fn messaging_logic_incoming( event: &mut dyn ServerEvent, handle: Arc, @@ -158,6 +165,64 @@ async fn messaging_logic_incoming( } return event; } + if let Some(join) = event.as_any_mut().downcast_mut::() { + let member_uin = handle + .resolve_stranger_uid2uin(&join.member_uid) + .await + .unwrap_or_default(); + let invitor_uin = handle + .uid2uin( + join.invitor_uid.as_deref().unwrap_or(""), + Some(join.group_uin), + ) + .await + .ok(); + if let Err(e) = + handle + .event_dispatcher + .group + .send(Some(GroupEvent::GroupMemberIncrease( + group_member_increase::GroupMemberIncreaseEvent { + group_uin: join.group_uin, + member_uin, + invitor_uin, + event_type: std::mem::take(&mut join.event_type), // FIXME: maybe bug? + }, + ))) + { + tracing::error!("Failed to send group increase event: {:?}", e); + } + return event; + } + if let Some(leave) = event.as_any_mut().downcast_mut::() { + let member_uin = handle + .resolve_stranger_uid2uin(&leave.member_uid) + .await + .unwrap_or_default(); + let operator_uin = handle + .uid2uin( + leave.operator_uid.as_deref().unwrap_or(""), + Some(leave.group_uin), + ) + .await + .ok(); + if let Err(e) = + handle + .event_dispatcher + .group + .send(Some(GroupEvent::GroupMemberDecrease( + group_member_decrease::GroupMemberDecreaseEvent { + group_uin: leave.group_uin, + member_uin, + operator_uin, + event_type: std::mem::take(&mut leave.event_type), // FIXME: maybe bug? + }, + ))) + { + tracing::error!("Failed to send group decrease event: {:?}", e); + } + return event; + } if let Some(poke) = event.as_any_mut().downcast_mut::() { if let Err(e) = handle .event_dispatcher diff --git a/mania/src/core/entity.rs b/mania/src/core/entity.rs index 02193ef..e2002af 100644 --- a/mania/src/core/entity.rs +++ b/mania/src/core/entity.rs @@ -1 +1,2 @@ pub mod fetch_group_requests; +pub mod group_sys_enum; diff --git a/mania/src/core/entity/group_sys_enum.rs b/mania/src/core/entity/group_sys_enum.rs new file mode 100644 index 0000000..6f0edf9 --- /dev/null +++ b/mania/src/core/entity/group_sys_enum.rs @@ -0,0 +1,21 @@ +use crate::core::event::prelude::TryFromPrimitive; + +#[derive(Debug, Default, Eq, PartialEq, TryFromPrimitive)] +#[repr(u32)] +pub enum GroupMemberIncreaseEventType { + #[default] + Unknown = 0, + Approve = 130, + Invite = 131, +} + +#[derive(Debug, Default, Eq, PartialEq, TryFromPrimitive)] +#[repr(u32)] +pub enum GroupMemberDecreaseEventType { + #[default] + Unknown = 0, + KickMe = 3, + Disband = 129, + Leave = 130, + Kick = 131, +} diff --git a/mania/src/core/event/message/push_msg.rs b/mania/src/core/event/message/push_msg.rs index 4b076cf..afd09da 100644 --- a/mania/src/core/event/message/push_msg.rs +++ b/mania/src/core/event/message/push_msg.rs @@ -1,12 +1,18 @@ +use crate::core::entity::group_sys_enum::{ + GroupMemberDecreaseEventType, GroupMemberIncreaseEventType, +}; use crate::core::event::notify::friend_sys_poke::FriendSysPokeEvent; use crate::core::event::notify::friend_sys_recall::FriendSysRecallEvent; +use crate::core::event::notify::group_sys_decrease::GroupSysDecreaseEvent; +use crate::core::event::notify::group_sys_increase::GroupSysIncreaseEvent; use crate::core::event::notify::group_sys_poke::GroupSysPokeEvent; use crate::core::event::notify::group_sys_reaction::GroupSysReactionEvent; use crate::core::event::notify::group_sys_recall::GroupSysRecallEvent; use crate::core::event::notify::group_sys_request_join::GroupSysRequestJoinEvent; use crate::core::event::prelude::*; use crate::core::protos::message::{ - FriendRecall, GeneralGrayTipInfo, GroupJoin, NotifyMessageBody, PushMsg, + FriendRecall, GeneralGrayTipInfo, GroupChange, GroupJoin, NotifyMessageBody, OperatorInfo, + PushMsg, }; use crate::message::chain::MessageChain; use crate::message::packer::MessagePacker; @@ -133,6 +139,76 @@ impl ClientEvent for PushMessageEvent { })); } } + PkgType::GroupMemberIncreaseNotice => { + if let Some(msg_content) = packet + .message + .and_then(|content| content.body) + .and_then(|body| body.msg_content) + { + let increase = GroupChange::decode(Bytes::from(msg_content))?; + let invitor_uid = increase + .operator + .and_then(|operator| String::from_utf8(operator).ok()); + extra + .as_mut() + .unwrap() + .push(Box::new(GroupSysIncreaseEvent { + group_uin: increase.group_uin, + member_uid: increase.member_uid, + invitor_uid, + event_type: GroupMemberIncreaseEventType::try_from( + increase.decrease_type, + ) + .unwrap_or_default(), + })); + } + } + PkgType::GroupMemberDecreaseNotice => { + if let Some(msg_content) = packet + .message + .and_then(|content| content.body) + .and_then(|body| body.msg_content) + { + let decrease = GroupChange::decode(Bytes::from(msg_content))?; + match decrease.decrease_type { + 3 => { + // bot itself is kicked + let op = OperatorInfo::decode(Bytes::from( + decrease.operator.unwrap_or_default(), + ))?; + extra + .as_mut() + .unwrap() + .push(Box::new(GroupSysDecreaseEvent { + group_uin: decrease.group_uin, + member_uid: decrease.member_uid, + operator_uid: op.operator_field1.map(|o| o.operator_uid), + event_type: GroupMemberDecreaseEventType::try_from( + decrease.decrease_type, + ) + .unwrap_or_default(), + })); + } + _ => { + let op_uid = decrease + .operator + .and_then(|operator| String::from_utf8(operator).ok()); + extra + .as_mut() + .unwrap() + .push(Box::new(GroupSysDecreaseEvent { + group_uin: decrease.group_uin, + member_uid: decrease.member_uid, + operator_uid: op_uid, + event_type: GroupMemberDecreaseEventType::try_from( + decrease.decrease_type, + ) + .unwrap_or_default(), + })); + } + } + } + } PkgType::Event0x2DC => { extra = process_event_0x2dc(&packet, &mut extra)?.take(); } diff --git a/mania/src/core/event/notify/group_sys_decrease.rs b/mania/src/core/event/notify/group_sys_decrease.rs new file mode 100644 index 0000000..234193c --- /dev/null +++ b/mania/src/core/event/notify/group_sys_decrease.rs @@ -0,0 +1,10 @@ +use crate::core::entity::group_sys_enum::GroupMemberDecreaseEventType; +use crate::core::event::prelude::*; + +#[derive(Debug, DummyEvent, Default)] +pub struct GroupSysDecreaseEvent { + pub group_uin: u32, + pub member_uid: String, + pub operator_uid: Option, + pub event_type: GroupMemberDecreaseEventType, +} diff --git a/mania/src/core/event/notify/group_sys_increase.rs b/mania/src/core/event/notify/group_sys_increase.rs new file mode 100644 index 0000000..45d98ca --- /dev/null +++ b/mania/src/core/event/notify/group_sys_increase.rs @@ -0,0 +1,10 @@ +use crate::core::entity::group_sys_enum::GroupMemberIncreaseEventType; +use crate::core::event::prelude::*; + +#[derive(Debug, DummyEvent, Default)] +pub struct GroupSysIncreaseEvent { + pub group_uin: u32, + pub member_uid: String, + pub invitor_uid: Option, + pub event_type: GroupMemberIncreaseEventType, +} diff --git a/mania/src/core/event/notify/mod.rs b/mania/src/core/event/notify/mod.rs index 91fd37f..d427037 100644 --- a/mania/src/core/event/notify/mod.rs +++ b/mania/src/core/event/notify/mod.rs @@ -1,5 +1,7 @@ pub mod friend_sys_poke; pub mod friend_sys_recall; +pub mod group_sys_decrease; +pub mod group_sys_increase; pub mod group_sys_poke; pub mod group_sys_reaction; pub mod group_sys_recall; diff --git a/mania/src/core/operation/cache_op.rs b/mania/src/core/operation/cache_op.rs index edd5267..ae52455 100644 --- a/mania/src/core/operation/cache_op.rs +++ b/mania/src/core/operation/cache_op.rs @@ -164,7 +164,11 @@ impl BusinessHandle { Ok(None::) } - async fn refresh_friends_cache(self: &Arc) -> ManiaResult<()> { + pub(crate) async fn refresh_friends_cache(self: &Arc) -> ManiaResult<()> { + if self.cache.cache_mode == CacheMode::None { + tracing::warn!("Cache mode is None, no need to refresh friends cache"); + return Ok(()); + } let mut friends: HashMap = HashMap::new(); let mut friend_groups: HashMap = HashMap::new(); self.iter_fetch_friends(|event: &mut FetchFriendsEvent| { @@ -242,7 +246,14 @@ impl BusinessHandle { Ok(None::) } - async fn refresh_group_members_cache(self: &Arc, group_uin: u32) -> ManiaResult<()> { + pub(crate) async fn refresh_group_members_cache( + self: &Arc, + group_uin: u32, + ) -> ManiaResult<()> { + if self.cache.cache_mode == CacheMode::None { + tracing::warn!("Cache mode is None, no need to refresh group members cache"); + return Ok(()); + } let mut group_members: Vec = Vec::new(); self.iter_fetch_group(group_uin, |event| { group_members.extend(event.group_members.clone()); diff --git a/mania/src/event/group/group_member_decrease.rs b/mania/src/event/group/group_member_decrease.rs index d559c5a..0be78a6 100644 --- a/mania/src/event/group/group_member_decrease.rs +++ b/mania/src/event/group/group_member_decrease.rs @@ -1,3 +1,4 @@ +use crate::core::entity::group_sys_enum::GroupMemberDecreaseEventType; pub use mania_macros::ManiaEvent; #[derive(ManiaEvent)] @@ -5,13 +6,5 @@ pub struct GroupMemberDecreaseEvent { pub group_uin: u32, pub member_uin: u32, pub operator_uin: Option, - pub event_type: EventType, -} - -#[derive(Debug)] -pub enum EventType { - KickMe = 3, - Disband = 129, - Leave = 130, - Kick = 131, + pub event_type: GroupMemberDecreaseEventType, } diff --git a/mania/src/event/group/group_member_increase.rs b/mania/src/event/group/group_member_increase.rs index d8abc2a..653fd4e 100644 --- a/mania/src/event/group/group_member_increase.rs +++ b/mania/src/event/group/group_member_increase.rs @@ -1,3 +1,4 @@ +use crate::core::entity::group_sys_enum::GroupMemberIncreaseEventType; pub use mania_macros::ManiaEvent; #[derive(ManiaEvent)] @@ -5,11 +6,5 @@ pub struct GroupMemberIncreaseEvent { pub group_uin: u32, pub member_uin: u32, pub invitor_uin: Option, - pub event_type: EventType, -} - -#[derive(Debug)] -pub enum EventType { - Approve = 130, - Invite = 131, + pub event_type: GroupMemberIncreaseEventType, }