diff --git a/Lagrange.Core/Events/EventArgs/BotFriendRequestEvent.cs b/Lagrange.Core/Events/EventArgs/BotFriendRequestEvent.cs new file mode 100644 index 00000000..59ed1297 --- /dev/null +++ b/Lagrange.Core/Events/EventArgs/BotFriendRequestEvent.cs @@ -0,0 +1,17 @@ +namespace Lagrange.Core.Events.EventArgs; + +public class BotFriendRequestEvent(string initiatorUid, long initiatorUin, string message, string source) : EventBase +{ + public string InitiatorUid { get; } = initiatorUid; + + public long InitiatorUin { get; } = initiatorUin; + + public string Message { get; } = message; + + public string Source { get; } = source; + + public override string ToEventMessage() + { + return $"{nameof(BotFriendRequestEvent)}: InitiatorUid: {InitiatorUid}, InitiatorUin: {InitiatorUin}, Message: {Message}, Source: {Source}"; + } +} diff --git a/Lagrange.Core/Internal/Logic/PushLogic.cs b/Lagrange.Core/Internal/Logic/PushLogic.cs index ea07b822..8385c19e 100644 --- a/Lagrange.Core/Internal/Logic/PushLogic.cs +++ b/Lagrange.Core/Internal/Logic/PushLogic.cs @@ -1,4 +1,3 @@ -using System.Text; using Lagrange.Core.Common; using Lagrange.Core.Common.Entity; using Lagrange.Core.Events.EventArgs; @@ -128,6 +127,25 @@ public async ValueTask Incoming(ProtocolEvent e) } break; } + case Type.Event0x210: + { + var pkgType210 = (Event0x210SubType)messageEvent.MsgPush.CommonMessage.ContentHead.SubType; + switch (pkgType210) + { + case Event0x210SubType.FriendRequestNotice + when messageEvent.MsgPush.CommonMessage.MessageBody.MsgContent is { } content: + var friendRequest = ProtoHelper.Deserialize(content.Span); + context.EventInvoker.PostEvent(new BotFriendRequestEvent( + friendRequest.Info!.SourceUid, + messageEvent.MsgPush.CommonMessage.RoutingHead.FromUin, + friendRequest.Info.Message, + friendRequest.Info.Source ?? string.Empty + )); + break; + } + + break; + } case Type.Event0x2DC: { var pkgType = (Event0x2DCSubType)messageEvent.MsgPush.CommonMessage.ContentHead.SubType; @@ -213,4 +231,10 @@ private enum Event0x2DCSubType16Field13 GroupTodoNotice = 23, GroupReactionNotice = 35, } + + private enum Event0x210SubType + { + FriendRequestNotice = 35, + FriendRecallNudgeNotice = 321, + } } diff --git a/Lagrange.Core/Internal/Packets/Notify/FriendRequest.cs b/Lagrange.Core/Internal/Packets/Notify/FriendRequest.cs new file mode 100644 index 00000000..d281a75f --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Notify/FriendRequest.cs @@ -0,0 +1,25 @@ +using Lagrange.Proto; + +namespace Lagrange.Core.Internal.Packets.Notify; + +#pragma warning disable CS8618 + +[ProtoPackable] +internal partial class FriendRequest +{ + [ProtoMember(1)] public FriendRequestInfo? Info { get; set; } +} + +[ProtoPackable] +internal partial class FriendRequestInfo +{ + [ProtoMember(1)] public string TargetUid { get; set; } + + [ProtoMember(2)] public string SourceUid { get; set; } + + [ProtoMember(5)] public string NewSource { get; set; } + + [ProtoMember(10)] public string Message { get; set; } + + [ProtoMember(11)] public string? Source { get; set; } +} diff --git a/Lagrange.Milky/Entity/Event/FriendRequestEvent.cs b/Lagrange.Milky/Entity/Event/FriendRequestEvent.cs new file mode 100644 index 00000000..417255bd --- /dev/null +++ b/Lagrange.Milky/Entity/Event/FriendRequestEvent.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; +using Lagrange.Milky.Extension; + +namespace Lagrange.Milky.Entity.Event; + +public class FriendRequestEvent(long time, long selfId, FriendRequestEventData data) : EventBase(time, selfId, "friend_request", data) { } + +public class FriendRequestEventData(string initiatorUid, long initiatorId, string comment, string via) +{ + [JsonPropertyName("initiator_uid")] + public string InitiatorUID { get; } = initiatorUid; + [JsonPropertyName("initiator_id")] + public long InitiatorID { get; } = initiatorId; + [JsonPropertyName("comment")] + public string Comment { get; } = comment; + [JsonPropertyName("via")] + public string Via { get; } = via; +} \ No newline at end of file diff --git a/Lagrange.Milky/Event/EventService.cs b/Lagrange.Milky/Event/EventService.cs index 073d5bb2..3313f38a 100644 --- a/Lagrange.Milky/Event/EventService.cs +++ b/Lagrange.Milky/Event/EventService.cs @@ -31,6 +31,7 @@ public Task StartAsync(CancellationToken token) _bot.EventInvoker.RegisterEvent(HandleMessageEvent); _bot.EventInvoker.RegisterEvent(HandleGroupNudgeEvent); _bot.EventInvoker.RegisterEvent(HandleGroupMemberDecreaseEvent); + _bot.EventInvoker.RegisterEvent(HandleFriendRequestEvent); return Task.CompletedTask; } @@ -149,6 +150,32 @@ private void HandleGroupMemberDecreaseEvent(BotContext bot, LgrEvents.BotGroupMe } } + private void HandleFriendRequestEvent(BotContext bot, LgrEvents.BotFriendRequestEvent @event) + { + try + { + _logger.LogBotFriendRequestEvent( + @event.InitiatorUid, + @event.InitiatorUin, + @event.Message, + @event.Source + ); + var result = _convert.FriendRequestEvent(@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.BotFriendRequestEvent), e); + } + } + public Task StopAsync(CancellationToken token) { // TODO: unregister @@ -190,6 +217,9 @@ public static partial class EventServiceLoggerExtension [LoggerMessage(EventId = 4, Level = LogLevel.Debug, Message = "BotGroupMemberDecreaseEvent {{ group: {group}, user: {user}, operator: {operator} }}")] public static partial void LogGroupMemberDecreaseEvent(this ILogger logger, long group, long user, long? @operator); + + [LoggerMessage(EventId = 5, Level = LogLevel.Debug, Message = "BotFriendRequestEvent {{ request: {request}, user: {user}, message: {message}, source: {source} }}")] + public static partial void LogBotFriendRequestEvent(this ILogger logger, string request, long user, string? message, string? source); [LoggerMessage(EventId = 999, Level = LogLevel.Error, Message = "Handle {event} exception")] public static partial void LogHandleEventException(this ILogger logger, string @event, Exception e); diff --git a/Lagrange.Milky/Utility/EntityConvert.Event.cs b/Lagrange.Milky/Utility/EntityConvert.Event.cs index 157fae10..f0448d4d 100644 --- a/Lagrange.Milky/Utility/EntityConvert.Event.cs +++ b/Lagrange.Milky/Utility/EntityConvert.Event.cs @@ -29,4 +29,11 @@ public partial class EntityConvert _bot.BotUin, new GroupMemberDecreaseEventData(@event.GroupUin, @event.UserUin, @event.OperatorUin == 0 ? null : @event.OperatorUin) ); + + public FriendRequestEvent FriendRequestEvent(LgrEventArgs.BotFriendRequestEvent @event) => new( + @event.EventTime.ToUnixTimeSeconds(), + _bot.BotUin, + new FriendRequestEventData(@event.InitiatorUid, @event.InitiatorUin, + @event.Message, @event.Source) + ); } diff --git a/Lagrange.Milky/Utility/JsonUtility.cs b/Lagrange.Milky/Utility/JsonUtility.cs index 1e3e4bda..7210fbe2 100644 --- a/Lagrange.Milky/Utility/JsonUtility.cs +++ b/Lagrange.Milky/Utility/JsonUtility.cs @@ -108,6 +108,8 @@ public static partial class JsonUtility [JsonSerializable(typeof(GroupNudgeEvent))] // group_member_decrease [JsonSerializable(typeof(GroupMemberDecreaseEvent))] + // friend_request + [JsonSerializable(typeof(FriendRequestEvent))] private partial class JsonContext : JsonSerializerContext; public static string Serialize(T value) where T : class