Skip to content
Merged
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
3 changes: 3 additions & 0 deletions Lagrange.Core/Common/Interface/OperationExt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,7 @@ public static Task<BotStranger> FetchStranger(this BotContext context, long uin)

public static Task SetGroupNotification(this BotContext context, long groupUin, ulong sequence, BotGroupNotificationType type, bool isFiltered, GroupNotificationOperate operate, string message = "") =>
context.EventContext.GetLogic<OperationLogic>().SetGroupNotification(groupUin, sequence, type, isFiltered, operate, message);

public static Task SetGroupReaction(this BotContext context, long groupUin, ulong sequence, string code, bool isAdd) =>
context.EventContext.GetLogic<OperationLogic>().SetGroupReaction(groupUin, sequence, code, isAdd);
}
21 changes: 21 additions & 0 deletions Lagrange.Core/Events/EventArgs/BotGroupReactionEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Lagrange.Core.Events.EventArgs;

public class BotGroupReactionEvent(long targetGroupUin, ulong targetSequence, long operatorUin, bool isAdd, string code, ulong currentCount) : EventBase
{
public long TargetGroupUin { get; } = targetGroupUin;

public ulong TargetSequence { get; } = targetSequence;

public long OperatorUin { get; } = operatorUin;

public bool IsAdd { get; } = isAdd;

public string Code { get; } = code;

public ulong CurrentCount { get; } = currentCount;

public override string ToEventMessage()
{
return $"{nameof(BotGroupReactionEvent)}: Target {TargetGroupUin} > {TargetSequence} Operator {OperatorUin} {(IsAdd ? "Add" : "Reduce")} {Code} Current {CurrentCount}";
}
}
30 changes: 17 additions & 13 deletions Lagrange.Core/Internal/Context/EventContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ namespace Lagrange.Core.Internal.Context;
internal class EventContext : IDisposable
{
private const string Tag = nameof(EventContext);

private readonly BotContext _context;

private readonly FrozenDictionary<Type, List<ILogic>> _events;

private readonly FrozenDictionary<Type, ILogic> _logics;
Expand All @@ -27,7 +27,7 @@ public EventContext(BotContext context)
{
var events = new Dictionary<Type, List<ILogic>>();
var logics = new Dictionary<Type, ILogic>();

foreach (var type in typeof(ILogic).Assembly.GetTypes())
{
if (type.HasImplemented<ILogic>() && Activator.CreateInstance(type, context) is ILogic instance)
Expand All @@ -39,30 +39,30 @@ public EventContext(BotContext context)
list = [];
events.Add(@event.EventType, list);
}

list.Add(instance);
}

logics[type] = instance;
}
}

_context = context;
_events = events.ToFrozenDictionary();
_logics = logics.ToFrozenDictionary();
}

public async ValueTask<T> SendEvent<T>(ProtocolEvent @event) where T : ProtocolEvent
{
try
{
await HandleOutgoingEvent(@event);
var (frame, attribute) = await _context.ServiceContext.Resolve(@event);
var (frame, attribute) = await _context.ServiceContext.Resolve(@event);
if (frame.Sequence == 0) throw new LagrangeException("The sequence number is 0 for the SSOFrame");

var @return = await _context.PacketContext.SendPacket(frame, attribute);
var resolved = await _context.ServiceContext.Resolve(@return);

if (resolved is T result)
{
await HandleIncomingEvent(result);
Expand All @@ -76,7 +76,7 @@ public async ValueTask<T> SendEvent<T>(ProtocolEvent @event) where T : ProtocolE
throw new LagrangeException("An error occurred while sending the event", e);
}
}

private async ValueTask HandleIncomingEvent(ProtocolEvent @event)
{
if (_events.TryGetValue(@event.GetType(), out var logics))
Expand Down Expand Up @@ -112,7 +112,7 @@ private async ValueTask HandleOutgoingEvent(ProtocolEvent @event)
}
}
}

public async ValueTask HandleOutgoingEvent(EventBase @event)
{
if (_events.TryGetValue(@event.GetType(), out var logics))
Expand Down Expand Up @@ -142,8 +142,12 @@ public async Task HandleServerPacket(SsoPacket packet)
{
_context.LogWarning(Tag, "Service not found for command: {0}", e, e.Command);
}
catch (Exception e)
{
_context.LogError(Tag, "Handle {0} server packet failed", e, packet.Command);
}
}

public T GetLogic<T>() where T : ILogic => (T)_logics[typeof(T)];

