From ffe73cfcdab0b3dfb63fd6f0dce13cb505f450eb Mon Sep 17 00:00:00 2001 From: Linwenxuan Date: Sun, 7 Apr 2024 15:57:10 +0800 Subject: [PATCH] Implemented CacheHandler --- KonataNT/Core/BaseClient.cs | 5 +- KonataNT/Core/Handlers/CacheHandler.cs | 93 ++++++++++---- KonataNT/Core/Handlers/HighwayHandler.cs | 18 +++ KonataNT/Core/Packet/Oidb/OidbFriend.cs | 15 +++ .../Core/Packet/Oidb/OidbFriendAdditional.cs | 13 ++ KonataNT/Core/Packet/Oidb/OidbFriendLayer1.cs | 11 ++ .../Core/Packet/Oidb/OidbFriendProperty.cs | 13 ++ KonataNT/Core/Packet/Oidb/OidbNumber.cs | 9 ++ .../Core/Packet/Oidb/OidbSvcTrpcTcp0xFD4_1.cs | 33 +++++ .../Oidb/OidbSvcTrpcTcp0xFD4_1Response.cs | 18 +++ .../Core/Packet/Oidb/OidbSvcTrpcTcp0xFE5_2.cs | 119 ++++++++++++++++++ .../Oidb/OidbSvcTrpcTcp0xFE5_2Response.cs | 38 ++++++ 12 files changed, 359 insertions(+), 26 deletions(-) create mode 100644 KonataNT/Core/Handlers/HighwayHandler.cs create mode 100644 KonataNT/Core/Packet/Oidb/OidbFriend.cs create mode 100644 KonataNT/Core/Packet/Oidb/OidbFriendAdditional.cs create mode 100644 KonataNT/Core/Packet/Oidb/OidbFriendLayer1.cs create mode 100644 KonataNT/Core/Packet/Oidb/OidbFriendProperty.cs create mode 100644 KonataNT/Core/Packet/Oidb/OidbNumber.cs create mode 100644 KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFD4_1.cs create mode 100644 KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFD4_1Response.cs create mode 100644 KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFE5_2.cs create mode 100644 KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFE5_2Response.cs diff --git a/KonataNT/Core/BaseClient.cs b/KonataNT/Core/BaseClient.cs index ed543d1..fd5d38b 100644 --- a/KonataNT/Core/BaseClient.cs +++ b/KonataNT/Core/BaseClient.cs @@ -45,7 +45,9 @@ public class BaseClient : IDisposable internal MessageHandler MessageHandler { get; } - internal ILogger Logger { get; init; } + internal HighwayHandler HighwayHandler { get; } + + internal ILogger Logger { get; } internal BaseClient(BotKeystore keystore, BotConfig config) { @@ -58,6 +60,7 @@ internal BaseClient(BotKeystore keystore, BotConfig config) PacketHandler = new PacketHandler(this); CacheHandler = new CacheHandler(this); PushHandler = new PushHandler(this); + HighwayHandler = new HighwayHandler(this); MessageHandler = new MessageHandler(this); Logger = config.Logger ?? new DefaultLogger(EventEmitter); diff --git a/KonataNT/Core/Handlers/CacheHandler.cs b/KonataNT/Core/Handlers/CacheHandler.cs index 1357d87..f756af2 100644 --- a/KonataNT/Core/Handlers/CacheHandler.cs +++ b/KonataNT/Core/Handlers/CacheHandler.cs @@ -12,7 +12,6 @@ internal class CacheHandler { private readonly BaseClient _client; - /// /// Caching Uid, , , /// @@ -22,50 +21,65 @@ public CacheHandler(BaseClient client) _client.EventEmitter.OnBotGroupMessageEvent += async (_, e) => { - if (!Members.ContainsKey(e.GroupUin)) await GetMembers(e.GroupUin); + if (!_groups.ContainsKey(e.GroupUin)) await GetGroups(e.GroupUin); + if (!_members.ContainsKey(e.GroupUin)) await GetMembers(e.GroupUin); }; _client.EventEmitter.OnBotPrivateMessageEvent += async (_, e) => { - if (!Friends.ContainsKey(e.FriendUin)) await GetFriend(e.FriendUin); + if (!_friends.ContainsKey(e.FriendUin)) await GetFriend(e.FriendUin); }; } - private Dictionary Friends { get; } = new(); + private readonly Dictionary _friends = new(); - private Dictionary Groups { get; } = new(); + private readonly Dictionary _groups = new(); - private Dictionary> Members { get; } = new(); + private readonly Dictionary> _members = new(); - private Dictionary UinToUid { get; } = new(); + private readonly Dictionary _uinToUid = new(); - public string this[uint index] => UinToUid[index]; + public string this[uint index] => _uinToUid[index]; - public uint this[string index] => UinToUid.FirstOrDefault(x => x.Value == index).Key; + public uint this[string index] => _uinToUid.FirstOrDefault(x => x.Value == index).Key; public async Task GetFriend(uint uin, bool refreshCache = false) { - if (refreshCache || Friends.Count == 0) // count == 0 for initial cache + if (refreshCache || _friends.Count == 0) // count == 0 for initial cache { + var packet = new OidbSvcTrpcTcp0xFD4_1 + { + Body = + [ + new OidbSvcTrpcTcp0xFD4_1Body { Type = 1, Number = new OidbNumber { Numbers = { 103, 102, 20002 } } }, + new OidbSvcTrpcTcp0xFD4_1Body { Type = 4, Number = new OidbNumber { Numbers = { 100, 101, 102 } } } + ] + }; - } - - throw new NotImplementedException("干什么!"); - } - - public async Task GetGroup(uint groupUin, bool refreshCache = false) - { - if (refreshCache || Groups.Count == 0) // count == 0 for initial cache - { + var response = await _client.PacketHandler.SendOidb(0xfd4, 1, packet.Serialize(), false); + var payload = response.Deserialize(); + var body = payload.Body?.Deserialize(); + + if (body == null) throw new InvalidOperationException("干什么!"); + foreach (var raw in body.Friends) + { + var additional = raw.Additional.First(x => x.Type == 1); + var properties = additional.Layer1.Properties.ToDictionary(x => x.Code, x => x.Value); + _friends[raw.Uin] = new BotFriendContext((BotClient)_client, raw.Uin, raw.Uid, properties[20002], properties[103], properties[102]); + + _uinToUid[raw.Uin] = raw.Uid; + } } - throw new NotImplementedException("干什么!"); + if (_friends.TryGetValue(uin, out var friend)) return friend; + + throw new InvalidOperationException("干什么!"); } - public async Task> GetMembers(uint groupUin, bool refreshCache = false) + private async Task> GetMembers(uint groupUin, bool refreshCache = false) { - if (refreshCache || !Members.TryGetValue(groupUin, out var members)) + if (refreshCache || !_members.TryGetValue(groupUin, out var members)) { var memberList = new List(); string? token = null; @@ -105,15 +119,44 @@ public async Task> GetMembers(uint groupUin, bool refresh member.MemberName, DateTimeOffset.FromUnixTimeSeconds(member.JoinTimestamp).DateTime, DateTimeOffset.FromUnixTimeSeconds(member.LastMsgTimestamp).DateTime))); + + foreach (var context in memberList) _uinToUid[context.Uin] = context.Uid; token = body.Token; } while (token != null); - Members[groupUin] = memberList; + _members[groupUin] = memberList; } - if (Members.TryGetValue(groupUin, out members)) return members; + if (_members.TryGetValue(groupUin, out members)) return members; + + throw new InvalidOperationException("干什么!"); + } + + private async Task GetGroups(uint groupUin, bool refreshCache = false) + { + if (refreshCache || !_groups.TryGetValue(groupUin, out var group)) + { + var packet = new OidbSvcTrpcTcp0xFE5_2 + { + Config = new OidbSvcTrpcTcp0xFE5_2Config + { + Config1 = new OidbSvcTrpcTcp0xFE5_2Config1(), + Config2 = new OidbSvcTrpcTcp0xFE5_2Config2(), + Config3 = new OidbSvcTrpcTcp0xFE5_2Config3() + } + }; + + var response = await _client.PacketHandler.SendOidb(0xfe5, 2, packet.Serialize(), false); + var payload = response.Deserialize(); + var body = payload.Body?.Deserialize(); + + if (body == null) throw new InvalidOperationException("干什么!"); + foreach (var raw in body.Groups) _groups[raw.GroupUin] = new BotGroupContext((BotClient)_client, raw.GroupUin, raw.Info.GroupName, raw.Info.MemberCount, raw.Info.MemberMax); + } - throw new NotImplementedException("干什么!"); + if (_groups.TryGetValue(groupUin, out group)) return group; + + throw new InvalidOperationException("干什么!"); } } \ No newline at end of file diff --git a/KonataNT/Core/Handlers/HighwayHandler.cs b/KonataNT/Core/Handlers/HighwayHandler.cs new file mode 100644 index 0000000..c6f22f2 --- /dev/null +++ b/KonataNT/Core/Handlers/HighwayHandler.cs @@ -0,0 +1,18 @@ +using KonataNT.Message; + +namespace KonataNT.Core.Handlers; + +internal class HighwayHandler(BaseClient client) +{ + private readonly HttpClient _client = new(); + + public Task UploadResources(MessageChain chain) + { + foreach (var baseChain in chain) + { + + } + + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/KonataNT/Core/Packet/Oidb/OidbFriend.cs b/KonataNT/Core/Packet/Oidb/OidbFriend.cs new file mode 100644 index 0000000..f6eae68 --- /dev/null +++ b/KonataNT/Core/Packet/Oidb/OidbFriend.cs @@ -0,0 +1,15 @@ +using ProtoBuf; + +#pragma warning disable CS8618 + +namespace KonataNT.Core.Packet.Oidb; + +[ProtoContract] +internal class OidbFriend +{ + [ProtoMember(1)] public string Uid { get; set; } + + [ProtoMember(3)] public uint Uin { get; set; } + + [ProtoMember(10001)] public List Additional { get; set; } +} \ No newline at end of file diff --git a/KonataNT/Core/Packet/Oidb/OidbFriendAdditional.cs b/KonataNT/Core/Packet/Oidb/OidbFriendAdditional.cs new file mode 100644 index 0000000..5bdfef8 --- /dev/null +++ b/KonataNT/Core/Packet/Oidb/OidbFriendAdditional.cs @@ -0,0 +1,13 @@ +using ProtoBuf; + +namespace KonataNT.Core.Packet.Oidb; + +#pragma warning disable CS8618 + +[ProtoContract] +internal class OidbFriendAdditional +{ + [ProtoMember(1)] public uint Type { get; set; } + + [ProtoMember(2)] public OidbFriendLayer1 Layer1 { get; set; } +} \ No newline at end of file diff --git a/KonataNT/Core/Packet/Oidb/OidbFriendLayer1.cs b/KonataNT/Core/Packet/Oidb/OidbFriendLayer1.cs new file mode 100644 index 0000000..24e23c9 --- /dev/null +++ b/KonataNT/Core/Packet/Oidb/OidbFriendLayer1.cs @@ -0,0 +1,11 @@ +using ProtoBuf; + +namespace KonataNT.Core.Packet.Oidb; + +#pragma warning disable CS8618 + +[ProtoContract] +internal class OidbFriendLayer1 +{ + [ProtoMember(2)] public List Properties { get; set; } +} \ No newline at end of file diff --git a/KonataNT/Core/Packet/Oidb/OidbFriendProperty.cs b/KonataNT/Core/Packet/Oidb/OidbFriendProperty.cs new file mode 100644 index 0000000..fbcb24b --- /dev/null +++ b/KonataNT/Core/Packet/Oidb/OidbFriendProperty.cs @@ -0,0 +1,13 @@ +using ProtoBuf; + +namespace KonataNT.Core.Packet.Oidb; + +#pragma warning disable CS8618 + +[ProtoContract] +internal class OidbFriendProperty +{ + [ProtoMember(1)] public uint Code { get; set; } + + [ProtoMember(2)] public string Value { get; set; } +} \ No newline at end of file diff --git a/KonataNT/Core/Packet/Oidb/OidbNumber.cs b/KonataNT/Core/Packet/Oidb/OidbNumber.cs new file mode 100644 index 0000000..50086f7 --- /dev/null +++ b/KonataNT/Core/Packet/Oidb/OidbNumber.cs @@ -0,0 +1,9 @@ +using ProtoBuf; + +namespace KonataNT.Core.Packet.Oidb; + +[ProtoContract] +internal class OidbNumber +{ + [ProtoMember(1)] public List Numbers { get; set; } = new(); +} \ No newline at end of file diff --git a/KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFD4_1.cs b/KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFD4_1.cs new file mode 100644 index 0000000..26786b8 --- /dev/null +++ b/KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFD4_1.cs @@ -0,0 +1,33 @@ +using ProtoBuf; + +namespace KonataNT.Core.Packet.Oidb; + +#pragma warning disable CS8618 +// ReSharper disable InconsistentNaming + +/// +/// Fetch Friends List +/// +[ProtoContract] +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 Body { get; set; } + + [ProtoMember(10002)] public List 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; } +} \ No newline at end of file diff --git a/KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFD4_1Response.cs b/KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFD4_1Response.cs new file mode 100644 index 0000000..4e6d1df --- /dev/null +++ b/KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFD4_1Response.cs @@ -0,0 +1,18 @@ +using ProtoBuf; + +namespace KonataNT.Core.Packet.Oidb; + +// 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 Friends { get; set; } +} \ No newline at end of file diff --git a/KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFE5_2.cs b/KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFE5_2.cs new file mode 100644 index 0000000..e69674b --- /dev/null +++ b/KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFE5_2.cs @@ -0,0 +1,119 @@ +// Resharper disable InconsistentNaming + +using ProtoBuf; + +#pragma warning disable CS8618 + +namespace KonataNT.Core.Packet.Oidb; + +[ProtoContract] +internal class OidbSvcTrpcTcp0xFE5_2 +{ + [ProtoMember(1)] public OidbSvcTrpcTcp0xFE5_2Config Config { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0xFE5_2Config +{ + [ProtoMember(1)] public OidbSvcTrpcTcp0xFE5_2Config1 Config1 { get; set; } + + [ProtoMember(2)] public OidbSvcTrpcTcp0xFE5_2Config2 Config2 { get; set; } + + [ProtoMember(3)] public OidbSvcTrpcTcp0xFE5_2Config3 Config3 { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0xFE5_2Config1 +{ + [ProtoMember(1)] public bool GroupOwner { get; set; } = true; + + [ProtoMember(2)] public bool Field2 { get; set; } = true; + + [ProtoMember(3)] public bool MemberMax { get; set; } = true; + + [ProtoMember(4)] public bool MemberCount { get; set; } = true; + + [ProtoMember(5)] public bool GroupName { get; set; } = true; + + [ProtoMember(8)] public bool Field8 { get; set; } = true; + + [ProtoMember(9)] public bool Field9 { get; set; } = true; + + [ProtoMember(10)] public bool Field10 { get; set; } = true; + + [ProtoMember(11)] public bool Field11 { get; set; } = true; + + [ProtoMember(12)] public bool Field12 { get; set; } = true; + + [ProtoMember(13)] public bool Field13 { get; set; } = true; + + [ProtoMember(14)] public bool Field14 { get; set; } = true; + + [ProtoMember(15)] public bool Field15 { get; set; } = true; + + [ProtoMember(16)] public bool Field16 { get; set; } = true; + + [ProtoMember(17)] public bool Field17 { get; set; } = true; + + [ProtoMember(18)] public bool Field18 { get; set; } = true; + + [ProtoMember(19)] public bool Question { get; set; } = true; + + [ProtoMember(20)] public bool Field20 { get; set; } = true; + + [ProtoMember(22)] public bool Field22 { get; set; } = true; + + [ProtoMember(23)] public bool Field23 { get; set; } = true; + + [ProtoMember(24)] public bool Field24 { get; set; } = true; + + [ProtoMember(25)] public bool Field25 { get; set; } = true; + + [ProtoMember(26)] public bool Field26 { get; set; } = true; + + [ProtoMember(27)] public bool Field27 { get; set; } = true; + + [ProtoMember(28)] public bool Field28 { get; set; } = true; + + [ProtoMember(29)] public bool Field29 { get; set; } = true; + + [ProtoMember(30)] public bool Field30 { get; set; } = true; + + [ProtoMember(31)] public bool Field31 { get; set; } = true; + + [ProtoMember(32)] public bool Field32 { get; set; } = true; + + [ProtoMember(5001)] public bool Field5001 { get; set; } = true; + + [ProtoMember(5002)] public bool Field5002 { get; set; } = true; + + [ProtoMember(5003)] public bool Field5003 { get; set; } = true; +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0xFE5_2Config2 +{ + [ProtoMember(1)] public bool Field1 { get; set; } = true; + + [ProtoMember(2)] public bool Field2 { get; set; } = true; + + [ProtoMember(3)] public bool Field3 { get; set; } = true; + + [ProtoMember(4)] public bool Field4 { get; set; } = true; + + [ProtoMember(5)] public bool Field5 { get; set; } = true; + + [ProtoMember(6)] public bool Field6 { get; set; } = true; + + [ProtoMember(7)] public bool Field7 { get; set; } = true; + + [ProtoMember(8)] public bool Field8 { get; set; } = true; +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0xFE5_2Config3 +{ + [ProtoMember(5)] public bool Field5 { get; set; } = true; + + [ProtoMember(6)] public bool Field6 { get; set; } = true; +} \ No newline at end of file diff --git a/KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFE5_2Response.cs b/KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFE5_2Response.cs new file mode 100644 index 0000000..3f9deed --- /dev/null +++ b/KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFE5_2Response.cs @@ -0,0 +1,38 @@ +using ProtoBuf; + +namespace KonataNT.Core.Packet.Oidb; + +// Resharper disable InconsistentNaming +#pragma warning disable CS8618 + +[ProtoContract] +internal class OidbSvcTrpcTcp0xFE5_2Response +{ + [ProtoMember(2)] public List Groups { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0xFE5_2Group +{ + [ProtoMember(3)] public uint GroupUin { get; set; } + + [ProtoMember(4)] public OidbSvcTrpcTcp0xFE5_2GroupInfo Info { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0xFE5_2GroupInfo +{ + [ProtoMember(1)] public OidbSvcTrpcTcp0xFE5_2Member GroupOwner { get; set; } + + [ProtoMember(3)] public uint MemberMax { get; set; } + + [ProtoMember(4)] public uint MemberCount { get; set; } + + [ProtoMember(5)] public string GroupName { get; set; } +} + +[ProtoContract] +internal class OidbSvcTrpcTcp0xFE5_2Member +{ + [ProtoMember(2)] public string Uid { get; set; } +} \ No newline at end of file