jack 10 months ago
parent
commit
c9e6a5ef9a

+ 1 - 0
manual/MyGrassio/account_details.txt

@@ -0,0 +1 @@
+yujieccyj11@hotmail.com|||2pcRp86m1r76nSzdtGy1DNpXjrF|||192.168.31.201:52012|||127.0.0.1:7890

+ 12 - 0
manual/MyGrassio/account_details_bk.txt

@@ -0,0 +1,12 @@
+yujiec0210@gmail.com|||28a3e1c1-3572-45a7-8c66-2843132af302|||192.168.31.201:52001|||192.168.31.201:53001
+yujieccyj01@hotmail.com|||2oL7nKR3rlHANh08znNYVNYgZXv|||192.168.31.201:52002|||192.168.31.201:53002
+yujieccyj02@hotmail.com|||2oWgZ1hCAD6u6fZjPcWsDJowo7Y|||192.168.31.201:52003|||192.168.31.201:53003
+yujieccyj03@hotmail.com|||2oWjwicrgUXjpUxtRNE7ufVSDxl|||192.168.31.201:52004|||192.168.31.201:53004
+yujieccyj04@hotmail.com|||2oWkFItRXDMW40AYKpDjGa3SJlw|||192.168.31.201:52005|||192.168.31.201:53005
+yujieccyj05@hotmail.com|||2oY2LqL7JDLSKZ8pScMqeGDXnV3|||192.168.31.201:52006|||192.168.31.201:53006
+yujieccyj06@hotmail.com|||2pT2P5xXpWgrlZa20ZlW4bdCsZT|||192.168.31.201:52007|||192.168.31.201:53007
+yujieccyj07@hotmail.com|||2pT2zNB1oYsMbb0okgnBvtTWYpZ|||192.168.31.201:52008|||192.168.31.201:53008
+yujieccyj08@hotmail.com|||2pT3nzb7IGEIRojfB2vypMgBcUw|||192.168.31.201:52009|||192.168.31.201:53009
+yujieccyj09@hotmail.com|||2pT49IOTlvXlr8AAqpPa08vBu5o|||192.168.31.201:52010|||192.168.31.201:53010
+yujieccyj10@hotmail.com|||2pT5tt43UBpk36v3Sf64KBAoQiR|||192.168.31.201:52011|||192.168.31.201:53011
+yujieccyj11@hotmail.com|||2pcRp86m1r76nSzdtGy1DNpXjrF|||192.168.31.201:52012|||192.168.31.201:53012

+ 108 - 0
manual/MyGrassio/grassio_login_and_get_userid.py

@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+import random
+import time
+
+import httpx
+
+
+class GrassClient:
+    def __init__(self, email, password, user_agent, proxy_ip, proxy_api_port, proxy_web_port):
+        self.email = email
+        self.password = password
+        self.user_agent = user_agent
+        self.proxy_ip = proxy_ip
+        self.proxy_api_port = proxy_api_port
+        self.proxy_web_port = proxy_web_port
+        self.session = httpx.Client()
+
+    def login(self):
+        url = 'https://api.getgrass.io/login'
+        json_data = {
+            'password': self.password,
+            'username': self.email,
+        }
+        headers = {
+            'authority': 'api.getgrass.io',
+            'accept': 'application/json, text/plain, */*',
+            'accept-language': 'uk-UA,uk;q=0.9,en-US;q=0.8,en;q=0.7',
+            'content-type': 'application/json',
+            'origin': 'https://app.getgrass.io',
+            'referer': 'https://app.getgrass.io/',
+            'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
+            'sec-ch-ua-mobile': '?0',
+            'sec-ch-ua-platform': '"Windows"',
+            'sec-fetch-dest': 'empty',
+            'sec-fetch-mode': 'cors',
+            'sec-fetch-site': 'same-site',
+            'user-agent': self.user_agent,
+        }
+
+        for retry in range(5):
+            try:
+                # 使用 httpx 发送 POST 请求
+                proxy_web_port = random.choice(self.proxy_web_port)
+                proxy = f"{self.proxy_ip}:{proxy_web_port}"
+                proxies = {
+                    "http://": f"http://{proxy}",
+                    "https://": f"http://{proxy}",
+                }
+                with httpx.Client(proxies=proxies, headers=headers) as client:
+                    response = client.post(url, json=json_data)
+                    if response.status_code != 200:
+                        error_message = response.text
+                        raise httpx.RequestError(f"登录失败,状态码 {response.status_code}: {error_message}")
+
+                data = response.json()
+                userId = data['result']['data']['userId']
+                return userId
+
+            except httpx.RequestError as e:
+                print(e)
+                time.sleep(3)
+
+    def close(self):
+        self.session.close()
+
+
+# 使用示例
+def main():
+    email_list = [
+        "yujiec0210@gmail.com",
+        "yujieccyj01@hotmail.com",
+        "yujieccyj02@hotmail.com",
+        "yujieccyj03@hotmail.com",
+        "yujieccyj04@hotmail.com",
+        "yujieccyj05@hotmail.com",
+        "yujieccyj06@hotmail.com",
+        "yujieccyj07@hotmail.com",
+        "yujieccyj08@hotmail.com",
+        "yujieccyj09@hotmail.com",
+        "yujieccyj10@hotmail.com",
+        "yujieccyj11@hotmail.com"
+    ]
+    proxy_api_port = ["52001", "52002", "52003", "52004", "52005", "52006", "52007", "52008", "52009", "52010", "52011",
+                      "52012"]
+    proxy_web_port = ["53001", "53002", "53003", "53004", "53005", "53006", "53007", "53008", "53009", "53010", "53011",
+                      "53012"]
+    password = "aaaAAA111!!!"
+    proxy_ip = "192.168.31.201"
+    user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
+    user_id_list = []
+    for email in email_list:
+        client = GrassClient(email, password, user_agent, proxy_ip, proxy_api_port, proxy_web_port)
+        try:
+            login_response = client.login()
+            print("userId:", f'{email} - {login_response}')
+            user_id_list.append(login_response)
+        finally:
+            client.close()
+
+    if user_id_list:
+        with open("account_details.txt", "w") as file:
+            for email, user_id, api_port, web_port in zip(email_list, user_id_list, proxy_api_port, proxy_web_port):
+                file.write(f"{email}|||{user_id}|||{proxy_ip}:{api_port}|||{proxy_ip}:{web_port}\n")
+
+
+# 运行主函数
+if __name__ == "__main__":
+    main()

