Update Current Progress
This commit is contained in:
parent
50b51875a7
commit
5df500be51
13 changed files with 244 additions and 52 deletions
|
@ -1,7 +1,6 @@
|
|||
using System.Collections.Concurrent;
|
||||
using System.Text;
|
||||
using Lagrange.Core.Common;
|
||||
using Lagrange.Core.Core.Network;
|
||||
using Lagrange.Core.Core.Packets;
|
||||
using Lagrange.Core.Core.Event.Protocol.System;
|
||||
using Lagrange.Core.Core.Packets.Service.Highway;
|
||||
using Lagrange.Core.Utility.Binary;
|
||||
using Lagrange.Core.Utility.Extension;
|
||||
|
@ -15,17 +14,21 @@ namespace Lagrange.Core.Core.Context;
|
|||
internal class HighwayContext : ContextBase
|
||||
{
|
||||
private readonly HttpClient _client;
|
||||
|
||||
private Dictionary<uint, List<Uri>>? _highwayUrls;
|
||||
private byte[]? _sigSession;
|
||||
|
||||
public HighwayContext(ContextCollection collection, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device)
|
||||
: base(collection, keystore, appInfo, device)
|
||||
{
|
||||
_client = new HttpClient
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
DefaultRequestHeaders =
|
||||
{
|
||||
{ "Accept-Encoding", "identity" },
|
||||
}
|
||||
ServerCertificateCustomValidationCallback = (_, _, _, _) => true,
|
||||
};
|
||||
|
||||
_client = new HttpClient(handler);
|
||||
_client.DefaultRequestHeaders.Add("Accept-Encoding", "identity");
|
||||
_client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2)");
|
||||
}
|
||||
|
||||
public async Task<bool> EchoAsync(Uri uri, uint seq)
|
||||
|
@ -56,9 +59,40 @@ internal class HighwayContext : ContextBase
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<bool> UploadSrcByStream(int commonId, uint uin, byte[] upKey, BinaryPacket data, long fileSize, byte[] md5)
|
||||
public async Task<bool> UploadSrcByStreamAsync(int commonId, uint uin, Stream data, byte[] md5, byte[]? extendInfo = null)
|
||||
{
|
||||
return false;
|
||||
if (_highwayUrls is null) await FetchHttpConnUri();
|
||||
|
||||
bool success = true;
|
||||
var upBlocks = new List<UpBlock>();
|
||||
var uri = _highwayUrls?[(uint)commonId][0] ?? throw new InvalidOperationException("No highway url");
|
||||
|
||||
long fileSize = data.Length;
|
||||
int sequence = 1;
|
||||
int offset = 0;
|
||||
int chunkSize = fileSize is >= 1024 and <= 1048575 ? 8192 : 1024 * 1024;
|
||||
|
||||
while (data.Position < data.Length)
|
||||
{
|
||||
var buffer = new byte[Math.Min(chunkSize, fileSize - offset)];
|
||||
int payload = await data.ReadAsync(buffer.AsMemory());
|
||||
var reqBody = new UpBlock(commonId, uin, Interlocked.Increment(ref sequence),
|
||||
(ulong)fileSize, (ulong)offset, md5, buffer, extendInfo,
|
||||
(ulong)DateTimeOffset.Now.ToUnixTimeMilliseconds());
|
||||
upBlocks.Add(reqBody);
|
||||
offset = (int)data.Position;
|
||||
|
||||
if (upBlocks.Count >= 32 || data.Position == data.Length)
|
||||
{
|
||||
var tasks = upBlocks.Select(x => SendUpBlockAsync(x, uri)).ToArray();
|
||||
var results = await Task.WhenAll(tasks);
|
||||
success &= results.All(x => x);
|
||||
|
||||
upBlocks.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
private async Task<bool> SendUpBlockAsync(UpBlock upBlock, Uri server)
|
||||
|
@ -69,22 +103,17 @@ internal class HighwayContext : ContextBase
|
|||
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,
|
||||
ServiceTicket = _sigSession ?? throw new InvalidOperationException("No login sig"),
|
||||
Md5 = (await upBlock.Block.Md5Async()).UnHex(),
|
||||
FileMd5 = upBlock.FileMd5,
|
||||
CachePort = 0,
|
||||
CacheAddr = 0
|
||||
};
|
||||
|
||||
var highwayHead = new ReqDataHighwayHead
|
||||
|
@ -93,13 +122,13 @@ internal class HighwayContext : ContextBase
|
|||
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);
|
||||
var payload = await SendPacketAsync(highwayHead, new BinaryPacket(upBlock.Block), server, isEnd);
|
||||
var (respHead, resp) = ParsePacket(payload);
|
||||
|
||||
return true;
|
||||
return respHead.ErrorCode == 0;
|
||||
}
|
||||
|
||||
private Task<BinaryPacket> SendPacketAsync(ReqDataHighwayHead head, BinaryPacket buffer, Uri server, bool end = true)
|
||||
|
@ -109,8 +138,8 @@ internal class HighwayContext : ContextBase
|
|||
|
||||
var writer = new BinaryPacket()
|
||||
.WriteByte(0x28) // packet start
|
||||
.WriteInt((int)stream.Length)
|
||||
.WriteInt((int)buffer.Length)
|
||||
.WriteInt((int)stream.Length, false)
|
||||
.WriteInt((int)buffer.Length, false)
|
||||
.WriteBytes(stream.ToArray())
|
||||
.WritePacket(buffer)
|
||||
.WriteByte(0x29); // packet end
|
||||
|
@ -122,8 +151,8 @@ internal class HighwayContext : ContextBase
|
|||
{
|
||||
if (packet.ReadByte() == 0x28)
|
||||
{
|
||||
int headLength = packet.ReadInt();
|
||||
int bodyLength = packet.ReadInt();
|
||||
int headLength = packet.ReadInt(false);
|
||||
int bodyLength = packet.ReadInt(false);
|
||||
var head = Serializer.Deserialize<RespDataHighwayHead>(packet.ReadBytes(headLength).AsSpan());
|
||||
var body = packet.ReadPacket(bodyLength);
|
||||
|
||||
|
@ -142,24 +171,33 @@ internal class HighwayContext : ContextBase
|
|||
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 async Task FetchHttpConnUri()
|
||||
{
|
||||
var highwayUrlEvent = HighwayUrlEvent.Create();
|
||||
var results = await Collection.Business.SendEvent(highwayUrlEvent);
|
||||
if (results.Count != 0)
|
||||
{
|
||||
var result = (HighwayUrlEvent)results[0];
|
||||
_highwayUrls = result.HighwayUrls;
|
||||
_sigSession = result.SigSession;
|
||||
}
|
||||
}
|
||||
|
||||
private record UpBlock(
|
||||
private record struct 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);
|
||||
ulong Timestamp = 0);
|
||||
}
|
|
@ -7,6 +7,7 @@ using Lagrange.Core.Message.Entity;
|
|||
using Lagrange.Core.Core.Event;
|
||||
using Lagrange.Core.Core.Event.EventArg;
|
||||
using Lagrange.Core.Core.Event.Protocol.Notify;
|
||||
using Lagrange.Core.Utility.Extension;
|
||||
|
||||
namespace Lagrange.Core.Core.Context.Logic.Implementation;
|
||||
|
||||
|
@ -83,7 +84,8 @@ internal class MessagingLogic : LogicBase
|
|||
switch (e)
|
||||
{
|
||||
case SendMessageEvent send: // resolve Uin to Uid
|
||||
await ResolveChainUid(send.Chain);
|
||||
await ResolveChainMetadata(send.Chain);
|
||||
await ResolveChainUid(send.Chain);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -144,13 +146,24 @@ internal class MessagingLogic : LogicBase
|
|||
}
|
||||
case ImageEntity image:
|
||||
{
|
||||
var imageUploadEvent = ImageUploadEvent.Create(image.ImageStream, Collection.Keystore.Uid ?? "");
|
||||
string uid = await Collection.Business.CachingLogic.ResolveUid(chain.GroupUin, chain.FriendUin) ?? throw new Exception($"Failed to resolve Uid for Uin {chain.FriendUin}");
|
||||
var imageUploadEvent = ImageUploadEvent.Create(image.ImageStream, uid);
|
||||
var results = await Collection.Business.SendEvent(imageUploadEvent);
|
||||
if (results.Count != 0)
|
||||
{
|
||||
var result = (ImageUploadEvent)results[0];
|
||||
bool hwSuccess = await Collection.Highway.UploadSrcByStreamAsync(21, Collection.Keystore.Uin, image.ImageStream, imageUploadEvent.FileMd5.UnHex());
|
||||
if (!hwSuccess)
|
||||
{
|
||||
Collection.Log.LogFatal(Tag, "Failed to upload image to highway");
|
||||
continue;
|
||||
}
|
||||
|
||||
image.CommonAdditional = result.CommonAdditional;
|
||||
image.ImageInfo = result.ImageInfo;
|
||||
|
||||
var successEvent = ImageUploadSuccessEvent.Create(uid, result.CommonAdditional);
|
||||
_ = await Collection.Business.SendEvent(successEvent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -16,11 +16,13 @@ internal class ImageUploadEvent : ProtocolEvent
|
|||
|
||||
public string FileSha1 { get; }
|
||||
|
||||
public string Ticket { get; }
|
||||
|
||||
public byte[] CommonAdditional { get; } // Field 6 in Response
|
||||
|
||||
public NotOnlineImage ImageInfo { get; } // Field 8 in Response
|
||||
|
||||
protected ImageUploadEvent(Stream stream, string targetUid) : base(true)
|
||||
private ImageUploadEvent(Stream stream, string targetUid) : base(true)
|
||||
{
|
||||
Stream = stream;
|
||||
TargetUid = targetUid;
|
||||
|
@ -29,14 +31,15 @@ internal class ImageUploadEvent : ProtocolEvent
|
|||
FileSha1 = stream.Sha1(true);
|
||||
}
|
||||
|
||||
protected ImageUploadEvent(int resultCode, byte[] commonAdditional, NotOnlineImage image) : base(resultCode)
|
||||
private ImageUploadEvent(int resultCode, string ticket, byte[] commonAdditional, NotOnlineImage image) : base(resultCode)
|
||||
{
|
||||
Ticket = ticket;
|
||||
CommonAdditional = commonAdditional;
|
||||
ImageInfo = image;
|
||||
}
|
||||
|
||||
public static ImageUploadEvent Create(Stream stream, string targetUid) => new(stream, targetUid);
|
||||
|
||||
public static ImageUploadEvent Result(int resultCode, byte[] commonAdditional, NotOnlineImage image)
|
||||
=> new(resultCode, commonAdditional, image);
|
||||
public static ImageUploadEvent Result(int resultCode, string ticket, byte[] commonAdditional, NotOnlineImage image)
|
||||
=> new(resultCode, ticket, commonAdditional, image);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using Lagrange.Core.Core.Packets.Message.Element.Implementation;
|
||||
using Lagrange.Core.Utility.Extension;
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace Lagrange.Core.Core.Event.Protocol.Message;
|
||||
|
||||
internal class ImageUploadSuccessEvent : ProtocolEvent
|
||||
{
|
||||
public string TargetUid { get; }
|
||||
|
||||
public byte[] CommonAdditional { get; } // Field 6 in Response
|
||||
|
||||
private ImageUploadSuccessEvent(string targetUid, byte[] commonAdditional) : base(true)
|
||||
{
|
||||
TargetUid = targetUid;
|
||||
CommonAdditional = commonAdditional;
|
||||
}
|
||||
|
||||
private ImageUploadSuccessEvent(int resultCode) : base(resultCode) { }
|
||||
|
||||
public static ImageUploadSuccessEvent Create(string targetUid, byte[] commonAdditional) => new(targetUid, commonAdditional);
|
||||
|
||||
public static ImageUploadSuccessEvent Result(int resultCode) => new(resultCode);
|
||||
}
|
|
@ -4,19 +4,20 @@ namespace Lagrange.Core.Core.Event.Protocol.System;
|
|||
|
||||
internal class HighwayUrlEvent : ProtocolEvent
|
||||
{
|
||||
private readonly Dictionary<uint, List<Uri>> _highwayUrls;
|
||||
|
||||
public Dictionary<uint, List<Uri>> HighwayUrls { get; }
|
||||
|
||||
public byte[] SigSession { get; }
|
||||
|
||||
private HighwayUrlEvent() : base(true) { }
|
||||
|
||||
private HighwayUrlEvent(int resultCode, Dictionary<uint, List<Uri>> highwayUrls) : base(resultCode)
|
||||
|
||||
private HighwayUrlEvent(int resultCode, byte[] sigSession, Dictionary<uint, List<Uri>> highwayUrls) : base(resultCode)
|
||||
{
|
||||
_highwayUrls = highwayUrls;
|
||||
SigSession = sigSession;
|
||||
HighwayUrls = highwayUrls;
|
||||
}
|
||||
|
||||
|
||||
public static HighwayUrlEvent Create() => new();
|
||||
|
||||
public static HighwayUrlEvent Result(int resultCode, Dictionary<uint, List<Uri>> highwayUrls)
|
||||
{
|
||||
return new HighwayUrlEvent(resultCode, highwayUrls);
|
||||
}
|
||||
|
||||
public static HighwayUrlEvent Result(int resultCode, byte[] sigSession, Dictionary<uint, List<Uri>> highwayUrls) =>
|
||||
new(resultCode, sigSession, highwayUrls);
|
||||
}
|
|
@ -9,5 +9,5 @@ namespace Lagrange.Core.Core.Packets.Message.Element.Implementation.Extra;
|
|||
[ProtoContract]
|
||||
internal class ImageExtra
|
||||
{
|
||||
|
||||
[ProtoMember(85)] public uint Field85 { get; set; } // 1
|
||||
}
|
|
@ -18,7 +18,7 @@ internal class OidbSvcTrpcTcp0x11C5_100
|
|||
[ProtoContract]
|
||||
internal class OidbSvcTrpcTcp0x11C5_100Body1
|
||||
{
|
||||
[ProtoMember(1)] public OidbTwoNumber Field1 { get; set; } // 1, 100
|
||||
[ProtoMember(1)] public OidbTwoNumber Command { get; set; } // 1, 100
|
||||
|
||||
[ProtoMember(2)] public OidbSvcTrpcTcp0x11C5_100Body1Field2 Field2 { get; set; }
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
using Lagrange.Core.Core.Packets.Service.Oidb.Generics;
|
||||
using ProtoBuf;
|
||||
|
||||
namespace Lagrange.Core.Core.Packets.Service.Oidb.Request;
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
#pragma warning disable CS8618
|
||||
|
||||
[ProtoContract]
|
||||
[OidbSvcTrpcTcp(0x11C5, 101)]
|
||||
internal class OidbSvcTrpcTcp0x11C5_101
|
||||
{
|
||||
[ProtoMember(1)] public OidbSvcTrpcTcp0x11C5_101Body1 Body1 { get; set; }
|
||||
|
||||
[ProtoMember(6)] public byte[] CommandAdditional { get; set; }
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
internal class OidbSvcTrpcTcp0x11C5_101Body1
|
||||
{
|
||||
[ProtoMember(1)] public OidbTwoNumber Command { get; set; } // 2, 101
|
||||
|
||||
[ProtoMember(2)] public OidbSvcTrpcTcp0x11C5_100Body1Field2 Field2 { get; set; }
|
||||
|
||||
[ProtoMember(3)] public OidbSvcTrpcTcp0x11C5_100Body1Field3 Field3 { get; set; }
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
internal class OidbSvcTrpcTcp0x11C5_101Body1Field2
|
||||
{
|
||||
[ProtoMember(101)] public uint Field101 { get; set; } // 2
|
||||
|
||||
[ProtoMember(102)] public uint Field102 { get; set; } // 1
|
||||
|
||||
[ProtoMember(200)] public uint Field200 { get; set; } // 1
|
||||
|
||||
[ProtoMember(201)] public OidbSvcTrpcTcp0x11C5_100Body1Field2Field201 Field201 { get; set; }
|
||||
}
|
||||
|
||||
[ProtoContract]
|
||||
internal class OidbSvcTrpcTcp0x11C5_101Body1Field2Field201
|
||||
{
|
||||
[ProtoMember(1)] public uint Type { get; set; } // 2
|
||||
|
||||
[ProtoMember(2)] public string TargetUid { get; set; }
|
||||
}
|
|
@ -39,7 +39,7 @@ internal class ImageUploadService : BaseService<ImageUploadEvent>
|
|||
{
|
||||
Body1 = new OidbSvcTrpcTcp0x11C5_100Body1
|
||||
{
|
||||
Field1 = new OidbTwoNumber { Number1 = 1, Number2 = 100 },
|
||||
Command = new OidbTwoNumber { Number1 = 1, Number2 = 100 },
|
||||
Field2 = new OidbSvcTrpcTcp0x11C5_100Body1Field2
|
||||
{
|
||||
Field101 = 2,
|
||||
|
@ -95,7 +95,7 @@ internal class ImageUploadService : BaseService<ImageUploadEvent>
|
|||
var payload = input.Payload.ReadBytes(BinaryPacket.Prefix.Uint32 | BinaryPacket.Prefix.WithPrefix);
|
||||
var packet = Serializer.Deserialize<OidbSvcTrpcTcpResponse<OidbSvcTrpcTcp0x11C5_100Response>>(payload.AsSpan());
|
||||
|
||||
output = ImageUploadEvent.Result(0, packet.Body.Data.CommonAdditional, packet.Body.Data.ImageInfo);
|
||||
output = ImageUploadEvent.Result(0, packet.Body.Data.HighwayTicket, packet.Body.Data.CommonAdditional, packet.Body.Data.ImageInfo);
|
||||
extraEvents = null;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
using Lagrange.Core.Common;
|
||||
using Lagrange.Core.Core.Event.Protocol;
|
||||
using Lagrange.Core.Core.Event.Protocol.Message;
|
||||
using Lagrange.Core.Core.Packets;
|
||||
using Lagrange.Core.Core.Packets.Service.Oidb;
|
||||
using Lagrange.Core.Core.Packets.Service.Oidb.Generics;
|
||||
using Lagrange.Core.Core.Packets.Service.Oidb.Request;
|
||||
using Lagrange.Core.Core.Service.Abstraction;
|
||||
using Lagrange.Core.Utility.Binary;
|
||||
using Lagrange.Core.Utility.Extension;
|
||||
using ProtoBuf;
|
||||
|
||||
namespace Lagrange.Core.Core.Service.Message;
|
||||
|
||||
[EventSubscribe(typeof(ImageUploadSuccessEvent))]
|
||||
[Service("OidbSvcTrpcTcp.0x11c5_101")]
|
||||
internal class ImageUploadSuccessService : BaseService<ImageUploadSuccessEvent>
|
||||
{
|
||||
protected override bool Build(ImageUploadSuccessEvent input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device,
|
||||
out BinaryPacket output, out List<BinaryPacket>? extraPackets)
|
||||
{
|
||||
var packet = new OidbSvcTrpcTcpBase<OidbSvcTrpcTcp0x11C5_101>(new OidbSvcTrpcTcp0x11C5_101
|
||||
{
|
||||
Body1 = new OidbSvcTrpcTcp0x11C5_101Body1
|
||||
{
|
||||
Command = new OidbTwoNumber { Number1 = 2, Number2 = 101 },
|
||||
Field2 = new OidbSvcTrpcTcp0x11C5_100Body1Field2
|
||||
{
|
||||
Field101 = 2,
|
||||
Field102 = 1,
|
||||
Field200 = 1,
|
||||
Field201 = new OidbSvcTrpcTcp0x11C5_100Body1Field2Field201 { Type = 2, TargetUid = input.TargetUid }
|
||||
},
|
||||
Field3 = new OidbSvcTrpcTcp0x11C5_100Body1Field3 { Type = 2 }
|
||||
},
|
||||
CommandAdditional = input.CommonAdditional
|
||||
});
|
||||
|
||||
using var stream = new MemoryStream();
|
||||
Serializer.Serialize(stream, packet);
|
||||
output = new BinaryPacket(stream);
|
||||
|
||||
extraPackets = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool Parse(SsoPacket input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device,
|
||||
out ImageUploadSuccessEvent output, out List<ProtocolEvent>? extraEvents)
|
||||
{
|
||||
var payload = input.Payload.ReadBytes(BinaryPacket.Prefix.Uint32 | BinaryPacket.Prefix.WithPrefix);
|
||||
Console.WriteLine("ImageUploadSuccessService: " + payload.Hex());
|
||||
|
||||
output = ImageUploadSuccessEvent.Result(0);
|
||||
extraEvents = null;
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -59,11 +59,11 @@ internal class HighwayUrlService : BaseService<HighwayUrlEvent>
|
|||
foreach (var serverAddr in serverInfo.ServerAddrs)
|
||||
{
|
||||
var ip = BitConverter.GetBytes(serverAddr.Ip);
|
||||
servers[type].Add(new Uri($"https://{ip[0]}.{ip[1]}.{ip[2]}.{ip[3]}:{serverAddr.Port}"));
|
||||
servers[type].Add(new Uri($"https://{ip[0]}.{ip[1]}.{ip[2]}.{ip[3]}:{serverAddr.Port}/cgi-bin/httpconn?htcmd=0x6FF0087&uin={keystore.Uin}"));
|
||||
}
|
||||
}
|
||||
|
||||
output = HighwayUrlEvent.Result(0, servers);
|
||||
output = HighwayUrlEvent.Result(0, packet.HttpConn.SigSession, servers);
|
||||
extraEvents = null;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using System.Numerics;
|
||||
using Lagrange.Core.Core.Packets.Message.Element;
|
||||
using Lagrange.Core.Core.Packets.Message.Element.Implementation;
|
||||
using Lagrange.Core.Core.Packets.Message.Element.Implementation.Extra;
|
||||
using ProtoBuf;
|
||||
|
||||
namespace Lagrange.Core.Message.Entity;
|
||||
|
||||
|
@ -44,6 +46,10 @@ public class ImageEntity : IMessageEntity
|
|||
{
|
||||
ImageStream?.Close();
|
||||
ImageStream?.Dispose();
|
||||
|
||||
var stream = new MemoryStream();
|
||||
var imageExtra = new ImageExtra { Field85 = 1 };
|
||||
Serializer.Serialize(stream, imageExtra);
|
||||
|
||||
return new Elem[]
|
||||
{
|
||||
|
@ -59,6 +65,10 @@ public class ImageEntity : IMessageEntity
|
|||
new()
|
||||
{
|
||||
NotOnlineImage = ImageInfo
|
||||
},
|
||||
new()
|
||||
{
|
||||
GeneralFlags = new GeneralFlags { PbReserve = stream.ToArray() }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ internal class MessagePacker
|
|||
{
|
||||
C2C = chain.IsGroup ? null : new C2C
|
||||
{
|
||||
Uid = chain.Uid,
|
||||
Uid = chain.FriendInfo?.Uid,
|
||||
Uin = chain.FriendUin
|
||||
},
|
||||
Grp = !chain.IsGroup ? null : new Grp // for consistency of code so inverted condition
|
||||
|
|
Loading…
Reference in a new issue