Skip to content

Commit

Permalink
Further Implemented HighwayContext.cs
Browse files Browse the repository at this point in the history
  • Loading branch information
Linwenxuan04 committed Aug 22, 2023
1 parent 0f35687 commit b75c91c
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 4 deletions.
149 changes: 147 additions & 2 deletions Lagrange.Core/Core/Context/HighwayContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -10,11 +14,152 @@ namespace Lagrange.Core.Core.Context;
/// </summary>
internal class HighwayContext : ContextBase
{
private readonly ConcurrentDictionary<uint, TaskCompletionSource<SsoPacket>> _uploadingTasks;
private readonly HttpClient _client;

public HighwayContext(ContextCollection collection, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device)
: base(collection, keystore, appInfo, device)
{
_uploadingTasks = new ConcurrentDictionary<uint, TaskCompletionSource<SsoPacket>>();
_client = new HttpClient
{
DefaultRequestHeaders =
{
{ "Accept-Encoding", "identity" },
}
};
}

public async Task<bool> 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<bool> UploadSrcByStream(int commonId, uint uin, byte[] upKey, BinaryPacket data, long fileSize, byte[] md5)

Check warning on line 59 in Lagrange.Core/Core/Context/HighwayContext.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 59 in Lagrange.Core/Core/Context/HighwayContext.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
return false;
}

private async Task<bool> 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<BinaryPacket> 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<RespDataHighwayHead>(packet.ReadBytes(headLength).AsSpan());
var body = packet.ReadPacket(bodyLength);

if (packet.ReadByte() == 0x29) return (head, body);
}

throw new InvalidOperationException("Invalid packet");
}

private async Task<BinaryPacket> 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);
}
29 changes: 29 additions & 0 deletions Lagrange.Core/Core/Packets/Service/Highway/DataHighwayHead.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
11 changes: 11 additions & 0 deletions Lagrange.Core/Core/Packets/Service/Highway/LoginSigHead.cs
Original file line number Diff line number Diff line change
@@ -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<byte>();
}
17 changes: 17 additions & 0 deletions Lagrange.Core/Core/Packets/Service/Highway/ReqDataHighwayHead.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
27 changes: 27 additions & 0 deletions Lagrange.Core/Core/Packets/Service/Highway/RespDataHighwayHead.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
33 changes: 33 additions & 0 deletions Lagrange.Core/Core/Packets/Service/Highway/SegHead.cs
Original file line number Diff line number Diff line change
@@ -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<byte>();

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

[ProtoMember(8)] public byte[] Md5 { get; set; } = Array.Empty<byte>();

[ProtoMember(9)] public byte[] FileMd5 { get; set; } = Array.Empty<byte>();

[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; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ protected override bool Build(RequestFriendSearchEvent input, BotKeystore keysto
{
var packet = new OidbSvcTrpcTcpBase<OidbSvcTrpcTcp0x972_6>(new OidbSvcTrpcTcp0x972_6
{
TargetUin = input.TargetUin,
TargetUin = input.TargetUin.ToString(),
Settings = new OidbSvcTrpcTcp0x972_6Settings
{
Field4 = 25,
Expand Down

0 comments on commit b75c91c

Please sign in to comment.