+ 60 - 86
manual/MyGrassio/main.py

@@ -11,6 +11,7 @@ from fake_useragent import UserAgent
 from tenacity import stop_after_attempt, retry, retry_if_not_exception_type, wait_random, retry_if_exception_type
 
 # 配置文件路径
+ACCOUNTS_DETAILS_FILE_PATH = "account_details.txt"
 ACCOUNTS_FILE_PATH = "accounts.txt"
 PROXIES_FILE_PATH = "proxies.txt"
 MIN_PROXY_SCORE = 50
@@ -53,18 +54,19 @@ class WebsocketClosedException(Exception):
 
 # Grass 类,负责登录、检测代理分数和持久连接
 class Grass:
-    def __init__(self, _id: int, email: str, password: str, proxy: str = None):
-        self.proxy = f"http://{proxy}" if proxy else None  # 添加协议
+    def __init__(self, _id: int, email: str, user_id: str, proxy: str = None):
+        self.proxy = f"socks5://{proxy}" if proxy else None  # 添加协议
         self.email = email
-        self.password = password
+        self.user_id = user_id
         self.user_agent = UserAgent().random
         self.proxy_score = None
         self.id = _id
         self.session = aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(ssl=False))
+        self.all_proxies_name = []
 
     async def start(self):
         try:
-            user_id = await self.login()
+            user_id = self.user_id
             browser_id = str(self.email)  # 使用邮箱作为浏览器ID
             await self.run(browser_id, user_id)
         except Exception as e:
@@ -119,8 +121,27 @@ class Grass:
         else:
             raise LowProxyScoreException(f"{self.id} | Too low proxy score: {proxy_score} for {self.proxy}. Exit...")
 
+    async def auth_to_extension(self, browser_id: str, user_id: str):
+        connection_id = await self.get_connection_id()
+        message = json.dumps(
+            {
+                "id": connection_id,
+                "origin_action": "AUTH",
+                "result": {
+                    "browser_id": browser_id,
+                    "user_id": user_id,
+                    "user_agent": self.user_agent,
+                    "timestamp": int(time.time()),
+                    "device_type": "extension",
+                    "version": "4.26.2"
+                }
+            }
+        )
+        print(message)
+        await self.send_message(message)
+
     async def connect(self):
