1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 11:07:40 +08:00

client: replace LogEvent with Logger

This commit is contained in:
wdvxdr 2022-03-01 22:52:22 +08:00
parent a7098f6000
commit abb3709a18
No known key found for this signature in database
GPG Key ID: 703F8C071DE7A1B6
20 changed files with 106 additions and 138 deletions

View File

@ -71,7 +71,7 @@ func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, info *ne
_, _ = c.sendAndWait(c.buildDeleteMessageRequestPacket(delItems)) _, _ = c.sendAndWait(c.buildDeleteMessageRequestPacket(delItems))
} }
if rsp.GetSyncFlag() != msg.SyncFlag_STOP { if rsp.GetSyncFlag() != msg.SyncFlag_STOP {
c.Debug("continue sync with flag: %v", rsp.SyncFlag) c.debug("continue sync with flag: %v", rsp.SyncFlag)
seq, pkt := c.buildGetMessageRequestPacket(rsp.GetSyncFlag(), time.Now().Unix()) seq, pkt := c.buildGetMessageRequestPacket(rsp.GetSyncFlag(), time.Now().Unix())
_, _ = c.sendAndWait(seq, pkt, info.Params) _, _ = c.sendAndWait(seq, pkt, info.Params)
} }
@ -80,12 +80,12 @@ func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, info *ne
func (c *QQClient) commMsgProcessor(pMsg *msg.Message, info *network.IncomingPacketInfo) { func (c *QQClient) commMsgProcessor(pMsg *msg.Message, info *network.IncomingPacketInfo) {
strKey := fmt.Sprintf("%d%d%d%d", pMsg.Head.GetFromUin(), pMsg.Head.GetToUin(), pMsg.Head.GetMsgSeq(), pMsg.Head.GetMsgUid()) strKey := fmt.Sprintf("%d%d%d%d", pMsg.Head.GetFromUin(), pMsg.Head.GetToUin(), pMsg.Head.GetMsgSeq(), pMsg.Head.GetMsgUid())
if _, ok := c.msgSvcCache.GetAndUpdate(strKey, time.Hour); ok { if _, ok := c.msgSvcCache.GetAndUpdate(strKey, time.Hour); ok {
c.Debug("c2c msg %v already exists in cache. skip.", pMsg.Head.GetMsgUid()) c.debug("c2c msg %v already exists in cache. skip.", pMsg.Head.GetMsgUid())
return return
} }
c.msgSvcCache.Add(strKey, unit{}, time.Hour) c.msgSvcCache.Add(strKey, unit{}, time.Hour)
if c.lastC2CMsgTime > int64(pMsg.Head.GetMsgTime()) && (c.lastC2CMsgTime-int64(pMsg.Head.GetMsgTime())) > 60*10 { if c.lastC2CMsgTime > int64(pMsg.Head.GetMsgTime()) && (c.lastC2CMsgTime-int64(pMsg.Head.GetMsgTime())) > 60*10 {
c.Debug("c2c msg filtered by time. lastMsgTime: %v msgTime: %v", c.lastC2CMsgTime, pMsg.Head.GetMsgTime()) c.debug("c2c msg filtered by time. lastMsgTime: %v msgTime: %v", c.lastC2CMsgTime, pMsg.Head.GetMsgTime())
return return
} }
c.lastC2CMsgTime = int64(pMsg.Head.GetMsgTime()) c.lastC2CMsgTime = int64(pMsg.Head.GetMsgTime())
@ -95,7 +95,7 @@ func (c *QQClient) commMsgProcessor(pMsg *msg.Message, info *network.IncomingPac
if decoder, _ := peekC2CDecoder(pMsg.Head.GetMsgType()); decoder != nil { if decoder, _ := peekC2CDecoder(pMsg.Head.GetMsgType()); decoder != nil {
decoder(c, pMsg, info) decoder(c, pMsg, info)
} else { } else {
c.Debug("unknown msg type on c2c processor: %v - %v", pMsg.Head.GetMsgType(), pMsg.Head.GetC2CCmd()) c.debug("unknown msg type on c2c processor: %v - %v", pMsg.Head.GetMsgType(), pMsg.Head.GetC2CCmd())
} }
} }
@ -137,7 +137,7 @@ func privateMessageDecoder(c *QQClient, pMsg *msg.Message, _ *network.IncomingPa
} }
c.PrivateMessageEvent.dispatch(c, c.parsePrivateMessage(pMsg)) c.PrivateMessageEvent.dispatch(c, c.parsePrivateMessage(pMsg))
default: default:
c.Debug("unknown c2c cmd on private msg decoder: %v", pMsg.Head.GetC2CCmd()) c.debug("unknown c2c cmd on private msg decoder: %v", pMsg.Head.GetC2CCmd())
} }
} }
@ -225,7 +225,7 @@ func troopAddMemberBroadcastDecoder(c *QQClient, pMsg *msg.Message, _ *network.I
if group != nil && group.FindMember(pMsg.Head.GetAuthUin()) == nil { if group != nil && group.FindMember(pMsg.Head.GetAuthUin()) == nil {
mem, err := c.GetMemberInfo(group.Code, pMsg.Head.GetAuthUin()) mem, err := c.GetMemberInfo(group.Code, pMsg.Head.GetAuthUin())
if err != nil { if err != nil {
c.Debug("error to fetch new member info: %v", err) c.debug("error to fetch new member info: %v", err)
return return
} }
group.Update(func(info *GroupInfo) { group.Update(func(info *GroupInfo) {
@ -255,7 +255,7 @@ func troopSystemMessageDecoder(c *QQClient, pMsg *msg.Message, info *network.Inc
reader := binary.NewReader(pMsg.Body.MsgContent) reader := binary.NewReader(pMsg.Body.MsgContent)
groupCode := uint32(reader.ReadInt32()) groupCode := uint32(reader.ReadInt32())
if info := c.FindGroup(int64(groupCode)); info != nil && pMsg.Head.GetGroupName() != "" && info.Name != pMsg.Head.GetGroupName() { if info := c.FindGroup(int64(groupCode)); info != nil && pMsg.Head.GetGroupName() != "" && info.Name != pMsg.Head.GetGroupName() {
c.Debug("group %v name updated. %v -> %v", groupCode, info.Name, pMsg.Head.GetGroupName()) c.debug("group %v name updated. %v -> %v", groupCode, info.Name, pMsg.Head.GetGroupName())
info.Name = pMsg.Head.GetGroupName() info.Name = pMsg.Head.GetGroupName()
} }
} }
@ -267,7 +267,7 @@ func msgType0x211Decoder(c *QQClient, pMsg *msg.Message, info *network.IncomingP
sub4 := msg.SubMsgType0X4Body{} sub4 := msg.SubMsgType0X4Body{}
if err := proto.Unmarshal(pMsg.Body.MsgContent, &sub4); err != nil { if err := proto.Unmarshal(pMsg.Body.MsgContent, &sub4); err != nil {
err = errors.Wrap(err, "unmarshal sub msg 0x4 error") err = errors.Wrap(err, "unmarshal sub msg 0x4 error")
c.Error("unmarshal sub msg 0x4 error: %v", err) c.error("unmarshal sub msg 0x4 error: %v", err)
return return
} }
if sub4.NotOnlineFile != nil && sub4.NotOnlineFile.GetSubcmd() == 1 { // subcmd: 1 -> sendPacket, 2-> recv if sub4.NotOnlineFile != nil && sub4.NotOnlineFile.GetSubcmd() == 1 { // subcmd: 1 -> sendPacket, 2-> recv

View File

@ -55,6 +55,7 @@ type QQClient struct {
transport *network.Transport transport *network.Transport
oicq *oicq.Codec oicq *oicq.Codec
logger Logger
// internal state // internal state
handlers HandlerMap handlers HandlerMap
@ -420,7 +421,7 @@ func (c *QQClient) SubmitSMS(code string) (*LoginResponse, error) {
func (c *QQClient) RequestSMS() bool { func (c *QQClient) RequestSMS() bool {
rsp, err := c.sendAndWait(c.buildSMSRequestPacket()) rsp, err := c.sendAndWait(c.buildSMSRequestPacket())
if err != nil { if err != nil {
c.Error("request sms error: %v", err) c.error("request sms error: %v", err)
return false return false
} }
return rsp.(LoginResponse).Error == SMSNeededError return rsp.(LoginResponse).Error == SMSNeededError
@ -428,7 +429,7 @@ func (c *QQClient) RequestSMS() bool {
func (c *QQClient) init(tokenLogin bool) error { func (c *QQClient) init(tokenLogin bool) error {
if len(c.sig.G) == 0 { if len(c.sig.G) == 0 {
c.Warning("device lock is disable. http api may fail.") c.warning("device lock is disable. http api may fail.")
} }
c.highwaySession.Uin = strconv.FormatInt(c.Uin, 10) c.highwaySession.Uin = strconv.FormatInt(c.Uin, 10)
if err := c.registerClient(); err != nil { if err := c.registerClient(); err != nil {
@ -703,7 +704,7 @@ func (c *QQClient) SolveFriendRequest(req *NewFriendRequest, accept bool) {
func (c *QQClient) getSKey() string { func (c *QQClient) getSKey() string {
if c.sig.SKeyExpiredTime < time.Now().Unix() && len(c.sig.G) > 0 { if c.sig.SKeyExpiredTime < time.Now().Unix() && len(c.sig.G) > 0 {
c.Debug("skey expired. refresh...") c.debug("skey expired. refresh...")
_, _ = c.sendAndWait(c.buildRequestTgtgtNopicsigPacket()) _, _ = c.sendAndWait(c.buildRequestTgtgtNopicsigPacket())
} }
return string(c.sig.SKey) return string(c.sig.SKey)

View File

@ -171,9 +171,9 @@ func decodeLoginResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []b
ErrorMessage: t146r.ReadStringShort(), ErrorMessage: t146r.ReadStringShort(),
}, nil }, nil
} }
c.Debug("unknown login response: %v", t) c.debug("unknown login response: %v", t)
for k, v := range m { for k, v := range m {
c.Debug("Type: %v Value: %v", strconv.FormatInt(int64(k), 16), hex.EncodeToString(v)) c.debug("Type: %v Value: %v", strconv.FormatInt(int64(k), 16), hex.EncodeToString(v))
} }
return nil, errors.Errorf("unknown login response: %v", t) // ? return nil, errors.Errorf("unknown login response: %v", t) // ?
} }
@ -188,7 +188,7 @@ func decodeClientRegisterResponse(c *QQClient, _ *network.IncomingPacketInfo, pa
svcRsp.ReadFrom(jce.NewJceReader(data.Map["SvcRespRegister"]["QQService.SvcRespRegister"][1:])) svcRsp.ReadFrom(jce.NewJceReader(data.Map["SvcRespRegister"]["QQService.SvcRespRegister"][1:]))
if svcRsp.Result != "" || svcRsp.ReplyCode != 0 { if svcRsp.Result != "" || svcRsp.ReplyCode != 0 {
if svcRsp.Result != "" { if svcRsp.Result != "" {
c.Error("reg error: %v", svcRsp.Result) c.error("reg error: %v", svcRsp.Result)
} }
return nil, errors.New("reg failed") return nil, errors.New("reg failed")
} }
@ -318,7 +318,7 @@ func decodePushReqPacket(c *QQClient, _ *network.IncomingPacketInfo, payload []b
if strings.Contains(s.Server, "com") { if strings.Contains(s.Server, "com") {
continue continue
} }
c.Debug("got new server addr: %v location: %v", s.Server, s.Location) c.debug("got new server addr: %v location: %v", s.Server, s.Location)
adds = append(adds, &net.TCPAddr{ adds = append(adds, &net.TCPAddr{
IP: net.ParseIP(s.Server), IP: net.ParseIP(s.Server),
Port: int(s.Port), Port: int(s.Port),
@ -341,7 +341,7 @@ func decodePushReqPacket(c *QQClient, _ *network.IncomingPacketInfo, payload []b
fmtPkt := jce.NewJceReader(jceBuf) fmtPkt := jce.NewJceReader(jceBuf)
list := &jce.FileStoragePushFSSvcList{} list := &jce.FileStoragePushFSSvcList{}
list.ReadFrom(fmtPkt) list.ReadFrom(fmtPkt)
c.Debug("got file storage svc push.") c.debug("got file storage svc push.")
// c.fileStorageInfo = list // c.fileStorageInfo = list
rsp := cmd0x6ff.C501RspBody{} rsp := cmd0x6ff.C501RspBody{}
if err := proto.Unmarshal(list.BigDataChannel.PbBuf, &rsp); err == nil && rsp.RspBody != nil { if err := proto.Unmarshal(list.BigDataChannel.PbBuf, &rsp); err == nil && rsp.RspBody != nil {

View File

@ -175,12 +175,6 @@ type (
client *QQClient client *QQClient
} }
LogEvent struct {
Type string
Message string
Dump []byte
}
ServerUpdatedEvent struct { ServerUpdatedEvent struct {
Servers []jce.SsoServerInfo Servers []jce.SsoServerInfo
} }

View File

@ -46,8 +46,6 @@ type eventHandlers struct {
guildChannelDestroyedHandlers []func(*QQClient, *GuildChannelOperationEvent) guildChannelDestroyedHandlers []func(*QQClient, *GuildChannelOperationEvent)
memberJoinedGuildHandlers []func(*QQClient, *MemberJoinGuildEvent) memberJoinedGuildHandlers []func(*QQClient, *MemberJoinGuildEvent)
// consider Logger interface?
logHandlers []func(*QQClient, *LogEvent)
serverUpdatedHandlers []func(*QQClient, *ServerUpdatedEvent) bool serverUpdatedHandlers []func(*QQClient, *ServerUpdatedEvent) bool
groupMessageReceiptHandlers sync.Map groupMessageReceiptHandlers sync.Map
} }
@ -84,10 +82,6 @@ func (c *QQClient) OnServerUpdated(f func(*QQClient, *ServerUpdatedEvent) bool)
c.eventHandlers.serverUpdatedHandlers = append(c.eventHandlers.serverUpdatedHandlers, f) c.eventHandlers.serverUpdatedHandlers = append(c.eventHandlers.serverUpdatedHandlers, f)
} }
func (c *QQClient) OnLog(f func(*QQClient, *LogEvent)) {
c.eventHandlers.logHandlers = append(c.eventHandlers.logHandlers, f)
}
func NewUinFilterPrivate(uin int64) func(*message.PrivateMessage) bool { func NewUinFilterPrivate(uin int64) func(*message.PrivateMessage) bool {
return func(msg *message.PrivateMessage) bool { return func(msg *message.PrivateMessage) bool {
return msg.Sender.Uin == uin return msg.Sender.Uin == uin
@ -186,17 +180,6 @@ func (c *QQClient) dispatchGroupMessageReceiptEvent(e *groupMessageReceiptEvent)
}) })
} }
func (c *QQClient) dispatchLogEvent(e *LogEvent) {
if e == nil {
return
}
for _, f := range c.eventHandlers.logHandlers {
cover(func() {
f(c, e)
})
}
}
func cover(f func()) { func cover(f func()) {
defer func() { defer func() {
if pan := recover(); pan != nil { if pan := recover(); pan != nil {

View File

@ -369,46 +369,3 @@ func unpackOIDBPackage(payload []byte, rsp proto.Message) error {
} }
return nil return nil
} }
func (c *QQClient) Error(msg string, args ...interface{}) {
c.dispatchLogEvent(&LogEvent{
Type: "ERROR",
Message: fmt.Sprintf(msg, args...),
})
}
func (c *QQClient) Warning(msg string, args ...interface{}) {
c.dispatchLogEvent(&LogEvent{
Type: "WARNING",
Message: fmt.Sprintf(msg, args...),
})
}
func (c *QQClient) Info(msg string, args ...interface{}) {
c.dispatchLogEvent(&LogEvent{
Type: "INFO",
Message: fmt.Sprintf(msg, args...),
})
}
func (c *QQClient) Debug(msg string, args ...interface{}) {
c.dispatchLogEvent(&LogEvent{
Type: "DEBUG",
Message: fmt.Sprintf(msg, args...),
})
}
func (c *QQClient) Trace(msg string, args ...interface{}) {
c.dispatchLogEvent(&LogEvent{
Type: "TRACE",
Message: fmt.Sprintf(msg, args...),
})
}
func (c *QQClient) Dump(msg string, data []byte, args ...interface{}) {
c.dispatchLogEvent(&LogEvent{
Type: "DUMP",
Message: fmt.Sprintf(msg, args...),
Dump: data,
})
}

View File

@ -71,7 +71,7 @@ func init() {
func (c *QQClient) GetGroupFileSystem(groupCode int64) (fs *GroupFileSystem, err error) { func (c *QQClient) GetGroupFileSystem(groupCode int64) (fs *GroupFileSystem, err error) {
defer func() { defer func() {
if pan := recover(); pan != nil { if pan := recover(); pan != nil {
c.Error("get group fs error: %v\n%s", pan, debug.Stack()) c.error("get group fs error: %v\n%s", pan, debug.Stack())
err = errors.New("fs error") err = errors.New("fs error")
} }
}() }()

View File

@ -61,7 +61,7 @@ func (c *QQClient) SendGroupMessage(groupCode int64, m *message.SendingMessage,
Message: m.Elements, Message: m.Elements,
})) }))
if err != nil { if err != nil {
c.Error("%v", err) c.error("%v", err)
return nil return nil
} }
ret := c.sendGroupMessage(groupCode, false, &message.SendingMessage{Elements: []message.IMessageElement{lmsg}}) ret := c.sendGroupMessage(groupCode, false, &message.SendingMessage{Elements: []message.IMessageElement{lmsg}})
@ -178,7 +178,7 @@ func (c *QQClient) uploadGroupLongMessage(groupCode int64, m *message.ForwardMes
} }
err := c.highwaySession.Upload(addr, input) err := c.highwaySession.Upload(addr, input)
if err != nil { if err != nil {
c.Error("highway upload long message error: %v", err) c.error("highway upload long message error: %v", err)
continue continue
} }
return genLongTemplate(rsp.MsgResid, m.Brief(), ts), nil return genLongTemplate(rsp.MsgResid, m.Brief(), ts), nil
@ -340,9 +340,9 @@ func decodeMsgSendResponse(c *QQClient, _ *network.IncomingPacketInfo, payload [
switch rsp.GetResult() { switch rsp.GetResult() {
case 0: // OK. case 0: // OK.
case 55: case 55:
c.Error("sendPacket msg error: %v Bot has blocked target's content", rsp.GetResult()) c.error("sendPacket msg error: %v Bot has blocked target's content", rsp.GetResult())
default: default:
c.Error("sendPacket msg error: %v %v", rsp.GetResult(), rsp.GetErrMsg()) c.error("sendPacket msg error: %v %v", rsp.GetResult(), rsp.GetErrMsg())
} }
return nil, nil return nil, nil
} }
@ -353,7 +353,7 @@ func decodeGetGroupMsgResponse(c *QQClient, info *network.IncomingPacketInfo, pa
return nil, errors.Wrap(err, "failed to unmarshal protobuf message") return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
} }
if rsp.GetResult() != 0 { if rsp.GetResult() != 0 {
c.Error("get msg error: %v %v", rsp.GetResult(), rsp.GetErrmsg()) c.error("get msg error: %v %v", rsp.GetResult(), rsp.GetErrmsg())
return nil, errors.Errorf("get msg error: %v msg: %v", rsp.GetResult(), rsp.GetErrmsg()) return nil, errors.Errorf("get msg error: %v msg: %v", rsp.GetResult(), rsp.GetErrmsg())
} }
var ret []*message.GroupMessage var ret []*message.GroupMessage
@ -363,7 +363,7 @@ func decodeGetGroupMsgResponse(c *QQClient, info *network.IncomingPacketInfo, pa
} }
if m.Content != nil && m.Content.GetPkgNum() > 1 && !info.Params.Bool("raw") { if m.Content != nil && m.Content.GetPkgNum() > 1 && !info.Params.Bool("raw") {
if m.Content.GetPkgIndex() == 0 { if m.Content.GetPkgIndex() == 0 {
c.Debug("build fragmented message from history") c.debug("build fragmented message from history")
i := m.Head.GetMsgSeq() - m.Content.GetPkgNum() i := m.Head.GetMsgSeq() - m.Content.GetPkgNum()
builder := &messageBuilder{} builder := &messageBuilder{}
for { for {
@ -412,10 +412,10 @@ func decodeAtAllRemainResponse(_ *QQClient, _ *network.IncomingPacketInfo, paylo
func (c *QQClient) parseGroupMessage(m *msg.Message) *message.GroupMessage { func (c *QQClient) parseGroupMessage(m *msg.Message) *message.GroupMessage {
group := c.FindGroup(m.Head.GroupInfo.GetGroupCode()) group := c.FindGroup(m.Head.GroupInfo.GetGroupCode())
if group == nil { if group == nil {
c.Debug("sync group %v.", m.Head.GroupInfo.GetGroupCode()) c.debug("sync group %v.", m.Head.GroupInfo.GetGroupCode())
info, err := c.GetGroupInfo(m.Head.GroupInfo.GetGroupCode()) info, err := c.GetGroupInfo(m.Head.GroupInfo.GetGroupCode())
if err != nil { if err != nil {
c.Error("error to sync group %v : %+v", m.Head.GroupInfo.GetGroupCode(), err) c.error("error to sync group %v : %+v", m.Head.GroupInfo.GetGroupCode(), err)
return nil return nil
} }
group = info group = info
@ -424,7 +424,7 @@ func (c *QQClient) parseGroupMessage(m *msg.Message) *message.GroupMessage {
if len(group.Members) == 0 { if len(group.Members) == 0 {
mem, err := c.GetGroupMembers(group) mem, err := c.GetGroupMembers(group)
if err != nil { if err != nil {
c.Error("error to sync group %v member : %+v", m.Head.GroupInfo.GroupCode, err) c.error("error to sync group %v member : %+v", m.Head.GroupInfo.GroupCode, err)
return nil return nil
} }
group.Members = mem group.Members = mem

View File

@ -710,7 +710,7 @@ func convertChannelInfo(info *channel.GuildChannelInfo) *ChannelInfo {
func (c *QQClient) syncChannelFirstView() { func (c *QQClient) syncChannelFirstView() {
rsp, err := c.sendAndWaitDynamic(c.buildSyncChannelFirstViewPacket()) rsp, err := c.sendAndWaitDynamic(c.buildSyncChannelFirstViewPacket())
if err != nil { if err != nil {
c.Error("sync channel error: %v", err) c.error("sync channel error: %v", err)
return return
} }
firstViewRsp := new(channel.FirstViewRsp) firstViewRsp := new(channel.FirstViewRsp)
@ -723,7 +723,7 @@ func (c *QQClient) syncChannelFirstView() {
c.GuildService.Nickname = self.Nickname c.GuildService.Nickname = self.Nickname
c.GuildService.AvatarUrl = self.AvatarUrl c.GuildService.AvatarUrl = self.AvatarUrl
} else { } else {
c.Error("get self guild profile error: %v", err) c.error("get self guild profile error: %v", err)
} }
} }
@ -754,7 +754,7 @@ func decodeGuildPushFirstView(c *QQClient, _ *network.IncomingPacketInfo, payloa
} }
channels, err := c.GuildService.FetchChannelList(info.GuildId) channels, err := c.GuildService.FetchChannelList(info.GuildId)
if err != nil { if err != nil {
c.Warning("waring: fetch guild %v channel error %v. will use sync node to fill channel list field", guild.GuildId, err) c.warning("waring: fetch guild %v channel error %v. will use sync node to fill channel list field", guild.GuildId, err)
for _, node := range guild.ChannelNodes { for _, node := range guild.ChannelNodes {
meta := new(channel.ChannelMsgMeta) meta := new(channel.ChannelMsgMeta)
_ = proto.Unmarshal(node.Meta, meta) _ = proto.Unmarshal(node.Meta, meta)

View File

@ -80,7 +80,7 @@ func decodeGuildEventFlowPacket(c *QQClient, _ *network.IncomingPacketInfo, payl
} }
eventBody := new(channel.EventBody) eventBody := new(channel.EventBody)
if err := proto.Unmarshal(common.PbElem, eventBody); err != nil { if err := proto.Unmarshal(common.PbElem, eventBody); err != nil {
c.Error("failed to unmarshal guild channel event body: %v", err) c.error("failed to unmarshal guild channel event body: %v", err)
continue continue
} }
c.processGuildEventBody(m, eventBody) c.processGuildEventBody(m, eventBody)
@ -106,7 +106,7 @@ func (c *QQClient) processGuildEventBody(m *channel.ChannelMsgContent, eventBody
var guild *GuildInfo var guild *GuildInfo
if m.Head.RoutingHead.GetGuildId() != 0 { if m.Head.RoutingHead.GetGuildId() != 0 {
if guild = c.GuildService.FindGuild(m.Head.RoutingHead.GetGuildId()); guild == nil { if guild = c.GuildService.FindGuild(m.Head.RoutingHead.GetGuildId()); guild == nil {
c.Warning("process channel event error: guild not found.") c.warning("process channel event error: guild not found.")
return return
} }
} }
@ -118,7 +118,7 @@ func (c *QQClient) processGuildEventBody(m *channel.ChannelMsgContent, eventBody
} }
channelInfo, err := c.GuildService.FetchChannelInfo(guild.GuildId, chanId.GetChanId()) channelInfo, err := c.GuildService.FetchChannelInfo(guild.GuildId, chanId.GetChanId())
if err != nil { if err != nil {
c.Warning("process create channel event error: fetch channel info error: %v", err) c.warning("process create channel event error: fetch channel info error: %v", err)
continue continue
} }
guild.Channels = append(guild.Channels, channelInfo) guild.Channels = append(guild.Channels, channelInfo)
@ -148,7 +148,7 @@ func (c *QQClient) processGuildEventBody(m *channel.ChannelMsgContent, eventBody
if oldInfo == nil { if oldInfo == nil {
info, err := c.GuildService.FetchChannelInfo(m.Head.RoutingHead.GetGuildId(), eventBody.ChangeChanInfo.GetChanId()) info, err := c.GuildService.FetchChannelInfo(m.Head.RoutingHead.GetGuildId(), eventBody.ChangeChanInfo.GetChanId())
if err != nil { if err != nil {
c.Error("error to decode channel info updated event: fetch channel info failed: %v", err) c.error("error to decode channel info updated event: fetch channel info failed: %v", err)
return return
} }
guild.Channels = append(guild.Channels, info) guild.Channels = append(guild.Channels, info)
@ -159,7 +159,7 @@ func (c *QQClient) processGuildEventBody(m *channel.ChannelMsgContent, eventBody
} }
newInfo, err := c.GuildService.FetchChannelInfo(m.Head.RoutingHead.GetGuildId(), eventBody.ChangeChanInfo.GetChanId()) newInfo, err := c.GuildService.FetchChannelInfo(m.Head.RoutingHead.GetGuildId(), eventBody.ChangeChanInfo.GetChanId())
if err != nil { if err != nil {
c.Error("error to decode channel info updated event: fetch channel info failed: %v", err) c.error("error to decode channel info updated event: fetch channel info failed: %v", err)
return return
} }
for i := range guild.Channels { for i := range guild.Channels {
@ -178,13 +178,13 @@ func (c *QQClient) processGuildEventBody(m *channel.ChannelMsgContent, eventBody
case eventBody.JoinGuild != nil: case eventBody.JoinGuild != nil:
/* 应该不会重复推送把, 不会吧不会吧 /* 应该不会重复推送把, 不会吧不会吧
if mem := guild.FindMember(eventBody.JoinGuild.GetMemberTinyid()); mem != nil { if mem := guild.FindMember(eventBody.JoinGuild.GetMemberTinyid()); mem != nil {
c.Info("ignore join guild event: member %v already exists", mem.TinyId) c.info("ignore join guild event: member %v already exists", mem.TinyId)
return return
} }
*/ */
profile, err := c.GuildService.FetchGuildMemberProfileInfo(guild.GuildId, eventBody.JoinGuild.GetMemberTinyid()) profile, err := c.GuildService.FetchGuildMemberProfileInfo(guild.GuildId, eventBody.JoinGuild.GetMemberTinyid())
if err != nil { if err != nil {
c.Error("error to decode member join guild event: get member profile error: %v", err) c.error("error to decode member join guild event: get member profile error: %v", err)
return return
} }
info := &GuildMemberInfo{ info := &GuildMemberInfo{
@ -210,7 +210,7 @@ func (c *QQClient) processGuildEventBody(m *channel.ChannelMsgContent, eventBody
if eventBody.UpdateMsg.GetEventType() == 4 { // 消息贴表情更新 (包含添加或删除) if eventBody.UpdateMsg.GetEventType() == 4 { // 消息贴表情更新 (包含添加或删除)
t, err := c.GuildService.pullChannelMessages(m.Head.RoutingHead.GetGuildId(), m.Head.RoutingHead.GetChannelId(), eventBody.UpdateMsg.GetMsgSeq(), eventBody.UpdateMsg.GetMsgSeq(), eventBody.UpdateMsg.GetEventVersion()-1, false) t, err := c.GuildService.pullChannelMessages(m.Head.RoutingHead.GetGuildId(), m.Head.RoutingHead.GetChannelId(), eventBody.UpdateMsg.GetMsgSeq(), eventBody.UpdateMsg.GetMsgSeq(), eventBody.UpdateMsg.GetEventVersion()-1, false)
if err != nil || len(t) == 0 { if err != nil || len(t) == 0 {
c.Error("process guild event flow error: pull eventMsg message error: %v", err) c.error("process guild event flow error: pull eventMsg message error: %v", err)
return return
} }
// 自己的消息被贴表情会单独推送一个tips, 这里不需要解析 // 自己的消息被贴表情会单独推送一个tips, 这里不需要解析

View File

@ -141,7 +141,7 @@ ok:
width := int32(i.Width) width := int32(i.Width)
height := int32(i.Height) height := int32(i.Height)
if err != nil && target.SourceType != message.SourceGroup { if err != nil && target.SourceType != message.SourceGroup {
c.Warning("waring: decode image error: %v. this image will be displayed by wrong size in pc guild client", err) c.warning("waring: decode image error: %v. this image will be displayed by wrong size in pc guild client", err)
width = 200 width = 200
height = 200 height = 200
} }

33
client/log.go Normal file
View File

@ -0,0 +1,33 @@
package client
type Logger interface {
Info(format string, args ...any)
Warning(format string, args ...any)
Error(format string, args ...any)
Debug(format string, args ...any)
Dump(dumped []byte, format string, args ...any)
}
func (c *QQClient) SetLogger(logger Logger) {
c.logger = logger
}
func (c *QQClient) info(msg string, args ...any) {
c.logger.Info(msg, args...)
}
func (c *QQClient) warning(msg string, args ...any) {
c.logger.Warning(msg, args...)
}
func (c *QQClient) error(msg string, args ...any) {
c.logger.Error(msg, args...)
}
func (c *QQClient) debug(msg string, args ...any) {
c.logger.Debug(msg, args...)
}
func (c *QQClient) dump(msg string, data []byte, args ...any) {
c.logger.Dump(data, msg, args...)
}

View File

@ -45,22 +45,22 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo {
var err error var err error
if r.ChatServerLatency, err = qualityTest(c.servers[c.currServerIndex].String()); err != nil { if r.ChatServerLatency, err = qualityTest(c.servers[c.currServerIndex].String()); err != nil {
c.Error("test chat server latency error: %v", err) c.error("test chat server latency error: %v", err)
r.ChatServerLatency = 9999 r.ChatServerLatency = 9999
} }
if addr, err := net.ResolveIPAddr("ip", "ssl.htdata.qq.com"); err == nil { if addr, err := net.ResolveIPAddr("ip", "ssl.htdata.qq.com"); err == nil {
if r.LongMessageServerLatency, err = qualityTest((&net.TCPAddr{IP: addr.IP, Port: 443}).String()); err != nil { if r.LongMessageServerLatency, err = qualityTest((&net.TCPAddr{IP: addr.IP, Port: 443}).String()); err != nil {
c.Error("test long message server latency error: %v", err) c.error("test long message server latency error: %v", err)
r.LongMessageServerLatency = 9999 r.LongMessageServerLatency = 9999
} }
} else { } else {
c.Error("resolve long message server error: %v", err) c.error("resolve long message server error: %v", err)
r.LongMessageServerLatency = 9999 r.LongMessageServerLatency = 9999
} }
if c.highwaySession.AddrLength() > 0 { if c.highwaySession.AddrLength() > 0 {
if r.SrvServerLatency, err = qualityTest(c.highwaySession.SsoAddr[0].String()); err != nil { if r.SrvServerLatency, err = qualityTest(c.highwaySession.SsoAddr[0].String()); err != nil {
c.Error("test srv server latency error: %v", err) c.error("test srv server latency error: %v", err)
r.SrvServerLatency = 9999 r.SrvServerLatency = 9999
} }
} }
@ -78,7 +78,7 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo {
if _, err := utils.HttpGetBytes("https://ssl.htdata.qq.com", ""); err == nil { if _, err := utils.HttpGetBytes("https://ssl.htdata.qq.com", ""); err == nil {
r.LongMessageServerResponseLatency = time.Since(start).Milliseconds() r.LongMessageServerResponseLatency = time.Since(start).Milliseconds()
} else { } else {
c.Error("test long message server response latency error: %v", err) c.error("test long message server response latency error: %v", err)
r.LongMessageServerResponseLatency = 9999 r.LongMessageServerResponseLatency = 9999
} }
wg.Wait() wg.Wait()
@ -87,7 +87,7 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo {
// connect 连接到 QQClient.servers 中的服务器 // connect 连接到 QQClient.servers 中的服务器
func (c *QQClient) connect() error { func (c *QQClient) connect() error {
c.Info("connect to server: %v", c.servers[c.currServerIndex].String()) c.info("connect to server: %v", c.servers[c.currServerIndex].String())
err := c.TCP.Connect(c.servers[c.currServerIndex]) err := c.TCP.Connect(c.servers[c.currServerIndex])
c.currServerIndex++ c.currServerIndex++
if c.currServerIndex == len(c.servers) { if c.currServerIndex == len(c.servers) {
@ -98,7 +98,7 @@ func (c *QQClient) connect() error {
if c.retryTimes > len(c.servers) { if c.retryTimes > len(c.servers) {
return errors.New("All servers are unreachable") return errors.New("All servers are unreachable")
} }
c.Error("connect server error: %v", err) c.error("connect server error: %v", err)
return err return err
} }
c.once.Do(func() { c.once.Do(func() {
@ -129,12 +129,12 @@ func (c *QQClient) quickReconnect() {
c.Disconnect() c.Disconnect()
time.Sleep(time.Millisecond * 200) time.Sleep(time.Millisecond * 200)
if err := c.connect(); err != nil { if err := c.connect(); err != nil {
c.Error("connect server error: %v", err) c.error("connect server error: %v", err)
c.DisconnectedEvent.dispatch(c, &ClientDisconnectedEvent{Message: "quick reconnect failed"}) c.DisconnectedEvent.dispatch(c, &ClientDisconnectedEvent{Message: "quick reconnect failed"})
return return
} }
if err := c.registerClient(); err != nil { if err := c.registerClient(); err != nil {
c.Error("register client failed: %v", err) c.error("register client failed: %v", err)
c.Disconnect() c.Disconnect()
c.DisconnectedEvent.dispatch(c, &ClientDisconnectedEvent{Message: "register error"}) c.DisconnectedEvent.dispatch(c, &ClientDisconnectedEvent{Message: "register error"})
return return
@ -251,23 +251,23 @@ func (c *QQClient) sendAndWaitDynamic(seq uint16, pkt []byte) ([]byte, error) {
// plannedDisconnect 计划中断线事件 // plannedDisconnect 计划中断线事件
func (c *QQClient) plannedDisconnect(_ *network.TCPListener) { func (c *QQClient) plannedDisconnect(_ *network.TCPListener) {
c.Debug("planned disconnect.") c.debug("planned disconnect.")
c.stat.DisconnectTimes.Add(1) c.stat.DisconnectTimes.Add(1)
c.Online.Store(false) c.Online.Store(false)
} }
// unexpectedDisconnect 非预期断线事件 // unexpectedDisconnect 非预期断线事件
func (c *QQClient) unexpectedDisconnect(_ *network.TCPListener, e error) { func (c *QQClient) unexpectedDisconnect(_ *network.TCPListener, e error) {
c.Error("unexpected disconnect: %v", e) c.error("unexpected disconnect: %v", e)
c.stat.DisconnectTimes.Add(1) c.stat.DisconnectTimes.Add(1)
c.Online.Store(false) c.Online.Store(false)
if err := c.connect(); err != nil { if err := c.connect(); err != nil {
c.Error("connect server error: %v", err) c.error("connect server error: %v", err)
c.DisconnectedEvent.dispatch(c, &ClientDisconnectedEvent{Message: "connection dropped by server."}) c.DisconnectedEvent.dispatch(c, &ClientDisconnectedEvent{Message: "connection dropped by server."})
return return
} }
if err := c.registerClient(); err != nil { if err := c.registerClient(); err != nil {
c.Error("register client failed: %v", err) c.error("register client failed: %v", err)
c.Disconnect() c.Disconnect()
c.DisconnectedEvent.dispatch(c, &ClientDisconnectedEvent{Message: "register error"}) c.DisconnectedEvent.dispatch(c, &ClientDisconnectedEvent{Message: "register error"})
return return
@ -284,7 +284,7 @@ func (c *QQClient) netLoop() {
continue continue
} }
if l < 4 || l > 1024*1024*10 { // max 10MB if l < 4 || l > 1024*1024*10 { // max 10MB
c.Error("parse incoming packet error: invalid packet length %v", l) c.error("parse incoming packet error: invalid packet length %v", l)
errCount++ errCount++
if errCount > 2 { if errCount > 2 {
go c.quickReconnect() go c.quickReconnect()
@ -295,7 +295,7 @@ func (c *QQClient) netLoop() {
resp, err := c.transport.ReadResponse(data) resp, err := c.transport.ReadResponse(data)
// pkt, err := packets.ParseIncomingPacket(data, c.sig.D2Key) // pkt, err := packets.ParseIncomingPacket(data, c.sig.D2Key)
if err != nil { if err != nil {
c.Error("parse incoming packet error: %v", err) c.error("parse incoming packet error: %v", err)
if errors.Is(err, network.ErrSessionExpired) || errors.Is(err, network.ErrPacketDropped) { if errors.Is(err, network.ErrSessionExpired) || errors.Is(err, network.ErrPacketDropped) {
c.Disconnect() c.Disconnect()
go c.DisconnectedEvent.dispatch(c, &ClientDisconnectedEvent{Message: "session expired"}) go c.DisconnectedEvent.dispatch(c, &ClientDisconnectedEvent{Message: "session expired"})
@ -310,7 +310,7 @@ func (c *QQClient) netLoop() {
if resp.EncryptType == network.EncryptTypeEmptyKey { if resp.EncryptType == network.EncryptTypeEmptyKey {
m, err := c.oicq.Unmarshal(resp.Body) m, err := c.oicq.Unmarshal(resp.Body)
if err != nil { if err != nil {
c.Error("decrypt payload error: %v", err) c.error("decrypt payload error: %v", err)
if errors.Is(err, oicq.ErrUnknownFlag) { if errors.Is(err, oicq.ErrUnknownFlag) {
go c.quickReconnect() go c.quickReconnect()
} }
@ -319,7 +319,7 @@ func (c *QQClient) netLoop() {
resp.Body = m.Body resp.Body = m.Body
} }
errCount = 0 errCount = 0
c.Debug("rev pkt: %v seq: %v", resp.CommandName, resp.SequenceID) c.debug("rev pkt: %v seq: %v", resp.CommandName, resp.SequenceID)
c.stat.PacketReceived.Add(1) c.stat.PacketReceived.Add(1)
pkt := &packets.IncomingPacket{ pkt := &packets.IncomingPacket{
SequenceId: uint16(resp.SequenceID), SequenceId: uint16(resp.SequenceID),
@ -329,8 +329,8 @@ func (c *QQClient) netLoop() {
go func(pkt *packets.IncomingPacket) { go func(pkt *packets.IncomingPacket) {
defer func() { defer func() {
if pan := recover(); pan != nil { if pan := recover(); pan != nil {
c.Error("panic on decoder %v : %v\n%s", pkt.CommandName, pan, debug.Stack()) c.error("panic on decoder %v : %v\n%s", pkt.CommandName, pan, debug.Stack())
c.Dump("packet decode error: %v - %v", pkt.Payload, pkt.CommandName, pan) c.dump("packet decode error: %v - %v", pkt.Payload, pkt.CommandName, pan)
} }
}() }()
@ -346,7 +346,7 @@ func (c *QQClient) netLoop() {
Params: info.getParams(), Params: info.getParams(),
}, pkt.Payload) }, pkt.Payload)
if err != nil { if err != nil {
c.Debug("decode pkt %v error: %+v", pkt.CommandName, err) c.debug("decode pkt %v error: %+v", pkt.CommandName, err)
} }
} }
if ok { if ok {
@ -358,7 +358,7 @@ func (c *QQClient) netLoop() {
// does not need decoder // does not need decoder
f.fun(pkt.Payload, nil) f.fun(pkt.Payload, nil)
} else { } else {
c.Debug("Unhandled Command: %s\nSeq: %d\nThis message can be ignored.", pkt.CommandName, pkt.SequenceId) c.debug("Unhandled Command: %s\nSeq: %d\nThis message can be ignored.", pkt.CommandName, pkt.SequenceId)
} }
}(pkt) }(pkt)
} }

View File

@ -139,7 +139,7 @@ func (c *QQClient) msgGrayTipProcessor(groupCode int64, tipInfo *notify.AIOGrayT
} }
} }
if event.Uin == 0 { if event.Uin == 0 {
c.Error("process special title updated tips error: missing cmd") c.error("process special title updated tips error: missing cmd")
return return
} }
if mem := c.FindGroup(groupCode).FindMember(event.Uin); mem != nil { if mem := c.FindGroup(groupCode).FindMember(event.Uin); mem != nil {

View File

@ -36,15 +36,15 @@ func (c *QQClient) buildOfflineFileDownloadRequestPacket(uuid []byte) (uint16, [
func decodeOfflineFileDownloadResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []byte) (interface{}, error) { func decodeOfflineFileDownloadResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []byte) (interface{}, error) {
rsp := cmd0x346.C346RspBody{} rsp := cmd0x346.C346RspBody{}
if err := proto.Unmarshal(payload, &rsp); err != nil { if err := proto.Unmarshal(payload, &rsp); err != nil {
c.Error("unmarshal cmd0x346 rsp body error: %v", err) c.error("unmarshal cmd0x346 rsp body error: %v", err)
return nil, errors.Wrap(err, "unmarshal cmd0x346 rsp body error") return nil, errors.Wrap(err, "unmarshal cmd0x346 rsp body error")
} }
if rsp.ApplyDownloadRsp == nil { if rsp.ApplyDownloadRsp == nil {
c.Error("decode apply download 1200 error: apply rsp is nil.") c.error("decode apply download 1200 error: apply rsp is nil.")
return nil, errors.New("apply rsp is nil") return nil, errors.New("apply rsp is nil")
} }
if rsp.ApplyDownloadRsp.RetCode != 0 { if rsp.ApplyDownloadRsp.RetCode != 0 {
c.Error("decode apply download 1200 error: %v", rsp.ApplyDownloadRsp.RetCode) c.error("decode apply download 1200 error: %v", rsp.ApplyDownloadRsp.RetCode)
return nil, errors.Errorf("apply download rsp error: %d", rsp.ApplyDownloadRsp.RetCode) return nil, errors.Errorf("apply download rsp error: %d", rsp.ApplyDownloadRsp.RetCode)
} }
return "http://" + rsp.ApplyDownloadRsp.DownloadInfo.DownloadDomain + rsp.ApplyDownloadRsp.DownloadInfo.DownloadUrl, nil return "http://" + rsp.ApplyDownloadRsp.DownloadInfo.DownloadDomain + rsp.ApplyDownloadRsp.DownloadInfo.DownloadUrl, nil

View File

@ -118,7 +118,7 @@ func decodeOnlinePushReqPacket(c *QQClient, info *network.IncomingPacketInfo, pa
return nil, errors.Wrap(err, "decode online push 0x210 error") return nil, errors.Wrap(err, "decode online push 0x210 error")
} }
} else { } else {
c.Debug("unknown online push 0x210 sub type 0x%v", strconv.FormatInt(subType, 16)) c.debug("unknown online push 0x210 sub type 0x%v", strconv.FormatInt(subType, 16))
} }
} }
} }
@ -241,7 +241,7 @@ func msgType0x210Sub44Decoder(c *QQClient, protobuf []byte) error {
if s44.GroupSyncMsg.GrpCode == 0 { // member sync if s44.GroupSyncMsg.GrpCode == 0 { // member sync
return errors.New("invalid group code") return errors.New("invalid group code")
} }
c.Debug("syncing members.") c.debug("syncing members.")
if group := c.FindGroup(s44.GroupSyncMsg.GrpCode); group != nil { if group := c.FindGroup(s44.GroupSyncMsg.GrpCode); group != nil {
group.lock.Lock() group.lock.Lock()
defer group.lock.Unlock() defer group.lock.Unlock()

View File

@ -52,7 +52,7 @@ func (c *QQClient) getQiDianAddressDetailList() ([]*FriendInfo, error) {
ret := []*FriendInfo{} ret := []*FriendInfo{}
for _, detail := range rsp.GetAddressDetailListRspBody.AddressDetail { for _, detail := range rsp.GetAddressDetailListRspBody.AddressDetail {
if len(detail.Qq) == 0 { if len(detail.Qq) == 0 {
c.Warning("address detail %v QQ is 0", string(detail.Name)) c.warning("address detail %v QQ is 0", string(detail.Name))
continue continue
} }
ret = append(ret, &FriendInfo{ ret = append(ret, &FriendInfo{

View File

@ -90,7 +90,7 @@ func (c *QQClient) SyncSessions() (*SessionSyncResponse, error) {
if e.GroupNum != -1 { if e.GroupNum != -1 {
groupNum = e.GroupNum groupNum = e.GroupNum
} }
c.Debug("sync session %v/%v", len(ret.GroupSessions), groupNum) c.debug("sync session %v/%v", len(ret.GroupSessions), groupNum)
if groupNum != -1 && len(ret.GroupSessions) >= int(groupNum) { if groupNum != -1 && len(ret.GroupSessions) >= int(groupNum) {
notifyChan <- true notifyChan <- true
} }

View File

@ -60,7 +60,7 @@ func (c *QQClient) GetGroupSystemMessages() (*GroupSystemMessages, error) {
func (c *QQClient) exceptAndDispatchGroupSysMsg() { func (c *QQClient) exceptAndDispatchGroupSysMsg() {
if c.groupSysMsgCache == nil { if c.groupSysMsgCache == nil {
c.Error("warning: groupSysMsgCache is nil") c.error("warning: groupSysMsgCache is nil")
c.groupSysMsgCache, _ = c.GetGroupSystemMessages() c.groupSysMsgCache, _ = c.GetGroupSystemMessages()
return return
} }
@ -243,12 +243,12 @@ func decodeSystemMsgGroupPacket(c *QQClient, _ *network.IncomingPacketInfo, payl
ActionUinNick: st.Msg.ActionUinQqNick, ActionUinNick: st.Msg.ActionUinQqNick,
}) })
default: default:
c.Debug("unknown group system message type: %v", st.Msg.GroupMsgType) c.debug("unknown group system message type: %v", st.Msg.GroupMsgType)
} }
case 3: // ? case 3: // ?
case 5: // 自身状态变更(管理员/加群退群) case 5: // 自身状态变更(管理员/加群退群)
default: default:
c.Debug("unknown group system msg: %v", st.Msg.SubType) c.debug("unknown group system msg: %v", st.Msg.SubType)
} }
} }
return ret, nil return ret, nil

View File

@ -139,11 +139,11 @@ func (c *QQClient) decodeT119R(data []byte) {
if t120, ok := m[0x120]; ok { if t120, ok := m[0x120]; ok {
c.sig.SKey = t120 c.sig.SKey = t120
c.sig.SKeyExpiredTime = time.Now().Unix() + 21600 c.sig.SKeyExpiredTime = time.Now().Unix() + 21600
c.Debug("skey updated: %v", c.sig.SKey) c.debug("skey updated: %v", c.sig.SKey)
} }
if t11a, ok := m[0x11a]; ok { if t11a, ok := m[0x11a]; ok {
c.Nickname, c.Age, c.Gender = readT11A(t11a) c.Nickname, c.Age, c.Gender = readT11A(t11a)
c.Debug("account info updated: " + c.Nickname) c.debug("account info updated: " + c.Nickname)
} }
} }