Skip to content

Commit

Permalink
feat: group & friend message recall
Browse files Browse the repository at this point in the history
  • Loading branch information
pk5ls20 committed Feb 11, 2025
1 parent 4d42e06 commit be09008
Show file tree
Hide file tree
Showing 9 changed files with 226 additions and 16 deletions.
2 changes: 1 addition & 1 deletion README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
| Linux | 🟢 | EasyLogin | 🟡 | File | 🟡[^1] | Leave Group | 🔴 | BotOffline | 🟢 |
| | | ~~UnusualDevice<br/>Password~~ | 🔴 | Forward | 🟢 | Set Special Title | 🔴 | Message | 🟢 |
| | | ~~UnusualDevice<br/>Easy~~ | 🔴 | ~~GreyTip~~ | 🔴 | Kick Member | 🔴 | Poke | 🟢 |
| | | ~~NewDeviceVerify~~ | 🔴 | GroupReaction | 🟡[^1] | Mute Member | 🔴 | MessageRecall | 🔴 |
| | | ~~NewDeviceVerify~~ | 🔴 | GroupReaction | 🟡[^1] | Mute Member | 🔴 | MessageRecall | 🟢 |
| | | | | Image | 🟢 | Set Admin | 🔴 | GroupMemberDecrease | 🔴 |
| | | | | Json | 🟢 | Friend Request | 🔴 | GroupMemberIncrease | 🔴 |
| | | | | KeyBoard | 🔴 | Group Request | 🔴 | GroupPromoteAdmin | 🔴 |
Expand Down
59 changes: 57 additions & 2 deletions mania/src/core/business/messaging_logic.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use crate::core::business::LogicRegistry;
use crate::core::business::{BusinessHandle, LogicFlow};
use crate::core::event::message::push_msg::PushMessageEvent;
use crate::core::event::notify::friend_sys_recall::FriendSysRecallEvent;
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::event::friend::{FriendEvent, friend_message};
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::system::{SystemEvent, temp_message};
use crate::message::chain::{MessageChain, MessageType};
Expand All @@ -20,7 +23,9 @@ use std::sync::Arc;
PushMessageEvent,
GroupSysRequestJoinEvent,
GroupSysPokeEvent,
GroupSysReactionEvent
GroupSysReactionEvent,
GroupSysRecallEvent,
FriendSysRecallEvent
)]
async fn messaging_logic(
event: &mut dyn ServerEvent,
Expand Down Expand Up @@ -170,6 +175,56 @@ async fn messaging_logic_incoming(
}
return event;
}
if let Some(recall) = event.as_any_mut().downcast_mut::<GroupSysRecallEvent>() {
if let Err(e) = handle
.event_dispatcher
.group
.send(Some(GroupEvent::GroupRecall(GroupRecallEvent {
group_uin: recall.group_uin,
author_uin: handle
.uid2uin(&recall.author_uid, Some(recall.group_uin))
.await
.unwrap_or_default(),
operator_uin: if let Some(uid) = recall.operator_uid.as_ref() {
handle
.uid2uin(uid, Some(recall.group_uin))
.await
.unwrap_or_default()
} else {
0
},
sequence: recall.sequence,
time: recall.time,
random: recall.random,
tip: recall.tip.to_owned(),
})))
{
tracing::error!("Failed to send group recall event: {:?}", e);
}
return event;
}
if let Some(recall) = event.as_any_mut().downcast_mut::<FriendSysRecallEvent>() {
if let Err(e) =
handle
.event_dispatcher
.friend
.send(Some(FriendEvent::FriendRecallEvent(
friend_recall::FriendRecallEvent {
friend_uin: handle
.uid2uin(&recall.from_uid, None)
.await
.unwrap_or_default(),
client_sequence: recall.client_sequence,
time: recall.time,
random: recall.random,
tip: recall.tip.to_owned(),
},
)))
{
tracing::error!("Failed to send friend recall event: {:?}", e);
}
return event;
}
}
event
}
Expand Down
135 changes: 122 additions & 13 deletions mania/src/core/event/message/push_msg.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::core::event::notify::friend_sys_recall::FriendSysRecallEvent;
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::{GroupJoin, NotifyMessageBody, PushMsg};
use crate::core::protos::message::{FriendRecall, GroupJoin, NotifyMessageBody, PushMsg};
use crate::message::chain::MessageChain;
use crate::message::packer::MessagePacker;

