jack 9 місяців тому
батько
коміт
9fa5ef9039

+ 13 - 8
api_tools/3dos/main.go → api_tools/3dos/daily_3dos.go

@@ -4,7 +4,6 @@ import (
 	"bytes"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
 	"net/http"
 	"strings"
 	"sync"
@@ -136,14 +135,20 @@ func dailyClaim3DOS(email, password string) string {
 func main() {
 	fmt.Println("开始执行...")
 
-	configPath := "account.txt"
-	content, err := ioutil.ReadFile(configPath)
-	if err != nil {
-		fmt.Println("读取配置失败")
-		return
+	accountList := []string{
+		"jack0210_@hotmail.com|||aaaAAA111!!!",
+		"yujieccyj01@hotmail.com|||aaaAAA111!!!",
+        "yujieccyj02@hotmail.com|||aaaAAA111!!!",
+        "yujieccyj03@hotmail.com|||aaaAAA111!!!",
+        "yujieccyj04@hotmail.com|||aaaAAA111!!!",
+        "yujieccyj05@hotmail.com|||aaaaAA111!!!",
+        "yujieccyj06@hotmail.com|||aaaAAA111!!!",
+        "yujieccyj07@hotmail.com|||aaaAAA111!!!",
+        "yujieccyj08@hotmail.com|||aaaAAA111!!!",
+        "yujieccyj09@hotmail.com|||aaaAAA111!!!",
+        "yujieccyj10@hotmail.com|||aaaAAA111!!!",
 	}
 
-	accountList := strings.Split(string(content), "\n")
 	var wg sync.WaitGroup
 	results := make(chan string, len(accountList))
 
@@ -165,4 +170,4 @@ func main() {
 	for result := range results {
 		fmt.Println(result)
 	}
-}
+}

+ 0 - 0
test/test.py → auto_web3_click/base_ref/move_mouse.py


+ 0 - 0
test/screen_percentage.py → auto_web3_click/base_ref/screen_percentage.py


+ 73 - 0
clash_fusion/main.py

@@ -0,0 +1,73 @@
+from nicegui import ui
+
+def expand_all_iframes():
+    for i in range(1, 11):
+        ui.run_javascript(f"var ifr = document.getElementById('iframe{i}'); if (ifr) {{ var links = ifr.contentWindow.document.querySelectorAll('a'); links.forEach(function(link) {{ if (link.textContent.includes('设置')) {{ link.click(); }} }}); }}")
+
+
+def speed_test_all_iframes():
+    # 在这里实现一键测速的功能
+    pass
+
+
+with ui.row().classes('w-full justify-center items-center'):
+    with ui.button('展开').on('click', expand_all_iframes):
+        pass
+    with ui.button('一键测速').on('click', speed_test_all_iframes):
+        pass
+
+with ui.row().classes('w-full justify-center gap-4'):
+    with ui.column().classes('items-center'):
+        with ui.label('01').classes('text-2xl font-bold'): pass
+        with ui.card().style('width: 630px; height: 700px;') as card:
+            ui.html('<iframe id="iframe1" src="http://192.168.31.194:58001/" width="200%" height="445%" style="overflow:auto;"></iframe>')
+
+    with ui.column().classes('items-center'):
+        with ui.label('02').classes('text-2xl font-bold'): pass
+        with ui.card().style('width: 630px; height: 700px;') as card:
+            ui.html('<iframe id="iframe2" src="http://192.168.31.194:58002/" width="200%" height="445%" style="overflow:auto;"></iframe>')
+
+    with ui.column().classes('items-center'):
+        with ui.label('03').classes('text-2xl font-bold'): pass
+        with ui.card().style('width: 630px; height: 700px;') as card:
+            ui.html('<iframe id="iframe1" src="http://192.168.31.194:58003/" width="200%" height="445%" style="overflow:auto;"></iframe>')
+
+with ui.row().classes('w-full justify-center gap-4'):
+    with ui.column().classes('items-center'):
+        with ui.label('04').classes('text-2xl font-bold'): pass
+        with ui.card().style('width: 630px; height: 700px;') as card:
+            ui.html('<iframe id="iframe4" src="http://192.168.31.194:58004/" width="200%" height="445%" style="overflow:auto;"></iframe>')
+
+    with ui.column().classes('items-center'):
+        with ui.label('05').classes('text-2xl font-bold'): pass
+        with ui.card().style('width: 630px; height: 700px;') as card:
+            ui.html('<iframe id="iframe5" src="http://192.168.31.194:58005/" width="200%" height="445%" style="overflow:auto;"></iframe>')
+
+    with ui.column().classes('items-center'):
+        with ui.label('06').classes('text-2xl font-bold'): pass
+        with ui.card().style('width: 630px; height: 700px;') as card:
+            ui.html('<iframe id="iframe6" src="http://192.168.31.194:58006/" width="200%" height="445%" style="overflow:auto;"></iframe>')
+
+with ui.row().classes('w-full justify-center gap-4'):
+    with ui.column().classes('items-center'):
+        with ui.label('07').classes('text-2xl font-bold'): pass
+        with ui.card().style('width: 630px; height: 700px;') as card:
+            ui.html('<iframe id="iframe7" src="http://192.168.31.194:58007/" width="200%" height="445%" style="overflow:auto;"></iframe>')
+
+    with ui.column().classes('items-center'):
+        with ui.label('08').classes('text-2xl font-bold'): pass
+        with ui.card().style('width: 630px; height: 700px;') as card:
+            ui.html('<iframe id="iframe8" src="http://192.168.31.194:58008/" width="200%" height="445%" style="overflow:auto;"></iframe>')
+
+    with ui.column().classes('items-center'):
+        with ui.label('09').classes('text-2xl font-bold'): pass
+        with ui.card().style('width: 630px; height: 700px;') as card:
+            ui.html('<iframe id="iframe9" src="http://192.168.31.194:58009/" width="200%" height="445%" style="overflow:auto;"></iframe>')
+
+with ui.row().classes('w-full justify-center gap-4'):
+    with ui.column().classes('items-center'):
+        with ui.label('10').classes('text-2xl font-bold'): pass
+        with ui.card().style('width: 630px; height: 700px;') as card:
+            ui.html('<iframe id="iframe10" src="http://192.168.31.194:58010/" width="200%" height="445%" style="overflow:auto;"></iframe>')
+
+ui.run()

+ 116 - 0
demo/web3_demo.py

@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+from web3 import Web3, HTTPProvider
+
+# 连接到以太坊节点
+w3 = Web3(HTTPProvider('http://127.0.0.1:8545'))
+
+# 检查是否连接成功
+if w3.isConnected():
+    print("Connected to Ethereum node")
+else:
+    print("Failed to connect to Ethereum node")
+    exit()
+
+# 1. 获取最新区块号
+latest_block = w3.eth.block_number
+print(f"Latest block number: {latest_block}")
+
+# 2. 获取区块信息
+block = w3.eth.get_block(latest_block)
+print(f"Block info: {block}")
+
+# 3. 获取账户余额
+account = '0xYourAccountAddress'  # 替换为你的账户地址
+balance = w3.eth.get_balance(account)
+print(f"Balance of {account}: {w3.fromWei(balance, 'ether')} ETH")
+
+# 4. 发送交易
+sender = '0xYourAccountAddress'  # 替换为你的账户地址
+private_key = 'YourPrivateKey'  # 替换为你的私钥
+receiver = '0xReceiverAddress'  # 替换为接收方地址
+
+nonce = w3.eth.get_transaction_count(sender)
+tx = {
+    'nonce': nonce,
+    'to': receiver,
+    'value': w3.toWei(0.01, 'ether'),
+    'gas': 2000000,
+    'gasPrice': w3.toWei('50', 'gwei'),
+}
+signed_tx = w3.eth.account.sign_transaction(tx, private_key)
+tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
+print(f"Transaction hash: {w3.toHex(tx_hash)}")
+
+# 5. 与智能合约交互
+contract_address = '0xYourContractAddress'  # 替换为合约地址
+contract_abi = [...]  # 替换为合约的ABI
+contract = w3.eth.contract(address=contract_address, abi=contract_abi)
+
+# 调用合约的只读方法
+result = contract.functions.yourReadOnlyMethod().call()
+print(f"Result from contract: {result}")
+
+# 调用合约的写方法
+tx = contract.functions.yourWriteMethod(param1, param2).buildTransaction({
+    'nonce': w3.eth.get_transaction_count(sender),
+    'gas': 2000000,
+    'gasPrice': w3.toWei('50', 'gwei'),
+})
+signed_tx = w3.eth.account.sign_transaction(tx, private_key)
+tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
+print(f"Transaction hash: {w3.toHex(tx_hash)}")
+
+# 6. 监听事件
+event_filter = contract.events.YourEvent.createFilter(fromBlock='latest')
+print("Listening for events...")
+while True:
+    for event in event_filter.get_new_entries():
+        print(f"New event: {event}")
+
+# 7. 获取交易收据
+tx_receipt = w3.eth.get_transaction_receipt(tx_hash)
+print(f"Transaction receipt: {tx_receipt}")
+
+# 8. 获取交易详情
+tx_detail = w3.eth.get_transaction(tx_hash)
+print(f"Transaction detail: {tx_detail}")
+
+# 9. 获取日志
+logs = w3.eth.get_logs({
+    'fromBlock': 0,
+    'toBlock': 'latest',
+    'address': contract_address,
+})
+print(f"Logs: {logs}")
+
+# 10. 获取当前 Gas 价格
+gas_price = w3.eth.gas_price
+print(f"Current gas price: {w3.fromWei(gas_price, 'gwei')} gwei")
+
+# 11. 获取账户交易数量
+transaction_count = w3.eth.get_transaction_count(sender)
+print(f"Transaction count: {transaction_count}")
+
+# 12. 获取合约代码
+contract_code = w3.eth.get_code(contract_address)
+print(f"Contract code: {contract_code}")
+
+# 13. 获取账户存储
+storage = w3.eth.get_storage_at(contract_address, 0)
+print(f"Storage at position 0: {storage}")
+
+# 14. 获取账户 nonce
+nonce = w3.eth.get_transaction_count(sender)
+print(f"Account nonce: {nonce}")
+
+# 15. 获取区块 gas 限制
+gas_limit = w3.eth.get_block('latest')['gasLimit']
+print(f"Gas limit: {gas_limit}")
+
+# 16. 获取区块 gas 使用量
+gas_used = w3.eth.get_block('latest')['gasUsed']
+print(f"Gas used: {gas_used}")
+
+# 17. 获取区块 gas 费用
+gas_fee = gas_used * gas_price
+print(f"Gas fee: {w3.fromWei(gas_fee, 'ether')} ETH")

+ 132 - 0
monad/faucet_official.py

@@ -0,0 +1,132 @@
+# -*- coding: utf-8 -*-
+import asyncio
+from loguru import logger
+import random
+import hashlib
+from eth_account import Account
+from pynocaptcha import CloudFlareCracker, TlsV1Cracker
+from curl_cffi.requests import AsyncSession
+
+SETTINGS = {
+    "ATTEMPTS": 3,
+    "RANDOM_PAUSE_BETWEEN_ACTIONS": [1, 5],
+}
+
+FAUCET = {
+    "USE_CAPSOLVER_FOR_CLOUDFLARE": False,
+    "CAPSOLVER_API_KEY": "your_capsolver_api_key",
+    "NOCAPTCHA_API_KEY": "your_nocaptcha_api_key",
+}
+
+
+async def faucet(
+        session: AsyncSession,
+        account_index: int,
+        wallet: Account,
+        proxy: str,
+) -> bool:
+    for retry in range(SETTINGS["ATTEMPTS"]):
+        try:
+            logger.info(f"[{account_index}] | Starting faucet for account {wallet.address}...")
+            user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
+            href = "https://testnet.monad.xyz/"
+
+            # Solve Cloudflare challenge
+            if FAUCET["USE_CAPSOLVER_FOR_CLOUDFLARE"]:
+                logger.info(f"[{account_index}] | Solving Cloudflare challenge with Capsolver...")
+                # 这里假设Capsolver类已经定义并且可用
+                capsolver = Capsolver(api_key=FAUCET["CAPSOLVER_API_KEY"], proxy=proxy, session=session)
+                cf_result = await capsolver.solve_turnstile("0x4AAAAAAA-3X4Nd7hf3mNGx", href)
+            else:
+                logger.info(f"[{account_index}] | Solving Cloudflare challenge with Nocaptcha...")
+                # 这里假设CloudFlareCracker类已经定义并且可用
+                cracker = CloudFlareCracker(
+                    internal_host=True,
+                    user_token=FAUCET["NOCAPTCHA_API_KEY"],
+                    href=href,
+                    sitekey="0x4AAAAAAA-3X4Nd7hf3mNGx",
+                    proxy=proxy,
+                    debug=False,
+                    show_ad=False,
+                    timeout=60,
+                )
+                cf_result = cracker.crack()
+                cf_result = cf_result["token"]
+
+            if not cf_result:
+                raise Exception("Failed to solve Cloudflare challenge")
+
+            logger.success(f"[{account_index}] | Cloudflare challenge solved")
+
+            # Generate visitor ID
+            visitor_id = hashlib.md5(str(random.random()).encode()).hexdigest()
+
+            json_data = {
+                "address": wallet.address,
+                "visitorId": visitor_id,
+                "cloudFlareResponseToken": cf_result,
+            }
+
+            headers = {
+                "sec-ch-ua-platform": '"Windows"',
+                "user-agent": user_agent,
+                "sec-ch-ua": '"Not(A:Brand";v="99", "Google Chrome";v="133", "Chromium";v="133"',
+                "content-type": "application/json",
+                "sec-ch-ua-mobile": "?0",
+                "accept": "*/*",
+                "origin": href,
+                "sec-fetch-site": "same-origin",
+                "sec-fetch-mode": "cors",
+                "sec-fetch-dest": "empty",
+                "referer": href,
+                "accept-language": "en-GB,en;q=0.9",
+                "priority": "u=1, i",
+            }
+
+            response = await session.post(
+                f"{href}api/faucet/claim", headers=headers, json=json_data
+            )
+            response_text = response.text
+
+            if not response_text:
+                raise Exception("Failed to send claim request")
+
+            if '"Success"' in response_text or '"message":"Success"' in response_text:
+                logger.success(f"[{account_index}] | Successfully got tokens from faucet")
+                return True
+
+            if "Claimed already" in response_text:
+                logger.success(f"[{account_index}] | Already claimed tokens from faucet")
+                return True
+
+            error_messages = {
+                "FUNCTION_INVOCATION_TIMEOUT": "Server is not responding, wait...",
+                "Vercel Security Checkpoint": "Failed to solve Vercel challenge, trying again...",
+                "Server error on QuickNode API": "FAUCET DOES NOT WORK, QUICKNODE IS DOWN",
+                "Over Enterprise free quota": "MONAD IS SHIT, FAUCET DOES NOT WORK, TRY LATER",
+                "invalid-keys": "PLEASE UPDATE THE BOT USING GITHUB",
+            }
+
+            for key, message in error_messages.items():
+                if key in response_text:
+                    logger.error(f"[{account_index}] | {message}")
+                    if key == "Over Enterprise free quota" or key == "invalid-keys":
+                        return False
+                    break
+            else:
+                logger.error(f"[{account_index}] | Failed to get tokens from faucet: {response_text}")
+
+            await asyncio.sleep(3)
+
+        except Exception as e:
+            random_pause = random.randint(*SETTINGS["RANDOM_PAUSE_BETWEEN_ACTIONS"])
+            if "operation timed out" in str(e):
+                logger.error(
+                    f"[{account_index}] | Error faucet to monad.xyz ({retry + 1}/{SETTINGS['ATTEMPTS']}): Connection timed out. Next faucet in {random_pause} seconds")
+            else:
+                logger.error(
+                    f"[{account_index}] | Error faucet to monad.xyz ({retry + 1}/{SETTINGS['ATTEMPTS']}): {e}. Next faucet in {random_pause} seconds")
+            await asyncio.sleep(random_pause)
+            continue
+
+    return False

+ 82 - 0
porxy_tools/clash/check_all_proxy.go

@@ -0,0 +1,82 @@
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"sync"
+)
+
+type ProxiesResponse struct {
+	Proxies map[string]interface{} `json:"proxies"`
+}
+
+func check(url string, wg *sync.WaitGroup) {
+	defer wg.Done()
+	for retry := 0; retry < 3; retry++ {
+		resp, err := http.Get(url)
+		if err != nil {
+			fmt.Printf("Error: %s - %s\n", url, err)
+			continue
+		}
+		defer resp.Body.Close()
+		if resp.StatusCode == http.StatusOK {
+			fmt.Printf("Success: %s\n", url)
+			return
+		} else {
+			fmt.Printf("Failed: %s (Status: %d)\n", url, resp.StatusCode)
+		}
+	}
+}
+func prepareCheck(nodeURL string, ports []string, proxyNameList []string, wg *sync.WaitGroup) {
+	for _, port := range ports {
+		proxyURL := fmt.Sprintf("%s:%s", nodeURL, port)
+		for _, proxy := range proxyNameList {
+			url := fmt.Sprintf("%s/api/proxies/%s/delay?timeout=5000&url=http://www.gstatic.com/generate_204", proxyURL, proxy)
+			wg.Add(1)
+			go check(url, wg)
+		}
+	}
+}
+func loadNodesDetails(nodes map[string][]string) {
+	var wg sync.WaitGroup
+	for nodeURL, ports := range nodes {
+		clashToolURL := fmt.Sprintf("%s:%s", nodeURL, ports[0])
+		url := fmt.Sprintf("%s/api/proxies", clashToolURL)
+		resp, err := http.Get(url)
+		if err != nil {
+			fmt.Printf("Error: %s - %s\n", url, err)
+			continue
+		}
+		defer resp.Body.Close()
+		if resp.StatusCode != http.StatusOK {
+			fmt.Printf("Failed to load proxies from %s (Status: %d)\n", url, resp.StatusCode)
+			continue
+		}
+		body, err := ioutil.ReadAll(resp.Body)
+		if err != nil {
+			fmt.Printf("Error reading response body: %s\n", err)
+			continue
+		}
+		var proxies ProxiesResponse
+		if err := json.Unmarshal(body, &proxies); err != nil {
+			fmt.Printf("Error unmarshalling JSON: %s\n", err)
+			continue
+		}
+		proxyNameList := make([]string, 0, len(proxies.Proxies))
+		for key := range proxies.Proxies {
+			proxyNameList = append(proxyNameList, key)
+		}
+		prepareCheck(nodeURL, ports, proxyNameList, &wg)
+	}
+	wg.Wait()
+}
+func main() {
+	nodes := map[string][]string{
+		"http://192.168.31.194": {"58001", "58002", "58003", "58004", "58005", "58006", "58007", "58008", "58009", "58010"},
+		"http://192.168.31.201": {"32001", "32002", "32003", "32004", "32005", "32006", "32007", "32008", "32009", "32010", "32011", "32012"},
+	}
+	loadNodesDetails(nodes)
+	fmt.Println("All done!")
+}

+ 130 - 0
porxy_tools/clash/check_now_proxy.go

@@ -0,0 +1,130 @@
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"net/url"
+	"strings"
+	"sync"
+	"time"
+)
+
+type ProxiesResponse struct {
+	Proxies map[string]interface{} `json:"proxies"`
+}
+
+var nodes = [][][]string{
+	{
+		{"192.168.31.194", "58001", "58002", "58003", "58004", "58005", "58006", "58007", "58008", "58009", "58010"},
+	},
+	{
+		{"192.168.31.201", "32001", "32002", "32003", "32004", "32005", "32006", "32007", "32008", "32009", "32010", "32011", "32012"},
+	},
+	{
+		{"127.0.0.1", "17888"},
+	},
+}
+var selectedNodes = nodes[0] // 默认选择第一个节点
+func checkProxy(proxyURL, chooseProxy string) string {
+	// 确保 proxyURL 包含协议
+	if !strings.HasPrefix(proxyURL, "http://") && !strings.HasPrefix(proxyURL, "https://") {
+		proxyURL = "http://" + proxyURL // 默认使用 http 协议
+	}
+	// 对 chooseProxy 进行 URL 编码
+	encodeProxyName := url.QueryEscape(chooseProxy)
+	// 构建完整的请求 URL
+	requestURL := fmt.Sprintf("%s/api/proxies/%s/delay?timeout=5000&url=http://www.gstatic.com/generate_204", proxyURL, encodeProxyName)
+
+	// 创建 HTTP 客户端
+	client := &http.Client{
+		Timeout: 6 * time.Second, // 设置超时时间
+	}
+	// 发送 HTTP GET 请求
+	resp, err := client.Get(requestURL)
+	if err != nil {
+		return fmt.Sprintf("Error: %v", err)
+	}
+	defer resp.Body.Close()
+	// 检查 HTTP 状态码
+	if resp.StatusCode != http.StatusOK {
+		return fmt.Sprintf("HTTP Error: %s", resp.Status)
+	}
+	// 解析 JSON 响应
+	var result map[string]interface{}
+	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
+		return fmt.Sprintf("Error parsing JSON: %v", err)
+	}
+	// 检查 meanDelay 字段是否存在
+	meanDelay, ok := result["meanDelay"]
+	if !ok {
+		return "meanDelay field not found in JSON"
+	}
+	// 返回 meanDelay 的值
+	return fmt.Sprintf("meanDelay: %v", meanDelay)
+}
+
+func checkNowProxy(ip, port string, wg *sync.WaitGroup) {
+	defer wg.Done()
+	urlAndPort := fmt.Sprintf("%s:%s", ip, port)
+	url := fmt.Sprintf("http://%s/api/proxies", urlAndPort)
+	headers := map[string]string{
+		"Accept":             "application/json, text/plain, */*",
+		"Accept-Encoding":    "gzip, deflate, br, zstd",
+		"Accept-Language":    "zh-CN,zh;q=0.8",
+		"Connection":         "keep-alive",
+		"Host":               urlAndPort,
+		"Referer":            fmt.Sprintf("http://%s/", urlAndPort),
+		"Sec-CH-UA":          `"Chromium";v="134", "Not:A-Brand";v="24", "Brave";v="134"`,
+		"Sec-CH-UA-Mobile":   "?0",
+		"Sec-CH-UA-Platform": `"macOS"`,
+		"Sec-Fetch-Dest":     "empty",
+		"Sec-Fetch-Mode":     "cors",
+		"Sec-Fetch-Site":     "same-origin",
+		"Sec-GPC":            "1",
+		"User-Agent":         "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
+	}
+	req, err := http.NewRequest("GET", url, nil)
+	if err != nil {
+		fmt.Printf("Error creating request: %v\n", err)
+		return
+	}
+	for key, value := range headers {
+		req.Header.Set(key, value)
+	}
+	client := &http.Client{}
+	resp, err := client.Do(req)
+	if err != nil {
+		fmt.Printf("Request failed: %v\n", err)
+		return
+	}
+	defer resp.Body.Close()
+	if resp.StatusCode != http.StatusOK {
+		fmt.Printf("Failed to load proxies from %s (Status: %d)\n", url, resp.StatusCode)
+		return
+	}
+	var jsonData ProxiesResponse
+	if err := json.NewDecoder(resp.Body).Decode(&jsonData); err != nil {
+		fmt.Printf("Error decoding JSON: %v\n", err)
+		return
+	}
+	proxies := jsonData.Proxies
+	proxyGlobal, ok := proxies["GLOBAL"].(map[string]interface{})
+	if !ok {
+		fmt.Println("Error: GLOBAL proxy not found")
+		return
+	}
+	nowProxy := proxyGlobal["now"].(string)
+	checkResult := checkProxy(urlAndPort, nowProxy)
+	message := fmt.Sprintf("%s --- %s --- %s", urlAndPort, nowProxy, checkResult)
+	fmt.Println(message)
+}
+func main() {
+	var wg sync.WaitGroup
+	ip := selectedNodes[0][0]
+	for _, port := range selectedNodes[0][1:] {
+		wg.Add(1)
+		go checkNowProxy(ip, port, &wg)
+	}
+	wg.Wait()
+}

