Skip to content

Commit

Permalink
[Core] Implemented Group Send & Uploading for RecordEntity.cs
Browse files Browse the repository at this point in the history
  • Loading branch information
Linwenxuan04 committed Feb 25, 2024
1 parent e2feeb5 commit e742ca5
Show file tree
Hide file tree
Showing 12 changed files with 344 additions and 24 deletions.
15 changes: 11 additions & 4 deletions Lagrange.Core/Internal/Context/HighwayContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ public async Task UploadResources(MessageChain chain)
}
}

public async Task<bool> UploadSrcByStreamAsync(int commonId, Stream data, string ticket, byte[] md5, byte[]? extendInfo = null)
public async Task<bool> UploadSrcByStreamAsync(int commonId, Stream data, byte[] ticket, byte[] md5, byte[]? extendInfo = null)
{
bool success = true;
var upBlocks = new List<UpBlock>();
var uri = new Uri($"http://htdata3.qq.com:80/cgi-bin/httpconn?htcmd=0x6FF0087&uin={Collection.Keystore.Uin}");

long fileSize = data.Length;
int offset = 0;
int chunkSize = fileSize is >= 1024 and <= 1048575 ? 8192 : 1024 * 1024;
int chunkSize = fileSize is >= 1024 and <= 1024 * 1024 - 1 ? 8192 : 1024 * 1024;
int concurrent = commonId == 2 ? 1 : 8;

data.Seek(0, SeekOrigin.Begin);
Expand Down Expand Up @@ -140,6 +140,7 @@ private async Task<bool> SendUpBlockAsync(UpBlock upBlock, Uri server)
Command = "PicUp.DataUp",
Seq = upBlock.Sequence,
AppId = (uint)AppInfo.SubAppId,
DataFlag = 16,
CommandId = (uint)upBlock.CommandId,
};
var segHead = new SegHead
Expand All @@ -151,13 +152,19 @@ private async Task<bool> SendUpBlockAsync(UpBlock upBlock, Uri server)
Md5 = (await upBlock.Block.Md5Async()).UnHex(),
FileMd5 = upBlock.FileMd5,
};

var loginHead = new LoginSigHead
{
Uint32LoginSigType = 8,
BytesLoginSig = Collection.Keystore.Session.Tgt,
AppId = (uint)Collection.AppInfo.AppId
};
var highwayHead = new ReqDataHighwayHead
{
MsgBaseHead = head,
MsgSegHead = segHead,
BytesReqExtendInfo = upBlock.ExtendInfo,
Timestamp = upBlock.Timestamp,
MsgLoginSigHead = loginHead
};

