Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[All] Friend Group #442

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Lagrange.Core/Common/Entity/BotFriend.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ internal BotFriend()
Nickname = string.Empty;
Remarks = string.Empty;
PersonalSign = string.Empty;
GroupId = 0;
GroupName = string.Empty;
}

internal BotFriend(uint uin,string uid, string nickname, string remarks, string personalSign)
internal BotFriend(uint uin,string uid, string nickname, string remarks, string personalSign, uint groupId, string groupName)
{
Uin = uin;
Uid = uid;
Nickname = nickname;
Remarks = remarks;
PersonalSign = personalSign;
GroupId = groupId;
GroupName = groupName;
}

public uint Uin { get; set; }
Expand All @@ -33,5 +37,9 @@ internal BotFriend(uint uin,string uid, string nickname, string remarks, string

public string PersonalSign { get; set; }

public uint GroupId { get; }

public string GroupName { get; set; }

public string Avatar => $"https://q1.qlogo.cn/g?b=qq&nk={Uin}&s=640";
}
12 changes: 12 additions & 0 deletions Lagrange.Core/Internal/Packets/Service/Oidb/Generics/OidbGroup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using ProtoBuf;
#pragma warning disable CS8618

namespace Lagrange.Core.Internal.Packets.Service.Oidb.Generics;

