1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 19:17:38 +08:00

feat: GuildChannelMessageEvent

This commit is contained in:
Mrs4s 2021-11-07 22:54:26 +08:00
parent 68628a3ca3
commit 1b9956b79b
No known key found for this signature in database
GPG Key ID: 3186E98FA19CE3A7
3 changed files with 115 additions and 21 deletions

View File

@ -14,6 +14,7 @@ type eventHandlers struct {
groupMessageHandlers []func(*QQClient, *message.GroupMessage) groupMessageHandlers []func(*QQClient, *message.GroupMessage)
selfPrivateMessageHandlers []func(*QQClient, *message.PrivateMessage) selfPrivateMessageHandlers []func(*QQClient, *message.PrivateMessage)
selfGroupMessageHandlers []func(*QQClient, *message.GroupMessage) selfGroupMessageHandlers []func(*QQClient, *message.GroupMessage)
guildChannelMessageHandlers []func(*QQClient, *message.GuildChannelMessage)
groupMuteEventHandlers []func(*QQClient, *GroupMuteEvent) groupMuteEventHandlers []func(*QQClient, *GroupMuteEvent)
groupRecalledHandlers []func(*QQClient, *GroupMessageRecalledEvent) groupRecalledHandlers []func(*QQClient, *GroupMessageRecalledEvent)
friendRecalledHandlers []func(*QQClient, *FriendMessageRecalledEvent) friendRecalledHandlers []func(*QQClient, *FriendMessageRecalledEvent)
@ -68,6 +69,10 @@ func (c *QQClient) OnSelfGroupMessage(f func(*QQClient, *message.GroupMessage))
c.eventHandlers.selfGroupMessageHandlers = append(c.eventHandlers.selfGroupMessageHandlers, f) c.eventHandlers.selfGroupMessageHandlers = append(c.eventHandlers.selfGroupMessageHandlers, f)
} }
func (s *GuildService) OnGuildChannelMessage(f func(*QQClient, *message.GuildChannelMessage)) {
s.c.eventHandlers.guildChannelMessageHandlers = append(s.c.eventHandlers.guildChannelMessageHandlers, f)
}
func (c *QQClient) OnGroupMuted(f func(*QQClient, *GroupMuteEvent)) { func (c *QQClient) OnGroupMuted(f func(*QQClient, *GroupMuteEvent)) {
c.eventHandlers.groupMuteEventHandlers = append(c.eventHandlers.groupMuteEventHandlers, f) c.eventHandlers.groupMuteEventHandlers = append(c.eventHandlers.groupMuteEventHandlers, f)
} }
@ -230,6 +235,17 @@ func (c *QQClient) dispatchGroupMessageSelf(msg *message.GroupMessage) {
} }
} }
func (c *QQClient) dispatchGuildChannelMessage(msg *message.GuildChannelMessage) {
if msg == nil {
return
}
for _, f := range c.eventHandlers.guildChannelMessageHandlers {
cover(func() {
f(c, msg)
})
}
}
func (c *QQClient) dispatchGroupMuteEvent(e *GroupMuteEvent) { func (c *QQClient) dispatchGroupMuteEvent(e *GroupMuteEvent) {
if e == nil { if e == nil {
return return

View File

@ -2,6 +2,7 @@ package client
import ( import (
"fmt" "fmt"
"github.com/Mrs4s/MiraiGo/message"
"github.com/Mrs4s/MiraiGo/binary" "github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/client/pb/channel" "github.com/Mrs4s/MiraiGo/client/pb/channel"
@ -80,28 +81,36 @@ type (
) )
func init() { func init() {
decoders["trpc.group_pro.synclogic.SyncLogic.PushFirstView"] = decodeChannelPushFirstView decoders["trpc.group_pro.synclogic.SyncLogic.PushFirstView"] = decodeGuildPushFirstView
decoders["MsgPush.PushGroupProMsg"] = decodeChannelMessagePushPacket decoders["MsgPush.PushGroupProMsg"] = decodeGuildMessagePushPacket
} }
func (c *QQClient) syncChannelFirstView() { func (s *GuildService) FindGuild(guildId uint64) *GuildInfo {
rsp, err := c.sendAndWaitDynamic(c.buildSyncChannelFirstViewPacket()) for _, i := range s.Guilds {
if err != nil { if i.GuildId == guildId {
c.Error("sync channel error: %v", err) return i
return }
} }
firstViewRsp := new(channel.FirstViewRsp) return nil
if err = proto.Unmarshal(rsp, firstViewRsp); err != nil { }
return
func (g *GuildInfo) FindMember(tinyId uint64) *GuildMemberInfo {
for i := 0; i < len(g.Members); i++ {
if g.Members[i].TinyId == tinyId {
return g.Members[i]
}
} }
c.GuildService.TinyId = firstViewRsp.GetSelfTinyid() for i := 0; i < len(g.Admins); i++ {
c.GuildService.GuildCount = firstViewRsp.GetGuildCount() if g.Admins[i].TinyId == tinyId {
if self, err := c.GuildService.GetUserProfile(c.GuildService.TinyId); err == nil { return g.Admins[i]
c.GuildService.Nickname = self.Nickname }
c.GuildService.AvatarUrl = self.AvatarUrl
} else {
c.Error("get self guild profile error: %v", err)
} }
for i := 0; i < len(g.Bots); i++ {
if g.Bots[i].TinyId == tinyId {
return g.Bots[i]
}
}
return nil
} }
func (s *GuildService) GetUserProfile(tinyId uint64) (*GuildUserProfile, error) { func (s *GuildService) GetUserProfile(tinyId uint64) (*GuildUserProfile, error) {
@ -150,7 +159,7 @@ func (s *GuildService) GetGuildMembers(guildId uint64) (bots []*GuildMemberInfo,
1: u1, 2: u1, 3: u1, 4: u1, 5: u1, 6: u1, 7: u1, 8: u1, 20: u1, 1: u1, 2: u1, 3: u1, 4: u1, 5: u1, 6: u1, 7: u1, 8: u1, 20: u1,
}, },
6: uint32(0), 6: uint32(0),
8: uint32(500), // max response? 8: uint32(500), // count
14: uint32(2), 14: uint32(2),
}) })
packet := packets.BuildUniPacket(s.c.Uin, seq, "OidbSvcTrpcTcp.0xf5b_1", 1, s.c.OutGoingPacketSessionId, []byte{}, s.c.sigInfo.d2Key, payload) packet := packets.BuildUniPacket(s.c.Uin, seq, "OidbSvcTrpcTcp.0xf5b_1", 1, s.c.OutGoingPacketSessionId, []byte{}, s.c.sigInfo.d2Key, payload)
@ -289,6 +298,26 @@ func (s *GuildService) fetchChannelListState(guildId uint64, channels []*Channel
} }
*/ */
func (c *QQClient) syncChannelFirstView() {
rsp, err := c.sendAndWaitDynamic(c.buildSyncChannelFirstViewPacket())
if err != nil {
c.Error("sync channel error: %v", err)
return
}
firstViewRsp := new(channel.FirstViewRsp)
if err = proto.Unmarshal(rsp, firstViewRsp); err != nil {
return
}
c.GuildService.TinyId = firstViewRsp.GetSelfTinyid()
c.GuildService.GuildCount = firstViewRsp.GetGuildCount()
if self, err := c.GuildService.GetUserProfile(c.GuildService.TinyId); err == nil {
c.GuildService.Nickname = self.Nickname
c.GuildService.AvatarUrl = self.AvatarUrl
} else {
c.Error("get self guild profile error: %v", err)
}
}
func (c *QQClient) buildSyncChannelFirstViewPacket() (uint16, []byte) { func (c *QQClient) buildSyncChannelFirstViewPacket() (uint16, []byte) {
seq := c.nextSeq() seq := c.nextSeq()
req := &channel.FirstViewReq{ req := &channel.FirstViewReq{
@ -301,11 +330,26 @@ func (c *QQClient) buildSyncChannelFirstViewPacket() (uint16, []byte) {
return seq, packet return seq, packet
} }
func decodeChannelMessagePushPacket(c *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) { func decodeGuildMessagePushPacket(c *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
push := new(channel.MsgOnlinePush)
if err := proto.Unmarshal(payload, push); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
}
for _, m := range push.Msgs {
if m.Head.ContentHead.GetType() == 3841 {
if m.Head.ContentHead.GetSubType() != 2 {
continue
}
continue
}
if cm := c.parseGuildChannelMessage(m); cm != nil {
c.dispatchGuildChannelMessage(cm)
}
}
return nil, nil return nil, nil
} }
func decodeChannelPushFirstView(c *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) { func decodeGuildPushFirstView(c *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
firstViewMsg := new(channel.FirstViewMsg) firstViewMsg := new(channel.FirstViewMsg)
if err := proto.Unmarshal(payload, firstViewMsg); err != nil { if err := proto.Unmarshal(payload, firstViewMsg); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal protobuf message") return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
@ -335,7 +379,6 @@ func decodeChannelPushFirstView(c *QQClient, _ *incomingPacketInfo, payload []by
} }
info.Bots, info.Members, info.Admins, _ = c.GuildService.GetGuildMembers(info.GuildId) info.Bots, info.Members, info.Admins, _ = c.GuildService.GetGuildMembers(info.GuildId)
c.GuildService.Guilds = append(c.GuildService.Guilds, info) c.GuildService.Guilds = append(c.GuildService.Guilds, info)
c.GuildService.FetchGuestGuild(info.GuildId)
} }
} }
if len(firstViewMsg.ChannelMsgs) > 0 { // sync msg if len(firstViewMsg.ChannelMsgs) > 0 { // sync msg
@ -343,3 +386,23 @@ func decodeChannelPushFirstView(c *QQClient, _ *incomingPacketInfo, payload []by
} }
return nil, nil return nil, nil
} }
func (c *QQClient) parseGuildChannelMessage(msg *channel.ChannelMsgContent) *message.GuildChannelMessage {
guild := c.GuildService.FindGuild(msg.Head.RoutingHead.GetGuildId())
if guild == nil {
return nil // todo: sync guild info
}
// mem := guild.FindMember(msg.Head.RoutingHead.GetFromTinyid())
return &message.GuildChannelMessage{
Id: msg.Head.ContentHead.GetSeq(),
InternalId: msg.Body.RichText.Attr.GetRandom(),
GuildId: msg.Head.RoutingHead.GetGuildId(),
ChannelId: msg.Head.RoutingHead.GetChannelId(),
Time: int64(msg.Head.ContentHead.GetTime()),
Sender: &message.GuildSender{
TinyId: msg.Head.RoutingHead.GetFromTinyid(),
Nickname: string(msg.ExtInfo.GetFromNick()),
},
Elements: message.ParseMessageElems(msg.Body.RichText.Elems),
}
}

View File

@ -46,6 +46,16 @@ type (
// OriginalElements []*msg.Elem // OriginalElements []*msg.Elem
} }
GuildChannelMessage struct {
Id uint64
InternalId int32
GuildId uint64
ChannelId uint64
Time int64
Sender *GuildSender
Elements []IMessageElement
}
SendingMessage struct { SendingMessage struct {
Elements []IMessageElement Elements []IMessageElement
} }
@ -58,6 +68,11 @@ type (
IsFriend bool IsFriend bool
} }
GuildSender struct {
TinyId uint64
Nickname string
}
AnonymousInfo struct { AnonymousInfo struct {
AnonymousId string AnonymousId string
AnonymousNick string AnonymousNick string