diff --git a/client/base.go b/client/base.go index 8ea78f4d..81c3a9fc 100644 --- a/client/base.go +++ b/client/base.go @@ -26,7 +26,7 @@ import ( ) // NewClient 创建一个新的 QQ Client -func NewClient(uin uint32, signUrl string, appInfo *auth.AppInfo) *QQClient { +func NewClient(uin uint32, appInfo *auth.AppInfo, signUrl ...string) *QQClient { client := &QQClient{ Uin: uin, oicq: oicq.NewCodec(int64(uin)), @@ -36,9 +36,9 @@ func NewClient(uin uint32, signUrl string, appInfo *auth.AppInfo) *QQClient { }, alive: true, } - client.signProvider = sign.NewProviderURL(signUrl, func(msg string) { + client.signProvider = sign.NewProviderURL(func(msg string) { client.debugln(msg) - }) + }, signUrl...) client.transport.Version = appInfo client.transport.Sig.D2Key = make([]byte, 0, 16) client.highwaySession.Uin = &client.transport.Sig.Uin @@ -50,7 +50,7 @@ func NewClient(uin uint32, signUrl string, appInfo *auth.AppInfo) *QQClient { type QQClient struct { Uin uint32 - signProvider sign.Provider + signProvider []sign.Provider stat Statistics once sync.Once diff --git a/client/packet.go b/client/packet.go index a865aecf..5a3902b7 100644 --- a/client/packet.go +++ b/client/packet.go @@ -9,8 +9,14 @@ import ( func (c *QQClient) uniPacket(command string, body []byte) (uint32, []byte) { seq := c.getAndIncreaseSequence() var sign map[string]string - if c.signProvider != nil { - sign = c.signProvider(command, seq, body) + // todo: 实现自动选择sign + if len(c.signProvider) != 0 { + for _, signProvider := range c.signProvider { + if sign = signProvider(command, seq, body); sign == nil { + continue + } + } + } req := network.Request{ SequenceID: seq, diff --git a/client/sign/http.go b/client/sign/http.go index a07713ca..6fd81e3e 100644 --- a/client/sign/http.go +++ b/client/sign/http.go @@ -70,42 +70,46 @@ func containSignPKG(cmd string) bool { return ok } -func NewProviderURL(rawUrl string, log func(msg string)) func(string, uint32, []byte) map[string]string { - if rawUrl == "" { +func NewProviderURL(log func(msg string), rawUrls ...string) []Provider { + if len(rawUrls) == 0 { return nil } - return func(cmd string, seq uint32, buf []byte) map[string]string { - if !containSignPKG(cmd) { - return nil - } - startTime := time.Now().UnixMilli() - resp := signResponse{} - sb := strings.Builder{} - sb.WriteString(`{"cmd":"` + cmd + `",`) - sb.WriteString(`"seq":` + strconv.Itoa(int(seq)) + `,`) - sb.WriteString(`"src":"` + fmt.Sprintf("%x", buf) + `"}`) - err := httpPost(rawUrl, bytes.NewReader(utils.S2B(sb.String())), 8*time.Second, &resp) - if err != nil || resp.Value.Sign == "" { - err := httpGet(rawUrl, map[string]string{ - "cmd": cmd, - "seq": strconv.Itoa(int(seq)), - "src": fmt.Sprintf("%x", buf), - }, 8*time.Second, &resp) - if err != nil { - log(err.Error()) + providers := make([]Provider, len(rawUrls)) + for i, rawUrl := range rawUrls { + providers[i] = func(cmd string, seq uint32, buf []byte) map[string]string { + if !containSignPKG(cmd) { return nil } - } + startTime := time.Now().UnixMilli() + resp := signResponse{} + sb := strings.Builder{} + sb.WriteString(`{"cmd":"` + cmd + `",`) + sb.WriteString(`"seq":` + strconv.Itoa(int(seq)) + `,`) + sb.WriteString(`"src":"` + fmt.Sprintf("%x", buf) + `"}`) + err := httpPost(rawUrl, bytes.NewReader(utils.S2B(sb.String())), 8*time.Second, &resp) + if err != nil || resp.Value.Sign == "" { + err := httpGet(rawUrl, map[string]string{ + "cmd": cmd, + "seq": strconv.Itoa(int(seq)), + "src": fmt.Sprintf("%x", buf), + }, 8*time.Second, &resp) + if err != nil { + log(err.Error()) + return nil + } + } - log(fmt.Sprintf("signed for [%s:%d](%dms)", - cmd, seq, time.Now().UnixMilli()-startTime)) + log(fmt.Sprintf("signed for [%s:%d](%dms)", + cmd, seq, time.Now().UnixMilli()-startTime)) - return map[string]string{ - "sign": resp.Value.Sign, - "extra": resp.Value.Extra, - "token": resp.Value.Token, + return map[string]string{ + "sign": resp.Value.Sign, + "extra": resp.Value.Extra, + "token": resp.Value.Token, + } } } + return providers } func httpGet(rawUrl string, queryParams map[string]string, timeout time.Duration, target interface{}) error { diff --git a/main.go b/main.go index a2119e32..389861a7 100644 --- a/main.go +++ b/main.go @@ -31,7 +31,7 @@ func main() { KernelVersion: "10.0.22631", } - qqclient := client.NewClient(0, "https://sign.lagrangecore.org/api/sign", appInfo) + qqclient := client.NewClient(0, appInfo, "https://sign.lagrangecore.org/api/sign") qqclient.SetLogger(protocolLogger{}) qqclient.UseDevice(deviceInfo) data, err := os.ReadFile("sig.bin")