From b75c91c35449d8895841044e84990b7b37374382 Mon Sep 17 00:00:00 2001 From: Linwenxuan05 Date: Tue, 22 Aug 2023 22:53:02 +0800 Subject: [PATCH] Further Implemented HighwayContext.cs --- Lagrange.Core/Core/Context/HighwayContext.cs | 149 +++++++++++++++++- .../Service/Highway/DataHighwayHead.cs | 29 ++++ .../Packets/Service/Highway/LoginSigHead.cs | 11 ++ .../Service/Highway/ReqDataHighwayHead.cs | 17 ++ .../Service/Highway/RespDataHighwayHead.cs | 27 ++++ .../Core/Packets/Service/Highway/SegHead.cs | 33 ++++ .../Oidb/Request/OidbSvcTrpcTcp0x972_6.cs | 2 +- .../Action/RequestFriendSearchService.cs | 2 +- 8 files changed, 266 insertions(+), 4 deletions(-) create mode 100644 Lagrange.Core/Core/Packets/Service/Highway/DataHighwayHead.cs create mode 100644 Lagrange.Core/Core/Packets/Service/Highway/LoginSigHead.cs create mode 100644 Lagrange.Core/Core/Packets/Service/Highway/ReqDataHighwayHead.cs create mode 100644 Lagrange.Core/Core/Packets/Service/Highway/RespDataHighwayHead.cs create mode 100644 Lagrange.Core/Core/Packets/Service/Highway/SegHead.cs diff --git a/Lagrange.Core/Core/Context/HighwayContext.cs b/Lagrange.Core/Core/Context/HighwayContext.cs index 9f8dcdabd..875e4789b 100644 --- a/Lagrange.Core/Core/Context/HighwayContext.cs +++ b/Lagrange.Core/Core/Context/HighwayContext.cs @@ -2,6 +2,10 @@ using Lagrange.Core.Common; using Lagrange.Core.Core.Network; using Lagrange.Core.Core.Packets; +using Lagrange.Core.Core.Packets.Service.Highway; +using Lagrange.Core.Utility.Binary; +using Lagrange.Core.Utility.Extension; +using ProtoBuf; namespace Lagrange.Core.Core.Context; @@ -10,11 +14,152 @@ namespace Lagrange.Core.Core.Context; /// internal class HighwayContext : ContextBase { - private readonly ConcurrentDictionary> _uploadingTasks; + private readonly HttpClient _client; public HighwayContext(ContextCollection collection, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device) : base(collection, keystore, appInfo, device) { - _uploadingTasks = new ConcurrentDictionary>(); + _client = new HttpClient + { + DefaultRequestHeaders = + { + { "Accept-Encoding", "identity" }, + } + }; } + + public async Task EchoAsync(Uri uri, uint seq) + { + var head = new ReqDataHighwayHead + { + MsgBaseHead = new DataHighwayHead + { + Version = 1, // isOpenUpEnable 2 else 1 + Uin = Keystore.Uin.ToString(), + Command = "PicUp.Echo", + Seq = seq, + AppId = (uint)AppInfo.SubAppId, + DataFlag = 4096, + CommandId = 0, + LocaleId = 2052 + } + }; + + try + { + await SendPacketAsync(head, new BinaryPacket(), uri); + return true; + } + catch (Exception) + { + return false; + } + } + + public async Task UploadSrcByStream(int commonId, uint uin, byte[] upKey, BinaryPacket data, long fileSize, byte[] md5) + { + return false; + } + + private async Task SendUpBlockAsync(UpBlock upBlock, Uri server) + { + var head = new DataHighwayHead + { + Version = 1, + Uin = upBlock.Uin.ToString(), + Command = "PicUp.DataUp", + Seq = (uint)upBlock.Sequence, + RetryTimes = 0, + AppId = (uint)AppInfo.SubAppId, + DataFlag = 4096, + CommandId = (uint)upBlock.CommandId, + LocaleId = 2052 + }; + var segHead = new SegHead + { + Filesize = upBlock.FileSize, + DataOffset = upBlock.Offset, + DataLength = (uint)upBlock.Block.Length, + ServiceTicket = upBlock.UpKey, + Md5 = (await upBlock.Block.Md5Async()).UnHex(), + FileMd5 = upBlock.FileMd5, + CachePort = 0, + CacheAddr = 0 + }; + + var highwayHead = new ReqDataHighwayHead + { + MsgBaseHead = head, + MsgSegHead = segHead, + BytesReqExtendInfo = upBlock.ExtendInfo, + Timestamp = upBlock.Timestamp, + MsgLoginSigHead = upBlock.LoginSig + }; + + bool isEnd = upBlock.Offset + (ulong)upBlock.Block.Length == upBlock.FileSize; + await SendPacketAsync(highwayHead, new BinaryPacket(upBlock.Block), server, isEnd); + + return true; + } + + private Task SendPacketAsync(ReqDataHighwayHead head, BinaryPacket buffer, Uri server, bool end = true) + { + using var stream = new MemoryStream(); + Serializer.Serialize(stream, head); + + var writer = new BinaryPacket() + .WriteByte(0x28) // packet start + .WriteInt((int)stream.Length) + .WriteInt((int)buffer.Length) + .WriteBytes(stream.ToArray()) + .WritePacket(buffer) + .WriteByte(0x29); // packet end + + return SendDataAsync(writer.ToArray(), server, end); + } + + private static (RespDataHighwayHead, BinaryPacket) ParsePacket(BinaryPacket packet) + { + if (packet.ReadByte() == 0x28) + { + int headLength = packet.ReadInt(); + int bodyLength = packet.ReadInt(); + var head = Serializer.Deserialize(packet.ReadBytes(headLength).AsSpan()); + var body = packet.ReadPacket(bodyLength); + + if (packet.ReadByte() == 0x29) return (head, body); + } + + throw new InvalidOperationException("Invalid packet"); + } + + private async Task SendDataAsync(byte[] packet, Uri server, bool end) + { + var content = new ByteArrayContent(packet); + var request = new HttpRequestMessage(HttpMethod.Post, server) + { + Content = content, + Headers = + { + { "Connection" , end ? "close" : "keep-alive" }, + { "Content-Type", "application/x-www-form-urlencoded" }, + } + }; + var response = await _client.SendAsync(request); + var data = await response.Content.ReadAsByteArrayAsync(); + return new BinaryPacket(data); + } + + private record UpBlock( + int CommandId, + uint Uin, + int Sequence, + ulong FileSize, + ulong Offset, + byte[] FileMd5, + byte[] UpKey, + byte[] Block, + byte[]? ExtendInfo = null, + ulong Timestamp = 0, + LoginSigHead? LoginSig = null); } \ No newline at end of file diff --git a/Lagrange.Core/Core/Packets/Service/Highway/DataHighwayHead.cs b/Lagrange.Core/Core/Packets/Service/Highway/DataHighwayHead.cs new file mode 100644 index 000000000..3ba303eb1 --- /dev/null +++ b/Lagrange.Core/Core/Packets/Service/Highway/DataHighwayHead.cs @@ -0,0 +1,29 @@ +using ProtoBuf; + +namespace Lagrange.Core.Core.Packets.Service.Highway; + +[ProtoContract] +internal class DataHighwayHead +{ + [ProtoMember(1)] public uint Version { get; set; } + + [ProtoMember(2)] public string? Uin { get; set; } + + [ProtoMember(3)] public string? Command { get; set; } + + [ProtoMember(4)] public uint Seq { get; set; } + + [ProtoMember(5)] public uint RetryTimes { get; set; } + + [ProtoMember(6)] public uint AppId { get; set; } + + [ProtoMember(7)] public uint DataFlag { get; set; } + + [ProtoMember(8)] public uint CommandId { get; set; } + + [ProtoMember(9)] public byte[]? BuildVer { get; set; } + + [ProtoMember(10)] public uint LocaleId { get; set; } + + [ProtoMember(11)] public uint EnvId { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Core/Packets/Service/Highway/LoginSigHead.cs b/Lagrange.Core/Core/Packets/Service/Highway/LoginSigHead.cs new file mode 100644 index 000000000..f0ae2ccf3 --- /dev/null +++ b/Lagrange.Core/Core/Packets/Service/Highway/LoginSigHead.cs @@ -0,0 +1,11 @@ +using ProtoBuf; + +namespace Lagrange.Core.Core.Packets.Service.Highway; + +[ProtoContract] +internal class LoginSigHead +{ + [ProtoMember(1)] public uint Uint32LoginSigType { get; set; } + + [ProtoMember(2)] public byte[] BytesLoginSig { get; set; } = Array.Empty(); +} \ No newline at end of file diff --git a/Lagrange.Core/Core/Packets/Service/Highway/ReqDataHighwayHead.cs b/Lagrange.Core/Core/Packets/Service/Highway/ReqDataHighwayHead.cs new file mode 100644 index 000000000..59437d427 --- /dev/null +++ b/Lagrange.Core/Core/Packets/Service/Highway/ReqDataHighwayHead.cs @@ -0,0 +1,17 @@ +using ProtoBuf; + +namespace Lagrange.Core.Core.Packets.Service.Highway; + +[ProtoContract] +internal class ReqDataHighwayHead +{ + [ProtoMember(1)] public DataHighwayHead? MsgBaseHead { get; set; } + + [ProtoMember(2)] public SegHead? MsgSegHead { get; set; } + + [ProtoMember(3)] public byte[]? BytesReqExtendInfo { get; set; } + + [ProtoMember(4)] public ulong Timestamp { get; set; } + + [ProtoMember(5)] public LoginSigHead? MsgLoginSigHead { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Core/Packets/Service/Highway/RespDataHighwayHead.cs b/Lagrange.Core/Core/Packets/Service/Highway/RespDataHighwayHead.cs new file mode 100644 index 000000000..08392d3f5 --- /dev/null +++ b/Lagrange.Core/Core/Packets/Service/Highway/RespDataHighwayHead.cs @@ -0,0 +1,27 @@ +using ProtoBuf; + +namespace Lagrange.Core.Core.Packets.Service.Highway; + +[ProtoContract] +internal class RespDataHighwayHead +{ + [ProtoMember(1)] public DataHighwayHead? MsgBaseHead { get; set; } + + [ProtoMember(2)] public SegHead? MsgSegHead { get; set; } + + [ProtoMember(3)] public uint ErrorCode { get; set; } + + [ProtoMember(4)] public uint AllowRetry { get; set; } + + [ProtoMember(5)] public uint CacheCost { get; set; } + + [ProtoMember(6)] public uint HtCost { get; set; } + + [ProtoMember(7)] public byte[]? BytesRspExtendInfo { get; set; } + + [ProtoMember(8)] public ulong Timestamp { get; set; } + + [ProtoMember(9)] public ulong Range { get; set; } + + [ProtoMember(10)] public uint IsReset { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Core/Packets/Service/Highway/SegHead.cs b/Lagrange.Core/Core/Packets/Service/Highway/SegHead.cs new file mode 100644 index 000000000..98b714498 --- /dev/null +++ b/Lagrange.Core/Core/Packets/Service/Highway/SegHead.cs @@ -0,0 +1,33 @@ +using ProtoBuf; + +namespace Lagrange.Core.Core.Packets.Service.Highway; + +[ProtoContract] +internal class SegHead +{ + [ProtoMember(1)] public uint ServiceId { get; set; } + + [ProtoMember(2)] public ulong Filesize { get; set; } + + [ProtoMember(3)] public ulong DataOffset { get; set; } + + [ProtoMember(4)] public uint DataLength { get; set; } + + [ProtoMember(5)] public uint RetCode { get; set; } + + [ProtoMember(6)] public byte[] ServiceTicket { get; set; } = Array.Empty(); + + [ProtoMember(7)] public uint Flag { get; set; } + + [ProtoMember(8)] public byte[] Md5 { get; set; } = Array.Empty(); + + [ProtoMember(9)] public byte[] FileMd5 { get; set; } = Array.Empty(); + + [ProtoMember(10)] public uint CacheAddr { get; set; } + + [ProtoMember(11)] public uint QueryTimes { get; set; } + + [ProtoMember(12)] public uint UpdateCacheIp { get; set; } + + [ProtoMember(13)] public uint CachePort { get; set; } +} \ No newline at end of file diff --git a/Lagrange.Core/Core/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x972_6.cs b/Lagrange.Core/Core/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x972_6.cs index f3ff167f5..1b9b1a0a1 100644 --- a/Lagrange.Core/Core/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x972_6.cs +++ b/Lagrange.Core/Core/Packets/Service/Oidb/Request/OidbSvcTrpcTcp0x972_6.cs @@ -9,7 +9,7 @@ namespace Lagrange.Core.Core.Packets.Service.Oidb.Request; [OidbSvcTrpcTcp(0x972, 6)] internal class OidbSvcTrpcTcp0x972_6 { - [ProtoMember(1)] public uint TargetUin { get; set; } + [ProtoMember(1)] public string TargetUin { get; set; } [ProtoMember(3)] public OidbSvcTrpcTcp0x972_6Settings Settings { get; set; } } diff --git a/Lagrange.Core/Core/Service/Action/RequestFriendSearchService.cs b/Lagrange.Core/Core/Service/Action/RequestFriendSearchService.cs index 97d55c180..454aca4dd 100644 --- a/Lagrange.Core/Core/Service/Action/RequestFriendSearchService.cs +++ b/Lagrange.Core/Core/Service/Action/RequestFriendSearchService.cs @@ -20,7 +20,7 @@ protected override bool Build(RequestFriendSearchEvent input, BotKeystore keysto { var packet = new OidbSvcTrpcTcpBase(new OidbSvcTrpcTcp0x972_6 { - TargetUin = input.TargetUin, + TargetUin = input.TargetUin.ToString(), Settings = new OidbSvcTrpcTcp0x972_6Settings { Field4 = 25,