Skip to content

Commit

Permalink
[All] Feat: MessageStyle (#766)
Browse files Browse the repository at this point in the history
* [Core] Add message style

* add and remove some fields in MessageStyleExtra.cs

* en summary

* Use ulong type for BubbleId and PendantId

* [Onebot] Added MessageStyle ability to onebot (Untested)

* nya

* abaaba

* ababa

* ababa ababa

* trigger CI
  • Loading branch information
dogdie233 authored Feb 15, 2025
1 parent a057c74 commit 903dce7
Show file tree
Hide file tree
Showing 19 changed files with 297 additions and 27 deletions.
25 changes: 25 additions & 0 deletions Lagrange.Core/Common/Entity/MessageStyle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace Lagrange.Core.Common.Entity;

public class MessageStyle
{
public ulong BubbleId { get; set; }

public ulong PendantId { get; set; }

public ushort FontId { get; set; }

/// <summary>
/// Font effect id, 2000 for super large font
/// </summary>
public uint FontEffectId { get; set; }

/// <summary>
/// Whether the "font grows and shrinks" effect is enabled
/// </summary>
public bool IsCsFontEffectEnabled { get; set; }

/// <summary>
/// Custom bubble sticker/text archive id
/// </summary>
public uint BubbleDiyTextId { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using ProtoBuf;

namespace Lagrange.Core.Internal.Packets.Message.Component.Extra;

[ProtoContract]
internal class MessageStyleExtra
{
/// <summary>
/// If the user is an admin or group owner, this field value is 10315
/// </summary>
[ProtoMember(4)] public int Field4 { get; set; } = 10315;
[ProtoMember(15)] public ulong Font { get; set; }
[ProtoMember(34)] public uint FontEffectId { get; set; }

[ProtoMember(51)] public ulong VipType { get; set; } = 337;

[ProtoMember(52)] public ulong VipLevel { get; set; } = 2;

[ProtoMember(56)] public ulong VipNameplate { get; set; }

[ProtoMember(65)] public GroupMemberLevelInfo? GroupMemberLevel { get; set; }

[ProtoMember(81)] public ulong GroupHonorStyle { get; set; }

[ProtoMember(107)] public uint MessageSequence { get; set; }

[ProtoContract]
internal class GroupMemberLevelInfo
{
[ProtoMember(2)] public int Level { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Lagrange.Core.Internal.Packets.Message.Element.Implementation;
[ProtoContract]
internal partial class ElemFlags2
{
[ProtoMember(1)] public uint ColorTextId { get; set; }
[ProtoMember(1)] public ulong ColorTextId { get; set; }

[ProtoMember(2)] public ulong MsgId { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Lagrange.Core.Internal.Packets.Message.Element.Implementation;
[ProtoContract]
internal class GeneralFlags
{
[ProtoMember(1)] public int BubbleDiyTextId { get; set; }
[ProtoMember(1)] public uint BubbleDiyTextId { get; set; }

[ProtoMember(2)] public int GroupFlagNew { get; set; }

Expand Down Expand Up @@ -38,7 +38,7 @@ internal class GeneralFlags

[ProtoMember(16)] public int BubbleSubId { get; set; }

[ProtoMember(17)] public long PendantId { get; set; }
[ProtoMember(17)] public ulong PendantId { get; set; }

[ProtoMember(18)] public byte[] RpIndex { get; set; }

Expand Down
7 changes: 7 additions & 0 deletions Lagrange.Core/Message/MessageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,13 @@ public MessageBuilder GreyTip(string greyTip)
return this;
}

public MessageBuilder Style(MessageStyle? style)
{
_chain.Style = style;

return this;
}

public MessageBuilder Add(IMessageEntity entity)
{
_chain.Add(entity);
Expand Down
2 changes: 2 additions & 0 deletions Lagrange.Core/Message/MessageChain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public sealed class MessageChain : List<IMessageEntity>

public BotGroupMember? GroupMemberInfo { get; internal set; }

public MessageStyle? Style { get; internal set; }

public uint Sequence { get; } // for C2C message, it's the sequence of the message, for group message, it's the sequence of the group message

public uint ClientSequence { get; } // only for C2C message
Expand Down
68 changes: 68 additions & 0 deletions Lagrange.Core/Message/MessagePacker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ public static Internal.Packets.Message.Message Build(MessageChain chain, string

BuildAdditional(chain, message);

BuildMessageStyle(chain, message.Body);

return message;
}

Expand All @@ -97,6 +99,9 @@ public static PushMsgBody BuildFake(MessageChain chain, string selfUid)
message.Body.MsgContent = stream.ToArray();
}
}

BuildMessageStyle(chain, message.Body);

return message;
}

Expand All @@ -118,6 +123,39 @@ private static void BuildAdditional(MessageChain chain, Internal.Packets.Message
}
}

private static void BuildMessageStyle(MessageChain chain, MessageBody? messageBody)
{
if (chain.Style == null || messageBody?.RichText == null) return;

messageBody.RichText.Elems.Add(new Elem
{
ElemFlags2 = new Internal.Packets.Message.Element.Implementation.ElemFlags2
{
ColorTextId = chain.Style.BubbleId,
}
});

ulong font = chain.Style.FontId == 0
? 0x10000
: (ulong)((chain.Style.FontId >> 8) | (chain.Style.FontId << 8) & 0xFFFF) | 0x20000;
if (chain.Style.IsCsFontEffectEnabled)
font |= 1 << 24;

messageBody.RichText.Elems.Add(new Elem
{
GeneralFlags = new Internal.Packets.Message.Element.Implementation.GeneralFlags
{
BubbleDiyTextId = chain.Style.BubbleDiyTextId,
PendantId = chain.Style.PendantId,
PbReserve = new MessageStyleExtra
{
Font = font,
FontEffectId = chain.Style.FontEffectId
}.Serialize().ToArray()
}
});
}

public static MessageChain Parse(PushMsgBody message, bool isFake = false)
{
var chain = isFake ? ParseFakeChain(message) : ParseChain(message);
Expand All @@ -138,6 +176,8 @@ public static MessageChain Parse(PushMsgBody message, bool isFake = false)
}
}
}

ParseMessageStyle(chain, element);
}
}

Expand Down Expand Up @@ -172,6 +212,34 @@ public static MessageChain ParsePrivateFile(PushMsgBody message)
throw new Exception();
}

