77 "fmt"
88 "net/http"
99 "strings"
10+ "sync"
11+ "sync/atomic"
1012
1113 "chatgpt-adapter/core/common"
1214 "chatgpt-adapter/core/logger"
@@ -16,12 +18,18 @@ import (
1618
1719const (
1820 baseUrl = "https://legacy.lmarena.ai"
19- ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0"
2021)
2122
2223var (
2324 baseCookies = "_gid=GA1.2.68066840.1717017781; _ga_K6D24EE9ED=GS1.1.1717087813.23.1.1717088648.0.0.0; _gat_gtag_UA_156449732_1=1; _ga_R1FN4KJKJH=GS1.1.1717087813.37.1.1717088648.0.0.0; _ga=GA1.1.1320014795.1715641484"
2425 ver = ""
26+
27+ userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0"
28+ clearance = ""
29+ lang = ""
30+
31+ mu sync.Mutex
32+ state int32 = 0 // 0 常态 1 等待中
2533)
2634
2735type options struct {
@@ -78,11 +86,11 @@ func partTwo(ctx context.Context, proxied, cookies, hash string, opts options) e
7886 POST (baseUrl + "/queue/join" ).
7987 JSONHeader ().
8088 Ja3 ().
81- Header ("User-Agent" , ua ).
89+ Header ("User-Agent" , userAgent ).
8290 Header ("Cookie" , cookies ).
8391 Header ("Origin" , baseUrl ).
8492 Header ("Referer" , baseUrl + "/" ).
85- Header ("Accept-Language" , "en-US,en;q=0.9" ).
93+ Header ("Accept-Language" , lang ).
8694 Header ("Cache-Control" , "no-cache" ).
8795 Header ("Priority" , "u=1, i" ).
8896 Body (obj ).
@@ -112,11 +120,11 @@ func partTwo(ctx context.Context, proxied, cookies, hash string, opts options) e
112120 Ja3 ().
113121 GET (baseUrl + "/queue/data" ).
114122 Query ("session_hash" , hash ).
115- Header ("User-Agent" , ua ).
123+ Header ("User-Agent" , userAgent ).
116124 Header ("Cookie" , cookies ).
117125 Header ("Origin" , baseUrl ).
118126 Header ("Referer" , baseUrl + "/" ).
119- Header ("Accept-Language" , "en-US,en;q=0.9" ).
127+ Header ("Accept-Language" , lang ).
120128 Header ("Cache-Control" , "no-cache" ).
121129 Header ("Priority" , "u=1, i" ).
122130 DoS (http .StatusOK )
@@ -153,11 +161,11 @@ func partThree(ctx context.Context, proxied, cookies, hash string, opts options)
153161 POST (baseUrl + "/queue/join" ).
154162 JSONHeader ().
155163 Ja3 ().
156- Header ("User-Agent" , ua ).
164+ Header ("User-Agent" , userAgent ).
157165 Header ("Cookie" , cookies ).
158166 Header ("Origin" , baseUrl ).
159167 Header ("Referer" , baseUrl + "/" ).
160- Header ("Accept-Language" , "en-US,en;q=0.9" ).
168+ Header ("Accept-Language" , lang ).
161169 Header ("Cache-Control" , "no-cache" ).
162170 Header ("Priority" , "u=1, i" ).
163171 Body (obj ).
@@ -185,11 +193,11 @@ func partThree(ctx context.Context, proxied, cookies, hash string, opts options)
185193 Ja3 ().
186194 GET (baseUrl + "/queue/data" ).
187195 Query ("session_hash" , hash ).
188- Header ("User-Agent" , ua ).
196+ Header ("User-Agent" , userAgent ).
189197 Header ("Cookie" , cookies ).
190198 Header ("Origin" , baseUrl ).
191199 Header ("Referer" , baseUrl + "/" ).
192- Header ("Accept-Language" , "en-US,en;q=0.9" ).
200+ Header ("Accept-Language" , lang ).
193201 Header ("Cache-Control" , "no-cache" ).
194202 Header ("Priority" , "u=1, i" ).
195203 DoS (http .StatusOK )
@@ -302,11 +310,11 @@ func partOne(ctx context.Context, env *env.Environment, proxied string, opts *op
302310 POST (baseUrl + "/queue/join" ).
303311 JSONHeader ().
304312 Ja3 ().
305- Header ("User-Agent" , ua ).
313+ Header ("User-Agent" , userAgent ).
306314 Header ("Cookie" , cookies ).
307315 Header ("Origin" , baseUrl ).
308316 Header ("Referer" , baseUrl + "/" ).
309- Header ("Accept-Language" , "en-US,en;q=0.9" ).
317+ Header ("Accept-Language" , lang ).
310318 Header ("Cache-Control" , "no-cache" ).
311319 Header ("Priority" , "u=1, i" ).
312320 Body (obj ).
@@ -336,11 +344,11 @@ func partOne(ctx context.Context, env *env.Environment, proxied string, opts *op
336344 Ja3 ().
337345 GET (baseUrl + "/queue/data" ).
338346 Query ("session_hash" , hash ).
339- Header ("User-Agent" , ua ).
347+ Header ("User-Agent" , userAgent ).
340348 Header ("Cookie" , cookies ).
341349 Header ("Origin" , baseUrl ).
342350 Header ("Referer" , baseUrl + "/" ).
343- Header ("Accept-Language" , "en-US,en;q=0.9" ).
351+ Header ("Accept-Language" , lang ).
344352 Header ("Cache-Control" , "no-cache" ).
345353 Header ("Priority" , "u=1, i" ).
346354 DoS (http .StatusOK )
@@ -420,6 +428,7 @@ func fetchCookies(ctx context.Context, proxied string) (cookies string) {
420428 if ver != "" {
421429 cookies = fmt .Sprintf ("SERVERID=%s|%s" , ver , common .Hex (5 ))
422430 cookies = emit .MergeCookies (baseCookies , cookies )
431+ cookies = emit .MergeCookies (cookies , clearance )
423432 return
424433 }
425434 retry := 3
@@ -435,14 +444,20 @@ label:
435444 Ja3 ().
436445 Header ("pragma" , "no-cache" ).
437446 Header ("cache-control" , "no-cache" ).
438- Header ("Accept-Language" , "en-US,en;q=0.9" ).
447+ Header ("Accept-Language" , lang ).
439448 Header ("Origin" , baseUrl ).
440449 Header ("Referer" , baseUrl + "/" ).
441450 Header ("priority" , "u=1, i" ).
442- Header ("cookie" , baseCookies ).
443- Header ("User-Agent" , ua ).
451+ Header ("cookie" , emit . MergeCookies ( baseCookies , clearance ) ).
452+ Header ("User-Agent" , userAgent ).
444453 DoS (http .StatusOK )
445454 if err != nil {
455+ var emitErr emit.Error
456+ // 人机验证
457+ if errors .As (err , & emitErr ) && emitErr .Code == 403 {
458+ err = hookCloudflare (env .Env )
459+ goto label
460+ }
446461 logger .Error (err )
447462 return
448463 }
@@ -460,6 +475,54 @@ label:
460475
461476 ver = co [0 ]
462477 cookies = fmt .Sprintf ("SERVERID=%s|%s" , ver , common .Hex (5 ))
463- cookies = emit .MergeCookies (baseCookies , cookies )
478+ cookies = emit .MergeCookies (baseCookies , clearance )
464479 return
465480}
481+
482+ func hookCloudflare (env * env.Environment ) error {
483+ atomic .CompareAndSwapInt32 (& state , 0 , 1 )
484+
485+ reversalUrl := env .GetString ("browser-less.reversal" )
486+ if ! env .GetBool ("browser-less.enabled" ) && reversalUrl == "" {
487+ return errors .New ("trying cloudflare failed, please setting `browser-less.enabled` or `browser-less.reversal`" )
488+ }
489+
490+ mu .Lock ()
491+ defer mu .Unlock ()
492+ if state != 1 {
493+ return nil
494+ }
495+
496+ defer func () { state = 0 }()
497+
498+ logger .Info ("trying cloudflare ..." )
499+
500+ if reversalUrl == "" {
501+ reversalUrl = "http://127.0.0.1:" + env .GetString ("browser-less.port" )
502+ }
503+
504+ r , err := emit .ClientBuilder (common .HTTPClient ).
505+ Header ("x-website" , baseUrl ).
506+ GET (reversalUrl + "/v0/clearance" ).
507+ DoC (emit .Status (http .StatusOK ), emit .IsJSON )
508+ if err != nil {
509+ logger .Error (err )
510+ if emit .IsJSON (r ) == nil {
511+ logger .Error (emit .TextResponse (r ))
512+ }
513+ return err
514+ }
515+
516+ defer r .Body .Close ()
517+ obj , err := emit .ToMap (r )
518+ if err != nil {
519+ logger .Error (err )
520+ return err
521+ }
522+
523+ data := obj ["data" ].(map [string ]interface {})
524+ clearance = data ["cookie" ].(string )
525+ userAgent = data ["userAgent" ].(string )
526+ lang = data ["lang" ].(string )
527+ return nil
528+ }
0 commit comments