-        uri = "wss://proxy.wynd.network:4444/"
+        uri = "wss://proxy.wynd.network:4650/"
         headers = {
             'Pragma': 'no-cache',
             'Origin': 'chrome-extension://ilehaonighjijnmpnagapkhpcdbhclfg',
@@ -139,6 +160,34 @@ class Grass:
                 raise ProxyForbiddenException(f"Low proxy score. Can't connect. Error: {e}")
             raise e
 
+    async def get_proxy_score_by_device_id(self):
+        url = 'https://api.getgrass.io/extension/user-score'
+        headers = {
+            'authority': 'api.getgrass.io',
+            'accept': 'application/json, text/plain, */*',
+            'accept-language': 'uk-UA,uk;q=0.9,en-US;q=0.8,en;q=0.7',
+            'content-type': 'application/json',
+            'origin': 'https://app.getgrass.io',
+            'referer': 'https://app.getgrass.io/',
+            'sec-ch-ua': '"Not(A:Brand";v="99", "Brave";v="133", "Chromium";v="133"',
+            'sec-ch-ua-mobile': '?0',
+            'sec-ch-ua-platform': '"Windows"',
+            'sec-fetch-dest': 'document',
+            'sec-fetch-mode': 'navigate',
+            'sec-fetch-site': 'none',
+            'user-agent': self.user_agent,
+        }
+        response = await self.session.get(url, headers=headers, proxy=self.proxy)
+        res_json = await response.json()
+        print(res_json)
+        if not (isinstance(res_json, dict) and res_json.get("data", None) is not None):
+            return
+        devices = res_json['data']['currentDeviceData']
+        self.ip = await self.get_ip()
+        logger.info(f"当前代理IP: {self.ip}")
+        return next((device['final_score'] for device in devices
+                     if device['device_ip'] == self.ip), None)
+
     async def send_message(self, message):
         await self.websocket.send_str(message)
 
@@ -152,24 +201,6 @@ class Grass:
         msg = await self.receive_message()
         return json.loads(msg)['id']
 
-    async def auth_to_extension(self, browser_id: str, user_id: str):
-        connection_id = await self.get_connection_id()
-        message = json.dumps(
-            {
-                "id": connection_id,
-                "origin_action": "AUTH",
-                "result": {
-                    "browser_id": browser_id,
-                    "user_id": user_id,
-                    "user_agent": self.user_agent,
-                    "timestamp": int(time.time()),
-                    "device_type": "extension",
-                    "version": "3.3.2"
-                }
-            }
-        )
-        await self.send_message(message)
-
     async def send_ping(self):
         message = json.dumps(
             {"id": str(uuid.uuid4()), "version": "1.0.0", "action": "PING", "data": {}}
@@ -183,58 +214,6 @@ class Grass:
         )
         await self.send_message(message)
 
-    async def login(self):
-        url = 'https://api.getgrass.io/login'
-        json_data = {
-            'password': self.password,
-            'username': self.email,
-        }
-        headers = {
-            'authority': 'api.getgrass.io',
-            'accept': 'application/json, text/plain, */*',
-            'accept-language': 'uk-UA,uk;q=0.9,en-US;q=0.8,en;q=0.7',
-            'content-type': 'application/json',
-            'origin': 'https://app.getgrass.io',
-            'referer': 'https://app.getgrass.io/',
-            'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
-            'sec-ch-ua-mobile': '?0',
-            'sec-ch-ua-platform': '"Windows"',
-            'sec-fetch-dest': 'empty',
-            'sec-fetch-mode': 'cors',
-            'sec-fetch-site': 'same-site',
-            'user-agent': self.user_agent,
-        }
-        response = await self.session.post(url, headers=headers, json=json_data, proxy=self.proxy)
-        if response.status != 200:
-            raise aiohttp.ClientConnectionError(f"login | {await response.text()}")
-        return await response.json()
-
-    async def get_proxy_score_by_device_id(self):
-        url = 'https://api.getgrass.io/extension/user-score'
-        headers = {
-            'authority': 'api.getgrass.io',
-            'accept': 'application/json, text/plain, */*',
-            'accept-language': 'uk-UA,uk;q=0.9,en-US;q=0.8,en;q=0.7',
-            'content-type': 'application/json',
-            'origin': 'https://app.getgrass.io',
-            'referer': 'https://app.getgrass.io/',
-            'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
-            'sec-ch-ua-mobile': '?0',
-            'sec-ch-ua-platform': '"Windows"',
-            'sec-fetch-dest': 'empty',
-            'sec-fetch-mode': 'cors',
-            'sec-fetch-site': 'same-site',
-            'user-agent': self.user_agent,
-        }
-        response = await self.session.get(url, headers=headers, proxy=self.proxy)
-        res_json = await response.json()
-        if not (isinstance(res_json, dict) and res_json.get("data", None) is not None):
-            return
-        devices = res_json['data']['currentDeviceData']
-        self.ip = await self.get_ip()
-        return next((device['final_score'] for device in devices
-                     if device['device_ip'] == self.ip), None)
-
     async def get_ip(self):
         return await (await self.session.get('https://api.ipify.org', proxy=self.proxy)).text()
 
@@ -245,20 +224,15 @@ class Grass:
 
 # 主函数
 async def main():
-    accounts = []
-    with open(ACCOUNTS_FILE_PATH, 'r') as f:
-        accounts = f.readlines()
-
-    proxies = []
-    with open(PROXIES_FILE_PATH, 'r') as f:
-        proxies = f.readlines()
+    account_details = []
+    with open(ACCOUNTS_DETAILS_FILE_PATH, 'r') as f:
+        account_details = f.readlines()
 
     grass_instances = []
     tasks = []
-    for i, account in enumerate(accounts):
-        email, password = account.strip().split(":")
-        proxy = proxies[i % len(proxies)].strip() if proxies else None
-        grass = Grass(i, email, password, proxy)
+    for i, account in enumerate(account_details):
+        email, user_id, proxy_web, proxy_api = account.strip().split("|||")
+        grass = Grass(i, email, user_id, proxy_api)
         grass_instances.append(grass)
         tasks.append(grass.start())
 

+ 12 - 12
manual/MyGrassio/proxies.txt

@@ -1,12 +1,12 @@
-192.168.31.201:59001
-192.168.31.201:59002
-192.168.31.201:59003
-192.168.31.201:59004
-192.168.31.201:59005
-192.168.31.201:59006
-192.168.31.201:59007
-192.168.31.201:59008
-192.168.31.201:59009
-192.168.31.201:59010
-192.168.31.201:59011
-192.168.31.201:59012
+192.168.31.201:53001
+192.168.31.201:53002
+192.168.31.201:53003
+192.168.31.201:53004
+192.168.31.201:53005
+192.168.31.201:53006
+192.168.31.201:53007
+192.168.31.201:53008
+192.168.31.201:53009
+192.168.31.201:53010
+192.168.31.201:53011
+192.168.31.201:53012

+ 172 - 0
manual/MyGrassio/random_proxy.py

@@ -0,0 +1,172 @@
+# -*- coding: utf-8 -*-
+'''
+切换到随机代理
+'''
+import random
+
+import httpx
+import time
+import logging
+import subprocess
+from typing import Optional, List
+
+logging.basicConfig(level=logging.INFO)
+
+BASE_URL = "http://192.168.31.201"
+
+PORT_LIST = [
+    ["52001", "53001"],
+    ["52002", "53002"],
+    ["52003", "53003"],
+    ["52004", "53004"],
+    ["52005", "53005"],
+    ["52006", "53006"],
+    ["52007", "53007"],
+    ["52008", "53008"],
+    ["52009", "53009"],
+    ["52011", "53012"],
+    ["52012", "53012"]
+]
+
+
+class ClashProxyManager:
+    def __init__(self, base_url, base_port):
+        self.key_group = 0
+        self.base_url = base_url
+        self.base_port = base_port
+        self.all_proxies = []
+
+    def get_all_proxies(self, clash_tool_url: str) -> List[str]:
+        url = f"{clash_tool_url}/api/proxies"
+        try:
+            response = httpx.get(url)
+            response.raise_for_status()
+            proxies = response.json()
+            logging.info("Available proxies:")
+            # 输出读取的所有代理信息
+            # for proxy_name, proxy_info in proxies['proxies'].items():
+            #     logging.info(f"Name: {proxy_name}, Type: {proxy_info.get('type', 'Unknown')}")
+            proxy_list = list(proxies['proxies'].keys())
+            filtered_list = [item for item in proxy_list if item not in {'REJECT', 'GLOBAL', 'DIRECT'}]
+            return filtered_list
+        except Exception as e:
+            logging.error(f"Failed to get proxies: {e}")
+            return []
+
+    def switch_proxy(self, proxy_name: str, url_and_port: str) -> None:
+        logging.info("switch proxy")
+        url = f"{url_and_port}/api/proxies/GLOBAL"
+        data = {"name": proxy_name}
+        try:
+            response = httpx.put(url, json=data)
+            if response.status_code == 204:
+                logging.info(f"Switched to proxy: {proxy_name}")
+            else:
+                logging.error(f"Failed to switch proxy: {response.status_code} - {proxy_name}")
+        except Exception as e:
+            logging.error(f"Failed to switch proxy: {e}")
+
+    def update_configs(self):
+        for base_port in self.base_port:
+            url_and_port = self.base_url + ":" + base_port[0]
+            key = "/api/configs"
+            url = url_and_port + key
+
+            headers = {
+                "accept": "application/json, text/plain, */*",
+                "accept-encoding": "gzip, deflate, br, zstd",
+                "accept-language": "zh-CN,zh",
+                "connection": "keep-alive",
+                "content-type": "application/json",
+                "origin": url_and_port,
+                "referer": url_and_port,
+                "sec-ch-ua": '"Not A(Brand";v="8", "Chromium";v="132", "Brave";v="132"',
+                "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/132.0.0.0 Safari/537.36",
+            }
+
+            # 请求体数据
+            data = {"mode": "Global"}  # 替换为实际的请求数据
+
+            # 使用 httpx 发送 PATCH 请求
+            try:
+                with httpx.Client() as client:
+                    response = client.patch(url, headers=headers, json=data)
+                    if response.status_code == 204:
+                        print(f"{url} OK")
+                    else:
+                        print("响应内容:", response.text)
+            except httpx.RequestError as exc:
+                print(f"请求失败: {exc}")
+
+    def check_proxy(self, proxy_url):
+        # proxy_url: 代理地址, 没有密码
+        # 测试目标地址:
+        command = ["curl", "-x", proxy_url, "ip.sb"]
+
+        # 执行命令并获取输出
+        try:
+            result = subprocess.run(command, capture_output=True, text=True, check=True)
+            # 打印命令的标准输出
+            print("Output:", result.stdout)
+            return True
+        except subprocess.CalledProcessError as e:
+            # 如果命令执行失败,打印错误信息
+            print("Error:", e.stderr)
+            return False
+
+    def main(self) -> None:
+        # 设置全局代理
+        self.update_configs()
+
+        # 读取所有代理
+        if not self.all_proxies:
+            for port_list in self.base_port:
+                base_url = self.base_url + ":" + port_list[0]
+                clash_tool_url = f"{base_url}"
+                proxies = self.get_all_proxies(clash_tool_url)
+                if proxies:
+                    self.all_proxies = proxies
+                    break
+
+        if not self.all_proxies:
+            logging.error("Failed to get all proxies")
+            return
+        else:
+            logging.info(f"Found {self.all_proxies} proxies.")
+            logging.info(f"Found {len(self.all_proxies)} proxies.")
+
+        # 遍历所有的线路api, 切换不重复代理
+        # 切换后, 检测代理, 如果检测返回失败, 再次切换
+        used_proxy = []
+        for base_port in self.base_port:
+            url_and_port = self.base_url + ":" + base_port[0]
+            proxy_url = self.base_url + ":" + base_port[1]
+            while True:
+                # 选一个代理
+                choose_proxy = random.choice(self.all_proxies)
+                # 如果已经选过就继续下一个
+                if choose_proxy in used_proxy:
+                    continue
+
+                # 切换代理
+                self.switch_proxy(choose_proxy, url_and_port)
+
+                # 切换后检测代理
+                if self.check_proxy(proxy_url):
+                    print(f"代理 {choose_proxy} 切换成功,检测通过!")
+                    used_proxy.append(choose_proxy)  # 标记为已使用
+                    break  # 成功后退出当前代理的重试循环
+                else:
+                    print(f"{url_and_port} 切换 {choose_proxy} 检测失败")
+                    time.sleep(1)
+
+
+if __name__ == "__main__":
+    manager = ClashProxyManager(BASE_URL, PORT_LIST)
+    manager.main()

+ 77 - 0
manual/MyGrassio/test_grass_connect.py

@@ -0,0 +1,77 @@
+import asyncio
+import random
+from fake_useragent import UserAgent
+import aiohttp
+import logging
+
+class ProxyForbiddenException(Exception):
+    pass
+
+
+class GrassConnect:
+    def __init__(self, proxy: str = None):
+        self.user_agent = UserAgent().random
+        self.proxy = proxy
+        self.session = None
+        self.websocket = None
+        logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
+        self.logger = logging.getLogger(__name__)
+
+    async def __aenter__(self):
+        self.session = aiohttp.ClientSession()
+        return self
+
+    async def __aexit__(self, exc_type, exc_val, exc_tb):
+        await self.close()
+
+    async def connect(self):
+        uri = f"wss://proxy.wynd.network:{random.choice(['4650', '4444'])}/"
+        headers = {
+            'Pragma': 'no-cache',
+            'Origin': 'chrome-extension://ilehaonighjijnmpnagapkhpcdbhclfg',
+            'Accept-Language': 'uk-UA,uk;q=0.9,en-US;q=0.8,en;q=0.7',
+            'User-Agent': self.user_agent,
+            'Upgrade': 'websocket',
+            'Cache-Control': 'no-cache',
+            'Connection': 'Upgrade',
+            'Sec-WebSocket-Version': '13',
+            'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits'
+        }
+        while True:
+            self.logger.info(f"Attempting to connect to {uri} using proxy {self.proxy}")
+            try:
+                self.websocket = await self.session.ws_connect(
+                    uri,
+                    headers=headers,
+                    proxy=self.proxy,
+                    proxy_headers=headers
+                )
+                self.logger.info(f"Successfully connected to {uri}")
+                return self.websocket
+            except aiohttp.ClientResponseError as e:
+                self.logger.error(f"HTTP error occurred: {e}")
+                if e.status == 403:
+                    raise ProxyForbiddenException(f"Low proxy score. Can't connect. Error: {e}")
+            except Exception as e:
+                self.logger.error(f"Unexpected error occurred: {e}")
+            self.logger.info("Connection failed. Retrying in 3 seconds...")
+            await asyncio.sleep(3)
+
+    async def close(self):
+        if self.websocket:
+            await self.websocket.close()
+            self.logger.info("Websocket connection closed.")
+        if self.session:
+            await self.session.close()
+            self.logger.info("Client session closed.")
+
+
+# Example usage
+async def main():
+    proxy = "socks5://192.168.31.201:53012"
+    async with GrassConnect(proxy=proxy) as connector:
+        websocket = await connector.connect()
+        # 继续处理websocket连接
+
+if __name__ == "__main__":
+    asyncio.run(main())

+ 2 - 0
manual/MyGrassio/test_grass_proxy_score.py

@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+

+ 5 - 6
manual/clash/set_global_switch_proxy_random.py

@@ -27,15 +27,12 @@ PORT_LIST = [
     ["58010", "59010"],
 ]
 
-TEST_URL = "https://httpbin.org/ip"
-
 
 class ClashProxyManager:
-    def __init__(self, base_url, base_port, test_url):
+    def __init__(self, base_url, base_port):
         self.key_group = 0
         self.base_url = base_url
         self.base_port = base_port
-        self.test_url = test_url
         self.all_proxies = []
 
     def get_all_proxies(self, clash_tool_url: str) -> List[str]:
@@ -48,7 +45,9 @@ class ClashProxyManager:
             # 输出读取的所有代理信息
             # for proxy_name, proxy_info in proxies['proxies'].items():
             #     logging.info(f"Name: {proxy_name}, Type: {proxy_info.get('type', 'Unknown')}")
-            return list(proxies['proxies'].keys())
+            proxy_list = list(proxies['proxies'].keys())
+            filtered_list = [item for item in proxy_list if item not in {'REJECT', 'GLOBAL', 'DIRECT'}]
+            return filtered_list
         except Exception as e:
             logging.error(f"Failed to get proxies: {e}")
             return []
@@ -165,5 +164,5 @@ class ClashProxyManager:
 
 
 if __name__ == "__main__":
-    manager = ClashProxyManager(BASE_URL, PORT_LIST, TEST_URL)
+    manager = ClashProxyManager(BASE_URL, PORT_LIST)
     manager.main()

+ 5 - 6
manual/clash/switch_proxy_group_group.py

@@ -25,11 +25,9 @@ PORT_LIST = [
     ["58010", "59010"],
 ]
 
-TEST_URL = "https://httpbin.org/ip"
-
 
 class ClashProxyManager:
-    def __init__(self, base_url, base_port, test_url):
+    def __init__(self, base_url, base_port):
         self.key_group = 0
         self.base_url = base_url
         self.base_port = base_port
@@ -37,7 +35,6 @@ class ClashProxyManager:
             ['sg', 'SG', '新加坡', '马来西亚'],
             ['jp', '日本'],
         ]
