Skip to content

Commit

Permalink
Merge pull request #9 from JustAnotherID/feature/group-event
Browse files Browse the repository at this point in the history
feat: Group Invited/Join/LeaveEvent and Group Member Join/Leave Event
  • Loading branch information
Redmomn authored Apr 16, 2024
2 parents 069b85f + 12790e9 commit a0c1f94
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 9 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ PROTO_FILES := \
$(PROTO_DIR)/service/*.proto \
$(PROTO_DIR)/service/highway/*.proto \
$(PROTO_DIR)/service/oidb/*.proto \
$(PROTO_DIR)/status/*.proto \
$(PROTO_DIR)/*.proto


Expand Down
13 changes: 10 additions & 3 deletions client/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"time"

"github.com/LagrangeDev/LagrangeGo/entity"
"github.com/LagrangeDev/LagrangeGo/event"

"github.com/LagrangeDev/LagrangeGo/info"
"github.com/LagrangeDev/LagrangeGo/message"
Expand Down Expand Up @@ -56,9 +57,15 @@ type QQClient struct {
friendCache map[uint32]*entity.Friend
groupCache map[uint32]map[uint32]*entity.GroupMember

GroupMessageEvent EventHandle[*message.GroupMessage]
PrivateMessageEvent EventHandle[*message.PrivateMessage]
TempMessageEvent EventHandle[*message.TempMessage]
GroupMessageEvent EventHandle[*message.GroupMessage]
PrivateMessageEvent EventHandle[*message.PrivateMessage]
TempMessageEvent EventHandle[*message.TempMessage]
GroupInvitedEvent EventHandle[*event.GroupMemberJoinRequest]
GroupJoinEvent EventHandle[*event.GroupMemberJoined]
GroupLeaveEvent EventHandle[*event.GroupMemberQuit]
GroupMemberJoinEvent EventHandle[*event.GroupMemberJoined]
GroupMemberLeaveEvent EventHandle[*event.GroupMemberQuit]
// GroupMuteEvent EventHandle[*event.GroupMuteMember] TODO: empty implementation now
}

func (c *QQClient) SendOidbPacket(pkt *oidb.OidbPacket) error {
Expand Down
23 changes: 19 additions & 4 deletions client/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"runtime/debug"
"sync"

"github.com/LagrangeDev/LagrangeGo/event"
"github.com/LagrangeDev/LagrangeGo/message"

"github.com/LagrangeDev/LagrangeGo/utils"
Expand Down Expand Up @@ -46,13 +47,27 @@ func (handle *EventHandle[T]) dispatch(client *QQClient, event T) {

// OnEvent 事件响应,耗时操作,需提交协程处理
func OnEvent(client *QQClient, msg any) {
switch msg.(type) {
switch msg := msg.(type) {
case *message.PrivateMessage:
client.PrivateMessageEvent.dispatch(client, msg.(*message.PrivateMessage))
client.PrivateMessageEvent.dispatch(client, msg)
case *message.GroupMessage:
client.GroupMessageEvent.dispatch(client, msg.(*message.GroupMessage))
client.GroupMessageEvent.dispatch(client, msg)
case *message.TempMessage:
client.TempMessageEvent.dispatch(client, msg.(*message.TempMessage))
client.TempMessageEvent.dispatch(client, msg)
case *event.GroupMemberJoinRequest:
client.GroupInvitedEvent.dispatch(client, msg)
case *event.GroupMemberJoined:
if client.uin == msg.Uin {
client.GroupJoinEvent.dispatch(client, msg)
} else {
client.GroupMemberJoinEvent.dispatch(client, msg)
}
case *event.GroupMemberQuit:
if client.uin == msg.Uin {
client.GroupLeaveEvent.dispatch(client, msg)
} else {
client.GroupMemberLeaveEvent.dispatch(client, msg)
}
case nil:
networkLogger.Errorf("nil event msg, ignore")
default:
Expand Down
47 changes: 45 additions & 2 deletions client/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import (
"errors"
"runtime/debug"

"github.com/LagrangeDev/LagrangeGo/packets/wtlogin"
"github.com/RomiChan/protobuf/proto"

eventConverter "github.com/LagrangeDev/LagrangeGo/event"
msgConverter "github.com/LagrangeDev/LagrangeGo/message"
"github.com/LagrangeDev/LagrangeGo/packets/pb/message"
"github.com/RomiChan/protobuf/proto"
"github.com/LagrangeDev/LagrangeGo/packets/pb/status"
"github.com/LagrangeDev/LagrangeGo/packets/wtlogin"
)

var listeners = map[string]func(*QQClient, *wtlogin.SSOPacket) (any, error){
Expand Down Expand Up @@ -40,6 +42,47 @@ func decodeOlPushServicePacket(c *QQClient, pkt *wtlogin.SSOPacket) (any, error)
return msgConverter.ParseGroupMessage(&msg), nil
case 141: // temp msg
return msgConverter.ParseTempMessage(&msg), nil
case 33: // member joined
pb := status.MemberChanged{}
err := proto.Unmarshal(msg.Message.Body.MsgContent, &pb)
if err != nil {
return nil, err
}
return eventConverter.ParseMemberJoined(&msg, &pb), nil
case 34: // member exit
pb := status.MemberChanged{}
err := proto.Unmarshal(msg.Message.Body.MsgContent, &pb)
if err != nil {
return nil, err
}
return eventConverter.ParseMemberQuit(&msg, &pb), nil
case 84:
pb := status.MemberJoinRequest{}
err := proto.Unmarshal(msg.Message.Body.MsgContent, &pb)
if err != nil {
return nil, err
}
return eventConverter.ParseMemberJoinRequest(&pb), nil
case 525:
pb := status.MemberInviteRequest{}
err := proto.Unmarshal(msg.Message.Body.MsgContent, &pb)
if err != nil {
return nil, err
}
return eventConverter.ParseMemberJoinRequestFromInvite(&pb), nil
case 0x2DC: // grp event, 732
subType := msg.Message.ContentHead.SubType.Unwrap()
switch subType {
case 12: // mute
pb := map[int]any{}
err := proto.Unmarshal(msg.Message.Body.MsgContent, &pb)
if err != nil {
return nil, err
}
return eventConverter.ParseGroupMuteEvent(&pb), nil
default:
networkLogger.Warningf("Unsupported group event, subType: %v", subType)
}
default:
networkLogger.Warningf("Unsupported message type: %v", msg.Message.ContentHead.Type)
}
Expand Down
96 changes: 96 additions & 0 deletions event/group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package event

import (
"github.com/LagrangeDev/LagrangeGo/packets/pb/message"
"github.com/LagrangeDev/LagrangeGo/packets/pb/status"
)

type (
GroupEvent struct {
GroupID uint32
}

GroupMuteMember struct {
GroupEvent
OperatorUid string
TargetUid string // when TargetUid is empty, mute all members
Duration uint32
}

GroupMemberJoinRequest struct {
GroupEvent
Uid string
InvitorUid string
Answer string // 问题:(.*)答案:(.*)
}

GroupMemberJoined struct {
GroupEvent
Uin uint32
Uid string
JoinType int32
}

GroupMemberQuit struct {
GroupEvent
Uin uint32
Uid string
ExitType int32
OperatorUid string
}
)

func (gmq *GroupMemberQuit) IsKicked() bool {
return gmq.ExitType == 131
}

func ParseMemberJoinRequest(event *status.MemberJoinRequest) *GroupMemberJoinRequest {
return &GroupMemberJoinRequest{
GroupEvent: GroupEvent{
GroupID: event.GroupID,
},
Uid: event.Uid,
Answer: event.RequestField.Unwrap(),
}
}
func ParseMemberJoinRequestFromInvite(event *status.MemberInviteRequest) *GroupMemberJoinRequest {
if event.Cmd == 87 {
inn := event.Info.Inner
return &GroupMemberJoinRequest{
GroupEvent: GroupEvent{
GroupID: inn.GroupID,
},
Uid: inn.Uid,
InvitorUid: inn.InvitorUid,
}
}
return nil
}

func ParseMemberJoined(msg *message.PushMsg, event *status.MemberChanged) *GroupMemberJoined {
return &GroupMemberJoined{
GroupEvent: GroupEvent{
GroupID: msg.Message.ResponseHead.FromUin,
},
Uin: event.Uin,
Uid: event.Uid,
JoinType: event.JoinType.Unwrap(),
}
}

func ParseMemberQuit(msg *message.PushMsg, event *status.MemberChanged) *GroupMemberQuit {
return &GroupMemberQuit{
GroupEvent: GroupEvent{
GroupID: msg.Message.ResponseHead.FromUin,
},
Uin: event.Uin,
Uid: event.Uid,
OperatorUid: event.OperatorUid.Unwrap(),
ExitType: event.ExitType.Unwrap(),
}
}

func ParseGroupMuteEvent(event *map[int]any) *GroupMuteMember {
// TODO Parse GroupMuteEvent
return nil
}
43 changes: 43 additions & 0 deletions packets/pb/status/group.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions packets/pb/status/group.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
syntax = "proto3";

option go_package = "github.com/LagrangeDev/LagrangeGo/packets/pb/status";

message MemberChanged {
uint32 Uin = 1;
string Uid = 3;
optional int32 ExitType = 4; // 131 kick 130 exit
optional string OperatorUid = 5;
optional int32 JoinType = 6; // 6 scan qr
}

message MemberJoinRequest {
// JoinType: Direct(scan qrcode or search GroupID)

uint32 GroupID = 1;
string Uid = 3;
int32 Src = 4;
optional string RequestField = 5;
optional bytes Field9 = 9;
}

message InviteInner {
uint32 GroupID = 1;
string Uid = 5;
string InvitorUid = 6;
}

message InviteInfo {
InviteInner Inner = 1;
}

message MemberInviteRequest {
// JoinType: Direct(scan qrcode or search GroupID)

int32 Cmd = 1;
InviteInfo Info = 2;
}

0 comments on commit a0c1f94

Please sign in to comment.