Expand Down Expand Up @@ -131,6 +133,9 @@ impl ClientEvent for PushMessageEvent {
PkgType::Event0x2DC => {
extra = process_event_0x2dc(&packet, &mut extra)?.take();
}
PkgType::Event0x210 => {
extra = process_event_0x210(&packet, &mut extra)?.take();
}
// TODO: handle other message types
_ => {
tracing::warn!("receive unknown message type: {:?}", packet_type);
Expand All @@ -140,6 +145,19 @@ impl ClientEvent for PushMessageEvent {
}
}

fn extract_fucking_head<T>(msg_content: &Vec<u8>) -> Result<(u32, T), EventError>
where
T: prost::Message + Default,
{
let mut packet_reader = PacketReader::new(Bytes::from(msg_content.to_owned()));
let group_uin = packet_reader.u32();
packet_reader.u8();
let proto =
packet_reader.read_with_length::<_, { PREFIX_U16 | PREFIX_LENGTH_ONLY }>(|p| p.bytes());
let msg_body = T::decode(proto)?;
Ok((group_uin, msg_body))
}

#[allow(clippy::single_match)] // FIXME:
fn process_event_0x2dc<'a>(
packet: &'a PushMsg,
Expand Down Expand Up @@ -183,12 +201,7 @@ fn process_event_0x2dc<'a>(
Some(content) => content,
None => return Ok(extra),
};
let mut packet_reader = PacketReader::new(Bytes::from(msg_content.to_owned()));
let group_uin = packet_reader.u32();
packet_reader.u8();
let proto = packet_reader
.read_with_length::<_, { PREFIX_U16 | PREFIX_LENGTH_ONLY }>(|p| p.bytes());
let msg_body = NotifyMessageBody::decode(proto)?;
let (group_uin, msg_body) = extract_fucking_head::<NotifyMessageBody>(msg_content)?;
match Event0x2DCSubType16Field13::try_from(msg_body.field13.unwrap_or_default()) {
Ok(ev) => match ev {
Event0x2DCSubType16Field13::GroupReactionNotice => {
Expand Down Expand Up @@ -221,6 +234,37 @@ fn process_event_0x2dc<'a>(
}
}
}
Event0x2DCSubType::GroupRecallNotice => {
let msg_content = match packet
.message
.as_ref()
.and_then(|m| m.body.as_ref())
.and_then(|b| b.msg_content.as_ref())
{
Some(content) => content,
None => return Ok(extra),
};
let (_, recall_notify) = extract_fucking_head::<NotifyMessageBody>(msg_content)?;
let recall = recall_notify.recall.ok_or(EventError::OtherError(
"Missing recall meta in 0x2dc sub type 17".into(),
))?;
let tip_info = recall.tip_info.unwrap_or_default();
let meta = recall
.recall_messages
.first()
.ok_or(EventError::OtherError(
"Missing recall message in 0x2dc sub type 17".into(),
))?;
extra.as_mut().unwrap().push(Box::new(GroupSysRecallEvent {
group_uin: recall_notify.group_uin,
author_uid: meta.author_uid.to_owned(),
operator_uid: recall.operator_uid,
sequence: meta.sequence as u32,
time: meta.time,
random: meta.random,
tip: tip_info.tip,
}));
}
Event0x2DCSubType::GroupGreyTipNotice => {
let msg_content = match packet
.message
Expand All @@ -231,12 +275,7 @@ fn process_event_0x2dc<'a>(
Some(content) => content,
None => return Ok(extra),
};
let mut packet_reader = PacketReader::new(Bytes::from(msg_content.to_owned()));
let group_uin = packet_reader.u32();
packet_reader.u8();
let proto = packet_reader
.read_with_length::<_, { PREFIX_U16 | PREFIX_LENGTH_ONLY }>(|p| p.bytes());
let grey_tip = NotifyMessageBody::decode(proto)?;
let (group_uin, grey_tip) = extract_fucking_head::<NotifyMessageBody>(msg_content)?;
let gray_tip_info = match grey_tip.gray_tip_info.as_ref() {
Some(info) if info.busi_type == 12 => info,
_ => return Ok(extra),
Expand Down Expand Up @@ -282,3 +321,73 @@ fn process_event_0x2dc<'a>(
}
Ok(extra)
}

