diff --git a/Lagrange.Core/Internal/Context/Logic/Implementation/MessagingLogic.cs b/Lagrange.Core/Internal/Context/Logic/Implementation/MessagingLogic.cs index f0b40aa02..da0988e7c 100644 --- a/Lagrange.Core/Internal/Context/Logic/Implementation/MessagingLogic.cs +++ b/Lagrange.Core/Internal/Context/Logic/Implementation/MessagingLogic.cs @@ -187,85 +187,92 @@ public override async Task Outgoing(ProtocolEvent e) private async Task ResolveIncomingChain(MessageChain chain) { - if (chain.HasTypeOf()) + foreach (var entity in chain) switch (entity) { - var file = chain.GetEntity(); - if (file?.IsGroup != false || file.FileHash == null || file.FileUuid == null) return; - - var @event = FileDownloadEvent.Create(file.FileUuid, file.FileHash, chain.Uid, chain.SelfUid); - var results = await Collection.Business.SendEvent(@event); - if (results.Count != 0) + case FileEntity { IsGroup: true, FileHash: not null, FileUuid: not null } file: { - var result = (FileDownloadEvent)results[0]; - file.FileUrl = result.FileUrl; + var @event = FileDownloadEvent.Create(file.FileUuid, file.FileHash, chain.Uid, chain.SelfUid); + var results = await Collection.Business.SendEvent(@event); + if (results.Count != 0) + { + var result = (FileDownloadEvent)results[0]; + file.FileUrl = result.FileUrl; + } + + break; } - } - - if (chain.HasTypeOf()) - { - var multi = chain.GetEntity(); - if (multi?.ResId == null) return; - - var @event = MultiMsgDownloadEvent.Create(chain.Uid ?? "", multi.ResId); - var results = await Collection.Business.SendEvent(@event); - if (results.Count != 0) + case MultiMsgEntity { ResId: not null } multi: { - var result = (MultiMsgDownloadEvent)results[0]; - multi.Chains.AddRange((IEnumerable?)result.Chains ?? Array.Empty()); + var @event = MultiMsgDownloadEvent.Create(chain.Uid ?? "", multi.ResId); + var results = await Collection.Business.SendEvent(@event); + if (results.Count != 0) + { + var result = (MultiMsgDownloadEvent)results[0]; + multi.Chains.AddRange((IEnumerable?)result.Chains ?? Array.Empty()); + } + + break; } - } - - if (chain.HasTypeOf()) - { - var record = chain.GetEntity(); - if (record?.MsgInfo == null) return; - - string uid = (chain.IsGroup - ? await Collection.Business.CachingLogic.ResolveUid(chain.GroupUin, chain.FriendUin) - : chain.Uid) ?? ""; - - var @event = chain.IsGroup - ? RecordGroupDownloadEvent.Create(chain.GroupUin ?? 0, record.MsgInfo) - : RecordDownloadEvent.Create(uid, record.MsgInfo); - - var results = await Collection.Business.SendEvent(@event); - if (results.Count != 0) + case RecordEntity { MsgInfo: not null } record: { - var result = (RecordDownloadEvent)results[0]; - record.AudioUrl = result.AudioUrl; + var @event = chain.IsGroup + ? RecordGroupDownloadEvent.Create(chain.GroupUin ?? 0, record.MsgInfo) + : RecordDownloadEvent.Create(chain.Uid ?? string.Empty, record.MsgInfo); + + var results = await Collection.Business.SendEvent(@event); + if (results.Count != 0) + { + var result = (RecordDownloadEvent)results[0]; + record.AudioUrl = result.AudioUrl; + } + + break; } - } - - if (chain.HasTypeOf()) - { - var video = chain.GetEntity(); - if (video?.VideoUuid == null) return; - - string uid = (chain.IsGroup - ? await Collection.Business.CachingLogic.ResolveUid(chain.GroupUin, chain.FriendUin) - : chain.Uid) ?? ""; - var @event = VideoDownloadEvent.Create(video.VideoUuid, uid, video.FilePath, "", "",chain.IsGroup); - var results = await Collection.Business.SendEvent(@event); - if (results.Count != 0) + case VideoEntity { VideoUuid: not null } video: { - var result = (VideoDownloadEvent)results[0]; - video.VideoUrl = result.AudioUrl; + string uid = (chain.IsGroup + ? await Collection.Business.CachingLogic.ResolveUid(chain.GroupUin, chain.FriendUin) + : chain.Uid) ?? ""; + var @event = VideoDownloadEvent.Create(video.VideoUuid, uid, video.FilePath, "", "",chain.IsGroup); + var results = await Collection.Business.SendEvent(@event); + if (results.Count != 0) + { + var result = (VideoDownloadEvent)results[0]; + video.VideoUrl = result.AudioUrl; + } + + break; } - } - - foreach (var mention in chain.OfType()) - { - if (chain is { IsGroup: true, GroupUin: not null }) + case MentionEntity mention when chain is { IsGroup: true, GroupUin: not null }: { var members = await Collection.Business.CachingLogic.GetCachedMembers(chain.GroupUin.Value, false); - var member = members.FirstOrDefault(x => x.Uin == mention.Uin)?.MemberCard; + string? member = members.FirstOrDefault(x => x.Uin == mention.Uin)?.MemberCard; if (member != null) mention.Name = $"@{member}"; + + break; } - else + case MentionEntity mention when chain is { IsGroup: false }: { var friends = await Collection.Business.CachingLogic.GetCachedFriends(false); - var friend = friends.FirstOrDefault(x => x.Uin == mention.Uin)?.Nickname; + string? friend = friends.FirstOrDefault(x => x.Uin == mention.Uin)?.Nickname; if (friend != null) mention.Name = $"@{friend}"; + + break; + } + case ImageEntity image when !image.ImageUrl.Contains("&rkey=") && image.MsgInfo is not null: + { + var @event = chain.IsGroup + ? ImageGroupDownloadEvent.Create(chain.GroupUin ?? 0, image.MsgInfo) + : ImageDownloadEvent.Create(chain.Uid ?? string.Empty, image.MsgInfo); + + var results = await Collection.Business.SendEvent(@event); + if (results.Count != 0) + { + var result = (ImageDownloadEvent)results[0]; + image.ImageUrl = result.ImageUrl; + } + + break; } } } diff --git a/Lagrange.Core/Internal/Event/Message/ImageDownloadEvent.cs b/Lagrange.Core/Internal/Event/Message/ImageDownloadEvent.cs new file mode 100644 index 000000000..1c1b91991 --- /dev/null +++ b/Lagrange.Core/Internal/Event/Message/ImageDownloadEvent.cs @@ -0,0 +1,29 @@ +using Lagrange.Core.Internal.Packets.Service.Oidb.Common; + +namespace Lagrange.Core.Internal.Event.Message; + +#pragma warning disable CS8618 + +internal class ImageDownloadEvent : ProtocolEvent +{ + public string SelfUid { get; } + + public IndexNode Node { get; } + + public string ImageUrl { get; } + + protected ImageDownloadEvent(string selfUid, MsgInfo info) : base(true) + { + SelfUid = selfUid; + Node = info.MsgInfoBody[0].Index; + } + + protected ImageDownloadEvent(int resultCode, string imageUrl) : base(resultCode) + { + ImageUrl = imageUrl; + } + + public static ImageDownloadEvent Create(string selfUid, MsgInfo info) => new(selfUid, info); + + public static ImageDownloadEvent Result(int resultCode, string url) => new(resultCode, url); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Event/Message/ImageGroupDownloadEvent.cs b/Lagrange.Core/Internal/Event/Message/ImageGroupDownloadEvent.cs new file mode 100644 index 000000000..fa185d76e --- /dev/null +++ b/Lagrange.Core/Internal/Event/Message/ImageGroupDownloadEvent.cs @@ -0,0 +1,19 @@ +using Lagrange.Core.Internal.Packets.Service.Oidb.Common; + +namespace Lagrange.Core.Internal.Event.Message; + +internal class ImageGroupDownloadEvent : ImageDownloadEvent +{ + public uint GroupUin { get; } + + private ImageGroupDownloadEvent(uint groupUin, MsgInfo info) : base("", info) + { + GroupUin = groupUin; + } + + private ImageGroupDownloadEvent(int resultCode, string imageUrl) : base(resultCode, imageUrl) { } + + public new static ImageGroupDownloadEvent Create(uint groupUin, MsgInfo info) => new(groupUin, info); + + public new static ImageGroupDownloadEvent Result(int resultCode, string url) => new(resultCode, url); +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Service/Message/ImageDownloadService.cs b/Lagrange.Core/Internal/Service/Message/ImageDownloadService.cs new file mode 100644 index 000000000..88c18bf27 --- /dev/null +++ b/Lagrange.Core/Internal/Service/Message/ImageDownloadService.cs @@ -0,0 +1,72 @@ +using Lagrange.Core.Common; +using Lagrange.Core.Internal.Event; +using Lagrange.Core.Internal.Event.Message; +using Lagrange.Core.Internal.Packets.Service.Oidb; +using Lagrange.Core.Internal.Packets.Service.Oidb.Common; +using Lagrange.Core.Utility.Binary; +using Lagrange.Core.Utility.Extension; +using ProtoBuf; + +namespace Lagrange.Core.Internal.Service.Message; + +[EventSubscribe(typeof(ImageDownloadEvent))] +[Service("OidbSvcTrpcTcp.0x11c5_200")] +internal class ImageDownloadService : BaseService +{ + protected override bool Build(ImageDownloadEvent input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, + out BinaryPacket output, out List? extraPackets) + { + var packet = new OidbSvcTrpcTcpBase(new NTV2RichMediaReq + { + ReqHead = new MultiMediaReqHead + { + Common = new CommonHead + { + RequestId = 1, + Command = 200 + }, + Scene = new SceneInfo + { + RequestType = 2, + BusinessType = 1, + SceneType = 1, + C2C = new C2CUserInfo + { + AccountType = 2, + TargetUid = input.SelfUid + } + }, + Client = new ClientMeta { AgentType = 2 } + }, + Download = new DownloadReq + { + Node = input.Node, + Download = new DownloadExt + { + Video = new VideoDownloadExt + { + BusiType = 0, + SceneType = 0 + } + } + } + }, 0x11c5, 200, false, true); + + output = packet.Serialize(); + extraPackets = null; + + return true; + } + + protected override bool Parse(byte[] input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, + out ImageDownloadEvent output, out List? extraEvents) + { + var payload = Serializer.Deserialize>(input.AsSpan()); + var body = payload.Body.Download; + string url = $"https://{body.Info.Domain}{body.Info.UrlPath}{body.RKeyParam}"; + + output = ImageDownloadEvent.Result((int)payload.ErrorCode, url); + extraEvents = null; + return true; + } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Service/Message/ImageGroupDownloadService.cs b/Lagrange.Core/Internal/Service/Message/ImageGroupDownloadService.cs new file mode 100644 index 000000000..78dfe8b4b --- /dev/null +++ b/Lagrange.Core/Internal/Service/Message/ImageGroupDownloadService.cs @@ -0,0 +1,68 @@ +using Lagrange.Core.Common; +using Lagrange.Core.Internal.Event; +using Lagrange.Core.Internal.Event.Message; +using Lagrange.Core.Internal.Packets.Service.Oidb; +using Lagrange.Core.Internal.Packets.Service.Oidb.Common; +using Lagrange.Core.Utility.Binary; +using Lagrange.Core.Utility.Extension; +using ProtoBuf; + +namespace Lagrange.Core.Internal.Service.Message; + +[EventSubscribe(typeof(ImageGroupDownloadEvent))] +[Service("OidbSvcTrpcTcp.0x11c4_200")] +internal class ImageGroupDownloadService : BaseService +{ + protected override bool Build(ImageGroupDownloadEvent input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, + out BinaryPacket output, out List? extraPackets) + { + var packet = new OidbSvcTrpcTcpBase(new NTV2RichMediaReq + { + ReqHead = new MultiMediaReqHead + { + Common = new CommonHead + { + RequestId = 1, + Command = 200 + }, + Scene = new SceneInfo + { + RequestType = 2, + BusinessType = 1, + SceneType = 2, + Group = new GroupInfo { GroupUin = input.GroupUin } + }, + Client = new ClientMeta { AgentType = 2 } + }, + Download = new DownloadReq + { + Node = input.Node, + Download = new DownloadExt + { + Video = new VideoDownloadExt + { + BusiType = 0, + SceneType = 0 + } + } + } + }, 0x11c4, 200, false, true); + + output = packet.Serialize(); + extraPackets = null; + + return true; + } + + protected override bool Parse(byte[] input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device, + out ImageGroupDownloadEvent output, out List? extraEvents) + { + var payload = Serializer.Deserialize>(input.AsSpan()); + var body = payload.Body.Download; + string url = $"https://{body.Info.Domain}{body.Info.UrlPath}{body.RKeyParam}"; + + output = ImageGroupDownloadEvent.Result((int)payload.ErrorCode, url); + extraEvents = null; + return true; + } +} \ No newline at end of file diff --git a/Lagrange.Core/Internal/Service/Message/RecordGroupDownloadService.cs b/Lagrange.Core/Internal/Service/Message/RecordGroupDownloadService.cs index b3e5b7c51..64a77ac2f 100644 --- a/Lagrange.Core/Internal/Service/Message/RecordGroupDownloadService.cs +++ b/Lagrange.Core/Internal/Service/Message/RecordGroupDownloadService.cs @@ -6,7 +6,6 @@ using Lagrange.Core.Utility.Binary; using Lagrange.Core.Utility.Extension; using ProtoBuf; -using FileInfo = Lagrange.Core.Internal.Packets.Service.Oidb.Common.FileInfo; namespace Lagrange.Core.Internal.Service.Message; diff --git a/Lagrange.Core/Message/Entity/ImageEntity.cs b/Lagrange.Core/Message/Entity/ImageEntity.cs index af777c04d..697bf1f01 100644 --- a/Lagrange.Core/Message/Entity/ImageEntity.cs +++ b/Lagrange.Core/Message/Entity/ImageEntity.cs @@ -112,7 +112,8 @@ IEnumerable IMessageEntity.PackElement() PictureSize = new Vector2(info.Width, info.Height), FilePath = info.FileName, ImageSize = info.FileSize, - ImageUrl = url + ImageUrl = url, + MsgInfo = extra }; }