+ 82 - 0
porxy_tools/clash/check_now_proxy.py

@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+from urllib.parse import quote
+import subprocess
+import httpx
+
+nodes = [
+    ["192.168.31.194", ['58001', '58002', '58003', '58004', '58005', '58006', '58007', '58008', '58009',
+                        '58010'], ],
+    ["192.168.31.201", ['32001', '32002', '32003', '32004', '32005', '32006', '32007', '32008', '32009',
+                        '32010', '32011', '32012']],
+    ["127.0.0.1", ['17888']]
+]
+
+selected_nodes = nodes[0]
+
+def check_proxy(proxy_url, choose_proxy):
+    encode_proxy_name = quote(choose_proxy, safe="")
+    command = [
+        "curl",
+        "-X", "GET",
+        f"{proxy_url}/api/proxies/{encode_proxy_name}/delay?timeout=5000&url=http:%2F%2Fwww.gstatic.com%2Fgenerate_204"
+    ]
+
+    try:
+        result = subprocess.run(command, capture_output=True, text=True, check=True)
+        # print("Output:", result.stdout)
+        if 'Timeout' in result.stdout:
+            return "Timeout"
+        res = eval(result.stdout).get("meanDelay")
+        return f"meanDelay: {res}"
+    except subprocess.CalledProcessError as e:
+        print("Error:", e.stderr)
+        return str(e)
+
+def check_now_proxy(ip, port):
+    url_and_port = f"{ip}:{port}"
+    url = f"http://{ip}:{port}/api/proxies"
+    headers = {
+        "Accept": "application/json, text/plain, */*",
+        "Accept-Encoding": "gzip, deflate, br, zstd",
+        "Accept-Language": "zh-CN,zh;q=0.8",
+        "Connection": "keep-alive",
+        "Host": url_and_port,
+        "Referer": f"http://{url_and_port}/",
+        "Sec-CH-UA": '"Chromium";v="134", "Not:A-Brand";v="24", "Brave";v="134"',
+        "Sec-CH-UA-Mobile": "?0",
+        "Sec-CH-UA-Platform": '"macOS"',
+        "Sec-Fetch-Dest": "empty",
+        "Sec-Fetch-Mode": "cors",
+        "Sec-Fetch-Site": "same-origin",
+        "Sec-GPC": "1",
+        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36"
+    }
+
+    try:
+        response = httpx.get(url, headers=headers)
+        json_data = response.json()
+        if not json_data or response.status_code != 200:
+            print("JSON data is empty or request failed")
+            return
+
+        proxies = json_data.get("proxies")
+        proxy_global = proxies.get("GLOBAL")
+        now_proxy = proxy_global.get("now")
+
+        check_result = check_proxy(url_and_port, now_proxy)
+
+        message = f"{url_and_port} --- {now_proxy} --- {check_result}"
+        print(message)
+
+    except httpx.RequestError as e:
+        print(f"Request failed: {e}")
+
+
+def main():
+    ip = selected_nodes[0]
+    for port in selected_nodes[1]:
+        check_now_proxy(ip, port)
+
+
+if __name__ == "__main__":
+    main()

