Implemented FetchFriends

This commit is contained in:
Linwenxuan05 2023-07-07 02:06:00 +08:00
parent ddbba0005a
commit 272d64cf63
13 changed files with 242 additions and 3 deletions

View file

@ -0,0 +1,25 @@
namespace Lagrange.Core.Common.Entity;
public class BotFriend
{
internal BotFriend(uint uin,string uid, string nickname, string remarks, string personalSign)
{
Uin = uin;
Uid = uid;
Nickname = nickname;
Remarks = remarks;
PersonalSign = personalSign;
}
public uint Uin { get; }
internal string Uid { get; }
public string Nickname { get; }
public string Remarks { get; }
public string PersonalSign { get; }
public string Avatar => $"https://q1.qlogo.cn/g?b=qq&nk={Uin}&s=640";
}

View file

@ -1,7 +1,12 @@
using Lagrange.Core.Common.Entity;
namespace Lagrange.Core.Common.Interface.Api;
public static class OperationExt
{
public static Task<List<BotFriend>> FetchFriends(this BotContext bot)
=> bot.ContextCollection.Business.OperationLogic.FetchFriends();
public static Task<List<string>> FetchCookies(this BotContext bot, List<string> domains)
=> bot.ContextCollection.Business.OperationLogic.GetCookies(domains);
}

View file

@ -23,6 +23,13 @@ internal class OperationLogic : LogicBase
return events.Count != 0 ? ((FetchCookieEvent)events[0]).Cookies : new List<string>();
}
public async Task<List<BotFriend>> FetchFriends()
{
var fetchFriendsEvent = FetchFriendsEvent.Create();
var events = await Collection.Business.SendEvent(fetchFriendsEvent);
return events.Count != 0 ? ((FetchFriendsEvent)events[0]).Friends : new List<BotFriend>();
}
private static int CalculateBkn(string sKey) =>
(int)sKey.Aggregate<char, long>(5381, (current, t) => current + (current << 5) + t) & int.MaxValue;
}

View file

@ -0,0 +1,21 @@
using Lagrange.Core.Common.Entity;
namespace Lagrange.Core.Core.Event.Protocol.System;
internal class FetchFriendsEvent : ProtocolEvent
{
public List<BotFriend> Friends { get; } = new();
private FetchFriendsEvent() : base(true)
{
}
private FetchFriendsEvent(int resultCode, List<BotFriend> friends) : base(resultCode)
{
Friends = friends;
}
public static FetchFriendsEvent Create() => new();
public static FetchFriendsEvent Result(int resultCode, List<BotFriend> friends) => new(resultCode, friends);
}

View file

@ -0,0 +1,15 @@
using ProtoBuf;
#pragma warning disable CS8618
namespace Lagrange.Core.Core.Packets.Service.Oidb.Generics;
[ProtoContract]
internal class OidbFriend
{
[ProtoMember(1)] public string Uid { get; set; }
[ProtoMember(3)] public uint Uin { get; set; }
[ProtoMember(10001)] public OidbFriendAdditional Additional { get; set; }
}

View file

@ -0,0 +1,13 @@
using ProtoBuf;
namespace Lagrange.Core.Core.Packets.Service.Oidb.Generics;
#pragma warning disable CS8618
[ProtoContract]
internal class OidbFriendAdditional
{
[ProtoMember(1)] public uint Type { get; set; }
[ProtoMember(2)] public OidbFriendLayer1 Layer1 { get; set; }
}

View file

@ -0,0 +1,9 @@
using ProtoBuf;
namespace Lagrange.Core.Core.Packets.Service.Oidb.Generics;
[ProtoContract]
internal class OidbFriendLayer1
{
[ProtoMember(2)] public List<OidbFriendProperty> Properties { get; set; }
}

View file

@ -0,0 +1,13 @@
using ProtoBuf;
namespace Lagrange.Core.Core.Packets.Service.Oidb.Generics;
#pragma warning disable CS8618
[ProtoContract]
internal class OidbFriendProperty
{
[ProtoMember(1)] public uint Code { get; set; }
[ProtoMember(2)] public string Value { get; set; }
}

View file

@ -0,0 +1,9 @@
using ProtoBuf;
namespace Lagrange.Core.Core.Packets.Service.Oidb.Generics;
[ProtoContract]
internal class OidbNumber
{
[ProtoMember(1)] public List<uint> Numbers { get; set; } = new();
}

View file