private static void ParseMessageStyle(MessageChain chain, Elem element)
{
if (element.ElemFlags2 != null)
{
chain.Style ??= new MessageStyle();
chain.Style.BubbleId = element.ElemFlags2.ColorTextId;
}

if (element.GeneralFlags == null) return;

chain.Style ??= new MessageStyle();
chain.Style.BubbleDiyTextId = element.GeneralFlags.BubbleDiyTextId;
chain.Style.PendantId = element.GeneralFlags.PendantId;

// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (element.GeneralFlags.PbReserve == null) return;

MessageStyleExtra? styleExtra;
try { styleExtra = Serializer.Deserialize<MessageStyleExtra>(element.GeneralFlags.PbReserve.AsSpan()); }
catch (Exception) { return; }

if (styleExtra == null) return;

chain.Style.FontId = (ushort)((styleExtra.Font & 0xFF00) >> 8 | (styleExtra.Font & 0x00FF) << 8);
chain.Style.FontEffectId = styleExtra.FontEffectId;
chain.Style.IsCsFontEffectEnabled = (styleExtra.Font & 0x010000) != 0;
}

private static Internal.Packets.Message.Message BuildPacketBase(MessageChain chain) => new()
{
RoutingHead = new RoutingHead
Expand Down
2 changes: 2 additions & 0 deletions Lagrange.OneBot/Core/Entity/Action/OneBotGroupMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public class OneBotGroupMessageBase
[JsonPropertyName("group_id")] public uint GroupId { get; set; }

[JsonPropertyName("auto_escape")] public bool? AutoEscape { get; set; }

[JsonPropertyName("message_style")] public OnebotMessageStyle? MessageStyle { get; set; }
}

[Serializable]
Expand Down
2 changes: 2 additions & 0 deletions Lagrange.OneBot/Core/Entity/Action/OneBotMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public class OneBotMessageBase
[JsonPropertyName("group_id")] public uint? GroupId { get; set; }

[JsonPropertyName("auto_escape")] public bool? AutoEscape { get; set; }

[JsonPropertyName("message_style")] public OnebotMessageStyle? MessageStyle { get; set; }
}

// ReSharper disable once ClassNeverInstantiated.Global
Expand Down
2 changes: 2 additions & 0 deletions Lagrange.OneBot/Core/Entity/Action/OneBotPrivateMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public class OneBotPrivateMessageBase
[JsonPropertyName("user_id")] public uint UserId { get; set; }

[JsonPropertyName("auto_escape")] public bool? AutoEscape { get; set; }

[JsonPropertyName("message_style")] public OnebotMessageStyle? MessageStyle { get; set; }
}

[Serializable]
Expand Down
12 changes: 8 additions & 4 deletions Lagrange.OneBot/Core/Entity/Message/OneBotGroupMsg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace Lagrange.OneBot.Core.Entity.Message;