-        self.test_url = test_url
         self.all_proxies = []
         self.selected_proxies = []
 
@@ -51,7 +48,9 @@ class ClashProxyManager:
             # 输出读取的所有代理信息
             # for proxy_name, proxy_info in proxies['proxies'].items():
             #     logging.info(f"Name: {proxy_name}, Type: {proxy_info.get('type', 'Unknown')}")
-            return list(proxies['proxies'].keys())
+            proxy_list = list(proxies['proxies'].keys())
+            filtered_list = [item for item in proxy_list if item not in {'REJECT', 'GLOBAL', 'DIRECT'}]
+            return filtered_list
         except Exception as e:
             logging.error(f"Failed to get proxies: {e}")
             return []
@@ -175,5 +174,5 @@ class ClashProxyManager:
 
 
 if __name__ == "__main__":
-    manager = ClashProxyManager(BASE_URL, PORT_LIST, TEST_URL)
+    manager = ClashProxyManager(BASE_URL, PORT_LIST)
     manager.main()

+ 0 - 12
manual/grassio/account.txt

@@ -1,12 +0,0 @@
-28a3e1c1-3572-45a7-8c66-2843132af302
-2oL7nKR3rlHANh08znNYVNYgZXv
-2oWgZ1hCAD6u6fZjPcWsDJowo7Y
-2oWjwicrgUXjpUxtRNE7ufVSDxl
-2oWkFItRXDMW40AYKpDjGa3SJlw
-2oY2LqL7JDLSKZ8pScMqeGDXnV3
-2pT2P5xXpWgrlZa20ZlW4bdCsZT
-2pT2zNB1oYsMbb0okgnBvtTWYpZ
-2pT3nzb7IGEIRojfB2vypMgBcUw
-2pT49IOTlvXlr8AAqpPa08vBu5o
-2pT5tt43UBpk36v3Sf64KBAoQiR
-2pcRp86m1r76nSzdtGy1DNpXjrF

