feat: Introduce advanced TLS client with browser fingerprinting and new backend modules for API processing, authentication, mail, and ChatGPT registration.
This commit is contained in:
@@ -67,6 +67,18 @@ type TeamProcessState struct {
|
||||
|
||||
var teamProcessState = &TeamProcessState{}
|
||||
|
||||
// waitGroupWithTimeout 带超时的 WaitGroup 等待,超时返回 false
|
||||
func waitGroupWithTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
|
||||
done := make(chan struct{})
|
||||
go func() { wg.Wait(); close(done) }()
|
||||
select {
|
||||
case <-done:
|
||||
return true
|
||||
case <-time.After(timeout):
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// getProxyDisplay 获取代理显示名称(隐藏密码)
|
||||
func getProxyDisplay(proxy string) string {
|
||||
if proxy == "" {
|
||||
@@ -648,8 +660,17 @@ func processSingleTeam(idx int, req TeamProcessRequest) (result TeamProcessResul
|
||||
memberLogPrefix := fmt.Sprintf("%s [Member %d]", logPrefix, memberIdx+1)
|
||||
memberStartTime := time.Now()
|
||||
|
||||
// 获取入库信号量
|
||||
s2aSem <- struct{}{}
|
||||
// 获取入库信号量(3分钟超时)
|
||||
select {
|
||||
case s2aSem <- struct{}{}:
|
||||
case <-time.After(3 * time.Minute):
|
||||
logger.Warning(fmt.Sprintf("%s 入库信号量等待超时 (3分钟)", memberLogPrefix), memberEmail, "team")
|
||||
atomic.AddInt32(&s2aFailCount, 1)
|
||||
memberMu.Lock()
|
||||
result.Errors = append(result.Errors, fmt.Sprintf("成员 %d 入库信号量超时", memberIdx+1))
|
||||
memberMu.Unlock()
|
||||
return false
|
||||
}
|
||||
defer func() { <-s2aSem }()
|
||||
|
||||
// 从代理池获取随机代理(默认轮询使用代理池,无代理则直连)
|
||||
@@ -764,23 +785,29 @@ func processSingleTeam(idx int, req TeamProcessRequest) (result TeamProcessResul
|
||||
currentEmail := email
|
||||
currentPassword := password
|
||||
if attempt > 0 {
|
||||
// 重试时使用新邮箱
|
||||
currentEmail = mail.GenerateEmail()
|
||||
currentPassword = register.GeneratePassword()
|
||||
logger.Warning(fmt.Sprintf("%s 重试 (第%d次), 新邮箱: %s", memberLogPrefix, attempt+1, currentEmail), currentEmail, "team")
|
||||
// 注册失败重试:保持原邮箱(邀请已发送),仅重新注册
|
||||
logger.Warning(fmt.Sprintf("%s 注册重试 (第%d次), 保持邮箱: %s", memberLogPrefix, attempt+1, currentEmail), currentEmail, "team")
|
||||
}
|
||||
|
||||
// 发送邀请
|
||||
if err := inviter.SendInvites([]string{currentEmail}); err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Error(fmt.Sprintf("%s 邀请失败: %v", memberLogPrefix, err), currentEmail, "team")
|
||||
// 首次尝试时发送邀请,重试时跳过(邀请已发送到该邮箱)
|
||||
if attempt == 0 {
|
||||
if err := inviter.SendInvites([]string{currentEmail}); err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Error(fmt.Sprintf("%s 邀请失败: %v", memberLogPrefix, err), currentEmail, "team")
|
||||
|
||||
// 检测 Team 已达邀请上限(401 或 maximum number of seats)
|
||||
if strings.Contains(errStr, "401") || strings.Contains(errStr, "maximum number of seats") {
|
||||
markTeamExhausted()
|
||||
return false
|
||||
// 检测 Team 已达邀请上限(401 或 maximum number of seats)
|
||||
if strings.Contains(errStr, "401") || strings.Contains(errStr, "maximum number of seats") {
|
||||
markTeamExhausted()
|
||||
return false
|
||||
}
|
||||
// 邀请失败时换新邮箱重试
|
||||
email = mail.GenerateEmail()
|
||||
password = register.GeneratePassword()
|
||||
currentEmail = email
|
||||
currentPassword = password
|
||||
logger.Warning(fmt.Sprintf("%s 邀请失败,换新邮箱: %s", memberLogPrefix, currentEmail), currentEmail, "team")
|
||||
continue
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// 再次检查是否应该停止(邀请期间其他 goroutine 可能已标记)
|
||||
@@ -841,11 +868,15 @@ func processSingleTeam(idx int, req TeamProcessRequest) (result TeamProcessResul
|
||||
registerAndS2AMember(idx, email, password)
|
||||
}(i)
|
||||
}
|
||||
regWg.Wait()
|
||||
if !waitGroupWithTimeout(®Wg, 8*time.Minute) {
|
||||
logger.Warning(fmt.Sprintf("%s 注册阶段超时 (8分钟),继续处理已完成的成员", logPrefix), owner.Email, "team")
|
||||
}
|
||||
|
||||
// 如果 Team 已满,等待已启动的入库完成
|
||||
if isTeamExhausted() {
|
||||
s2aWg.Wait()
|
||||
if !waitGroupWithTimeout(&s2aWg, 5*time.Minute) {
|
||||
logger.Warning(fmt.Sprintf("%s 入库等待超时 (5分钟)", logPrefix), owner.Email, "team")
|
||||
}
|
||||
result.AddedToS2A = int(atomic.LoadInt32(&s2aSuccessCount))
|
||||
result.Errors = append(result.Errors, "Team 邀请已满")
|
||||
result.DurationMs = time.Since(startTime).Milliseconds()
|
||||
@@ -874,7 +905,9 @@ func processSingleTeam(idx int, req TeamProcessRequest) (result TeamProcessResul
|
||||
}
|
||||
|
||||
// 等待所有入库完成
|
||||
s2aWg.Wait()
|
||||
if !waitGroupWithTimeout(&s2aWg, 10*time.Minute) {
|
||||
logger.Warning(fmt.Sprintf("%s 入库阶段超时 (10分钟),继续统计结果", logPrefix), owner.Email, "team")
|
||||
}
|
||||
|
||||
// 补救后再次检查 Team 是否已满
|
||||
if isTeamExhausted() {
|
||||
|
||||
Reference in New Issue
Block a user