Skip to content

Commit

Permalink
optimize login speed.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mrs4s committed Mar 4, 2021
1 parent 6c17f29 commit ffb9cc5
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 81 deletions.
32 changes: 16 additions & 16 deletions client/c2c_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"google.golang.org/protobuf/proto"
)

var c2cDecoders = map[int32]func(*QQClient, *msg.Message, *c2cExtraOption){
var c2cDecoders = map[int32]func(*QQClient, *msg.Message, *incomingPacketInfo){
33: troopAddMemberBroadcastDecoder,
35: troopSystemMessageDecoder, 36: troopSystemMessageDecoder, 37: troopSystemMessageDecoder,
45: troopSystemMessageDecoder, 46: troopSystemMessageDecoder, 84: troopSystemMessageDecoder,
Expand All @@ -25,11 +25,7 @@ var c2cDecoders = map[int32]func(*QQClient, *msg.Message, *c2cExtraOption){
529: msgType0x211Decoder,
}

type c2cExtraOption struct {
UsedRegProxy bool
}

func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, opt *c2cExtraOption) {
func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, info *incomingPacketInfo) {
c.syncCookie = rsp.SyncCookie
c.pubAccountCookie = rsp.PubAccountCookie
c.msgCtrlBuf = rsp.MsgCtrlBuf
Expand Down Expand Up @@ -59,8 +55,11 @@ func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, opt *c2c
continue
}
c.msgSvcCache.Add(strKey, "", time.Minute*5)
if info.Params.bool("init") {
continue
}
if decoder, ok := c2cDecoders[pMsg.Head.GetMsgType()]; ok {
decoder(c, pMsg, opt)
decoder(c, pMsg, info)
}
/*
switch pMsg.Head.GetMsgType() {
Expand Down Expand Up @@ -150,11 +149,12 @@ func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, opt *c2c
_, _ = c.sendAndWait(c.buildDeleteMessageRequestPacket(delItems))
if rsp.GetSyncFlag() != msg.SyncFlag_STOP {
c.Debug("continue sync with flag: %v", rsp.SyncFlag.String())
_, _ = c.sendAndWait(c.buildGetMessageRequestPacket(rsp.GetSyncFlag(), time.Now().Unix()))
seq, pkt := c.buildGetMessageRequestPacket(rsp.GetSyncFlag(), time.Now().Unix())
_, _ = c.sendAndWait(seq, pkt, info.Params)
}
}

func privateMessageDecoder(c *QQClient, pMsg *msg.Message, _ *c2cExtraOption) {
func privateMessageDecoder(c *QQClient, pMsg *msg.Message, _ *incomingPacketInfo) {
if pMsg.Head.GetFromUin() == c.Uin {
for {
frdSeq := atomic.LoadInt32(&c.friendSeq)
Expand All @@ -173,7 +173,7 @@ func privateMessageDecoder(c *QQClient, pMsg *msg.Message, _ *c2cExtraOption) {
c.dispatchFriendMessage(c.parsePrivateMessage(pMsg))
}

func privatePttDecoder(c *QQClient, pMsg *msg.Message, _ *c2cExtraOption) {
func privatePttDecoder(c *QQClient, pMsg *msg.Message, _ *incomingPacketInfo) {
if pMsg.Body == nil || pMsg.Body.RichText == nil || pMsg.Body.RichText.Ptt == nil {
return
}
Expand All @@ -184,7 +184,7 @@ func privatePttDecoder(c *QQClient, pMsg *msg.Message, _ *c2cExtraOption) {
c.dispatchFriendMessage(c.parsePrivateMessage(pMsg))
}

func tempSessionDecoder(c *QQClient, pMsg *msg.Message, _ *c2cExtraOption) {
func tempSessionDecoder(c *QQClient, pMsg *msg.Message, _ *incomingPacketInfo) {
if pMsg.Head.C2CTmpMsgHead == nil || pMsg.Body == nil {
return
}
Expand All @@ -200,7 +200,7 @@ func tempSessionDecoder(c *QQClient, pMsg *msg.Message, _ *c2cExtraOption) {
}
}

func troopAddMemberBroadcastDecoder(c *QQClient, pMsg *msg.Message, _ *c2cExtraOption) {
func troopAddMemberBroadcastDecoder(c *QQClient, pMsg *msg.Message, _ *incomingPacketInfo) {
groupJoinLock.Lock()
defer groupJoinLock.Unlock()
group := c.FindGroupByUin(pMsg.Head.GetFromUin())
Expand All @@ -226,13 +226,13 @@ func troopAddMemberBroadcastDecoder(c *QQClient, pMsg *msg.Message, _ *c2cExtraO
}
}

func systemMessageDecoder(c *QQClient, pMsg *msg.Message, _ *c2cExtraOption) {
func systemMessageDecoder(c *QQClient, pMsg *msg.Message, _ *incomingPacketInfo) {
_, pkt := c.buildSystemMsgNewFriendPacket()
_ = c.send(pkt)
}

func troopSystemMessageDecoder(c *QQClient, pMsg *msg.Message, opt *c2cExtraOption) {
if !opt.UsedRegProxy && pMsg.Head.GetMsgType() != 85 && pMsg.Head.GetMsgType() != 36 {
func troopSystemMessageDecoder(c *QQClient, pMsg *msg.Message, info *incomingPacketInfo) {
if !info.Params.bool("used_reg_proxy") && pMsg.Head.GetMsgType() != 85 && pMsg.Head.GetMsgType() != 36 {
c.exceptAndDispatchGroupSysMsg()
}
if len(pMsg.Body.GetMsgContent()) == 0 {
Expand All @@ -246,7 +246,7 @@ func troopSystemMessageDecoder(c *QQClient, pMsg *msg.Message, opt *c2cExtraOpti
}
}

func msgType0x211Decoder(c *QQClient, pMsg *msg.Message, _ *c2cExtraOption) {
func msgType0x211Decoder(c *QQClient, pMsg *msg.Message, _ *incomingPacketInfo) {
sub4 := msg.SubMsgType0X4Body{}
if err := proto.Unmarshal(pMsg.Body.MsgContent, &sub4); err != nil {
err = errors.Wrap(err, "unmarshal sub msg 0x4 error")
Expand Down
39 changes: 31 additions & 8 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (

var json = jsoniter.ConfigFastest

//go:generate go run github.com/a8m/syncmap -o "handler_map_gen.go" -pkg client -name HandlerMap "map[uint16]func(i interface{}, err error)"
//go:generate go run github.com/a8m/syncmap -o "handler_map_gen.go" -pkg client -name HandlerMap "map[uint16]*handlerInfo"

type QQClient struct {
Uin int64
Expand Down Expand Up @@ -121,6 +121,11 @@ type loginSigInfo struct {
pt4TokenMap map[string][]byte
}

type handlerInfo struct {
fun func(i interface{}, err error)
params requestParams
}

var decoders = map[string]func(*QQClient, *incomingPacketInfo, []byte) (interface{}, error){
"wtlogin.login": decodeLoginResponse,
"wtlogin.exchange_emp": decodeExchangeEmpResponse,
Expand Down Expand Up @@ -313,7 +318,10 @@ func (c *QQClient) init() {
go c.doHeartbeat()
}
_ = c.RefreshStatus()
_, _ = c.sendAndWait(c.buildGetMessageRequestPacket(msg.SyncFlag_START, time.Now().Unix()))
go func() {
seq, pkt := c.buildGetMessageRequestPacket(msg.SyncFlag_START, time.Now().Unix())
_, _ = c.sendAndWait(seq, pkt, requestParams{"used_reg_proxy": true, "init": true})
}()
_, _ = c.SyncSessions()
c.stat.once.Do(func() {
c.OnGroupMessage(func(_ *QQClient, _ *message.GroupMessage) {
Expand Down Expand Up @@ -796,7 +804,7 @@ func (c *QQClient) send(pkt []byte) error {
return errors.Wrap(err, "Packet failed to send")
}

func (c *QQClient) sendAndWait(seq uint16, pkt []byte) (interface{}, error) {
func (c *QQClient) sendAndWait(seq uint16, pkt []byte, params ...requestParams) (interface{}, error) {
type T struct {
Response interface{}
Error error
Expand All @@ -809,12 +817,20 @@ func (c *QQClient) sendAndWait(seq uint16, pkt []byte) (interface{}, error) {

ch := make(chan T)
defer close(ch)
c.handlers.Store(seq, func(i interface{}, err error) {

p := func() requestParams {
if len(params) == 0 {
return nil
}
return params[0]
}()

c.handlers.Store(seq, &handlerInfo{fun: func(i interface{}, err error) {
ch <- T{
Response: i,
Error: err,
}
})
}, params: p})

retry := 0
for true {
Expand Down Expand Up @@ -916,21 +932,28 @@ func (c *QQClient) netLoop() {

if decoder, ok := decoders[pkt.CommandName]; ok {
// found predefined decoder
info, ok := c.handlers.LoadAndDelete(pkt.SequenceId)
rsp, err := decoder(c, &incomingPacketInfo{
SequenceId: pkt.SequenceId,
CommandName: pkt.CommandName,
Params: func() requestParams {
if !ok {
return nil
}
return info.params
}(),
}, payload)
if err != nil {
c.Debug("decode pkt %v error: %+v", pkt.CommandName, err)
}
if f, ok := c.handlers.LoadAndDelete(pkt.SequenceId); ok {
f(rsp, err)
if ok {
info.fun(rsp, err)
} else if f, ok := c.waiters.Load(pkt.CommandName); ok { // 在不存在handler的情况下触发wait
f.(func(interface{}, error))(rsp, err)
}
} else if f, ok := c.handlers.LoadAndDelete(pkt.SequenceId); ok {
// does not need decoder
f(nil, nil)
f.fun(nil, nil)
} else {
c.Debug("Unhandled Command: %s\nSeq: %d\nThis message can be ignored.", pkt.CommandName, pkt.SequenceId)
}
Expand Down
4 changes: 2 additions & 2 deletions client/decoders.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,13 +288,13 @@ func decodePushReqPacket(c *QQClient, _ *incomingPacketInfo, payload []byte) (in
}

// MessageSvc.PbGetMsg
func decodeMessageSvcPacket(c *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
func decodeMessageSvcPacket(c *QQClient, info *incomingPacketInfo, payload []byte) (interface{}, error) {
rsp := msg.GetMessageResponse{}
err := proto.Unmarshal(payload, &rsp)
if err != nil {
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
}
c.c2cMessageSyncProcessor(&rsp, &c2cExtraOption{UsedRegProxy: false})
c.c2cMessageSyncProcessor(&rsp, info)
return nil, nil
}

Expand Down
14 changes: 14 additions & 0 deletions client/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ type (
incomingPacketInfo struct {
CommandName string
SequenceId uint16
Params requestParams
}

requestParams map[string]interface{}
)

// default
Expand Down Expand Up @@ -584,6 +587,17 @@ func genLongTemplate(resId, brief string, ts int64) *message.ServiceElement {
}
}

func (p requestParams) bool(k string) bool {
if p == nil {
return false
}
i, ok := p[k]
if !ok {
return false
}
return i.(bool)
}

func (c *QQClient) packOIDBPackage(cmd, serviceType int32, body []byte) []byte {
pkg := &oidb.OIDBSSOPkg{
Command: cmd,
Expand Down
Loading

0 comments on commit ffb9cc5

Please sign in to comment.