+ 0 - 12
manual/grassio/account_proxy.txt

@@ -1,12 +0,0 @@
-28a3e1c1-3572-45a7-8c66-2843132af302==socks5://47.79.34.67:60001
-2oL7nKR3rlHANh08znNYVNYgZXv==socks5://47.79.34.67:60002
-2oWgZ1hCAD6u6fZjPcWsDJowo7Y==socks5://47.79.34.67:60003
-2oWjwicrgUXjpUxtRNE7ufVSDxl==socks5://47.79.34.67:60004
-2oWkFItRXDMW40AYKpDjGa3SJlw==socks5://47.79.34.67:60005
-2oY2LqL7JDLSKZ8pScMqeGDXnV3==socks5://47.79.34.67:60006
-2pT2P5xXpWgrlZa20ZlW4bdCsZT==socks5://47.79.34.67:60007
-2pT2zNB1oYsMbb0okgnBvtTWYpZ==socks5://47.79.34.67:60008
-2pT3nzb7IGEIRojfB2vypMgBcUw==socks5://47.79.34.67:60009
-2pT49IOTlvXlr8AAqpPa08vBu5o==socks5://47.79.34.67:60010
-2pT5tt43UBpk36v3Sf64KBAoQiR==socks5://47.79.34.67:60011
-2pcRp86m1r76nSzdtGy1DNpXjrF==socks5://47.79.34.67:60012