[Serializable]
public class OneBotGroupMsg(uint selfId, uint groupUin, List<OneBotSegment> message, string rawMessage, BotGroupMember member, int messageId, long time) : OneBotEntityBase(selfId, "message", time)
public class OneBotGroupMsg(uint selfId, uint groupUin, List<OneBotSegment> message, string rawMessage, BotGroupMember member, int messageId, long time, OnebotMessageStyle? messageStyle) : OneBotEntityBase(selfId, "message", time)
{
[JsonPropertyName("message_type")] public string MessageType { get; set; } = "group";

Expand All @@ -22,13 +22,15 @@ public class OneBotGroupMsg(uint selfId, uint groupUin, List<OneBotSegment> mess

[JsonPropertyName("raw_message")] public string RawMessage { get; set; } = rawMessage;

[JsonPropertyName("font")] public int Font { get; set; } = 0;
[JsonPropertyName("font")] public int Font { get; set; } = messageStyle?.FontId ?? 0;

[JsonPropertyName("sender")] public OneBotGroupSender GroupSender { get; set; } = new(member.Uin, member.MemberName, member.MemberCard ?? string.Empty, (int)member.GroupLevel, member.Permission);

[JsonPropertyName("message_style")] public OnebotMessageStyle? MessageStyle { get; set; } = messageStyle;
}

[Serializable]
public class OneBotGroupStringMsg(uint selfId, uint groupUin, string message, BotGroupMember member, int messageId, long time) : OneBotEntityBase(selfId, "message", time)
public class OneBotGroupStringMsg(uint selfId, uint groupUin, string message, BotGroupMember member, int messageId, long time, OnebotMessageStyle? messageStyle) : OneBotEntityBase(selfId, "message", time)
{
[JsonPropertyName("message_type")] public string MessageType { get; set; } = "group";

Expand All @@ -46,7 +48,9 @@ public class OneBotGroupStringMsg(uint selfId, uint groupUin, string message, Bo

[JsonPropertyName("raw_message")] public string RawMessage { get; set; } = message;

[JsonPropertyName("font")] public int Font { get; set; } = 0;
[JsonPropertyName("font")] public int Font { get; set; } = messageStyle?.FontId ?? 0;

[JsonPropertyName("sender")] public OneBotGroupSender GroupSender { get; set; } = new(member.Uin, member.MemberName, member.MemberCard ?? string.Empty, (int)member.GroupLevel, member.Permission);

[JsonPropertyName("message_style")] public OnebotMessageStyle? MessageStyle { get; set; } = messageStyle;
}
4 changes: 4 additions & 0 deletions Lagrange.OneBot/Core/Entity/Message/OneBotPrivateMsg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public class OneBotPrivateMsg(uint selfId, OneBotSender groupSender, string subT
[JsonPropertyName("sender")] public OneBotSender GroupSender { get; set; } = groupSender;

[JsonPropertyName("target_id")] public uint TargetId { get; set; }

[JsonPropertyName("message_style")] public OnebotMessageStyle? MessageStyle { get; set; }
}

[Serializable]
Expand All @@ -44,4 +46,6 @@ public class OneBotPrivateStringMsg(uint selfId, OneBotSender groupSender, strin
[JsonPropertyName("sender")] public OneBotSender GroupSender { get; set; } = groupSender;

[JsonPropertyName("target_id")] public uint TargetId { get; set; }

[JsonPropertyName("message_style")] public OnebotMessageStyle? MessageStyle { get; set; }
}
2 changes: 2 additions & 0 deletions Lagrange.OneBot/Core/Entity/OneBotFakeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class OneBotFakeNodeBase

// For onebot 11 compatibility
[JsonPropertyName("nickname")] public string Nickname { set => Name = value; }

[JsonPropertyName("message_style")] public OnebotMessageStyle? MessageStyle { get; set; }
}

[Serializable]
Expand Down
31 changes: 31 additions & 0 deletions Lagrange.OneBot/Core/Entity/OnebotMessageStyle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Text.Json.Serialization;
using Lagrange.Core.Common.Entity;

namespace Lagrange.OneBot.Core.Entity;

public class OnebotMessageStyle
{
[JsonPropertyName("bubble_id")] public ulong BubbleId { get; set; }

[JsonPropertyName("pendant_id")] public ulong PendantId { get; set; }

[JsonPropertyName("font_id")] public ushort FontId { get; set; }

[JsonPropertyName("font_effect_id")] public uint FontEffectId { get; set; }

[JsonPropertyName("is_cs_font_effect_enabled")] public bool IsCsFontEffectEnabled { get; set; }

[JsonPropertyName("bubble_diy_text_id")] public uint BubbleDiyTextId { get; set; }

public OnebotMessageStyle() {}

public OnebotMessageStyle(MessageStyle style)
{
BubbleId = style.BubbleId;
PendantId = style.PendantId;
FontId = style.FontId;
FontEffectId = style.FontEffectId;
IsCsFontEffectEnabled = style.IsCsFontEffectEnabled;
BubbleDiyTextId = style.BubbleDiyTextId;
}
}
Loading

0 comments on commit 903dce7

Please sign in to comment.