Skip to content

Commit

Permalink
Implemented CacheHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
Linwenxuan04 committed Apr 7, 2024
1 parent 8791d25 commit ffe73cf
Show file tree
Hide file tree
Showing 12 changed files with 359 additions and 26 deletions.
5 changes: 4 additions & 1 deletion KonataNT/Core/BaseClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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);
Expand Down
93 changes: 68 additions & 25 deletions KonataNT/Core/Handlers/CacheHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ internal class CacheHandler
{
private readonly BaseClient _client;


/// <summary>
/// Caching Uid, <see cref="BotFriendContext"/>, <see cref="BotGroupContext"/>, <see cref="BotMemberContext"/>
/// </summary>
Expand All @@ -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<uint, BotFriendContext> Friends { get; } = new();
private readonly Dictionary<uint, BotFriendContext> _friends = new();

private Dictionary<uint, BotGroupContext> Groups { get; } = new();
private readonly Dictionary<uint, BotGroupContext> _groups = new();

private Dictionary<uint, List<BotMemberContext>> Members { get; } = new();
private readonly Dictionary<uint, List<BotMemberContext>> _members = new();

private Dictionary<uint, string> UinToUid { get; } = new();
private readonly Dictionary<uint, string> _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<BotFriendContext> 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<BotGroupContext> 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<OidbSvcBase>();
var body = payload.Body?.Deserialize<OidbSvcTrpcTcp0xFD4_1Response>();

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<List<BotMemberContext>> GetMembers(uint groupUin, bool refreshCache = false)
private async Task<List<BotMemberContext>> 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<BotMemberContext>();
string? token = null;
Expand Down Expand Up @@ -105,15 +119,44 @@ public async Task<List<BotMemberContext>> 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<BotGroupContext> 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<OidbSvcBase>();
var body = payload.Body?.Deserialize<OidbSvcTrpcTcp0xFE5_2Response>();

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("干什么!");
}
}
18 changes: 18 additions & 0 deletions KonataNT/Core/Handlers/HighwayHandler.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
15 changes: 15 additions & 0 deletions KonataNT/Core/Packet/Oidb/OidbFriend.cs
Original file line number Diff line number Diff line change
@@ -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<OidbFriendAdditional> Additional { get; set; }
}
13 changes: 13 additions & 0 deletions KonataNT/Core/Packet/Oidb/OidbFriendAdditional.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
11 changes: 11 additions & 0 deletions KonataNT/Core/Packet/Oidb/OidbFriendLayer1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using ProtoBuf;

namespace KonataNT.Core.Packet.Oidb;

#pragma warning disable CS8618

[ProtoContract]
internal class OidbFriendLayer1
{
[ProtoMember(2)] public List<OidbFriendProperty> Properties { get; set; }
}
13 changes: 13 additions & 0 deletions KonataNT/Core/Packet/Oidb/OidbFriendProperty.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
9 changes: 9 additions & 0 deletions KonataNT/Core/Packet/Oidb/OidbNumber.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using ProtoBuf;

namespace KonataNT.Core.Packet.Oidb;

[ProtoContract]
internal class OidbNumber
{
[ProtoMember(1)] public List<uint> Numbers { get; set; } = new();
}
33 changes: 33 additions & 0 deletions KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFD4_1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using ProtoBuf;

namespace KonataNT.Core.Packet.Oidb;

#pragma warning disable CS8618
// ReSharper disable InconsistentNaming

/// <summary>
/// Fetch Friends List
/// </summary>
[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<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; }
}
18 changes: 18 additions & 0 deletions KonataNT/Core/Packet/Oidb/OidbSvcTrpcTcp0xFD4_1Response.cs
Original file line number Diff line number Diff line change
@@ -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<OidbFriend> Friends { get; set; }
}
Loading

0 comments on commit ffe73cf

Please sign in to comment.