@ -0,0 +1,35 @@
using Lagrange.Core.Core.Packets.Service.Oidb.Generics;
using ProtoBuf;
namespace Lagrange.Core.Core.Packets.Service.Oidb.Request;
#pragma warning disable CS8618
// ReSharper disable InconsistentNaming
/// <summary>
/// Fetch Friends List
/// </summary>
[ProtoContract]
[OidbSvcTrpcTcp(0xfd4, 1)]
internal class OidbSvcTrpcTcp0xFD4_1
{
[ProtoMember(2)] public uint Field2 { get; set; } = 300;
[ProtoMember(4)] public uint Field4 { get; set; } = 0;
[ProtoMember(6)] public uint Field6 { get; set; } = 1;
[ProtoMember(10001)] public List<OidbSvcTrpcTcp0xFD4_1Body> Body { get; set; }
[ProtoMember(10002)] public List<uint> Field10002 { get; set; } = new() { 13578, 13579, 13573, 13572, 13568 };
[ProtoMember(10003)] public uint Field10003 { get; set; } = 4051;
}
[ProtoContract]
internal class OidbSvcTrpcTcp0xFD4_1Body
{
[ProtoMember(1)] public uint Type { get; set; }
[ProtoMember(2)] public OidbNumber Number { get; set; }
}

View file

@ -0,0 +1,19 @@
using Lagrange.Core.Core.Packets.Service.Oidb.Generics;
using ProtoBuf;
namespace Lagrange.Core.Core.Packets.Service.Oidb.Resopnse;
// ReSharper disable InconsistentNaming
#pragma warning disable CS8618
[ProtoContract]
internal class OidbSvcTrpcTcp0xFD4_1Response
{
[ProtoMember(3)] public uint DisplayFriendCount { get; set; }
[ProtoMember(6)] public uint Timestamp { get; set; }
[ProtoMember(7)] public uint SelfUin { get; set; }
[ProtoMember(101)] public List<OidbFriend> Friends { get; set; }
}

View file

@ -0,0 +1,71 @@
using Lagrange.Core.Common;
using Lagrange.Core.Common.Entity;
using Lagrange.Core.Core.Event.Protocol;
using Lagrange.Core.Core.Event.Protocol.System;
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.Packets.Service.Oidb.Resopnse;
using Lagrange.Core.Core.Service.Abstraction;
using Lagrange.Core.Utility.Binary;
using ProtoBuf;
namespace Lagrange.Core.Core.Service.System;
[EventSubscribe(typeof(FetchFriendsEvent))]
[Service("OidbSvcTrpcTcp.0xfd4_1")]
internal class FetchFriendsService : BaseService<FetchFriendsEvent>
{
protected override bool Build(FetchFriendsEvent input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device,
out BinaryPacket output, out List<BinaryPacket>? extraPackets)
{
var packet = new OidbSvcTrpcTcpBase<OidbSvcTrpcTcp0xFD4_1>(new OidbSvcTrpcTcp0xFD4_1
{
Body = new List<OidbSvcTrpcTcp0xFD4_1Body>
{
new() { Type = 1, Number = new OidbNumber { Numbers = { 103, 102, 20002 } } },
new() { Type = 4, Number = new OidbNumber { Numbers = { 100, 101, 102 } } }
}
});
/*
* OidbNumber里面的东西代表你想要拿到的PropertyProperty将会在返回的数据里面的Preserve的Field
* 102
* 103
* 20002
*/
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 FetchFriendsEvent output, out List<ProtocolEvent>? extraEvents)
{
var payload = input.Payload.ReadBytes(BinaryPacket.Prefix.Uint32 | BinaryPacket.Prefix.WithPrefix);
var packet = Serializer.Deserialize<OidbSvcTrpcTcpResponse<OidbSvcTrpcTcp0xFD4_1Response>>(payload.AsSpan());
var friends = new List<BotFriend>();
foreach (var raw in packet.Body.Friends)
{
var properties = Property(raw.Additional.Layer1.Properties);
friends.Add(new BotFriend(raw.Uin, raw.Uid, properties[20002], properties[103], properties[102]));
}
output = FetchFriendsEvent.Result(0, friends);
extraEvents = null;
return true;
}
private static Dictionary<uint, string> Property(List<OidbFriendProperty> properties)
{
var dict = new Dictionary<uint, string>(properties.Capacity);
foreach (var property in properties) dict[property.Code] = property.Value;
return dict;
}
}

View file

@ -29,9 +29,6 @@ internal class SsoAliveService : BaseService<SsoAliveEvent>
protected override bool Parse(SsoPacket input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device,
out SsoAliveEvent output, out List<ProtocolEvent>? extraEvents)
{
var payload = input.Payload.ReadBytes(BinaryPacket.Prefix.Uint32 | BinaryPacket.Prefix.WithPrefix);
Console.WriteLine(payload.Hex());
output = SsoAliveEvent.Result();
extraEvents = null;
return true;