public void Dispose()
Expand Down
12 changes: 6 additions & 6 deletions Lagrange.Core/Internal/Context/PacketContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public ValueTask<SsoPacket> SendPacket(SsoPacket packet, ServiceAttribute option
Task.Run(async () => // Schedule the task to the ThreadPool
{
ReadOnlyMemory<byte> frame;

switch (options.RequestType)
{
case RequestType.D2Auth:
Expand Down Expand Up @@ -72,18 +72,18 @@ public ValueTask<SsoPacket> SendPacket(SsoPacket packet, ServiceAttribute option
throw new InvalidOperationException($"Unknown RequestType: {options.RequestType}");
}
}

await _context.SocketContext.Send(frame);
});

return new ValueTask<SsoPacket>(tcs, 0);
}

public void DispatchPacket(ReadOnlySpan<byte> buffer)
{
var service = _servicePacker.Parse(buffer);
var sso = _ssoPacker.Parse(service);

if (_pendingTasks.TryRemove(sso.Sequence, out var tcs))
{
if (sso is { RetCode: not 0, Extra: var extra })
Expand All @@ -98,7 +98,7 @@ public void DispatchPacket(ReadOnlySpan<byte> buffer)
}
else
{
_ = _context.EventContext.HandleServerPacket(sso);
Task.Run(() => _context.EventContext.HandleServerPacket(sso));
}
}
}
}
15 changes: 15 additions & 0 deletions Lagrange.Core/Internal/Events/System/AddGroupReactionEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Lagrange.Core.Internal.Events.System;

internal class AddGroupReactionEventReq(long groupUin, ulong sequence, string code) : ProtocolEvent
{
public long GroupUin { get; } = groupUin;

public ulong Sequence { get; } = sequence;

public string Code { get; } = code;
}

internal class AddGroupReactionEventResp : ProtocolEvent
{
public static readonly AddGroupReactionEventResp Default = new();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Lagrange.Core.Internal.Events.System;

internal class ReduceGroupReactionEventReq(long groupUin, ulong sequence, string code) : ProtocolEvent
{
public long GroupUin { get; } = groupUin;

public ulong Sequence { get; } = sequence;

public string Code { get; } = code;
}

internal class ReduceGroupReactionEventResp : ProtocolEvent
{
public static readonly ReduceGroupReactionEventResp Default = new();
}
10 changes: 10 additions & 0 deletions Lagrange.Core/Internal/Logic/OperationLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -274,4 +274,14 @@ await context.EventContext.SendEvent<SetGroupNotificationEventResp>(
);
}
}

public async Task SetGroupReaction(long groupUin, ulong sequence, string code, bool isAdd)
{
if (isAdd) await context.EventContext.SendEvent<AddGroupReactionEventResp>(
new AddGroupReactionEventReq(groupUin, sequence, code)
);
else await context.EventContext.SendEvent<ReduceGroupReactionEventResp>(
new ReduceGroupReactionEventReq(groupUin, sequence, code)
);
}
}
53 changes: 45 additions & 8 deletions Lagrange.Core/Internal/Logic/PushLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public async ValueTask Incoming(ProtocolEvent e)
case Type.TempMessage:
{
var message = await context.EventContext.GetLogic<MessagingLogic>().Parse(messageEvent.MsgPush.CommonMessage);
if (message.Entities[0] is LightAppEntity {AppName: "com.tencent.qun.invite"} || message.Entities[0] is LightAppEntity {AppName: "com.tencent.tuwen.lua"})
if (message.Entities[0] is LightAppEntity { AppName: "com.tencent.qun.invite" } || message.Entities[0] is LightAppEntity { AppName: "com.tencent.tuwen.lua" })
{
var app = (LightAppEntity)message.Entities[0];
using var document = JsonDocument.Parse(app.Payload);
Expand Down Expand Up @@ -152,8 +152,8 @@ public async ValueTask Incoming(ProtocolEvent e)
var pkgType210 = (Event0x210SubType)messageEvent.MsgPush.CommonMessage.ContentHead.SubType;
switch (pkgType210)
{
case Event0x210SubType.FriendRequestNotice
when messageEvent.MsgPush.CommonMessage.MessageBody.MsgContent is { } content:
case Event0x210SubType.FriendRequestNotice when messageEvent.MsgPush.CommonMessage.MessageBody.MsgContent is { } content:
{
var friendRequest = ProtoHelper.Deserialize<FriendRequest>(content.Span);
context.EventInvoker.PostEvent(new BotFriendRequestEvent(
friendRequest.Info!.SourceUid,
Expand All @@ -162,6 +162,12 @@ public async ValueTask Incoming(ProtocolEvent e)
friendRequest.Info.Source ?? string.Empty
));
break;
}
default:
{
context.LogWarning(nameof(PushLogic), "Unknown 0x210 sub type: {0}", null, pkgType210);
break;
}
}

break;
Expand Down Expand Up @@ -195,6 +201,40 @@ public async ValueTask Incoming(ProtocolEvent e)
}
break;
}
case Event0x2DCSubType.SubType16 when messageEvent.MsgPush.CommonMessage.MessageBody.MsgContent is { } content:
{
var reader = new BinaryPacket(content);
// group uin and 1 byte
reader.Skip(4 + 1);
var proto = reader.ReadBytes(Prefix.Int16 | Prefix.LengthOnly);
var body = ProtoHelper.Deserialize<NotifyMessageBody>(proto);

switch ((Event0x2DCSubType16SubType)body.SubType)
{
case Event0x2DCSubType16SubType.GroupReactionNotice:
{
var reaction = body.Reaction.Data.Data;

long @operator = context.CacheContext.ResolveUin(reaction.Data.OperatorUid);

context.EventInvoker.PostEvent(new BotGroupReactionEvent(
body.GroupUin,
reaction.Target.Sequence,
@operator,
reaction.Data.Type == 1,
reaction.Data.Code,
reaction.Data.CurrentCount
));
break;
}
default:
{
context.LogWarning(nameof(PushLogic), "Unknown 0x2DCSub16 sub type: {0}", null, body.SubType);
break;
}
}
break;
}
default:
{
context.LogWarning(nameof(PushLogic), "Unknown 0x2DC sub type: {0}", null, pkgType);
Expand Down Expand Up @@ -244,14 +284,11 @@ private enum Event0x2DCSubType
GroupGreyTipNotice20 = 20,
}

