Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Lagrange.Core/Events/EventArgs/BotGroupNudgeEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Lagrange.Core.Events.EventArgs;

public class BotGroupNudgeEvent(Int64 groupUin, Int64 operatorUin, Int64 targetUin) : EventBase
{
public Int64 GroupUin { get; } = groupUin;

public Int64 OperatorUin { get; } = operatorUin;

public Int64 TargetUin { get; } = targetUin;

public override string ToEventMessage()
{
return $"{nameof(BotGroupNudgeEvent)}: GroupUin={GroupUin}, OperatorUin={OperatorUin}, TargetUin={TargetUin}";
}
}
52 changes: 51 additions & 1 deletion Lagrange.Core/Internal/Logic/PushLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
using Lagrange.Core.Events.EventArgs;
using Lagrange.Core.Internal.Events;
using Lagrange.Core.Internal.Events.Message;
using Lagrange.Core.Internal.Packets.Notify;
using Lagrange.Core.Utility.Binary;
using ProtoHelper = Lagrange.Core.Utility.ProtoHelper;

namespace Lagrange.Core.Internal.Logic;

Expand All @@ -20,6 +23,34 @@ public async ValueTask Incoming(ProtocolEvent e)
var message = await context.EventContext.GetLogic<MessagingLogic>().Parse(messageEvent.MsgPush.CommonMessage);
context.EventInvoker.PostEvent(new BotMessageEvent(message, messageEvent.Raw));
break;
case Type.Event0x2DC:
var pkgType = (Event0x2DCSubType)messageEvent.MsgPush.CommonMessage.ContentHead.SubType;
switch (pkgType)
{
case Event0x2DCSubType.GroupGreyTipNotice20 when messageEvent.MsgPush.CommonMessage.MessageBody.MsgContent is {} content:
var packet = new BinaryPacket(content);
Int64 groupUin = packet.Read<Int32>(); // group uin
_ = packet.Read<byte>(); // unknown byte
var proto = packet.ReadBytes(Prefix.Int16 | Prefix.LengthOnly);
var greyTip = ProtoHelper.Deserialize<NotifyMessageBody>(proto);
var templates = greyTip.GeneralGrayTip.MsgTemplParam.ToDictionary(x => x.Name, x => x.Value);

if (!templates.TryGetValue("action_str", out var actionStr) && !templates.TryGetValue("alt_str1", out actionStr))
{
actionStr = string.Empty;
}

if (greyTip.GeneralGrayTip.BusiType == 12) // poke
{
context.EventInvoker.PostEvent(new BotGroupNudgeEvent(
groupUin,
uint.Parse(templates["uin_str1"]),
uint.Parse(templates["uin_str2"]))
);
}
break;
}
break;
}
}

Expand All @@ -28,5 +59,24 @@ private enum Type
PrivateMessage = 166,
GroupMessage = 82,
TempMessage = 141,
Event0x210 = 528, // friend related event
Event0x2DC = 732, // group related event
}

private enum Event0x2DCSubType
{
GroupMuteNotice = 12,
SubType16 = 16,
GroupRecallNotice = 17,
GroupGreyTipNotice21 = 21,
GroupGreyTipNotice20 = 20,
}

private enum Event0x2DCSubType16Field13
{
GroupMemberSpecialTitleNotice = 6,
GroupNameChangeNotice = 12,
GroupTodoNotice = 23,
GroupReactionNotice = 35,
}
}
}
31 changes: 31 additions & 0 deletions Lagrange.Core/Internal/Packets/Notify/GroupEssenceMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Lagrange.Proto;

namespace Lagrange.Core.Internal.Packets.Notify;

#pragma warning disable CS8618

[ProtoPackable]
internal partial class EssenceMessage
{
[ProtoMember(1)] public long GroupUin;

[ProtoMember(2)] public long MsgSequence;

[ProtoMember(3)] public uint Random;

[ProtoMember(4)] public uint SetFlag; // set 1 remove 2

[ProtoMember(5)] public uint MemberUin;

[ProtoMember(6)] public uint OperatorUin;

[ProtoMember(7)] public uint TimeStamp;

[ProtoMember(8)] public uint MsgSequence2; // removed 0

[ProtoMember(9)] public string OperatorNickName;

[ProtoMember(10)] public string MemberNickName;

[ProtoMember(11)] public uint SetFlag2;
}
43 changes: 43 additions & 0 deletions Lagrange.Core/Internal/Packets/Notify/GroupReaction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Lagrange.Proto;

namespace Lagrange.Core.Internal.Packets.Notify;

#pragma warning disable CS8618