+ 0 - 83
manual/grassio/check_grassio_proxy.py

@@ -1,83 +0,0 @@
-import httpx
-import time
-import json
-import uuid
-import logging
-import websockets
-from typing import Optional
-from websockets import WebSocketCommonProtocol
-
-# 配置日志
-logging.basicConfig(level=logging.INFO)
-
-# Clash API 的基础 URL
-CLASH_API_BASE_URL = "http://localhost:17888/api"
-
-# 服务的基础 URL 和端口
-SERVER_HOSTNAME = "proxy.wynd.network"
-SERVER_PORT = 4444
-SERVER_URL = f"wss://{SERVER_HOSTNAME}:{SERVER_PORT}/"
-TEST_USER_ID = '2pcRp86m1r76nSzdtGy1DNpXjrF'
-PROXY_URL = "http://127.0.0.1:17890"  # 代理地址
-
-
-def get_all_proxies():
-    """获取Clash中所有可用的代理"""
-    url = f"{CLASH_API_BASE_URL}/proxies"
-    try:
-        response = httpx.get(url)
-        response.raise_for_status()  # 检查请求是否成功
-        proxies = response.json()
-        logging.info("Available proxies:")
-        for proxy_name, proxy_info in proxies['proxies'].items():
-            logging.info(f"Name: {proxy_name}, Type: {proxy_info.get('type', 'Unknown')}")
-        return list(proxies['proxies'].keys())
-    except Exception as e:
-        logging.error(f"Failed to get proxies: {e}")
-        return []
-
-
-def switch_proxy(proxy_name):
-    """切换到指定的代理"""
-    url = f"{CLASH_API_BASE_URL}/proxies/GLOBAL"
-    data = {"name": proxy_name}
-    response = httpx.put(url, json=data)
-    if response.status_code == 204:
-        logging.info(f"Switched to proxy: {proxy_name}")
-    else:
-        logging.error(f"Failed to switch proxy: {response.status_code} - {proxy_name}")
-
-
-def test_grassio(proxy_name):
-    pass
-
-
-def main():
-    # 获取所有代理
-    proxies = get_all_proxies()
-    if proxies:
-        logging.info(f"Found {len(proxies)} proxies.")
-
-        ok_proxy_list = []
-
-        for proxy_name in proxies:
-            if proxy_name in ["DIRECT", "REJECT", "GLOBAL"]:
-                continue
-
-            # 切换到指定的代理
-            switch_proxy(proxy_name)
-            # 暂停一段时间,避免频繁切换
-            time.sleep(0.5)
-            # 测试通过代理连接 grassio 服务
-            result = test_grassio(proxy_name)
-            if result:
-                ok_proxy_list.append(proxy_name)
-
-        for proxy_name in ok_proxy_list:
-            logging.info(f"Proxy {proxy_name} is OK.")
-    else:
-        logging.info("No proxies found. Exiting.")
-
-
-if __name__ == "__main__":
-    main()