private enum Event0x2DCSubType16Field13
private enum Event0x2DCSubType16SubType
{
GroupMemberSpecialTitleNotice = 6,
GroupNameChangeNotice = 12,
GroupTodoNotice = 23,
GroupReactionNotice = 35,
}

private enum Event0x210SubType
{
FriendRequestNotice = 35,
Expand Down
2 changes: 1 addition & 1 deletion Lagrange.Core/Internal/Packets/Notify/GroupReaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ internal partial class GroupReactionData3
{
[ProtoMember(1)] public string Code { get; set; }

[ProtoMember(3)] public uint Count { get; set; }
[ProtoMember(3)] public uint CurrentCount { get; set; }

[ProtoMember(4)] public string OperatorUid { get; set; }

Expand Down
4 changes: 2 additions & 2 deletions Lagrange.Core/Internal/Packets/Notify/NotifyMessageBody.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ namespace Lagrange.Core.Internal.Packets.Notify;
[ProtoPackable]
internal partial class NotifyMessageBody
{
[ProtoMember(1)] public uint Type { get; set; }
[ProtoMember(1)] public uint NotifyType { get; set; }

[ProtoMember(4)] public long GroupUin { get; set; }

[ProtoMember(5)] public byte[]? EventParam { get; set; }

[ProtoMember(11)] public GroupRecall Recall { get; set; }

[ProtoMember(13)] public uint? Field13 { get; set; }
[ProtoMember(13)] public uint SubType { get; set; }

[ProtoMember(21)] public string OperatorUid { get; set; }

Expand Down
20 changes: 20 additions & 0 deletions Lagrange.Core/Internal/Packets/Service/SetGroupReaction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Lagrange.Proto;

namespace Lagrange.Core.Internal.Packets.Service;

#pragma warning disable CS8618

[ProtoPackable]
public partial class SetGroupReactionRequest
{
[ProtoMember(2)] public long GroupUin { get; set; }

[ProtoMember(3)] public ulong Sequence { get; set; }

[ProtoMember(4)] public string Code { get; set; }

[ProtoMember(5)] public ulong Type { get; set; }
}

[ProtoPackable]
public partial class SetGroupReactionResponse;
31 changes: 31 additions & 0 deletions Lagrange.Core/Internal/Services/System/AddGroupReactionService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Lagrange.Core.Common;
using Lagrange.Core.Internal.Events;
using Lagrange.Core.Internal.Events.System;
using Lagrange.Core.Internal.Packets.Service;

namespace Lagrange.Core.Internal.Services.System;

[EventSubscribe<AddGroupReactionEventReq>(Protocols.All)]
[Service("OidbSvcTrpcTcp.0x9082_1")]
internal class AddGroupReactionService : OidbService<AddGroupReactionEventReq, AddGroupReactionEventResp, SetGroupReactionRequest, SetGroupReactionResponse>
{
private protected override uint Command => 0x9082;

private protected override uint Service => 1;

private protected override Task<SetGroupReactionRequest> ProcessRequest(AddGroupReactionEventReq request, BotContext context)
{
return Task.FromResult(new SetGroupReactionRequest
{
GroupUin = request.GroupUin,
Sequence = request.Sequence,
Code = request.Code,
Type = request.Code.Length <= 3 ? 1ul : 2ul
});
}

private protected override Task<AddGroupReactionEventResp> ProcessResponse(SetGroupReactionResponse response, BotContext context)
{
return Task.FromResult(AddGroupReactionEventResp.Default);
}
}
Loading
Loading