#[allow(clippy::single_match)] // FIXME:
fn process_event_0x210<'a>(
packet: &'a PushMsg,
extra: &'a mut Option<Vec<Box<dyn ServerEvent>>>,
) -> Result<&'a mut Option<Vec<Box<dyn ServerEvent>>>, EventError> {
let sub_type = Event0x210SubType::try_from(
packet
.message
.as_ref()
.ok_or(EventError::OtherError(
"Cannot get message in PushMsg".to_string(),
))?
.content_head
.as_ref()
.ok_or(EventError::OtherError(
"Cannot get content_head in PushMsg".to_string(),
))?
.sub_type
.ok_or(EventError::OtherError(
"Cannot get sub_type in PushMsgContentHead".to_string(),
))?,
);
let sub_type = match sub_type {
Ok(sub_type) => sub_type,
Err(_) => {
tracing::warn!(
"receive unknown olpush message 0x210 sub type: {:?}",
sub_type
);
return Ok(extra);
}
};
match sub_type {
Event0x210SubType::FriendRecallNotice => {
let msg_content = match packet
.message
.as_ref()
.and_then(|m| m.body.as_ref())
.and_then(|b| b.msg_content.as_ref())
{
Some(content) => content,
None => return Ok(extra),
};
let response_head = match packet
.message
.as_ref()
.and_then(|m| m.response_head.as_ref())
{
Some(content) => content,
None => return Ok(extra),
};
let friend_request = FriendRecall::decode(Bytes::from(msg_content.to_owned()))?;
let info = friend_request.info.ok_or(EventError::OtherError(
"Missing friend request info in 0x210 sub type 138".into(),
))?;
extra.as_mut().unwrap().push(Box::new(FriendSysRecallEvent {
from_uid: response_head.from_uid.to_owned().unwrap_or_default(),
client_sequence: info.sequence,
time: info.time,
random: info.random,
tip: info.tip_info.unwrap_or_default().tip.unwrap_or_default(),
}));
}
_ => {
tracing::warn!("receive unknown message 0x210 sub type: {:?}", sub_type);
}
}
Ok(extra)
}
10 changes: 10 additions & 0 deletions mania/src/core/event/notify/friend_sys_recall.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use crate::core::event::prelude::*;

#[derive(Debug, DummyEvent, Default)]
pub struct FriendSysRecallEvent {
pub from_uid: String,
pub client_sequence: u32,
pub time: u32,
pub random: u32,
pub tip: String,
}
12 changes: 12 additions & 0 deletions mania/src/core/event/notify/group_sys_recall.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::core::event::prelude::*;

#[derive(Debug, DummyEvent, Default)]
pub struct GroupSysRecallEvent {
pub group_uin: u32,
pub author_uid: String,
pub operator_uid: Option<String>,
pub sequence: u32,
pub time: u32,
pub random: u32,
pub tip: String,
}
2 changes: 2 additions & 0 deletions mania/src/core/event/notify/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod friend_sys_recall;
pub mod group_sys_poke;
pub mod group_sys_reaction;
pub mod group_sys_recall;
pub mod group_sys_request_join;
10 changes: 10 additions & 0 deletions mania/src/core/protos/message/notify.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ message FriendRecallInfo {
uint32 PkgNum = 7;
uint32 PkgIndex = 8;
uint32 DivSeq = 9;
FriendRecallTipInfo TipInfo = 13;
}

message FriendRecallTipInfo {
optional string Tip = 2;
}

message NewFriend {
Expand Down Expand Up @@ -157,6 +162,11 @@ message GroupRecall {
bytes UserDef = 5;
int32 GroupType = 6;
int32 OpType = 7;
GroupRecallTipInfo TipInfo = 9;
}

message GroupRecallTipInfo {
string Tip = 2;
}

message RecallMessage {
Expand Down
2 changes: 2 additions & 0 deletions mania/src/event/friend.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
pub mod friend_message;
pub mod friend_poke;
pub mod friend_recall;

#[derive(Debug)]
#[allow(clippy::large_enum_variant)] // FIXME: do we need spilt or refactoring?
pub enum FriendEvent {
FriendPokeEvent(friend_poke::FriendPokeEvent), // FIXME: clippy warn: at least 80 bytes
FriendMessageEvent(friend_message::FriendMessageEvent), // FIXME: clippy warn: at least 320 bytes
FriendRecallEvent(friend_recall::FriendRecallEvent),
}
10 changes: 10 additions & 0 deletions mania/src/event/friend/friend_recall.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
pub use mania_macros::ManiaEvent;

#[derive(ManiaEvent)]
pub struct FriendRecallEvent {
pub friend_uin: u32,
pub client_sequence: u32,
pub time: u32,
pub random: u32,
pub tip: String,
}

0 comments on commit be09008

Please sign in to comment.