[ProtoPackable]
internal partial class GroupReactionData0
{
[ProtoMember(1)] public GroupReactionData1 Data { get; set; }
}

[ProtoPackable]
internal partial class GroupReactionData1
{
[ProtoMember(1)] public GroupReactionData2 Data { get; set; }
}

[ProtoPackable]
internal partial class GroupReactionData2
{
[ProtoMember(2)] public GroupReactionTarget Target { get; set; }

[ProtoMember(3)] public GroupReactionData3 Data { get; set; }
}

[ProtoPackable]
internal partial class GroupReactionTarget
{
[ProtoMember(1)] public long Sequence { get; set; }
}

[ProtoPackable]
internal partial class GroupReactionData3
{
[ProtoMember(1)] public string Code { get; set; }

[ProtoMember(3)] public uint Count { get; set; }

[ProtoMember(4)] public string OperatorUid { get; set; }

[ProtoMember(5)] public uint Type { get; set; } // 1 Add 2 Remove
}
43 changes: 43 additions & 0 deletions Lagrange.Core/Internal/Packets/Notify/GroupRecall.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Lagrange.Proto;

namespace Lagrange.Core.Internal.Packets.Notify;

#pragma warning disable CS8618

[ProtoPackable]
internal partial class GroupRecall
{
[ProtoMember(1)] public string? OperatorUid { get; set; }

[ProtoMember(3)] public List<RecallMessage> RecallMessages { get; set; }

[ProtoMember(5)] public byte[] UserDef { get; set; }

[ProtoMember(6)] public int GroupType { get; set; }

[ProtoMember(7)] public int OpType { get; set; }

[ProtoMember(9)] public GroupRecallTipInfo? TipInfo { get; set; }
}

[ProtoPackable]
internal partial class RecallMessage
{
[ProtoMember(1)] public uint Sequence { get; set; }

[ProtoMember(2)] public uint Time { get; set; }

[ProtoMember(3)] public uint Random { get; set; }

[ProtoMember(4)] public uint Type { get; set; }

[ProtoMember(5)] public uint Flag { get; set; }

[ProtoMember(6)] public string AuthorUid { get; set; }
}

[ProtoPackable]
internal partial class GroupRecallTipInfo
{
[ProtoMember(2)] public string Tip { get; set; }
}
17 changes: 17 additions & 0 deletions Lagrange.Core/Internal/Packets/Notify/GroupRecallNudge.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Lagrange.Proto;

namespace Lagrange.Core.Internal.Packets.Notify;

#pragma warning disable CS8618

[ProtoPackable]
internal partial class GroupRecallNudge
{
[ProtoMember(1)] public string OperatorUid { get; set; }

[ProtoMember(3)] public long GroupUin { get; set; }

[ProtoMember(4)] public ulong BusiId { get; set; }

[ProtoMember(5)] public ulong TipsSeqId { get; set; }
}
87 changes: 87 additions & 0 deletions Lagrange.Core/Internal/Packets/Notify/NotifyMessageBody.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using Lagrange.Proto;

namespace Lagrange.Core.Internal.Packets.Notify;

#pragma warning disable CS8618

[ProtoPackable]
internal partial class NotifyMessageBody
{
[ProtoMember(1)] public uint Type { get; set; }

[ProtoMember(4)] public long GroupUin { get; set; }

[ProtoMember(5)] public byte[]? EventParam { get; set; }

[ProtoMember(11)] public GroupRecall Recall { get; set; }

[ProtoMember(13)] public uint? Field13 { get; set; }

[ProtoMember(21)] public string OperatorUid { get; set; }

[ProtoMember(26)] public GeneralGrayTipInfo GeneralGrayTip { get; set; }

[ProtoMember(33)] public EssenceMessage EssenceMessage;

[ProtoMember(37)] public long MsgSequence { get; set; }

[ProtoMember(39)] public uint Field39 { get; set; }

[ProtoMember(40)] public GroupRecallNudge GroupRecallNudge { get; set; }

[ProtoMember(44)] public GroupReactionData0 Reaction { get; set; }

[ProtoMember(50)] public ulong TipsSeqId { get; set; }
}

[ProtoPackable]
internal partial class GeneralGrayTipInfo
{
[ProtoMember(1)] public ulong BusiType { get; set; }

[ProtoMember(2)] public ulong BusiId { get; set; }

[ProtoMember(3)] public uint CtrlFlag { get; set; }

[ProtoMember(4)] public uint C2CType { get; set; }

[ProtoMember(5)] public uint ServiceType { get; set; }

[ProtoMember(6)] public ulong TemplId { get; set; }

[ProtoMember(7)] public List<TemplParam> MsgTemplParam { get; set; }

[ProtoMember(8)] public string Content { get; set; }

[ProtoMember(10)] public ulong TipsSeqId { get; set; }

[ProtoMember(100)] public GrayTipMsgInfo MsgInfo { get; set; }
}