+ 1 - 1
porxy_tools/clash/switch_random_proxy_web3.py

@@ -105,7 +105,7 @@ class ClashProxyManager:
         command = [
             "curl",
             "-X", "GET",
-            f"{proxy_url}/api/proxies/{encode_proxy_name}/delay?timeout=5000&url=http:%2F%2Fwww.gstatic.com%2Fgenerate_204"
+            f"http://{proxy_url}/api/proxies/{encode_proxy_name}/delay?timeout=5000&url=http:%2F%2Fwww.gstatic.com%2Fgenerate_204"
         ]
 
         try:

+ 133 - 0
test/click_test.py

@@ -0,0 +1,133 @@
+import os
+import pyautogui
+import tkinter as tk
+from tkinter import messagebox
+import time
+
+
+class AutoClicker:
+    def __init__(self, src_folder="src"):
+        self.src_folder = src_folder
+        self.png_files = []
+
+    def load_png_list(self):
+        """加载src文件夹中的所有PNG文件"""
+        if not os.path.exists(self.src_folder):
+            os.makedirs(self.src_folder)
+            print(f"文件夹 {self.src_folder} 不存在,已创建。")
+            return []
+
+        self.png_files = [f for f in os.listdir(self.src_folder) if f.endswith(".png")]
+        print(f"加载PNG文件列表: {self.png_files}")
+        return self.png_files
+
+    def check_image_on_screen(self, image_path, confidence=0.8):
+        """检查当前屏幕是否存在图片"""
+        location = pyautogui.locateOnScreen(image_path, confidence=confidence)
+        if location:
+            print(f'图片: {image_path} 找到,坐标: {location}')
+            return location
+        else:
+            print(f'没有找到图片: {image_path}')
+            return None
+
+    def click_image_center(self, image_path, confidence=0.8):
+        """点击图片中心"""
+        location = self.check_image_on_screen(image_path, confidence)
+        if location:
+            button_x, button_y = pyautogui.center(location)
+            print(f'图片中心坐标: {button_x}, {button_y}')
+            pyautogui.click(button_x, button_y)
+            return True
+        return False
+
+    def move_mouse_to(self, x, y):
+        """移动鼠标到指定坐标"""
+        pyautogui.moveTo(x, y)
+        print(f'鼠标移动到坐标: {x}, {y}')
+
+    def mouse_click(self):
+        """鼠标点击"""
+        pyautogui.click()
+        print('鼠标点击')
+
+    def scroll_mouse(self, delta):
+        """滚动鼠标滚轮"""
+        pyautogui.scroll(delta)
+        print(f'鼠标滚轮滚动: {delta}')
+
+
+def main():
+    # 创建自动化点击器实例
+    auto_clicker = AutoClicker()
+
+    # 加载PNG文件
+    auto_clicker.load_png_list()
+
+    # 创建GUI
+    root = tk.Tk()
+    root.title("自动化点击器")
+    root.geometry("480x320")
+
+    button_font = ("Arial", 12)
+    # 修改背景色和文字颜色
+    button_bg_color = "lightblue"
+    button_fg_color = "black"
+    button_border_width = 2
+
+    # 测试按钮
+    def test_check_image():
+        file = auto_clicker.png_files[0] if auto_clicker.png_files else "1.png"
+        location = auto_clicker.check_image_on_screen(os.path.join(auto_clicker.src_folder, file))
+        if location:
+            messagebox.showinfo("测试结果", f"图片 {file} 找到!")
+        else:
+            messagebox.showerror("测试结果", f"图片 {file} 未找到!")
+
+    def test_click_image():
+        file = auto_clicker.png_files[0] if auto_clicker.png_files else "1.png"
+        if auto_clicker.click_image_center(os.path.join(auto_clicker.src_folder, file)):
+            messagebox.showinfo("测试结果", f"点击图片 {file} 成功!")
+        else:
+            messagebox.showerror("测试结果", f"点击图片 {file} 失败!")
+
+    def test_move_mouse():
+        auto_clicker.move_mouse_to(100, 100)
+        messagebox.showinfo("测试结果", "鼠标已移动到 (100, 100)")
+
+    def test_mouse_click():
+        auto_clicker.mouse_click()
+        messagebox.showinfo("测试结果", "鼠标点击完成")
+
+    def test_scroll_mouse():
+        auto_clicker.scroll_mouse(10)
+        messagebox.showinfo("测试结果", "鼠标滚轮滚动完成")
+
+    def start_tasks():
+        while True:
+            # 在这里添加你的任务代码
+            print("开始任务")
+            time.sleep(1)
+            print("任务结束")
+            time.sleep(1)
+
+    # 创建按钮
+    tk.Button(root, text="开始任务", command=start_tasks, font=button_font, bg=button_bg_color,
+              fg=button_fg_color, bd=button_border_width).pack(pady=5)
+    tk.Button(root, text="测试检查图片", command=test_check_image, font=button_font, bg=button_bg_color,
+              fg=button_fg_color, bd=button_border_width).pack(pady=5)
+    tk.Button(root, text="测试点击图片", command=test_click_image, font=button_font, bg=button_bg_color,
+              fg=button_fg_color, bd=button_border_width).pack(pady=5)
+    tk.Button(root, text="测试移动鼠标", command=test_move_mouse, font=button_font, bg=button_bg_color,
+              fg=button_fg_color, bd=button_border_width).pack(pady=5)
+    tk.Button(root, text="测试鼠标点击", command=test_mouse_click, font=button_font, bg=button_bg_color,
+              fg=button_fg_color, bd=button_border_width).pack(pady=5)
+    tk.Button(root, text="测试滚动鼠标", command=test_scroll_mouse, font=button_font, bg=button_bg_color,
+              fg=button_fg_color, bd=button_border_width).pack(pady=5)
+
+    # 启动GUI
+    root.mainloop()
+
+
+if __name__ == "__main__":
+    main()

