diff --git a/Lagrange.Core/Common/Interface/Api/OperationExt.cs b/Lagrange.Core/Common/Interface/Api/OperationExt.cs index e53e60e70..c1fe6c111 100644 --- a/Lagrange.Core/Common/Interface/Api/OperationExt.cs +++ b/Lagrange.Core/Common/Interface/Api/OperationExt.cs @@ -281,4 +281,13 @@ public static Task UploadImage(this BotContext bot, ImageEntity entity) public static Task<(int Code, string ErrMsg, List? Result)> GetAiCharacters(this BotContext bot, uint chatType, uint groupUin = 42) => bot.ContextCollection.Business.OperationLogic.GetAiCharacters(chatType, groupUin); + + public static Task<(int Retcode, string Message, List FriendUins, List GroupUins)> GetPins(this BotContext bot) + => bot.ContextCollection.Business.OperationLogic.GetPins(); + + public static Task<(int Retcode, string Message)> SetPinFriend(this BotContext bot, uint uin, bool isPin) + => bot.ContextCollection.Business.OperationLogic.SetPinFriend(uin, isPin); + + public static Task<(int Retcode, string Message)> SetPinGroup(this BotContext bot, uint uin, bool isPin) + => bot.ContextCollection.Business.OperationLogic.SetPinGroup(uin, isPin); } \ No newline at end of file diff --git a/Lagrange.Core/Event/EventArg/PinChangedEvent.cs b/Lagrange.Core/Event/EventArg/PinChangedEvent.cs new file mode 100644 index 000000000..dd45b3d7b --- /dev/null +++ b/Lagrange.Core/Event/EventArg/PinChangedEvent.cs @@ -0,0 +1,26 @@ +namespace Lagrange.Core.Event.EventArg; + +public class PinChangedEvent : EventBase +{ + public ChatType Type { get; } + + public uint Uin { get; } + + public bool IsPin { get; } + + public PinChangedEvent(ChatType type, uint uin, bool isPin) + { + Type = type; + Uin = uin; + IsPin = isPin; + + EventMessage = $"{nameof(PinChangedEvent)} {{ChatType: {Type} | Uin: {Uin} | IsPin: {IsPin}}}"; + } + + public enum ChatType + { + Friend, + Group, + Service + } +} diff --git a/Lagrange.Core/Event/EventInvoker.Events.cs b/Lagrange.Core/Event/EventInvoker.Events.cs index 4d3c4f19a..c5725b17c 100644 --- a/Lagrange.Core/Event/EventInvoker.Events.cs +++ b/Lagrange.Core/Event/EventInvoker.Events.cs @@ -57,4 +57,6 @@ public partial class EventInvoker public event LagrangeEvent? OnGroupTodoEvent; public event LagrangeEvent? OnGroupMemberEnterEvent; + + public event LagrangeEvent? OnPinChangedEvent; } \ No newline at end of file diff --git a/Lagrange.Core/Event/EventInvoker.cs b/Lagrange.Core/Event/EventInvoker.cs index bd9e8a3a1..925ea82ba 100644 --- a/Lagrange.Core/Event/EventInvoker.cs +++ b/Lagrange.Core/Event/EventInvoker.cs @@ -1,6 +1,5 @@ using System.Runtime.CompilerServices; using Lagrange.Core.Event.EventArg; -using Lagrange.Core.Internal.Event.Notify; namespace Lagrange.Core.Event; @@ -43,6 +42,7 @@ internal EventInvoker(BotContext context) RegisterEvent((GroupNameChangeEvent e) => OnGroupNameChangeEvent?.Invoke(context, e)); RegisterEvent((GroupTodoEvent e) => OnGroupTodoEvent?.Invoke(context, e)); RegisterEvent((GroupMemberEnterEvent e) => OnGroupMemberEnterEvent?.Invoke(context, e)); + RegisterEvent((PinChangedEvent e) => OnPinChangedEvent?.Invoke(context, e)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Lagrange.Core/Internal/Context/Logic/Implementation/MessagingLogic.cs b/Lagrange.Core/Internal/Context/Logic/Implementation/MessagingLogic.cs index d3eaff54a..71c7df0e7 100644 --- a/Lagrange.Core/Internal/Context/Logic/Implementation/MessagingLogic.cs +++ b/Lagrange.Core/Internal/Context/Logic/Implementation/MessagingLogic.cs @@ -10,7 +10,6 @@ using Lagrange.Core.Message; using Lagrange.Core.Message.Entity; using Lagrange.Core.Message.Filter; -using Lagrange.Core.Utility.Extension; using FriendPokeEvent = Lagrange.Core.Event.EventArg.FriendPokeEvent; using GroupPokeEvent = Lagrange.Core.Event.EventArg.GroupPokeEvent; @@ -41,6 +40,9 @@ namespace Lagrange.Core.Internal.Context.Logic.Implementation; [EventSubscribe(typeof(LoginNotifyEvent))] [EventSubscribe(typeof(MultiMsgDownloadEvent))] [EventSubscribe(typeof(GroupSysTodoEvent))] +[EventSubscribe(typeof(SysPinChangedEvent))] +[EventSubscribe(typeof(FetchPinsEvent))] +[EventSubscribe(typeof(SetPinFriendEvent))] [BusinessLogic("MessagingLogic", "Manage the receiving and sending of messages and notifications")] internal class MessagingLogic : LogicBase { @@ -251,6 +253,26 @@ public override async Task Incoming(ProtocolEvent e) Collection.Invoker.PostEvent(new GroupTodoEvent(todo.GroupUin, uin)); break; } + case SysPinChangedEvent pin: + { + uint uin = pin.GroupUin ?? await Collection.Business.CachingLogic.ResolveUin(null, pin.Uid) ?? 0; + + Collection.Invoker.PostEvent(new PinChangedEvent( + pin.GroupUin == null ? PinChangedEvent.ChatType.Friend : PinChangedEvent.ChatType.Group, + uin, + pin.IsPin + )); + break; + } + case FetchPinsEvent pins: + { + foreach (var friendUid in pins.FriendUids) + { + pins.FriendUins.Add(await Collection.Business.CachingLogic.ResolveUin(null, friendUid) ?? 0); + } + + break; + } } } @@ -275,6 +297,13 @@ public override async Task Outgoing(ProtocolEvent e) await Collection.Highway.UploadResources(send.Chain); break; } + case SetPinFriendEvent pinFriend: // resolve Uin to Uid + { + pinFriend.Uid = await Collection.Business.CachingLogic.ResolveUid(null, pinFriend.Uin) + ?? throw new Exception(); + + break; + } } } @@ -396,7 +425,6 @@ private async Task ResolveOutgoingChain(MessageChain chain) face.SysFaceEntry ??= await cache.GetCachedFaceEntity(face.FaceId); break; } - case ForwardEntity forward when forward.TargetUin != 0: { var cache = Collection.Business.CachingLogic; diff --git a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs index f4e70a411..1eae3b5b0 100644 --- a/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs +++ b/Lagrange.Core/Internal/Context/Logic/Implementation/OperationLogic.cs @@ -798,4 +798,46 @@ public async Task UploadImage(ImageEntity image) var imageUrl = await UploadImage(image); return await ImageOcr(imageUrl); } + + public async Task<(int Retcode, string Message, List FriendUins, List GroupUins)> GetPins() + { + var @event = FetchPinsEvent.Create(); + + var results = await Collection.Business.SendEvent(@event); + if (results.Count == 0) + { + return (-1, "No Result", new(), new()); + } + + var result = (FetchPinsEvent)results[0]; + return (result.ResultCode, result.Message, result.FriendUins, result.GroupUins); + } + + public async Task<(int Retcode, string Message)> SetPinFriend(uint uin, bool isPin) + { + var @event = SetPinFriendEvent.Create(uin, isPin); + + var results = await Collection.Business.SendEvent(@event); + if (results.Count == 0) + { + return (-1, "No Result"); + } + + var result = (SetPinFriendEvent)results[0]; + return (result.ResultCode, result.Message); + } + + public async Task<(int Retcode, string Message)> SetPinGroup(uint uin, bool isPin) + { + var @event = SetPinGroupEvent.Create(uin, isPin); + + var results = await Collection.Business.SendEvent(@event); + if (results.Count == 0) + { + return (-1, "No Result"); + } + + var result = (SetPinGroupEvent)results[0]; + return (result.ResultCode, result.Message); + } } \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Action/FetchPinsEvent.cs b/Lagrange.Core/Internal/Event/Action/FetchPinsEvent.cs new file mode 100644 index 000000000..de76723e2 --- /dev/null +++ b/Lagrange.Core/Internal/Event/Action/FetchPinsEvent.cs @@ -0,0 +1,42 @@ +namespace Lagrange.Core.Internal.Event.Action; + +internal class FetchPinsEvent : ProtocolEvent +{ + internal List FriendUids { get; set; } + + public List FriendUins { get; set; } + + public List GroupUins { get; set; } + + public string Message { get; set; } + + protected FetchPinsEvent() : base(true) + { + FriendUids = new(); + FriendUins = new(); + GroupUins = new(); + Message = string.Empty; + } + + protected FetchPinsEvent(List friendUids, List groupUins) : base(0) + { + FriendUids = friendUids; + FriendUins = new(); + GroupUins = groupUins; + Message = string.Empty; + } + + protected FetchPinsEvent(int retcode, string message) : base(retcode) + { + FriendUids = new(); + FriendUins = new(); + GroupUins = new(); + Message = string.Empty; + } + + public static FetchPinsEvent Create() => new(); + + public static FetchPinsEvent Result(List friendUids, List groupUins) => new(friendUids, groupUins); + + public static FetchPinsEvent Result(int retcode, string message) => new(retcode, message); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Action/SetPinFriendEvent.cs b/Lagrange.Core/Internal/Event/Action/SetPinFriendEvent.cs new file mode 100644 index 000000000..35955452c --- /dev/null +++ b/Lagrange.Core/Internal/Event/Action/SetPinFriendEvent.cs @@ -0,0 +1,31 @@ +namespace Lagrange.Core.Internal.Event.Action; + +internal class SetPinFriendEvent : ProtocolEvent +{ + internal string Uid { get; set; } + + public uint Uin { get; set; } + + public bool IsPin { get; set; } + + public string Message { get; set; } + + protected SetPinFriendEvent(uint uin, bool isPin) : base(true) + { + Uid = string.Empty; + Uin = uin; + Message = string.Empty; + IsPin = isPin; + } + + protected SetPinFriendEvent(int retcode, string message) : base(retcode) + { + Uid = string.Empty; + Uin = 0; + Message = message; + } + + public static SetPinFriendEvent Create(uint uin, bool isPin) => new(uin, isPin); + + public static SetPinFriendEvent Result(int retcode, string message) => new(retcode, message); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Action/SetPinGroupEvent.cs b/Lagrange.Core/Internal/Event/Action/SetPinGroupEvent.cs new file mode 100644 index 000000000..de3168730 --- /dev/null +++ b/Lagrange.Core/Internal/Event/Action/SetPinGroupEvent.cs @@ -0,0 +1,27 @@ +namespace Lagrange.Core.Internal.Event.Action; + +internal class SetPinGroupEvent : ProtocolEvent +{ + public uint Uin { get; set; } + + public bool IsPin { get; set; } + + public string Message { get; set; } + + protected SetPinGroupEvent(uint uin, bool isPin) : base(true) + { + Uin = uin; + Message = string.Empty; + IsPin = isPin; + } + + protected SetPinGroupEvent(int retcode, string message) : base(retcode) + { + Uin = 0; + Message = message; + } + + public static SetPinGroupEvent Create(uint uin, bool isPin) => new(uin, isPin); + + public static SetPinGroupEvent Result(int retcode, string message) => new(retcode, message); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Notify/SysPinChangedEvent.cs b/Lagrange.Core/Internal/Event/Notify/SysPinChangedEvent.cs new file mode 100644 index 000000000..bf3f2ed47 --- /dev/null +++ b/Lagrange.Core/Internal/Event/Notify/SysPinChangedEvent.cs @@ -0,0 +1,19 @@ +namespace Lagrange.Core.Internal.Event.Notify; + +internal class SysPinChangedEvent : ProtocolEvent +{ + public string Uid { get; } + + public uint? GroupUin { get; } + + public bool IsPin { get; } + + private SysPinChangedEvent(string uid, uint? groupUin, bool isPin) : base(0) + { + Uid = uid; + GroupUin = groupUin; + IsPin = isPin; + } + + public static SysPinChangedEvent Result(string uid, uint? groupUin, bool isPin) => new(uid, groupUin, isPin); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Message/Notify/FriendDeleteOrPinChanged.cs b/Lagrange.Core/Internal/Packets/Message/Notify/FriendDeleteOrPinChanged.cs new file mode 100644 index 000000000..1a6f57ab4 --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Message/Notify/FriendDeleteOrPinChanged.cs @@ -0,0 +1,48 @@ +using ProtoBuf; + +namespace Lagrange.Core.Internal.Packets.Message.Notify; + +#pragma warning disable CS8618 + +// Stupid TX +// TODO: Currently only supports PinChanged +[ProtoContract] +internal class FriendDeleteOrPinChanged +{ + [ProtoMember(1)] public FriendDeleteOrPinChangedBody Body { get; set; } +} + +[ProtoContract] +internal class FriendDeleteOrPinChangedBody +{ + // Maybe is type, need check + // 7 Pin changed + // 5 Friend delete + [ProtoMember(2)] public uint Type { get; set; } + + [ProtoMember(20)] public PinChanged? PinChanged { get; set; } +} + +[ProtoContract] +internal class PinChanged +{ + [ProtoMember(1)] public PinChangedBody Body { get; set; } +} + +[ProtoContract] +internal class PinChangedBody +{ + [ProtoMember(1)] public string Uid { get; set; } + + [ProtoMember(2)] public uint? GroupUin { get; set; } + + [ProtoMember(400)] public PinChangedInfo Info { get; set; } +} + +[ProtoContract] +internal class PinChangedInfo +{ + // if (Timestamp.Length != 0) pin + // if (Timestamp.Length == 0) unpin + [ProtoMember(2)] public byte[] Timestamp { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x5D6_1.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x5D6_1.cs new file mode 100644 index 000000000..2d3f596ff --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x5D6_1.cs @@ -0,0 +1,32 @@ +using ProtoBuf; + +#pragma warning disable CS8618 + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Request; + +[ProtoContract] +[OidbSvcTrpcTcp(0x5d6, 1)] +internal class OidbSvcTrpcTcp0x5D6_1 +{ + [ProtoMember(1)] public uint Field1 { get; set; } + + [ProtoMember(2)] public OidbSvcTrpcTcp0x5D6_1Info Info { get; set; } + + [ProtoMember(3)] public uint Field3 { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x5D6_1Info +{ + [ProtoMember(2)] public uint GroupUin { get; set; } + + [ProtoMember(400)] public OidbSvcTrpcTcp0x5D6_1Field4_2_400 Field400 { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x5D6_1Field4_2_400 +{ + [ProtoMember(1)] public uint Field1 { get; set; } + + [ProtoMember(2)] public byte[] Timestamp { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x5D6_18.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x5D6_18.cs new file mode 100644 index 000000000..7140119cc --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x5D6_18.cs @@ -0,0 +1,32 @@ +using ProtoBuf; + +#pragma warning disable CS8618 + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Request; + +[ProtoContract] +[OidbSvcTrpcTcp(0x5d6, 18)] +internal class OidbSvcTrpcTcp0x5D6_18 +{ + [ProtoMember(1)] public uint Field1 { get; set; } + + [ProtoMember(2)] public OidbSvcTrpcTcp0x5D6_18Info Info { get; set; } + + [ProtoMember(3)] public uint Field3 { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x5D6_18Info +{ + [ProtoMember(1)] public string FriendUid { get; set; } + + [ProtoMember(400)] public OidbSvcTrpcTcp0x5D6_18Field4_2_400 Field400 { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x5D6_18Field4_2_400 +{ + [ProtoMember(1)] public uint Field1 { get; set; } + + [ProtoMember(2)] public byte[] Timestamp { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x12B3_0Response.cs b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x12B3_0Response.cs new file mode 100644 index 000000000..92b312c46 --- /dev/null +++ b/Lagrange.Core/Internal/Packets/Service/Oidb/Response/OidbSvcTrpcTcp0x12B3_0Response.cs @@ -0,0 +1,25 @@ +using ProtoBuf; + +#pragma warning disable CS8618 + +namespace Lagrange.Core.Internal.Packets.Service.Oidb.Request; + +[ProtoContract] +internal class OidbSvcTrpcTcp0x12B3_0Response +{ + [ProtoMember(1)] public List? Friends { get; set; } + + [ProtoMember(3)] public List? Groups { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x12B3_0ResponseFriend +{ + [ProtoMember(1)] public string Uid { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0x12B3_0ResponseGroup +{ + [ProtoMember(1)] public uint Uin { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Service/Action/FetchPinsService.cs b/Lagrange.Core/Internal/Service/Action/FetchPinsService.cs new file mode 100644 index 000000000..a52cc57a9 --- /dev/null +++ b/Lagrange.Core/Internal/Service/Action/FetchPinsService.cs @@ -0,0 +1,43 @@ +using Lagrange.Core.Common; +using Lagrange.Core.Internal.Event; +using Lagrange.Core.Internal.Event.Action; +using Lagrange.Core.Internal.Packets.Service.Oidb; +using Lagrange.Core.Internal.Packets.Service.Oidb.Request; +using Lagrange.Core.Utility.Extension; +using ProtoBuf; + +namespace Lagrange.Core.Internal.Service.Action; + +[EventSubscribe(typeof(FetchPinsEvent))] +[Service("OidbSvcTrpcTcp.0x12b3_0")] +internal class FetchPinsService : BaseService +{ + protected override bool Build(FetchPinsEvent input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, out Span output, out List>? extraPackets) + { + var packet = new OidbSvcTrpcTcpBase(Array.Empty(), 0x12b3, 0); + + output = packet.Serialize(); + extraPackets = null; + + return true; + } + + protected override bool Parse(Span input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, out FetchPinsEvent output, out List? extraEvents) + { + var payload = Serializer.Deserialize>(input); + + if (payload.ErrorCode != 0) + { + output = FetchPinsEvent.Result((int)payload.ErrorCode, payload.ErrorMsg); + extraEvents = null; + return true; + } + + var friendUids = payload.Body.Friends?.Select(f => f.Uid).ToList() ?? new List(); + var groupUins = payload.Body.Groups?.Select(f => f.Uin).ToList() ?? new List(); + + output = FetchPinsEvent.Result(friendUids, groupUins); + extraEvents = null; + return true; + } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Service/Action/SetPinFriendService.cs b/Lagrange.Core/Internal/Service/Action/SetPinFriendService.cs new file mode 100644 index 000000000..95349a40b --- /dev/null +++ b/Lagrange.Core/Internal/Service/Action/SetPinFriendService.cs @@ -0,0 +1,55 @@ +using System.Buffers.Binary; +using Lagrange.Core.Common; +using Lagrange.Core.Internal.Event; +using Lagrange.Core.Internal.Event.Action; +using Lagrange.Core.Internal.Packets.Service.Oidb; +using Lagrange.Core.Internal.Packets.Service.Oidb.Request; +using Lagrange.Core.Utility.Extension; +using ProtoBuf; + +namespace Lagrange.Core.Internal.Service.Action; + +[EventSubscribe(typeof(SetPinFriendEvent))] +[Service("OidbSvcTrpcTcp.0x5d6_18")] +internal class SetPinFriendService : BaseService +{ + protected override bool Build(SetPinFriendEvent input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, out Span output, out List>? extraPackets) + { + var packet = new OidbSvcTrpcTcpBase( + new OidbSvcTrpcTcp0x5D6_18 + { + Field1 = 0, + Info = new OidbSvcTrpcTcp0x5D6_18Info + { + FriendUid = input.Uid, + Field400 = new OidbSvcTrpcTcp0x5D6_18Field4_2_400 + { + Field1 = 13578, + Timestamp = input.IsPin ? GetTimestamp() : Array.Empty() + } + }, + Field3 = 1 + } + ); + + output = packet.Serialize(); + extraPackets = null; + + return true; + } + + protected override bool Parse(Span input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, out SetPinFriendEvent output, out List? extraEvents) + { + var payload = Serializer.Deserialize>(input); + + output = SetPinFriendEvent.Result((int)payload.ErrorCode, payload.ErrorMsg); + extraEvents = null; + return true; + } + + private static byte[] GetTimestamp() { + byte[] timestamp = new byte[4]; + BinaryPrimitives.WriteInt32BigEndian(timestamp, (int)DateTimeOffset.Now.ToUnixTimeSeconds()); + return timestamp; + } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Service/Action/SetPinGroupService.cs b/Lagrange.Core/Internal/Service/Action/SetPinGroupService.cs new file mode 100644 index 000000000..1964b8b52 --- /dev/null +++ b/Lagrange.Core/Internal/Service/Action/SetPinGroupService.cs @@ -0,0 +1,55 @@ +using System.Buffers.Binary; +using Lagrange.Core.Common; +using Lagrange.Core.Internal.Event; +using Lagrange.Core.Internal.Event.Action; +using Lagrange.Core.Internal.Packets.Service.Oidb; +using Lagrange.Core.Internal.Packets.Service.Oidb.Request; +using Lagrange.Core.Utility.Extension; +using ProtoBuf; + +namespace Lagrange.Core.Internal.Service.Action; + +[EventSubscribe(typeof(SetPinGroupEvent))] +[Service("OidbSvcTrpcTcp.0x5d6_1")] +internal class SetPinGroupService : BaseService +{ + protected override bool Build(SetPinGroupEvent input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, out Span output, out List>? extraPackets) + { + var packet = new OidbSvcTrpcTcpBase( + new OidbSvcTrpcTcp0x5D6_1 + { + Field1 = 0, + Info = new OidbSvcTrpcTcp0x5D6_1Info + { + GroupUin = input.Uin, + Field400 = new OidbSvcTrpcTcp0x5D6_1Field4_2_400 + { + Field1 = 13569, + Timestamp = input.IsPin ? GetTimestamp() : Array.Empty() + } + }, + Field3 = 11 + } + ); + + output = packet.Serialize(); + extraPackets = null; + + return true; + } + + protected override bool Parse(Span input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, out SetPinGroupEvent output, out List? extraEvents) + { + var payload = Serializer.Deserialize>(input); + + output = SetPinGroupEvent.Result((int)payload.ErrorCode, payload.ErrorMsg); + extraEvents = null; + return true; + } + + private static byte[] GetTimestamp() { + byte[] timestamp = new byte[4]; + BinaryPrimitives.WriteInt32BigEndian(timestamp, (int)DateTimeOffset.Now.ToUnixTimeSeconds()); + return timestamp; + } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Service/Message/PushMessageService.cs b/Lagrange.Core/Internal/Service/Message/PushMessageService.cs index 49b873849..04c1406aa 100644 --- a/Lagrange.Core/Internal/Service/Message/PushMessageService.cs +++ b/Lagrange.Core/Internal/Service/Message/PushMessageService.cs @@ -6,7 +6,6 @@ using Lagrange.Core.Internal.Packets.Message.Notify; using Lagrange.Core.Message; using Lagrange.Core.Utility.Binary; -using Lagrange.Core.Utility.Extension; using ProtoBuf; // ReSharper disable InconsistentNaming @@ -264,9 +263,20 @@ private static void ProcessEvent0x210(Span payload, PushMsg msg, List(content.AsSpan()); + // if (info.Body.Data.Type == 5 && info.Body.Data.FriendDelete != null) // Friend Delete // 0A8D010A4008AFB39FF80A1218755F54305768425A6368695A684555496253786F6F63474128AFB39FF80A3218755F54305768425A6368695A684555496253786F6F634741122108900410271827209092D9C10228F2C00330809096AF06609092D9C182808080021A260A0012220A2008001005721A0A18755F597831586B5A4E4E656E4E3141356A53423361576667 + if (info.Body.Type == 7 && info.Body.PinChanged is { } data) + { + var @event = SysPinChangedEvent.Result( + data.Body.Uid, + data.Body.GroupUin, + data.Body.Info.Timestamp.Length != 0 + ); + extraEvents.Add(@event); + } break; } case Event0x210SubType.FriendRecallNotice when msg.Message.Body?.MsgContent is { } content: @@ -282,6 +292,11 @@ private static void ProcessEvent0x210(Span payload, PushMsg msg, List