@@ -3,29 +3,21 @@ package gocq
3
3
import (
4
4
"bufio"
5
5
"bytes"
6
- "encoding/hex"
7
6
"fmt"
8
7
"image"
9
8
"image/png"
10
- "net/http"
11
- "net/url"
12
9
"os"
13
- "strconv"
14
10
"strings"
15
- "sync"
16
- "sync/atomic"
17
11
"time"
18
12
19
13
"github.com/Mrs4s/MiraiGo/client"
20
14
"github.com/Mrs4s/MiraiGo/utils"
21
15
"github.com/mattn/go-colorable"
22
16
"github.com/pkg/errors"
23
17
log "github.com/sirupsen/logrus"
24
- "github.com/tidwall/gjson"
25
18
"gopkg.ilharper.com/x/isatty"
26
19
27
20
"github.com/Mrs4s/go-cqhttp/global"
28
- "github.com/Mrs4s/go-cqhttp/internal/base"
29
21
"github.com/Mrs4s/go-cqhttp/internal/download"
30
22
)
31
23
@@ -268,279 +260,3 @@ func fetchCaptcha(id string) string {
268
260
}
269
261
return ""
270
262
}
271
-
272
- func energy (uin uint64 , id string , _ string , salt []byte ) ([]byte , error ) {
273
- signServer := base .SignServer
274
- if ! strings .HasSuffix (signServer , "/" ) {
275
- signServer += "/"
276
- }
277
- headers := make (map [string ]string )
278
- signServerBearer := base .SignServerBearer
279
- if signServerBearer != "-" && signServerBearer != "" {
280
- headers ["Authorization" ] = "Bearer " + signServerBearer
281
- }
282
- req := download.Request {
283
- Method : http .MethodGet ,
284
- Header : headers ,
285
- URL : signServer + "custom_energy" + fmt .Sprintf ("?data=%v&salt=%v&uin=%v&android_id=%v&guid=%v" ,
286
- id , hex .EncodeToString (salt ), uin , utils .B2S (device .AndroidId ), hex .EncodeToString (device .Guid )),
287
- }.WithTimeout (time .Duration (base .SignServerTimeout ) * time .Second )
288
- if base .IsBelow110 {
289
- req .URL = signServer + "custom_energy" + fmt .Sprintf ("?data=%v&salt=%v" , id , hex .EncodeToString (salt ))
290
- }
291
- response , err := req .Bytes ()
292
- if err != nil {
293
- log .Warnf ("获取T544 sign时出现错误: %v server: %v" , err , signServer )
294
- return nil , err
295
- }
296
- data , err := hex .DecodeString (gjson .GetBytes (response , "data" ).String ())
297
- if err != nil {
298
- log .Warnf ("获取T544 sign时出现错误: %v" , err )
299
- return nil , err
300
- }
301
- if len (data ) == 0 {
302
- log .Warnf ("获取T544 sign时出现错误: %v" , "data is empty" )
303
- return nil , errors .New ("data is empty" )
304
- }
305
- return data , nil
306
- }
307
-
308
- // signSubmit 提交的操作类型
309
- func signSubmit (uin string , cmd string , callbackID int64 , buffer []byte , t string ) {
310
- signServer := base .SignServer
311
- if ! strings .HasSuffix (signServer , "/" ) {
312
- signServer += "/"
313
- }
314
- buffStr := hex .EncodeToString (buffer )
315
- log .Infof ("submit %v: uin=%v, cmd=%v, callbackID=%v, buffer-end=%v" , t , uin , cmd , callbackID ,
316
- buffStr [len (buffStr )- 10 :])
317
- _ , err := download.Request {
318
- Method : http .MethodGet ,
319
- URL : signServer + "submit" + fmt .Sprintf ("?uin=%v&cmd=%v&callback_id=%v&buffer=%v" ,
320
- uin , cmd , callbackID , buffStr ),
321
- }.WithTimeout (time .Duration (base .SignServerTimeout ) * time .Second ).Bytes ()
322
- if err != nil {
323
- log .Warnf ("提交 callback 时出现错误: %v server: %v" , err , signServer )
324
- }
325
- }
326
-
327
- // signCallback request token 和签名的回调
328
- func signCallback (uin string , results []gjson.Result , t string ) {
329
- for _ , result := range results {
330
- cmd := result .Get ("cmd" ).String ()
331
- callbackID := result .Get ("callbackId" ).Int ()
332
- body , _ := hex .DecodeString (result .Get ("body" ).String ())
333
- ret , err := cli .SendSsoPacket (cmd , body )
334
- if err != nil {
335
- log .Warnf ("callback error: %v" , err )
336
- }
337
- signSubmit (uin , cmd , callbackID , ret , t )
338
- }
339
- }
340
-
341
- func signRequset (seq uint64 , uin string , cmd string , qua string , buff []byte ) (sign []byte , extra []byte , token []byte , err error ) {
342
- signServer := base .SignServer
343
- if ! strings .HasSuffix (signServer , "/" ) {
344
- signServer += "/"
345
- }
346
- headers := map [string ]string {"Content-Type" : "application/x-www-form-urlencoded" }
347
- signServerBearer := base .SignServerBearer
348
- if signServerBearer != "-" && signServerBearer != "" {
349
- headers ["Authorization" ] = "Bearer " + signServerBearer
350
- }
351
- response , err := download.Request {
352
- Method : http .MethodPost ,
353
- URL : signServer + "sign" ,
354
- Header : headers ,
355
- Body : bytes .NewReader ([]byte (fmt .Sprintf ("uin=%v&qua=%s&cmd=%s&seq=%v&buffer=%v&android_id=%v&guid=%v" ,
356
- uin , qua , cmd , seq , hex .EncodeToString (buff ), utils .B2S (device .AndroidId ), hex .EncodeToString (device .Guid )))),
357
- }.WithTimeout (time .Duration (base .SignServerTimeout ) * time .Second ).Bytes ()
358
- if err != nil {
359
- return nil , nil , nil , err
360
- }
361
- sign , _ = hex .DecodeString (gjson .GetBytes (response , "data.sign" ).String ())
362
- extra , _ = hex .DecodeString (gjson .GetBytes (response , "data.extra" ).String ())
363
- token , _ = hex .DecodeString (gjson .GetBytes (response , "data.token" ).String ())
364
- if ! base .IsBelow110 {
365
- go signCallback (uin , gjson .GetBytes (response , "data.requestCallback" ).Array (), "sign" )
366
- }
367
- return sign , extra , token , nil
368
- }
369
-
370
- var registerLock sync.Mutex
371
-
372
- func signRegister (uin int64 , androidID , guid []byte , qimei36 , key string ) {
373
- if base .IsBelow110 {
374
- log .Warn ("签名服务器版本低于1.1.0, 跳过实例注册" )
375
- return
376
- }
377
- signServer := base .SignServer
378
- if ! strings .HasSuffix (signServer , "/" ) {
379
- signServer += "/"
380
- }
381
- resp , err := download.Request {
382
- Method : http .MethodGet ,
383
- URL : signServer + "register" + fmt .Sprintf ("?uin=%v&android_id=%v&guid=%v&qimei36=%v&key=%s" ,
384
- uin , utils .B2S (androidID ), hex .EncodeToString (guid ), qimei36 , key ),
385
- }.WithTimeout (time .Duration (base .SignServerTimeout ) * time .Second ).Bytes ()
386
- if err != nil {
387
- log .Warnf ("注册QQ实例时出现错误: %v server: %v" , err , signServer )
388
- return
389
- }
390
- msg := gjson .GetBytes (resp , "msg" )
391
- if gjson .GetBytes (resp , "code" ).Int () != 0 {
392
- log .Warnf ("注册QQ实例时出现错误: %v server: %v" , msg , signServer )
393
- return
394
- }
395
- log .Infof ("注册QQ实例 %v 成功: %v" , uin , msg )
396
- }
397
-
398
- func signRefreshToken (uin string ) error {
399
- signServer := base .SignServer
400
- if ! strings .HasSuffix (signServer , "/" ) {
401
- signServer += "/"
402
- }
403
- log .Info ("正在刷新 token" )
404
- resp , err := download.Request {
405
- Method : http .MethodGet ,
406
- URL : signServer + "request_token" + fmt .Sprintf ("?uin=%v" , uin ),
407
- }.WithTimeout (time .Duration (base .SignServerTimeout ) * time .Second ).Bytes ()
408
- if err != nil {
409
- return err
410
- }
411
- msg := gjson .GetBytes (resp , "msg" )
412
- if gjson .GetBytes (resp , "code" ).Int () != 0 {
413
- return errors .New (msg .String ())
414
- }
415
- go signCallback (uin , gjson .GetBytes (resp , "data" ).Array (), "request token" )
416
- return nil
417
- }
418
-
419
- var missTokenCount = uint64 (0 )
420
-
421
- func sign (seq uint64 , uin string , cmd string , qua string , buff []byte ) (sign []byte , extra []byte , token []byte , err error ) {
422
- i := 0
423
- for {
424
- sign , extra , token , err = signRequset (seq , uin , cmd , qua , buff )
425
- if err != nil {
426
- log .Warnf ("获取sso sign时出现错误: %v server: %v" , err , base .SignServer )
427
- }
428
- if i > 0 {
429
- break
430
- }
431
- i ++
432
- if (! base .IsBelow110 ) && base .Account .AutoRegister && err == nil && len (sign ) == 0 {
433
- if registerLock .TryLock () { // 避免并发时多处同时销毁并重新注册
434
- log .Warn ("获取签名为空,实例可能丢失,正在尝试重新注册" )
435
- defer registerLock .Unlock ()
436
- err := signServerDestroy (uin )
437
- if err != nil {
438
- log .Warnln (err )
439
- return nil , nil , nil , err
440
- }
441
- signRegister (base .Account .Uin , device .AndroidId , device .Guid , device .QImei36 , base .Key )
442
- }
443
- continue
444
- }
445
- if (! base .IsBelow110 ) && base .Account .AutoRefreshToken && len (token ) == 0 {
446
- log .Warnf ("token 已过期, 总丢失 token 次数为 %v" , atomic .AddUint64 (& missTokenCount , 1 ))
447
- if registerLock .TryLock () {
448
- defer registerLock .Unlock ()
449
- if err := signRefreshToken (uin ); err != nil {
450
- log .Warnf ("刷新 token 出现错误: %v server: %v" , err , base .SignServer )
451
- } else {
452
- log .Info ("刷新 token 成功" )
453
- }
454
- }
455
- continue
456
- }
457
- break
458
- }
459
- return sign , extra , token , err
460
- }
461
-
462
- func signServerDestroy (uin string ) error {
463
- signServer := base .SignServer
464
- if ! strings .HasSuffix (signServer , "/" ) {
465
- signServer += "/"
466
- }
467
- signVersion , err := signVersion ()
468
- if err != nil {
469
- return errors .Wrapf (err , "获取签名服务版本出现错误, server: %v" , signServer )
470
- }
471
- if global .VersionNameCompare ("v" + signVersion , "v1.1.6" ) {
472
- return errors .Errorf ("当前签名服务器版本 %v 低于 1.1.6,无法使用 destroy 接口" , signVersion )
473
- }
474
- resp , err := download.Request {
475
- Method : http .MethodGet ,
476
- URL : signServer + "destroy" + fmt .Sprintf ("?uin=%v&key=%v" , uin , base .Key ),
477
- }.WithTimeout (time .Duration (base .SignServerTimeout ) * time .Second ).Bytes ()
478
- if err != nil || gjson .GetBytes (resp , "code" ).Int () != 0 {
479
- return errors .Wrapf (err , "destroy 实例出现错误, server: %v" , signServer )
480
- }
481
- return nil
482
- }
483
-
484
- func signVersion () (version string , err error ) {
485
- signServer := base .SignServer
486
- resp , err := download.Request {
487
- Method : http .MethodGet ,
488
- URL : signServer ,
489
- }.WithTimeout (time .Duration (base .SignServerTimeout ) * time .Second ).Bytes ()
490
- if err != nil {
491
- return "" , err
492
- }
493
- if gjson .GetBytes (resp , "code" ).Int () == 0 {
494
- return gjson .GetBytes (resp , "data.version" ).String (), nil
495
- }
496
- return "" , errors .New ("empty version" )
497
- }
498
-
499
- // 定时刷新 token, interval 为间隔时间(分钟)
500
- func signStartRefreshToken (interval int64 ) {
501
- if interval <= 0 {
502
- log .Warn ("定时刷新 token 已关闭" )
503
- return
504
- }
505
- log .Infof ("每 %v 分钟将刷新一次签名 token" , interval )
506
- if interval < 10 {
507
- log .Warnf ("间隔时间 %v 分钟较短,推荐 30~40 分钟" , interval )
508
- }
509
- if interval > 60 {
510
- log .Warn ("间隔时间不能超过 60 分钟,已自动设置为 60 分钟" )
511
- interval = 60
512
- }
513
- t := time .NewTicker (time .Duration (interval ) * time .Minute )
514
- defer t .Stop ()
515
- for range t .C {
516
- err := signRefreshToken (strconv .FormatInt (base .Account .Uin , 10 ))
517
- if err != nil {
518
- log .Warnf ("刷新 token 出现错误: %v server: %v" , err , base .SignServer )
519
- }
520
- }
521
- }
522
-
523
- func signWaitServer () bool {
524
- t := time .NewTicker (time .Second * 5 )
525
- defer t .Stop ()
526
- i := 0
527
- for range t .C {
528
- if i > 3 {
529
- return false
530
- }
531
- i ++
532
- u , err := url .Parse (base .SignServer )
533
- if err != nil {
534
- log .Warnf ("连接到签名服务器出现错误: %v" , err )
535
- continue
536
- }
537
- r := utils .RunTCPPingLoop (u .Host , 4 )
538
- if r .PacketsLoss > 0 {
539
- log .Warnf ("连接到签名服务器出现错误: 丢包%d/%d 时延%dms" , r .PacketsLoss , r .PacketsSent , r .AvgTimeMill )
540
- continue
541
- }
542
- break
543
- }
544
- log .Infof ("连接至签名服务器: %s" , base .SignServer )
545
- return true
546
- }
0 commit comments