158 lines
4.6 KiB
Go
158 lines
4.6 KiB
Go
package wxrouter
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
"xiawan/wx/clientsdk"
|
|
"xiawan/wx/clientsdk/baseinfo"
|
|
"xiawan/wx/clientsdk/baseutils"
|
|
"xiawan/wx/db"
|
|
"xiawan/wx/protobuf/wechat"
|
|
"xiawan/wx/srv/wxcore"
|
|
"xiawan/wx/srv/wxface"
|
|
|
|
"github.com/gogo/protobuf/proto"
|
|
)
|
|
|
|
// WXCheckQrcodeRouter 检测二维码状态响应路由
|
|
type WXCheckQrcodeRouter struct {
|
|
wxcore.WXBaseRouter
|
|
}
|
|
|
|
// Handle 处理conn业务的方法
|
|
func (cqr *WXCheckQrcodeRouter) Handle(wxResp wxface.IWXResponse) error {
|
|
defer wxcore.TryE("WXCheckQrcodeRouter Handle")
|
|
currentWXConn := wxResp.GetWXConncet()
|
|
currentAccount := currentWXConn.GetWXAccount()
|
|
currentInvoker := currentWXConn.GetWXReqInvoker()
|
|
currentCache := currentWXConn.GetWXCache()
|
|
currentUserInfo := currentAccount.GetUserInfo()
|
|
|
|
// 解析检测二维码响应
|
|
var checkResp wechat.CheckLoginQRCodeResponse
|
|
err := clientsdk.ParseResponseData(currentUserInfo, wxResp.GetPackHeader(), &checkResp)
|
|
if err != nil {
|
|
// 请求出问题了,判断是否掉线,并重连
|
|
currentWXConn.Stop()
|
|
return err
|
|
}
|
|
|
|
// 解密出现问题,说明协议出现了问题
|
|
qrcodeInfo := currentCache.GetQrcodeInfo()
|
|
retBytes, err := baseutils.AesDecryptByteKey(checkResp.LoginQrcodeNotifyPkg.NotifyData.Buffer, qrcodeInfo.QrCodeKey)
|
|
|
|
if err != nil {
|
|
// 请求出问题了,应该关闭链接
|
|
currentWXConn.Stop()
|
|
return err
|
|
}
|
|
|
|
lgQrNotify := &wechat.LoginQRCodeNotify{}
|
|
err = proto.Unmarshal(retBytes, lgQrNotify)
|
|
if err != nil {
|
|
// 请求出问题了,应该关闭链接
|
|
currentWXConn.Stop()
|
|
return err
|
|
}
|
|
|
|
errMsg := ""
|
|
if lgQrNotify.GetState() == 2 {
|
|
// 每秒查一次数据库太频繁了,这里改为仅在扫码成功后查一次
|
|
bind, _ := db.IsLicenseBind(currentUserInfo.UUID)
|
|
if bind != nil && len(lgQrNotify.GetWxid()) > 0 && lgQrNotify.GetWxid() != bind.WxId {
|
|
errMsg = "该授权码(KEY)已绑定其他微信号, 请换一个KEY"
|
|
}
|
|
|
|
}
|
|
|
|
// 添加扫码状态缓存
|
|
db.AddCheckStatusCache(currentUserInfo.UUID, &baseinfo.CheckLoginQrCodeResult{
|
|
LoginQRCodeNotify: lgQrNotify,
|
|
Msg: errMsg,
|
|
})
|
|
|
|
if len(errMsg) != 0 {
|
|
// 当前 License 已绑定其他微信号, 需要更换 License
|
|
currentWXConn.Stop()
|
|
return errors.New(errMsg)
|
|
}
|
|
|
|
str := byteArrayToString(retBytes)
|
|
ticketValue := extractTicketValue(str)
|
|
// fmt.Println(ticketValue, 111111111111)
|
|
|
|
if ticketValue != "" {
|
|
// 赋值ticketValue
|
|
currentUserInfo.Ticket = ticketValue
|
|
currentUserInfo.LoginDataInfo.Ticket = ticketValue
|
|
db.AddCheckStatusCache(currentUserInfo.UUID, &baseinfo.CheckLoginQrCodeResult{
|
|
LoginQRCodeNotify: lgQrNotify,
|
|
Msg: "请提交验证码后登录",
|
|
Ret: int32(0),
|
|
})
|
|
}
|
|
|
|
if lgQrNotify.GetState() == 2 {
|
|
// 扫码成功发送登录包
|
|
err := currentInvoker.SendManualAuthRequest(lgQrNotify.GetWxnewpass(), lgQrNotify.GetWxid())
|
|
if err != nil {
|
|
// 在停止连接前,确保扫码状态被正确持久化保存
|
|
db.AddCheckStatusCache(currentUserInfo.UUID, &baseinfo.CheckLoginQrCodeResult{
|
|
LoginQRCodeNotify: lgQrNotify,
|
|
Msg: "登录包发送失败:" + err.Error(),
|
|
Ret: int32(300),
|
|
})
|
|
// 确保状态被保存后再停止连接
|
|
time.Sleep(time.Millisecond * 200)
|
|
currentWXConn.Stop()
|
|
return err
|
|
}
|
|
go func() {
|
|
// 3 秒后发送指令
|
|
time.Sleep(3 * time.Second)
|
|
currentCache.SetScanFinish(true)
|
|
|
|
// 扫码完成后再次更新状态缓存,确保登录成功的状态被持久化
|
|
db.AddCheckStatusCache(currentUserInfo.UUID, &baseinfo.CheckLoginQrCodeResult{
|
|
LoginQRCodeNotify: lgQrNotify,
|
|
Msg: "登录成功",
|
|
Ret: int32(0),
|
|
})
|
|
}()
|
|
} else if lgQrNotify.GetState() == 4 {
|
|
// 在停止连接前,确保状态被正确保存
|
|
db.AddCheckStatusCache(currentUserInfo.UUID, &baseinfo.CheckLoginQrCodeResult{
|
|
LoginQRCodeNotify: lgQrNotify,
|
|
Msg: "二维码失效",
|
|
Ret: int32(301),
|
|
})
|
|
// 确保状态被保存后再停止连接
|
|
time.Sleep(time.Millisecond * 200)
|
|
currentWXConn.Stop()
|
|
return errors.New("WXCheckQrcodeRouter err: 二维码失效")
|
|
} else {
|
|
currentUserInfo.HeadURL = lgQrNotify.GetHeadImgUrl()
|
|
err := currentWXConn.GetWXReqInvoker().SendCheckLoginQrcodeRequest(qrcodeInfo.QrCodeUUID, qrcodeInfo.QrCodeKey)
|
|
if err != nil {
|
|
currentWXConn.Stop()
|
|
return err
|
|
}
|
|
time.Sleep(time.Second)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func byteArrayToString(data []byte) string {
|
|
return string(data)
|
|
}
|
|
|
|
func extractTicketValue(str string) string {
|
|
index := strings.Index(str, "ticket=")
|
|
if index == -1 {
|
|
return ""
|
|
}
|
|
return str[index+len("ticket="):]
|
|
}
|