[ProtoContract]
internal class OidbGroup
{
[ProtoMember(1)] public uint GroupId { get; set; }

[ProtoMember(2)] public string GroupName { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ namespace Lagrange.Core.Internal.Packets.Service.Oidb.Response;
internal class OidbSvcTrpcTcp0xFD4_1Response
{
[ProtoMember(2)] public OidbSvcTrpcTcp0xFD4_1ResponseUin? Next { get; set; }

[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; }

[ProtoMember(102)] public List<OidbGroup> Groups { get; set; }
}

[ProtoContract]
Expand Down
37 changes: 24 additions & 13 deletions Lagrange.Core/Internal/Service/System/FetchFriendsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Lagrange.Core.Internal.Service.System;
internal class FetchFriendsService : BaseService<FetchFriendsEvent>
{
private const int MaxFriendCount = 300;

protected override bool Build(FetchFriendsEvent input, BotKeystore keystore, BotAppInfo appInfo, BotDeviceInfo device,
out BinaryPacket output, out List<BinaryPacket>? extraPackets)
{
Expand All @@ -32,14 +32,14 @@ protected override bool Build(FetchFriendsEvent input, BotKeystore keystore, Bot
});

if (input.NextUin != null) packet.Body.NextUin = new OidbSvcTrpcTcp0xFD4_1Uin { Uin = input.NextUin.Value };

/*
* OidbNumber里面的东西代表你想要拿到的Property,这些Property将会在返回的数据里面的Preserve的Field,
* 102:个性签名
* 103:备注
* 20002:昵称
*/

output = packet.Serialize();
extraPackets = null;
return true;
Expand All @@ -50,23 +50,34 @@ protected override bool Parse(Span<byte> input, BotKeystore keystore, BotAppInfo
{
var packet = Serializer.Deserialize<OidbSvcTrpcTcpBase<OidbSvcTrpcTcp0xFD4_1Response>>(input);

var friends = new List<BotFriend>();
foreach (var raw in packet.Body.Friends)
var groups = Group(packet.Body.Groups);
var friends = packet.Body.Friends.Select(f =>
{
var additional = raw.Additional.First(x => x.Type == 1);
var properties = Property(additional.Layer1.Properties);
friends.Add(new BotFriend(raw.Uin, raw.Uid, properties[20002], properties[103], properties[102]));
}

var properties = Property(f.Additional.First(a => a.Type == 1).Layer1.Properties);

return new BotFriend(
f.Uin,
f.Uid,
properties[20002],
properties[102],
properties[102],
f.CustomGroup,
groups[f.CustomGroup]
);
}).ToList();

output = FetchFriendsEvent.Result(0, friends, packet.Body.Next?.Uin); // 全家4完了才能想出来这种分页的逻辑
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;
return properties.ToDictionary(p => p.Code, p => p.Value);
}

private static Dictionary<uint, string> Group(List<OidbGroup> groups)
{
return groups.ToDictionary(g => g.GroupId, g => g.GroupName);
}
}
54 changes: 27 additions & 27 deletions Lagrange.Core/Message/MessagePacker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal static class MessagePacker
{
private static readonly Dictionary<Type, List<PropertyInfo>> EntityToElem;
private static readonly Dictionary<Type, IMessageEntity> Factory;

static MessagePacker()
{
EntityToElem = new Dictionary<Type, List<PropertyInfo>>();
Expand All @@ -34,7 +34,7 @@ static MessagePacker()
var assembly = Assembly.GetExecutingAssembly();
var types = assembly.GetTypeWithMultipleAttributes<MessageElementAttribute>(out var attributeArrays);
var elemType = typeof(Elem);

for (int i = 0; i < types.Count; i++)
{
var type = types[i];
Expand Down Expand Up @@ -73,12 +73,12 @@ public static Internal.Packets.Message.Message Build(MessageChain chain, string
message.Body.MsgContent = stream.ToArray();
}
}

BuildAdditional(chain, message);

return message;
}

public static PushMsgBody BuildFake(MessageChain chain, string selfUid)
{
var message = BuildFakePacketBase(chain, selfUid);
Expand All @@ -87,7 +87,7 @@ public static PushMsgBody BuildFake(MessageChain chain, string selfUid)
{
entity.SetSelfUid(selfUid);
message.Body?.RichText?.Elems.AddRange(entity.PackElement());

if (message.Body != null)
{
if (entity.PackMessageContent() is not { } content) continue;
Expand All @@ -104,34 +104,34 @@ public static PushMsgBody BuildFake(MessageChain chain, string selfUid)
private static void BuildAdditional(MessageChain chain, Internal.Packets.Message.Message message)
{
if (message.Body?.RichText == null) return;

foreach (var entity in chain)
{
switch (entity)
{
case RecordEntity { Compat: { } compat }: // Append Tag 04 -> Ptt
{
message.Body.RichText.Ptt = compat.Ptt;
message.Body.RichText.Elems.AddRange(compat.Elems);
break;
}
{
message.Body.RichText.Ptt = compat.Ptt;
message.Body.RichText.Elems.AddRange(compat.Elems);
break;
}
}
}
}

public static MessageChain Parse(PushMsgBody message, bool isFake = false)
{
var chain = isFake ? ParseFakeChain(message) : ParseChain(message);

if (message.Body?.RichText is { Elems: { } elements}) // 怎么Body还能是null的
if (message.Body?.RichText is { Elems: { } elements }) // 怎么Body还能是null的
{
foreach (var element in elements)
{
foreach (var (entityType, expectElems) in EntityToElem)
{
foreach (var expectElem in expectElems)
{
if (expectElem.GetValueByExpr(element) is not null &&
if (expectElem.GetValueByExpr(element) is not null &&
Factory[entityType].UnpackElement(element) is { } entity)
{
chain.Add(entity);
Expand All @@ -147,8 +147,8 @@ public static MessageChain Parse(PushMsgBody message, bool isFake = false)
case { } groupPtt when chain.IsGroup && groupPtt.FileId != 0: // for legacy ptt
chain.Add(new RecordEntity(groupPtt.GroupFileKey, groupPtt.FileName));
break;
case { } privatePtt when !chain.IsGroup:
if (chain.OfType<RecordEntity>().FirstOrDefault(x => x.AudioName == privatePtt.FileName) == null)
case { } privatePtt when !chain.IsGroup:
if (chain.OfType<RecordEntity>().FirstOrDefault(x => x.AudioName == privatePtt.FileName) == null)
chain.Add(new RecordEntity(privatePtt.FileUuid, privatePtt.FileName));
break;
}
Expand All @@ -159,13 +159,13 @@ public static MessageChain Parse(PushMsgBody message, bool isFake = false)
public static MessageChain ParsePrivateFile(PushMsgBody message)
{
if (message.Body?.MsgContent == null) throw new Exception();

var chain = ParseChain(message);

var extra = Serializer.Deserialize<FileExtra>(message.Body.MsgContent.AsSpan());
var file = extra.File;

if ( file is { FileSize: not null, FileName: not null, FileMd5: not null, FileUuid: not null, FileHash: not null })
if (file is { FileSize: not null, FileName: not null, FileMd5: not null, FileUuid: not null, FileHash: not null })
{
chain.Add(new FileEntity((long)file.FileSize, file.FileName, file.FileMd5, file.FileUuid, file.FileHash));
return chain;
Expand Down Expand Up @@ -243,29 +243,29 @@ public static MessageChain ParsePrivateFile(PushMsgBody message)
},
Body = new MessageBody { RichText = new RichText { Elems = new List<Elem>() } }
};

private static MessageChain ParseChain(PushMsgBody message)
{
var chain = message.ResponseHead.Grp == null
? new MessageChain(
message.ResponseHead.FromUin,
message.ResponseHead.ToUid ?? string.Empty ,
message.ResponseHead.FromUid ?? string.Empty,
message.ResponseHead.ToUid ?? string.Empty,
message.ResponseHead.FromUid ?? string.Empty,
message.ResponseHead.ToUin,
message.ContentHead.Sequence ?? 0,
message.ContentHead.NewId ?? 0,
message.ContentHead.Type == 141 ? MessageChain.MessageType.Temp : MessageChain.MessageType.Friend)

: new MessageChain(
message.ResponseHead.Grp.GroupUin,
message.ResponseHead.FromUin,
message.ResponseHead.Grp.GroupUin,
message.ResponseHead.FromUin,
message.ContentHead.Sequence ?? 0,
message.ContentHead.NewId ?? 0);

if (message.Body?.RichText?.Elems is { } elems) chain.Elements.AddRange(elems);

chain.Time = DateTimeOffset.FromUnixTimeSeconds(message.ContentHead.Timestamp ?? 0).DateTime;

return chain;
}

Expand All @@ -284,9 +284,9 @@ private static MessageChain ParseFakeChain(PushMsgBody message)
}
else
{
@base.FriendInfo = new BotFriend(0, message.ResponseHead.FromUid ?? string.Empty, message.ResponseHead.Forward?.FriendName ?? string.Empty, string.Empty, string.Empty);
@base.FriendInfo = new BotFriend(0, message.ResponseHead.FromUid ?? string.Empty, message.ResponseHead.Forward?.FriendName ?? string.Empty, string.Empty, string.Empty, 0, string.Empty);
}

return @base;
}

Expand Down
4 changes: 4 additions & 0 deletions Lagrange.OneBot/Core/Entity/OneBotFriend.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ public class OneBotFriend
[JsonPropertyName("nickname")] public string NickName { get; set; } = "";

[JsonPropertyName("remark")] public string Remark { get; set; } = "";

[JsonPropertyName("group_id")] public uint GroupId { get; set; } = 0;

[JsonPropertyName("group_name")] public string GroupName { get; set; } = "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public async Task<OneBotResult> HandleOperation(BotContext context, JsonNode? pa
{
UserId = x.Uin,
NickName = x.Nickname,
Remark = x.Remarks
Remark = x.Remarks,
GroupName = x.GroupName
}).ToArray(), 0, "ok");
}
10 changes: 5 additions & 5 deletions Lagrange.OneBot/Core/Operation/Message/MessageCommon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public MessageCommon(LiteDatabase database, ILogger<MessageCommon> logger)

public MessageBuilder ParseFakeChain(OneBotFakeNode message, uint? groupUin)
{
var builder = groupUin != null
var builder = groupUin != null
? MessageBuilder.FakeGroup((uint)groupUin, uint.Parse(message.Uin))
: MessageBuilder.Friend(uint.Parse(message.Uin));
BuildMessages(builder, message.Content);
Expand All @@ -50,17 +50,17 @@ public MessageBuilder ParseFakeChain(OneBotFakeNode message, uint? groupUin)

public MessageBuilder ParseFakeChain(OneBotFakeNodeSimple message, uint? groupUin)
{
var builder = groupUin != null
var builder = groupUin != null
? MessageBuilder.FakeGroup((uint)groupUin, uint.Parse(message.Uin))
: MessageBuilder.Friend(uint.Parse(message.Uin));
BuildMessages(builder, message.Content);

return builder;
}

public MessageBuilder ParseFakeChain(OneBotFakeNodeText message, uint? groupUin)
{
var builder = groupUin != null
var builder = groupUin != null
? MessageBuilder.FakeGroup((uint)groupUin, uint.Parse(message.Uin))
: MessageBuilder.Friend(uint.Parse(message.Uin));
BuildMessages(builder, message.Content);
Expand Down Expand Up @@ -249,7 +249,7 @@ public List<MessageChain> BuildForwardChains(BotContext context, OneBotForward f
_ => throw new Exception()
};
string uid = context.ContextCollection.Keystore.Uid ?? throw new InvalidOperationException();
chain.FriendInfo = new BotFriend(uint.Parse(element.Uin), uid, element.Name, string.Empty, string.Empty);
chain.FriendInfo = new BotFriend(uint.Parse(element.Uin), uid, element.Name, string.Empty, string.Empty, 0, string.Empty);
chains.Add(chain); // as fake is constructed, use uid from bot itself to upload image
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public async Task<OneBotResult> HandleOperation(BotContext context, JsonNode? pa
context.ContextCollection.Keystore.Uid ?? string.Empty,
context.BotName ?? string.Empty,
string.Empty,
string.Empty,
0,
string.Empty
),
GroupMemberInfo = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public async Task<OneBotResult> HandleOperation(BotContext context, JsonNode? pa
context.ContextCollection.Keystore.Uid ?? string.Empty,
context.BotName ?? string.Empty,
string.Empty,
string.Empty,
0,
string.Empty
),
GroupMemberInfo = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public async Task<OneBotResult> HandleOperation(BotContext context, JsonNode? pa
context.ContextCollection.Keystore.Uid ?? string.Empty,
context.BotName ?? string.Empty,
string.Empty,
string.Empty,
0,
string.Empty
),
GroupMemberInfo = null,
Expand Down