[ProtoPackable]
internal partial class GrayTipMsgInfo
{
[ProtoMember(6)] public ulong Sequence { get; set; }
}

[ProtoPackable]
internal partial class TemplParam
{
[ProtoMember(1)] public string Name { get; set; }

[ProtoMember(2)] public string Value { get; set; }
}

[ProtoPackable]
internal partial class FriendRecallPokeInfo
{
[ProtoMember(1)] public string SelfUid { get; set; }

[ProtoMember(2)] public string PeerUid { get; set; }

[ProtoMember(3)] public string OperatorUid { get; set; }

[ProtoMember(4)] public ulong BusiId { get; set; }

[ProtoMember(5)] public ulong TipsSeqId { get; set; }
}
17 changes: 17 additions & 0 deletions Lagrange.Milky/Entity/Event/GroupNudgeEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Text.Json.Serialization;

namespace Lagrange.Milky.Entity.Event;

public class GroupNudgeEvent(long time, long selfId, GroupNudgeEventData data) : EventBase<GroupNudgeEventData>(time, selfId, "group_nudge", data) { }

public class GroupNudgeEventData(Int64 groupID, Int64 sender_id, Int64 receiver_id)
{
[JsonPropertyName("group_id")]
public Int64 GroupID { get; } = groupID;

[JsonPropertyName("sender_id")]
public Int64 SenderID { get; } = sender_id;

[JsonPropertyName("receiver_id")]
public Int64 ReceiverID { get; } = receiver_id;
}
29 changes: 29 additions & 0 deletions Lagrange.Milky/Event/EventService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public Task StartAsync(CancellationToken token)
{
_bot.EventInvoker.RegisterEvent<LgrEvents.BotOfflineEvent>(HandleOfflineEvent);
_bot.EventInvoker.RegisterEvent<LgrEvents.BotMessageEvent>(HandleMessageEvent);
_bot.EventInvoker.RegisterEvent<LgrEvents.BotGroupNudgeEvent>(HandleGroupNudgeEvent);

return Task.CompletedTask;
}
Expand Down Expand Up @@ -96,6 +97,31 @@ private void HandleMessageEvent(BotContext bot, LgrEvents.BotMessageEvent @event
_logger.LogHandleEventException(nameof(LgrEvents.BotMessageEvent), e);
}
}

private void HandleGroupNudgeEvent(BotContext bot, LgrEvents.BotGroupNudgeEvent @event)
{
try
{
_logger.LogGroupNudgeEvent(
@event.GroupUin,
@event.OperatorUin,
@event.TargetUin
);
var result = _convert.GroupNudgeEvent(@event);
byte[] bytes = JsonUtility.SerializeToUtf8Bytes(result.GetType(), result);
using (_lock.UsingReadLock())
{
foreach (var handler in _handlers)
{
handler(bytes);
}
}
}
catch (Exception e)
{
_logger.LogHandleEventException(nameof(LgrEvents.BotGroupNudgeEvent), e);
}
}

public Task StopAsync(CancellationToken token)
{
Expand Down Expand Up @@ -132,6 +158,9 @@ public static partial class EventServiceLoggerExtension

[LoggerMessage(EventId = 2, Level = LogLevel.Debug, Message = "BotMessageEvent {{ {type} {sender} {entities} }}")]
public static partial void LogPrivateMessage(this ILogger<EventService> logger, MessageType type, long sender, string entities);

[LoggerMessage(EventId = 3, Level = LogLevel.Debug, Message = "BotGroupNudgeEvent {{ group: {group}, sender: {sender} target: {target} }}")]
public static partial void LogGroupNudgeEvent(this ILogger<EventService> logger, long group, long sender, long target);

[LoggerMessage(EventId = 999, Level = LogLevel.Error, Message = "Handle {event} exception")]
public static partial void LogHandleEventException(this ILogger<EventService> logger, string @event, Exception e);
Expand Down
8 changes: 7 additions & 1 deletion Lagrange.Milky/Utility/EntityConvert.Event.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ public partial class EntityConvert
_bot.BotUin,
MessageBase(@event.Message)
);
}

public GroupNudgeEvent GroupNudgeEvent(LgrEventArgs.BotGroupNudgeEvent @event) => new(
@event.EventTime.ToUnixTimeSeconds(),
_bot.BotUin,
new GroupNudgeEventData(@event.GroupUin, @event.OperatorUin, @event.TargetUin)
);
}
Loading