Skip to content

Commit e681ad0

Browse files
authored
[Core] Split PushLogic's message processing methods (#74)
1 parent 34b4ee6 commit e681ad0

11 files changed

Lines changed: 409 additions & 305 deletions
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Lagrange.Core.Events.EventArgs;
2+
using Lagrange.Core.Internal.Events.Message;
3+
using Lagrange.Core.Internal.Packets.Notify;
4+
using Lagrange.Core.Utility;
5+
6+
namespace Lagrange.Core.Internal.Logic.MsgPushProccessors;
7+
8+
[MsgPushProcessor(MsgType.Event0x210, 35, true)] // FriendRequestNotice
9+
internal class FriendRequestProcessor : MsgPushProcessorBase
10+
{
11+
internal override ValueTask<bool> Handle(BotContext context, MsgType msgType, int subType,
12+
PushMessageEvent msgEvt, ReadOnlyMemory<byte>? content)
13+
{
14+
var friendRequest = ProtoHelper.Deserialize<FriendRequest>(content!.Value.Span);
15+
context.EventInvoker.PostEvent(new BotFriendRequestEvent(
16+
friendRequest.Info!.SourceUid,
17+
msgEvt.MsgPush.CommonMessage.RoutingHead.FromUin,
18+
friendRequest.Info.Message,
19+
friendRequest.Info.Source ?? string.Empty
20+
));
21+
return ValueTask.FromResult(true);
22+
}
23+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using Lagrange.Core.Common.Entity;
2+
using Lagrange.Core.Events.EventArgs;
3+
using Lagrange.Core.Internal.Events.Message;
4+
using Lagrange.Core.Internal.Events.System;
5+
using Lagrange.Core.Internal.Packets.Notify;
6+
using Lagrange.Core.Utility;
7+
8+
namespace Lagrange.Core.Internal.Logic.MsgPushProccessors;
9+
10+
[MsgPushProcessor(MsgType.Event0x20D, true)]
11+
internal class GroupInviteProcessor : MsgPushProcessorBase
12+
{
13+
// another in `RichTextMsgProcessor` for private send invitation card.
14+
internal override async ValueTask<bool> Handle(BotContext context, MsgType msgType, int subType,
15+
PushMessageEvent msgEvt, ReadOnlyMemory<byte>? content)
16+
{
17+
var @event = ProtoHelper.Deserialize<Event0x20D>(content!.Value.Span);
18+
if (@event.SubType != 87) return false; // GroupInviteNotification
19+
20+
var body = ProtoHelper.Deserialize<GroupInvite>(@event.Body);
21+
22+
var response = await context.EventContext.SendEvent<FetchGroupNotificationsEventResp>(
23+
new FetchGroupNotificationsEventReq(20)
24+
);
25+
var inviteNotifications = response
26+
.GroupNotifications
27+
.OfType<BotGroupInviteNotification>();
28+
var notification = inviteNotifications.FirstOrDefault(notification =>
29+
body.Body.GroupUin == notification.GroupUin &&
30+
body.Body.InviterUid == notification.InviterUid &&
31+
body.Body.TargetUid == notification.TargetUid &&
32+
notification.State == BotGroupNotificationState.Wait
33+
);
34+
if (notification == null)
35+
{
36+
context.LogWarning(nameof(PushLogic),
37+
"Received GroupInviteNotification but no corresponding notification found");
38+
return false;
39+
}
40+
41+
context.EventInvoker.PostEvent(new BotGroupInviteNotificationEvent(notification));
42+
return true;
43+
}
44+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Lagrange.Core.Common.Entity;
2+
using Lagrange.Core.Events.EventArgs;
3+
using Lagrange.Core.Internal.Events.Message;
4+
using Lagrange.Core.Internal.Events.System;
5+
using Lagrange.Core.Internal.Packets.Notify;
6+
using Lagrange.Core.Utility;
7+
8+
namespace Lagrange.Core.Internal.Logic.MsgPushProccessors;
9+
10+
[MsgPushProcessor(MsgType.GroupJoinNotification, true)]
11+
internal class GroupJoinProcessor : MsgPushProcessorBase
12+
{
13+
internal override async ValueTask<bool> Handle(BotContext context, MsgType msgType, int subType, PushMessageEvent msgEvt, ReadOnlyMemory<byte>? content)
14+
{
15+
var join = ProtoHelper.Deserialize<GroupJoin>(content!.Value.Span);
16+
var response = await context.EventContext.SendEvent<FetchGroupNotificationsEventResp>(
17+
new FetchGroupNotificationsEventReq(20)
18+
);
19+
var joinNotifications = response
20+
.GroupNotifications
21+
.OfType<BotGroupJoinNotification>();
22+
var notification = joinNotifications.FirstOrDefault(notification =>
23+
join.GroupUin == notification.GroupUin &&
24+
join.TargetUid == notification.TargetUid &&
25+
notification.State == BotGroupNotificationState.Wait
26+
);
27+
if (notification == null)
28+
{
29+
context.LogWarning(nameof(PushLogic), "Received GroupJoinNotification but no corresponding notification found");
30+
return false;
31+
}
32+
33+
context.EventInvoker.PostEvent(new BotGroupJoinNotificationEvent(notification));
34+
return true;
35+
}
36+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using Lagrange.Core.Events.EventArgs;
2+
using Lagrange.Core.Internal.Events.Message;
3+
using Lagrange.Core.Internal.Packets.Notify;
4+
using Lagrange.Core.Utility;
5+
6+
namespace Lagrange.Core.Internal.Logic.MsgPushProccessors;
7+
8+
[MsgPushProcessor(MsgType.GroupMemberDecreaseNotice, true)]
9+
internal class GroupMemberDecreaseProcessor : MsgPushProcessorBase
10+
{
11+
internal override async ValueTask<bool> Handle(BotContext context, MsgType msgType, int subType, PushMessageEvent msgEvt, ReadOnlyMemory<byte>? content)
12+
{
13+
var decrease = ProtoHelper.Deserialize<GroupChange>(content!.Value.Span);
14+
switch ((DecreaseType)decrease.DecreaseType)
15+
{
16+
case DecreaseType.KickSelf:
17+
{
18+
var op = ProtoHelper.Deserialize<OperatorInfo>(decrease.Operator.AsSpan());
19+
context.EventInvoker.PostEvent(new BotGroupMemberDecreaseEvent(
20+
decrease.GroupUin,
21+
context.CacheContext.ResolveUin(decrease.MemberUid),
22+
op.Operator.Uid != null ? context.CacheContext.ResolveUin(op.Operator.Uid) : null
23+
));
24+
return true;
25+
}
26+
case DecreaseType.Exit:
27+
{
28+
await context.CacheContext.GetMemberList(decrease.GroupUin);
29+
context.EventInvoker.PostEvent(new BotGroupMemberDecreaseEvent(
30+
decrease.GroupUin,
31+
context.CacheContext.ResolveUin(decrease.MemberUid),
32+
null
33+
));
34+
return true;
35+
}
36+
case DecreaseType.Kick:
37+
{
38+
await context.CacheContext.GetMemberList(decrease.GroupUin);
39+
goto case DecreaseType.KickSelf;
40+
}
41+
default:
42+
{
43+
context.LogDebug(nameof(PushLogic), "Unknown decrease type: {0}", null, decrease.DecreaseType);
44+
break;
45+
}
46+
}
47+
48+
return false;
49+
}
50+
51+
private enum DecreaseType
52+
{
53+
KickSelf = 3,
54+
Exit = 130,
55+
Kick = 131
56+
}
57+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.Text;
2+
using Lagrange.Core.Common.Entity;
3+
using Lagrange.Core.Events.EventArgs;
4+
using Lagrange.Core.Internal.Events.Message;
5+
using Lagrange.Core.Internal.Events.System;
6+
using Lagrange.Core.Internal.Packets.Notify;
7+
using Lagrange.Core.Utility;
8+
9+
namespace Lagrange.Core.Internal.Logic.MsgPushProccessors;
10+
11+
[MsgPushProcessor(MsgType.GroupMemberIncreaseNotice, true)]
12+
internal class GroupMemberIncreaseProcessor : MsgPushProcessorBase
13+
{
14+
internal override async ValueTask<bool> Handle(BotContext context, MsgType msgType, int subType, PushMessageEvent msgEvt, ReadOnlyMemory<byte>? content)
15+
{
16+
var increase = ProtoHelper.Deserialize<GroupChange>(content!.Value.Span);
17+
var response = await context.EventContext.SendEvent<FetchGroupNotificationsEventResp>(
18+
new FetchGroupNotificationsEventReq(20)
19+
);
20+
var inviteNotifications = response
21+
.GroupNotifications
22+
.OfType<BotGroupInviteNotification>();
23+
var notification = inviteNotifications.FirstOrDefault(notification =>
24+
increase.GroupUin == notification.GroupUin &&
25+
increase.MemberUid == notification.TargetUid &&
26+
notification.State == BotGroupNotificationState.Accept
27+
);
28+
var operatorUin = notification?.OperatorUin;
29+
context.EventInvoker.PostEvent(new BotGroupMemberIncreaseEvent(
30+
increase.GroupUin,
31+
context.CacheContext.ResolveUin(increase.MemberUid),
32+
context.CacheContext.ResolveUin(Encoding.UTF8.GetString(increase.Operator.AsSpan())),
33+
increase.IncreaseType,
34+
operatorUin));
35+
return true;
36+
}
37+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using Lagrange.Core.Events.EventArgs;
2+
using Lagrange.Core.Internal.Events.Message;
3+
using Lagrange.Core.Internal.Packets.Notify;
4+
using Lagrange.Core.Utility;
5+
using Lagrange.Core.Utility.Binary;
6+
7+
namespace Lagrange.Core.Internal.Logic.MsgPushProccessors;
8+
9+
[MsgPushProcessor(MsgType.Event0x2DC, 20, true)] // GroupGreyTipNotice20
10+
internal class GroupNudgeProcessor : MsgPushProcessorBase
11+
{
12+
internal override ValueTask<bool> Handle(BotContext context, MsgType msgType, int subType,
13+
PushMessageEvent msgEvt, ReadOnlyMemory<byte>? content)
14+
{
15+
var packet = new BinaryPacket(content!.Value.Span);
16+
long groupUin = packet.Read<int>(); // group uin
17+
_ = packet.Read<byte>(); // unknown byte
18+
var proto = packet.ReadBytes(Prefix.Int16 | Prefix.LengthOnly);
19+
var greyTip = ProtoHelper.Deserialize<NotifyMessageBody>(proto);
20+
21+
if (greyTip.SubType != 19) return ValueTask.FromResult(false); // GroupNudgeNotice
22+
23+
var @params = greyTip.GeneralGrayTip.MsgTemplParam.ToDictionary(x => x.Name, x => x.Value);
24+
25+
if (greyTip.GeneralGrayTip.BusiType == 12) // poke
26+
{
27+
context.EventInvoker.PostEvent(new BotGroupNudgeEvent(
28+
groupUin,
29+
long.Parse(@params["uin_str1"]),
30+
@params["action_str"],
31+
@params["action_img_url"],
32+
long.Parse(@params["uin_str2"]),
33+
@params["suffix_str"]
34+
));
35+
return ValueTask.FromResult(true);
36+
}
37+
38+
return ValueTask.FromResult(false);
39+
}
40+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using Lagrange.Core.Events.EventArgs;
2+
using Lagrange.Core.Internal.Events.Message;
3+
using Lagrange.Core.Internal.Packets.Notify;
4+
using Lagrange.Core.Utility;
5+
using Lagrange.Core.Utility.Binary;
6+
7+
namespace Lagrange.Core.Internal.Logic.MsgPushProccessors;
8+
9+
[MsgPushProcessor(MsgType.Event0x2DC, 16, true)]
10+
internal class GroupReactionProcessor : MsgPushProcessorBase
11+
{
12+
internal override ValueTask<bool> Handle(BotContext context, MsgType msgType, int subType,
13+
PushMessageEvent msgEvt, ReadOnlyMemory<byte>? content)
14+
{
15+
var reader = new BinaryPacket(content!.Value.Span);
16+
// group uin and 1 byte
17+
reader.Skip(4 + 1);
18+
var proto = reader.ReadBytes(Prefix.Int16 | Prefix.LengthOnly);
19+
var body = ProtoHelper.Deserialize<NotifyMessageBody>(proto);
20+
if (body.SubType != 35) return ValueTask.FromResult(false); // GroupReactionNotice
21+
var reaction = body.Reaction.Data.Data;
22+
23+
long @operator = context.CacheContext.ResolveUin(reaction.Data.OperatorUid);
24+
25+
context.EventInvoker.PostEvent(new BotGroupReactionEvent(
26+
body.GroupUin,
27+
reaction.Target.Sequence,
28+
@operator,
29+
reaction.Data.Type == 1,
30+
reaction.Data.Code,
31+
reaction.Data.CurrentCount
32+
));
33+
return ValueTask.FromResult(true);
34+
}
35+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System.Text.Json;
2+
using System.Web;
3+
using Lagrange.Core.Common.Entity;
4+
using Lagrange.Core.Events.EventArgs;
5+
using Lagrange.Core.Internal.Events.Message;
6+
using Lagrange.Core.Message.Entities;
7+
8+
namespace Lagrange.Core.Internal.Logic.MsgPushProccessors;
9+
10+
[MsgPushProcessor(MsgType.GroupMessage)]
11+
[MsgPushProcessor(MsgType.PrivateMessage)]
12+
[MsgPushProcessor(MsgType.TempMessage)]
13+
internal class RichTextMsgProcessor : MsgPushProcessorBase
14+
{
15+
internal override async ValueTask<bool> Handle(BotContext context, MsgType msgType, int subType, PushMessageEvent msgEvt, ReadOnlyMemory<byte>? content)
16+
{
17+
var message = await context.EventContext.GetLogic<MessagingLogic>().Parse(msgEvt.MsgPush.CommonMessage);
18+
if (message.Entities[0] is LightAppEntity { AppName: "com.tencent.qun.invite" } || message.Entities[0] is LightAppEntity { AppName: "com.tencent.tuwen.lua" })
19+
{
20+
var app = (LightAppEntity)message.Entities[0];
21+
using var document = JsonDocument.Parse(app.Payload);
22+
var root = document.RootElement;
23+
24+
string url = root.GetProperty("meta").GetProperty("news").GetProperty("jumpUrl").GetString() ?? throw new Exception("sb tx! Is this 'com.tencent.qun.invite' or 'com.tencent.tuwen.lua'?");
25+
var query = HttpUtility.ParseQueryString(new Uri(url).Query);
26+
long groupUin = uint.Parse(query["groupcode"] ?? throw new Exception("sb tx! Is this '/group/invite_join'?"));
27+
ulong sequence = ulong.Parse(query["msgseq"] ?? throw new Exception("sb tx! Is this '/group/invite_join'?"));
28+
context.EventInvoker.PostEvent(new BotGroupInviteNotificationEvent(new BotGroupInviteNotification(
29+
groupUin,
30+
sequence,
31+
context.BotUin,
32+
context.CacheContext.ResolveCachedUid(context.BotUin) ?? string.Empty,
33+
BotGroupNotificationState.Wait,
34+
null,
35+
null,
36+
message.Contact.Uin,
37+
message.Contact.Uid,
38+
false
39+
)));
40+
return true;
41+
}
42+
context.EventInvoker.PostEvent(new BotMessageEvent(message, msgEvt.Raw));
43+
return true;
44+
}
45+
}

0 commit comments

Comments
 (0)