package main // #include import "C" import ( "crypto/md5" "encoding/json" "fmt" "github.com/parnurzeal/gorequest" "log" "math/rand" "net/url" "strings" "sync" "time" ) // 代理类型常量 const ( CalfElephantProxyType = "CALF_ELEPHANT_PROXY" TailProxyType = "TAIL_PROXY" ) // 代理服务器列表 var ( servers = []string{ "http-dynamic.xiaoxiangdaili.com", "http-dynamic-S02.xiaoxiangdaili.com", "http-dynamic-S03.xiaoxiangdaili.com", "http-dynamic-S04.xiaoxiangdaili.com", } randMutex sync.Mutex globalRand *rand.Rand // 代理健康状态管理 proxyHealthMaps = make(map[string]*ProxyHealth) proxyHealthMutex sync.RWMutex ) // ProxyManager 代理管理器结构体 type ProxyManager struct { servers []string `json:"servers"` // 代理服务器列表 username string `json:"username"` // 代理账号 password string `json:"password"` // 代理密码 tailCardSecret string `json:"tail_card_secret"` // 尾巴代理卡密 proxyType string `json:"proxy_type"` // 代理类型 CALF_ELEPHANT_PROXY/TAIL_PROXY } // 代理健康状态 type ProxyHealth struct { SuccessCount int // 成功次数 FailCount int // 失败次数 LastCheck time.Time // 最后检查时间 ResponseTime time.Duration // 响应时间 IsHealthy bool // 是否健康 } func init() { // 创建全局的随机数生成器 globalRand = rand.New(rand.NewSource(time.Now().UnixNano())) } // 获取代理URL func proxyTypeManager(proxyType, username, password, machineCode string) (string, error) { switch proxyType { case CalfElephantProxyType: return buildCalfElephantProxyURL(username, password) case TailProxyType: return buildTailProxyURL(machineCode) default: return "", fmt.Errorf("不支持的代理类型: %s", proxyType) } } // 构建小象代理URL func buildCalfElephantProxyURL(username, password string) (string, error) { server := randomServer() proxyURL := fmt.Sprintf("http://%s:%s@%s:%d", url.QueryEscape(username), url.QueryEscape(password), server, 10030) // 检测代理可用性 if err := checkProxyHealth(proxyURL); err != nil { log.Printf("[WARN] 代理 %s 检测失败: %v", server, err) // 尝试下一个代理服务器 return tryNextCalfElephantProxy(username, password, server) } log.Printf("[INFO] 使用小象代理: %s", server) return proxyURL, nil } // 尝试下一个小象代理服务器 func tryNextCalfElephantProxy(username, password, failedServer string) (string, error) { // 创建服务器副本并排除失败的服务器 availableServers := make([]string, 0) for _, server := range servers { if server != failedServer { availableServers = append(availableServers, server) } } if len(availableServers) == 0 { return "", fmt.Errorf("所有小象代理服务器都不可用") } // 随机尝试可用服务器 for _, server := range shuffleServers(availableServers) { proxyURL := fmt.Sprintf("http://%s:%s@%s:%d", url.QueryEscape(username), url.QueryEscape(password), server, 10030) if err := checkProxyHealth(proxyURL); err == nil { log.Printf("[INFO] 切换到可用代理: %s", server) return proxyURL, nil } log.Printf("[WARN] 代理 %s 检测失败", server) } return "", fmt.Errorf("所有可用的小象代理服务器都检测失败") } // 构建内置代理URL func buildTailProxyURL(machineCode string) (string, error) { proxies, err := getProxies(machineCode) if err != nil { return "", err } if len(proxies) == 0 { return "", fmt.Errorf("未获取到有效代理") } // 过滤并选择健康的代理 healthyProxies := filterHealthyProxies(proxies) if len(healthyProxies) > 0 { proxyURL := "http://" + randomElement(healthyProxies) log.Printf("[INFO] 使用健康尾巴代理: %s", proxyURL) return proxyURL, nil } // 如果没有健康代理,检测所有代理 log.Printf("[INFO] 未找到健康代理,开始检测代理可用性...") return findWorkingTailProxy(proxies) } // 过滤健康代理 func filterHealthyProxies(proxies []string) []string { proxyHealthMutex.RLock() defer proxyHealthMutex.RUnlock() var healthy []string for _, proxy := range proxies { if health, exists := proxyHealthMaps[proxy]; exists && health.IsHealthy { // 检查是否在最近检查过(5分钟内) if time.Since(health.LastCheck) < 5*time.Minute { healthy = append(healthy, proxy) } } } return healthy } // 查找可用的尾巴代理 func findWorkingTailProxy(proxies []string) (string, error) { // 打乱代理顺序 shuffledProxies := shuffleServers(proxies) // 并发检测代理 type proxyResult struct { proxy string err error } ch := make(chan proxyResult, len(shuffledProxies)) var wg sync.WaitGroup // 限制并发数 sem := make(chan struct{}, 5) for _, proxy := range shuffledProxies { wg.Add(1) go func(p string) { defer wg.Done() sem <- struct{}{} defer func() { <-sem }() proxyURL := "http://" + p err := checkProxyHealth(proxyURL) ch <- proxyResult{proxy: p, err: err} }(proxy) } wg.Wait() close(ch) // 收集结果 var workingProxies []string for result := range ch { if result.err == nil { workingProxies = append(workingProxies, result.proxy) // 更新健康状态 updateProxyHealth(result.proxy, true, 0) } else { updateProxyHealth(result.proxy, false, 0) } } if len(workingProxies) > 0 { selected := randomElement(workingProxies) log.Printf("[INFO] 找到可用代理: %s (共 %d 个可用)", selected, len(workingProxies)) return "http://" + selected, nil } return "", fmt.Errorf("所有尾巴代理都不可用") } // 检测代理健康状态 func checkProxyHealth(proxyURL string) error { start := time.Now() req := gorequest.New().Proxy(proxyURL).Timeout(10 * time.Second) resp, _, errs := req.Get("https://shop.kongfz.com/").End() responseTime := time.Since(start) if len(errs) > 0 { updateProxyHealth(proxyURL, false, responseTime) return fmt.Errorf("代理连接失败: %v", errs) } if resp.StatusCode != 200 { updateProxyHealth(proxyURL, false, responseTime) return fmt.Errorf("代理响应状态码错误: %d", resp.StatusCode) } updateProxyHealth(proxyURL, true, responseTime) log.Printf("[DEBUG] 代理 %s 检测成功, 响应时间: %v", getProxyHost(proxyURL), responseTime) return nil } // 更新代理健康状态 func updateProxyHealth(proxyURL string, success bool, responseTime time.Duration) { proxyHealthMutex.Lock() defer proxyHealthMutex.Unlock() host := getProxyHost(proxyURL) if _, exists := proxyHealthMaps[host]; !exists { proxyHealthMaps[host] = &ProxyHealth{} } health := proxyHealthMaps[host] health.LastCheck = time.Now() if success { health.SuccessCount++ health.FailCount = 0 health.ResponseTime = responseTime health.IsHealthy = true } else { health.FailCount++ health.SuccessCount = 0 // 连续失败3次标记为不健康 if health.FailCount >= 3 { health.IsHealthy = false } } } // 获取代理主机名 func getProxyHost(proxyURL string) string { if strings.HasPrefix(proxyURL, "http://") { proxyURL = proxyURL[7:] } // 去除认证信息 if atIndex := strings.Index(proxyURL, "@"); atIndex != -1 { proxyURL = proxyURL[atIndex+1:] } // 去除端口 if colonIndex := strings.Index(proxyURL, ":"); colonIndex != -1 { proxyURL = proxyURL[:colonIndex] } return proxyURL } // 随机代理服务器 func randomServer() string { return randomElement(servers) } // 线程安全的随机元素选择 func randomElement(slice []string) string { randMutex.Lock() defer randMutex.Unlock() return slice[globalRand.Intn(len(slice))] } // 打乱服务器顺序 func shuffleServers(servers []string) []string { randMutex.Lock() defer randMutex.Unlock() shuffled := make([]string, len(servers)) copy(shuffled, servers) globalRand.Shuffle(len(shuffled), func(i, j int) { shuffled[i], shuffled[j] = shuffled[j], shuffled[i] }) return shuffled } // 检查卡密是否过期 func checkTailCardSecretExpired(tailCardSecret string) (bool, error) { code, err := getMachineCode(tailCardSecret) if err != nil { return false, fmt.Errorf("请求错误: %v", err) } targetTime, err := time.Parse("2006-01-02 15:04:05", code.Data.IpExpTime) if err != nil { return false, fmt.Errorf("时间格式错误: %v", err) } currentTime := time.Now() if targetTime.After(currentTime) { return true, nil } else { return false, fmt.Errorf("卡密已经过期!过期时间: %v", targetTime) } } // 定义响应结构体 type getMachineCodeResp struct { Code int `json:"code"` Message string `json:"message"` Data struct { MachineCode string `json:"machine_code"` IpExpTime string `json:"ip_exp_time"` IpThread int `json:"ip_thread"` IpCardCode string `json:"ip_card_code"` } `json:"data"` } // 查询机器码 func getMachineCode(tailCardSecret string) (*getMachineCodeResp, error) { url := "http://114.66.2.223:7842/api/proxies/ip_show" data := map[string]interface{}{ "ip_card_code": tailCardSecret, "agent_id": 9999, } _, body, errs := gorequest.New().Post(url).Send(data).End() if len(errs) > 0 { return nil, fmt.Errorf("查询机器码失败: %v", errs) } var resp getMachineCodeResp if err := json.Unmarshal([]byte(body), &resp); err != nil { return nil, fmt.Errorf("解析响应失败: %v", err) } if resp.Code == 201 { machineCode, err := rechargeCard(tailCardSecret, resp.Data.MachineCode) if err != nil { return nil, err } resp.Data.MachineCode = machineCode return &resp, nil } else if resp.Code == 200 { return &resp, nil } else { return nil, fmt.Errorf("查询机器码失败: %s", resp.Message) } } // 充值卡密 func rechargeCard(tailCardSecret, machineCode string) (string, error) { url := "http://114.66.2.223:7842/api/proxies/ip_recharge" data := map[string]interface{}{ "machine_code": machineCode, "ip_card_code": tailCardSecret, "agent_id": 9999, } _, body, errs := gorequest.New().Post(url).Send(data).End() if len(errs) > 0 { return "", fmt.Errorf("充值卡密失败: %v", errs) } var resp struct { Code int `json:"code"` // 状态码 Message string `json:"message"` // 返回消息 Data struct { IpExpTime string `json:"ip_exp_time"` // 过期时间 IpThread int `json:"ip_thread"` // 线程 MachineCode string `json:"machine_code"` // 机器码 } `json:"data"` } if err := json.Unmarshal([]byte(body), &resp); err != nil { return "", fmt.Errorf("解析响应失败: %v", err) } if resp.Code != 200 { return "", fmt.Errorf("充值卡密失败: %s", resp.Message) } return resp.Data.MachineCode, nil } // 获取代理服务器列表 func getProxies(machineCode string) ([]string, error) { log.Printf("[INFO] 开始获取代理列表: %s", machineCode) // 生成签名 sign := fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("9999%s9999", machineCode)))) GetProxiesUrl := fmt.Sprintf("http://114.66.2.223:7842/api/proxies/get_proxy?machine_code=%s&sign=%s&agent_id=9999", machineCode, sign) req := gorequest.New().Get(GetProxiesUrl).Timeout(20 * time.Second) _, body, errs := req.End() if len(errs) > 0 { return nil, fmt.Errorf("获取代理失败: %v", errs) } // 检查是否为JSON错误响应 if strings.HasPrefix(strings.TrimSpace(body), "{") && strings.HasSuffix(strings.TrimSpace(body), "}") { // 尝试解析为JSON错误响应 var errorResp struct { Code int `json:"code"` Message string `json:"message"` } if err := json.Unmarshal([]byte(body), &errorResp); err == nil { return nil, fmt.Errorf("获取代理失败: %s (错误码: %d)", errorResp.Message, errorResp.Code) } } // 解析响应 lines := strings.Split(strings.TrimSpace(body), "\n") var proxies []string for _, line := range lines { line = strings.TrimSpace(line) if line != "" && !strings.HasPrefix(line, "{") { proxies = append(proxies, line) } } if len(proxies) == 0 { return nil, fmt.Errorf("未获取到有效代理") } log.Printf("[INFO] 获取到 %d 个代理", len(proxies)) return proxies, nil } // 初始化代理信息 func initProxy() { } // 导出函数:获取代理健康状态(用于调试) // //export GetProxyHealth func GetProxyHealth() *C.char { proxyHealthMutex.RLock() defer proxyHealthMutex.RUnlock() healthInfo := make(map[string]interface{}) for proxy, health := range proxyHealthMaps { healthInfo[proxy] = map[string]interface{}{ "success_count": health.SuccessCount, "fail_count": health.FailCount, "last_check": health.LastCheck.Format(time.RFC3339), "response_time": health.ResponseTime.String(), "is_healthy": health.IsHealthy, } } jsonData, err := json.Marshal(healthInfo) if err != nil { return C.CString(fmt.Sprintf(`{"error": "序列化健康信息失败: %v"}`, err)) } return C.CString(string(jsonData)) } // 导出函数:代理类型管理器 // //export ProxyTypeManager func ProxyTypeManager(proxyType, username, password, machineCode *C.char) *C.char { goProxyType := C.GoString(proxyType) goUsername := C.GoString(username) goPassword := C.GoString(password) goMachineCode := C.GoString(machineCode) log.Printf("[DEBUG] 代理类型管理器调用: type=%s", goProxyType) proxyURL, err := proxyTypeManager(goProxyType, goUsername, goPassword, goMachineCode) if err != nil { errorMsg := fmt.Sprintf("ERROR: %v", err) log.Printf("[ERROR] 代理类型管理器错误: %v", err) return C.CString(errorMsg) } log.Printf("[DEBUG] 代理类型管理器返回: %s", proxyURL) return C.CString(proxyURL) } //// 导出函数:释放C字符串内存 //// ////export FreeCString //func FreeCString(str *C.char) { // C.free(unsafe.Pointer(str)) //} // //func main() { // //}