+ 0 - 111
manual/grassio/main.py

@@ -1,111 +0,0 @@
-import aiohttp
-import asyncio
-import re
-import random
-
-
-class GrassRest:
-    def __init__(self, email: str, password: str, user_agent: str = None, proxy: str = None):
-        self.email = email
-        self.password = password
-        self.user_agent = user_agent
-        self.proxy = proxy
-
-        self.website_headers = {
-            'authority': 'api.getgrass.io',
-            'accept': 'application/json, text/plain, */*',
-            'accept-language': 'uk-UA,uk;q=0.9,en-US;q=0.8,en;q=0.7',
-            'content-type': 'application/json',
-            'origin': 'https://app.getgrass.io',
-            'referer': 'https://app.getgrass.io/',
-            'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
-            'sec-ch-ua-mobile': '?0',
-            'sec-ch-ua-platform': '"Windows"',
-            'sec-fetch-dest': 'empty',
-            'sec-fetch-mode': 'cors',
-            'sec-fetch-site': 'same-site',
-            'user-agent': self.user_agent,
-        }
-
-        self.session = None
-
-    async def login(self):
-        url = 'https://api.getgrass.io/login'
-
-        json_data = {
-            'password': self.password,
-            'username': self.email,
-        }
-
-        async with self.session.post(url, headers=self.website_headers, json=json_data, proxy=self.proxy) as response:
-            if response.status != 200:
-                raise Exception(f"Login failed for {self.email}: {await response.text()}")
-            return await response.json()
-
-    async def enter_account(self):
-        res_json = await self.login()
-        self.website_headers['Authorization'] = res_json['result']['data']['accessToken']
-        return res_json['result']['data']['userId']
-
-
-async def main():
-    # 账号列表
-    account_list = [
-        # 'jack0210_@hotmail.com',
-        'yujiec0210@gmail.com',
-        'yujieccyj01@hotmail.com',
-        'yujieccyj02@hotmail.com',
-        'yujieccyj03@hotmail.com',
-        'yujieccyj04@hotmail.com',
-        'yujieccyj05@hotmail.com',
-        'yujieccyj06@hotmail.com',
-        'yujieccyj07@hotmail.com',
-        'yujieccyj08@hotmail.com',
-        'yujieccyj09@hotmail.com',
-        'yujieccyj10@hotmail.com',
-        'yujieccyj11@hotmail.com'
-    ]
-    # 密码(假设所有账号的密码相同,如果不同请自行修改)
-    password = "aaaAAA111!!!"
-    user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
-    proxy = None  # 如果需要代理,可以设置代理地址
-
-    async with aiohttp.ClientSession() as session:
-        tasks = []
-        for email in account_list:
-            grass_rest = GrassRest(email, password, user_agent, proxy)
-            grass_rest.session = session
-            tasks.append(grass_rest.enter_account())
-
-        user_ids = await asyncio.gather(*tasks, return_exceptions=True)
-
-    with open("account.txt", "w") as f:
-        for email, user_id in zip(account_list, user_ids):
-            if isinstance(user_id, Exception):
-                print(f"{email}: Error - {user_id}")
-            else:
-                print(f"{email}: {user_id}")
-                f.write(f"{user_id}\n")
-
-    print("UserID 获取完成,已保存到 account.txt 文件中。")
-
-
-def add_proxy():
-    with open("account.txt", "r") as f:
-        user_ids = f.readlines()
-
-    str_data = ''
-
-    for index, user_id in enumerate(user_ids, start=1):
-        user_id_and_proxy = f"{user_id.strip()}==socks5://47.79.34.67:600{str(index).zfill(2)}"
-        str_data += user_id_and_proxy + '\n'
-
-    with open("account_proxy.txt", "w") as f:
-        f.write(str_data)
-
-
-if __name__ == "__main__":
-    asyncio.run(main())
-
-    # 顺手添加代理
-    add_proxy()