Skip to content

Commit

Permalink
Get the MessageChain for the Reply through the BotContext.
Browse files Browse the repository at this point in the history
  • Loading branch information
DarkRRb committed Sep 29, 2024
1 parent 321a898 commit e3a0536
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 59 deletions.
40 changes: 19 additions & 21 deletions Lagrange.Kritor/src/Converters/MessageConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using Google.Protobuf.Collections;
using Kritor.Common;
using Lagrange.Core;
using Lagrange.Core.Message;
using Lagrange.Core.Message.Entity;
using Lagrange.Kritor.Utilities;
Expand Down Expand Up @@ -156,23 +159,23 @@ public static bool TryToForwardElement(this XmlDocument document, [NotNullWhen(t
return true;
}

public static MessageChain ToGroupChain(this RepeatedField<Element> elements, uint groupUin) {
return elements.Aggregate(
MessageBuilder.Group(groupUin),
(builder, element) => builder.AddElement(element),
(builder) => builder.Build()
);
public static async Task<MessageChain> ToGroupChainAsync(this RepeatedField<Element> elements, BotContext bot, uint groupUin, CancellationToken token) {
MessageBuilder builder = MessageBuilder.Group(groupUin);
foreach (Element element in elements) {
await builder.AddElementAsync(bot, element, token);
}
return builder.Build();
}

public static MessageChain ToFriendChain(this RepeatedField<Element> elements, uint userUin) {
return elements.Aggregate(
MessageBuilder.Friend(userUin),
(builder, element) => builder.AddElement(element),
(builder) => builder.Build()
);
public static async Task<MessageChain> ToFriendChainAsync(this RepeatedField<Element> elements, BotContext bot, uint userUin, CancellationToken token) {
MessageBuilder builder = MessageBuilder.Friend(userUin);
foreach (Element element in elements) {
await builder.AddElementAsync(bot, element, token);
}
return builder.Build();
}

public static MessageBuilder AddElement(this MessageBuilder builder, Element element) {
public static async Task<MessageBuilder> AddElementAsync(this MessageBuilder builder, BotContext bot, Element element, CancellationToken token) {
return element.Type switch {
Element.Types.ElementType.Unspecified => throw new NotSupportedException(
$"Not supported ElementType({Element.Types.ElementType.Unspecified})"
Expand All @@ -188,12 +191,7 @@ public static MessageBuilder AddElement(this MessageBuilder builder, Element ele
Element.Types.ElementType.BubbleFace => throw new NotSupportedException(
$"Not supported ElementType({Element.Types.ElementType.BubbleFace})"
),
Element.Types.ElementType.Reply => builder.Add(new ForwardEntity {
Time = DateTimeOffset.Now.DateTime,
Sequence = MessageIdUtility.GetSequence(element.Reply.MessageId),
ClientSequence = 0, // Private reply need
TargetUin = 1 // Tail at
}),
Element.Types.ElementType.Reply => builder.Forward(await bot.GetMessageByMessageIdAsync(element.Reply.MessageId, token)),
Element.Types.ElementType.Image => element.Image.DataCase switch {
ImageElement.DataOneofCase.None => throw new NotSupportedException(
$"Not supported DataOneofCase({ImageElement.DataOneofCase.None})"
Expand Down Expand Up @@ -293,8 +291,8 @@ public static MessageBuilder AddElement(this MessageBuilder builder, Element ele
Type = button.Action.Type,
Permission = new Permission {
Type = button.Action.Permission.Type,
SpecifyRoleIds = button.Action.Permission.RoleIds.ToList(),
SpecifyUserIds = button.Action.Permission.UserIds.ToList(),
SpecifyRoleIds = [.. button.Action.Permission.RoleIds],
SpecifyUserIds = [.. button.Action.Permission.UserIds],
},
UnsupportTips = button.Action.UnsupportedTips,
Data = button.Action.Data,
Expand Down
4 changes: 2 additions & 2 deletions Lagrange.Kritor/src/Converters/NoticeEventConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ public static EventStructure ToNoticeEvent(this EventBase @event) {
// NoticeId = Guid.NewGuid().ToString(),
// PrivateRecall = new PrivateRecallNotice {
// OperatorUin = recall.FriendUin,
// MessageId = MessageIdUtility.BuildPrivateMessageId(recall.FriendUin, recall.Sequence)
// MessageId = MessageIdUtility.BuildPrivateMessageId(recall.FriendUin, recall.ClientSequence)
// }
// }
// }
// },
GroupPokeEvent poke => new EventStructure {
Type = EventType.Notice,
Notice = new NoticeEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using Lagrange.Core;
using Lagrange.Core.Common.Entity;
using Lagrange.Core.Common.Interface.Api;
using Lagrange.Core.Message.Entity;
using static Kritor.Friend.FriendService;

namespace Lagrange.Kritor.Services.Kritor.Grpc.Friend;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
using Lagrange.Core;
using Lagrange.Core.Common.Entity;
using Lagrange.Core.Common.Interface.Api;
using Lagrange.Core.Message.Entity;
using static Kritor.Group.GroupService;
using MSFile = System.IO.File;

namespace Lagrange.Kritor.Services.Kritor.Grpc.Group;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,46 +16,30 @@ namespace Lagrange.Kritor.Services.Kritor.Grpc.Message;
public class KritorMessageService(BotContext bot) : MessageServiceBase {
private readonly BotContext _bot = bot;

private async Task<SendMessageResponse> SendGroupMessage(SendMessageRequest request, CancellationToken token) {
uint groupUin = uint.Parse(request.Contact.Peer);
public override async Task<SendMessageResponse> SendMessage(SendMessageRequest request, ServerCallContext context) {
uint uin = uint.Parse(request.Contact.Peer);

MessageResult result = await _bot.SendMessage(request.Elements.ToGroupChain(groupUin));
if (result.Result != 0 || result.Sequence == null) {
throw new Exception($"Send group message failed");
}

return new SendMessageResponse {
MessageId = MessageIdUtility.BuildGroupMessageId(groupUin, (ulong)result.Sequence),
MessageTime = result.Timestamp
MessageChain chain = request.Contact.Scene switch {
Scene.Unspecified => throw new NotSupportedException($"Not supported Scene({Scene.Unspecified})"),
Scene.Group => await request.Elements.ToGroupChainAsync(_bot, uin, context.CancellationToken),
Scene.Friend => await request.Elements.ToFriendChainAsync(_bot, uin, context.CancellationToken),
Scene.Guild => throw new NotSupportedException($"Not supported Scene({Scene.Guild})"),
Scene.StrangerFromGroup => throw new NotSupportedException($"Not supported Scene({Scene.StrangerFromGroup})"),
Scene.Nearby => throw new NotSupportedException($"Not supported Scene({Scene.Nearby})"),
Scene.Stranger => throw new NotSupportedException($"Not supported Scene({Scene.Stranger})"),
Scene unknown => throw new NotSupportedException($"Not supported Scene({unknown})"),
};
}

private async Task<SendMessageResponse> SendFriendMessage(SendMessageRequest request, CancellationToken token) {
uint groupUin = uint.Parse(request.Contact.Peer);

MessageResult result = await _bot.SendMessage(request.Elements.ToFriendChain(groupUin));
MessageResult result = await _bot.SendMessage(chain);
if (result.Result != 0 || result.Sequence == null) {
throw new Exception($"Send friend message failed");
throw new Exception($"({result.Result}) Send message failed");
}

return new SendMessageResponse {
MessageId = MessageIdUtility.BuildGroupMessageId(groupUin, (ulong)result.Sequence),
MessageId = MessageIdUtility.BuildGroupMessageId(uin, (ulong)result.Sequence),
MessageTime = result.Timestamp
};
}

public override Task<SendMessageResponse> SendMessage(SendMessageRequest request, ServerCallContext context) {
return request.Contact.Scene switch {
Scene.Unspecified => throw new NotSupportedException($"Not supported Scene({Scene.Unspecified})"),
Scene.Group => SendGroupMessage(request, context.CancellationToken),
Scene.Friend => SendFriendMessage(request, context.CancellationToken),
Scene.Guild => throw new NotSupportedException($"Not supported Scene({Scene.Guild})"),
Scene.StrangerFromGroup => throw new NotSupportedException($"Not supported Scene({Scene.StrangerFromGroup})"),
Scene.Nearby => throw new NotSupportedException($"Not supported Scene({Scene.Nearby})"),
Scene.Stranger => throw new NotSupportedException($"Not supported Scene({Scene.Stranger})"),
Scene unknown => throw new NotSupportedException($"Not supported Scene({unknown})"),
};
}

// TODO I'm tired. I'll do it next time.
}
29 changes: 29 additions & 0 deletions Lagrange.Kritor/src/Utilities/BotContextUtility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Lagrange.Core;
using Lagrange.Core.Common.Interface.Api;
using Lagrange.Core.Message;

namespace Lagrange.Kritor.Utilities;

public static class BotContextUtility {
public static async Task<MessageChain> GetMessageByMessageIdAsync(this BotContext bot, string id, CancellationToken token) {
uint sequence = MessageIdUtility.GetSequence(id);
uint uin = MessageIdUtility.GetUin(id);

List<MessageChain>? chains;
if (MessageIdUtility.IsGroup(id)) {
chains = await bot.GetGroupMessage(uin, sequence, sequence);
} else if (MessageIdUtility.IsGroup(id)) {
chains = await bot.GetC2cMessage(uin, sequence, sequence);
} else throw new NotSupportedException($"Not supported message id({id})");

if (chains == null || chains.Count != 1) {
throw new Exception($"Get message chain by message id({id}) failed");
}

return chains[0];
}
}
16 changes: 14 additions & 2 deletions Lagrange.Kritor/src/Utilities/MessageIdUtility.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
namespace Lagrange.Kritor.Utilities;

public static class MessageIdUtility {
public static string BuildPrivateMessageId(ulong uin, ulong sequence) {
return $"p{uin:D20}{sequence:D20}";
}

public static string BuildGroupMessageId(ulong uin, ulong sequence) {
return $"g{uin:D20}{sequence:D20}";
}

public static string BuildPrivateMessageId(ulong uin, ulong sequence) {
return $"p{uin:D20}{sequence:D20}";
public static bool IsGroup(string id) {
return id.StartsWith('g');
}

public static bool IsPrivate(string id) {
return id.StartsWith('p');
}

public static uint GetUin(string id) {
return uint.Parse(id[1..21]);
}

public static uint GetSequence(string id) {
Expand Down

0 comments on commit e3a0536

Please sign in to comment.