bool isEnd = upBlock.Offset + (ulong)upBlock.Block.Length == upBlock.FileSize;
Expand Down Expand Up @@ -222,7 +229,7 @@ private record struct UpBlock(
uint Sequence,
ulong FileSize,
ulong Offset,
string Ticket,
byte[] Ticket,
byte[] FileMd5,
byte[] Block,
byte[]? ExtendInfo = null,
Expand Down
9 changes: 5 additions & 4 deletions Lagrange.Core/Internal/Context/Uploader/ImageUploader.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Text;
using Lagrange.Core.Internal.Event.Message;
using Lagrange.Core.Message;
using Lagrange.Core.Message.Entity;
Expand All @@ -8,8 +9,6 @@ namespace Lagrange.Core.Internal.Context.Uploader;
[HighwayUploader(typeof(ImageEntity))]
internal class ImageUploader : IHighwayUploader
{
private const string Tag = nameof(ImageUploader);

public async Task UploadPrivate(ContextCollection context, MessageChain chain, IMessageEntity entity)
{
if (entity is ImageEntity { ImageStream: not null } image)
Expand All @@ -23,7 +22,8 @@ public async Task UploadPrivate(ContextCollection context, MessageChain chain, I
var ticketResult = (ImageUploadEvent)results[0];
if (!ticketResult.IsExist)
{
bool hwSuccess = await context.Highway.UploadSrcByStreamAsync(1, image.ImageStream, ticketResult.Ticket, @event.FileMd5.UnHex());
var ticket = Encoding.UTF8.GetBytes(ticketResult.Ticket);
bool hwSuccess = await context.Highway.UploadSrcByStreamAsync(1, image.ImageStream, ticket, @event.FileMd5.UnHex());
if (!hwSuccess) throw new Exception();
}

Expand All @@ -44,7 +44,8 @@ public async Task UploadGroup(ContextCollection context, MessageChain chain, IMe
var ticketResult = (ImageGroupUploadEvent)results[0];
if (!ticketResult.IsExist)
{
bool hwSuccess = await context.Highway.UploadSrcByStreamAsync(2, image.ImageStream, ticketResult.Ticket, @event.FileMd5.UnHex());
var ticket = Encoding.UTF8.GetBytes(ticketResult.Ticket);
bool hwSuccess = await context.Highway.UploadSrcByStreamAsync(1, image.ImageStream, ticket, @event.FileMd5.UnHex());
if (!hwSuccess) throw new Exception();
}

Expand Down
57 changes: 53 additions & 4 deletions Lagrange.Core/Internal/Context/Uploader/PttUploader.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,69 @@
using Lagrange.Core.Internal.Event.Message;
using Lagrange.Core.Internal.Event.System;
using Lagrange.Core.Internal.Packets.Service.Highway;
using Lagrange.Core.Internal.Packets.Service.Oidb.Common;
using Lagrange.Core.Message;
using Lagrange.Core.Message.Entity;
using Lagrange.Core.Utility.Extension;

namespace Lagrange.Core.Internal.Context.Uploader;

[HighwayUploader(typeof(RecordEntity))]
internal class PttUploader : IHighwayUploader
{
private const string Tag = nameof(PttUploader);

public Task UploadPrivate(ContextCollection context, MessageChain chain, IMessageEntity entity)
{
throw new NotImplementedException();
}

public Task UploadGroup(ContextCollection context, MessageChain chain, IMessageEntity entity)
public async Task UploadGroup(ContextCollection context, MessageChain chain, IMessageEntity entity)
{
throw new NotImplementedException();
if (entity is RecordEntity { AudioStream: not null } record)
{
var uploadEvent = RecordUploadEvent.Create(record, chain.GroupUin);
var uploadResult = await context.Business.SendEvent(uploadEvent);
var metaResult = (RecordUploadEvent)uploadResult[0];

var hwUrlEvent = HighwayUrlEvent.Create();
var highwayUrlResult = await context.Business.SendEvent(hwUrlEvent);
var ticketResult = (HighwayUrlEvent)highwayUrlResult[0];

var index = metaResult.MsgInfo.MsgInfoBody[0].Index;
var extend = new NTV2RichMediaHighwayExt
{
FileUuid = index.FileUuid,
UKey = metaResult.UKey,
Network = Convert(metaResult.Network),
MsgInfoBody = metaResult.MsgInfo.MsgInfoBody,
BlockSize = 1024 * 1024,
Hash = new NTHighwayHash { FileSha1 = index.Info.FileSha1.UnHex() }
};
var extStream = extend.Serialize();

bool hwSuccess = await context.Highway.UploadSrcByStreamAsync(1008, record.AudioStream, ticketResult.SigSession, index.Info.FileHash.UnHex(), extStream.ToArray());
if (!hwSuccess) throw new Exception();

record.MsgInfo = metaResult.MsgInfo; // directly constructed by Tencent's BDH Server
record.Compat = metaResult.Compat; // for legacy QQ
}
}

private static NTHighwayNetwork Convert(List<IPv4> ipv4s) => new()
{
IPv4s = ipv4s.Select(x => new NTHighwayIPv4
{
Domain = new NTHighwayDomain
{
IsEnable = true,
IP = ConvertIP(x.OutIP)
},
Port = x.OutPort
}).ToList()
};

private static string ConvertIP(uint raw)
{
var ip = BitConverter.GetBytes(raw);
return $"{ip[0]}.{ip[1]}.{ip[2]}.{ip[3]}";
}
}
42 changes: 42 additions & 0 deletions Lagrange.Core/Internal/Event/Message/RecordUploadEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Lagrange.Core.Internal.Packets.Message.Component;
using Lagrange.Core.Internal.Packets.Service.Oidb.Common;
using Lagrange.Core.Message.Entity;

#pragma warning disable CS8618

namespace Lagrange.Core.Internal.Event.Message;

internal class RecordUploadEvent : ProtocolEvent
{
public RecordEntity Entity { get; }

public uint? GroupUin { get; }

public string UKey { get; }

public MsgInfo MsgInfo { get; }

public List<IPv4> Network { get; }

public RichText Compat { get; }

private RecordUploadEvent(RecordEntity entity, uint? groupUin) : base(true)
{
Entity = entity;
GroupUin = groupUin;
}

private RecordUploadEvent(int resultCode, string uKey, MsgInfo msgInfo, List<IPv4> network, RichText compat) : base(resultCode)
{
UKey = uKey;
MsgInfo = msgInfo;
Network = network;
Compat = compat;
}

public static RecordUploadEvent Create(RecordEntity entity, uint? groupUin)
=> new(entity, groupUin);

public static RecordUploadEvent Result(int resultCode, string uKey, MsgInfo msgInfo, List<IPv4> network, RichText compat)
=> new(resultCode, uKey, msgInfo, network, compat);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal class DataHighwayHead

[ProtoMember(6)] public uint AppId { get; set; }

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

[ProtoMember(8)] public uint CommandId { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ internal class LoginSigHead
[ProtoMember(1)] public uint Uint32LoginSigType { get; set; }

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

[ProtoMember(3)] public uint AppId { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using Lagrange.Core.Internal.Packets.Service.Oidb.Common;
using ProtoBuf;

namespace Lagrange.Core.Internal.Packets.Service.Highway;

//Resharper Disable InconsistentNaming
#pragma warning disable CS8618

[ProtoContract]
internal class NTV2RichMediaHighwayExt
{
[ProtoMember(1)] public string FileUuid { get; set; }

[ProtoMember(2)] public string UKey { get; set; }

[ProtoMember(5)] public NTHighwayNetwork Network { get; set; }

[ProtoMember(6)] public List<MsgInfoBody> MsgInfoBody { get; set; }

[ProtoMember(10)] public uint BlockSize { get; set; }

[ProtoMember(11)] public NTHighwayHash Hash { get; set; }
}

[ProtoContract]
internal class NTHighwayHash
{
[ProtoMember(1)] public byte[] FileSha1 { get; set; }
}

[ProtoContract]
internal class NTHighwayNetwork
{
[ProtoMember(1)] public List<NTHighwayIPv4> IPv4s { get; set; }
}


[ProtoContract]
internal class NTHighwayIPv4
{
[ProtoMember(1)] public NTHighwayDomain Domain { get; set; }

[ProtoMember(2)] public uint Port { get; set; }
}

[ProtoContract]
internal class NTHighwayDomain
{
[ProtoMember(1)] public bool IsEnable { get; set; } // true

[ProtoMember(2)] public string IP { get; set; }
}
2 changes: 1 addition & 1 deletion Lagrange.Core/Internal/Packets/Service/Highway/SegHead.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal class SegHead

[ProtoMember(5)] public uint RetCode { get; set; }

[ProtoMember(6)] public string ServiceTicket { get; set; } = string.Empty;
[ProtoMember(6)] public byte[] ServiceTicket { get; set; } = Array.Empty<byte>();

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

Expand Down
Loading

0 comments on commit e742ca5

Please sign in to comment.