Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Group Invited/Join/LeaveEvent and Group Member Join/Leave Event #9

Merged
merged 1 commit into from
Apr 16, 2024
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
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;
}
Loading