BIN
test/src/1.png


BIN
test/src/2.png


BIN
test/src/3.png


+ 13 - 0
test/temp.txt

@@ -0,0 +1,13 @@
+soup elephant glare success violin unusual blade swing twenty tent cable require trap major cloud item infant ensure proof glimpse bulk gain grape annual
+surge quit style joy armor save inside jungle man practice admit ball
+drama follow rhythm grit myth glow immense pretty sorry royal board armed virtual avocado meadow exist urge club major cool saddle dad regular cigar
+level blue fall burger famous thing subway zone undo panic clog voyage drum fade bracket bone attend pass level fetch trap brain client judge
+cry margin renew bean awful hedgehog canyon often ahead frame master crazy luggage gown desert entire enrich grape human item faculty satisfy occur kind
+cram kidney drip smart solar treat cry cushion volume under chief crowd today pond smart tomato net card shallow large act unlock boss private
+nerve expand focus fury topic benefit fruit coach win betray guard clarify sketch project cat prize define anxiety remember acoustic client cave noodle sword
+loud crucial output pony year attract lock barrel level entire price affair version shallow forward flock near badge mass box above future arm soup
+ethics hobby gun relax goose apple reduce frequent jungle affair rotate solid ready ridge siege tide when suggest cannon change display marble expand tired
+shaft dial garden surface dismiss kitchen clap ice manual answer spider walk open slogan earn cave boil magic wave olive medal sing dinner accident
+
+
+