Skip to content

Commit

Permalink
[OneBot] Fixed deserialization of CQ Code of send_msg
Browse files Browse the repository at this point in the history
  • Loading branch information
Linwenxuan authored and Linwenxuan committed Feb 13, 2024
1 parent f5ffc79 commit a53a101
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 12 deletions.
40 changes: 29 additions & 11 deletions Lagrange.OneBot/Core/Operation/Message/MessageCommon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,25 @@
using Lagrange.OneBot.Core.Entity.Message;
using Lagrange.OneBot.Message;
using LiteDB;
using Microsoft.Extensions.Logging;
using JsonSerializer = System.Text.Json.JsonSerializer;

namespace Lagrange.OneBot.Core.Operation.Message;

public partial class MessageCommon
{
private readonly ILogger<MessageCommon> _logger;

private readonly Dictionary<string, SegmentBase> _typeToSegment;

public MessageCommon(LiteDatabase database)
public MessageCommon(LiteDatabase database, ILogger<MessageCommon> logger)
{
_logger = logger;
_typeToSegment = new Dictionary<string, SegmentBase>();

foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
{
var attribute = type.GetCustomAttribute<SegmentSubscriberAttribute>();
if (attribute != null)
if (type.GetCustomAttribute<SegmentSubscriberAttribute>() is { } attribute)
{
var instance = (SegmentBase)type.CreateInstance(false);
instance.Database = database;
Expand Down Expand Up @@ -51,12 +54,20 @@ public MessageBuilder ParseChain(OneBotMessageSimple message)
return builder;
}

public static MessageBuilder ParseChain(OneBotMessageText message)
public MessageBuilder ParseChain(OneBotMessageText message)
{
var builder = message.MessageType == "private"
? MessageBuilder.Friend(message.UserId ?? 0)
: MessageBuilder.Group(message.GroupId ?? 0);
builder.Text(message.Messages);

if (message.AutoEscape == true)
{
builder.Text(message.Messages);
}
else
{
BuildMessages(builder, message.Messages);
}

return builder;
}
Expand Down Expand Up @@ -152,8 +163,9 @@ private void BuildMessages(MessageBuilder builder, string message)
var pair = capture.Value.Split('=', 2);
if (pair.Length == 2) data[pair[0]] = UnescapeCQ(pair[1]);
}
var cast = (SegmentBase)JsonSerializer.SerializeToElement(data).Deserialize(instance.GetType())!;
instance.Build(builder, cast);

if (JsonSerializer.SerializeToElement(data).Deserialize(instance.GetType()) is SegmentBase cast) instance.Build(builder, cast);
else Log.LogCQFailed(_logger, type, string.Empty);
}
}

Expand All @@ -166,8 +178,8 @@ private void BuildMessages(MessageBuilder builder, List<OneBotSegment> segments)
{
if (_typeToSegment.TryGetValue(segment.Type, out var instance))
{
var cast = (SegmentBase)((JsonElement)segment.Data).Deserialize(instance.GetType())!;
instance.Build(builder, cast);
if (((JsonElement)segment.Data).Deserialize(instance.GetType()) is SegmentBase cast) instance.Build(builder, cast);
else Log.LogCQFailed(_logger, segment.Type, string.Empty);
}
}
}
Expand All @@ -176,8 +188,14 @@ private void BuildMessages(MessageBuilder builder, OneBotSegment segment)
{
if (_typeToSegment.TryGetValue(segment.Type, out var instance))
{
var cast = (SegmentBase)((JsonElement)segment.Data).Deserialize(instance.GetType())!;
instance.Build(builder, cast);
if (((JsonElement)segment.Data).Deserialize(instance.GetType()) is SegmentBase cast) instance.Build(builder, cast);
else Log.LogCQFailed(_logger, segment.Type, string.Empty);
}
}

private static partial class Log
{
[LoggerMessage(EventId = 1, Level = LogLevel.Warning, Message = "Segment {type} Deserialization failed for code {code}")]
public static partial void LogCQFailed(ILogger logger, string type, string code);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public async Task<OneBotResult> HandleOperation(BotContext context, JsonObject?
{
OneBotMessage message => await context.SendMessage(common.ParseChain(message).Build()),
OneBotMessageSimple messageSimple => await context.SendMessage(common.ParseChain(messageSimple).Build()),
OneBotMessageText messageText => await context.SendMessage(MessageCommon.ParseChain(messageText).Build()),
OneBotMessageText messageText => await context.SendMessage(common.ParseChain(messageText).Build()),
_ => throw new Exception()
};

Expand Down
1 change: 1 addition & 0 deletions Lagrange.OneBot/Core/Operation/OperationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public OperationService(BotContext bot, ILogger<OperationService> logger, LiteDa
service.AddSingleton(logger);
service.AddSingleton(message);
service.AddSingleton<MessageCommon>();
service.AddLogging();

foreach (var (_, type) in _operations) service.AddScoped(type);
_service = service.BuildServiceProvider();
Expand Down

0 comments on commit a53a101

Please sign in to comment.