From a6662268312eb645cc7b5bf9f2ad6f5635d3cb28 Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期日, 27 七月 2025 22:47:06 +0800
Subject: [PATCH] add network client and android app

---
 network/sening_vdp.py |  139 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 139 insertions(+), 0 deletions(-)

diff --git a/network/sening_vdp.py b/network/sening_vdp.py
index e69de29..7c070d7 100644
--- a/network/sening_vdp.py
+++ b/network/sening_vdp.py
@@ -0,0 +1,139 @@
+import os
+import subprocess
+import time
+import logging
+import sys
+import getpass
+
+APP_NAME = "sening_vdp"
+LOG_FILE = "sening_vdp.log"
+
+BASE_DIR = os.path.abspath(os.path.dirname(sys.executable))
+
+logging.basicConfig(
+    filename=os.path.join(BASE_DIR, LOG_FILE),
+    level=logging.INFO,
+    format='%(asctime)s - %(levelname)s - %(message)s'
+)
+
+def start_process(name, exe_path, args, log_file):
+    try:
+        full_path = os.path.abspath(exe_path)
+        logging.info(f"Starting {name}: {full_path} {' '.join(args)}")
+
+        # 鎵撳紑鏃ュ織鏂囦欢锛岃拷鍔犲啓鍏�
+        log_fh = open(log_file, "a", encoding="utf-8")
+
+        # CREATE_NO_WINDOW 闅愯棌绐楀彛
+        CREATE_NO_WINDOW = 0x08000000
+
+        process = subprocess.Popen(
+            [full_path] + args,
+            cwd=os.path.dirname(full_path),
+            stdout=log_fh,
+            stderr=subprocess.STDOUT,
+            creationflags=CREATE_NO_WINDOW,
+            universal_newlines=True
+        )
+        return process
+    except Exception as e:
+        logging.error(f"Failed to start {name}: {e}")
+        return None
+
+
+
+def start_process_with_retry(name, exe_path, args, log_file, retry_interval=120):
+    full_path = os.path.abspath(exe_path)
+    CREATE_NO_WINDOW = 0x08000000
+
+    while True:
+        try:
+            logging.info(f"[{name}] 灏濊瘯鍚姩锛歿full_path} {' '.join(args)}")
+
+            process = subprocess.Popen(
+                [full_path] + args,
+                cwd=os.path.dirname(full_path),
+                stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT,
+                creationflags=CREATE_NO_WINDOW,
+                universal_newlines=True,
+                encoding="utf-8",
+            )
+
+            success = False
+            while True:
+                line = process.stdout.readline()
+                print(line)
+                if not line:
+                    break
+                logging.info(f"[{name}] {line.strip()}")
+
+                if "connect to server error" in line or "login to the server failed" in line:
+                    logging.warning(f"[{name}] 杩炴帴澶辫触锛寋retry_interval} 绉掑悗閲嶈瘯...")
+                    process.kill()
+                    time.sleep(retry_interval)
+                    break
+
+                if "start proxy success" in line :
+                    success = True
+
+            if success:
+                logging.info(f"[{name}] 鎴愬姛鍚姩骞惰繛鎺�")
+                return process
+
+        except Exception as e:
+            logging.error(f"[{name}] 鍚姩寮傚父锛歿e}")
+            time.sleep(retry_interval)
+
+def add_to_startup():
+    try:
+        # 鑾峰彇褰撳墠鐢ㄦ埛鍚嶅拰璺緞
+        user = getpass.getuser()
+        startup_folder = fr"C:\Users\{user}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"
+
+        # 褰撳墠鍙墽琛屾枃浠惰矾寰�
+        exe_path = os.path.join(BASE_DIR,"sening_vdp.exe")
+
+        shortcut_path = os.path.join(startup_folder, "sening_vdp.lnk")
+
+        # 鍒涘缓蹇嵎鏂瑰紡
+        import pythoncom
+        from win32com.shell import shell, shellcon
+        from win32com.client import Dispatch
+
+        shell = Dispatch('WScript.Shell')
+        shortcut = shell.CreateShortcut(shortcut_path)
+        shortcut.TargetPath = exe_path
+        shortcut.WorkingDirectory = os.path.dirname(exe_path)
+        shortcut.IconLocation = exe_path
+        shortcut.Save()
+    except Exception as e:
+        print(f"e")
+        pass
+
+if __name__ == "__main__":
+    logging.info("绋嬪簭鍚姩")
+    add_to_startup()
+    import sys
+    import win32event
+    import win32api
+    import winerror
+    mutex = win32event.CreateMutex(None, False, "Global\\SeningVDPOnlyOne")
+    last_error = win32api.GetLastError()
+    if last_error == winerror.ERROR_ALREADY_EXISTS:
+        # 宸茬粡杩愯杩囦簡锛岄��鍑�
+        sys.exit(0)
+    # 鍚姩 Clash锛堝綋鍓嶇洰褰曚笅 clash.exe锛岄厤缃枃浠� clash.yaml锛�
+    clash_process = start_process("sening_vdp1", "sening_vdp1.exe", ["-f", "sening_vdp1.yaml"], LOG_FILE)
+    time.sleep(2)
+
+    # 鍚姩 frpc锛堝綋鍓嶇洰褰曚笅 frpc.exe锛岄厤缃枃浠� frpc.toml锛�
+    frpc_process = start_process_with_retry("sening_vdp2", "sening_vdp2.exe", ["-c", "sening_vdp2.toml"], LOG_FILE)
+
+    try:
+        if clash_process:
+            clash_process.wait()
+        if frpc_process:
+            frpc_process.wait()
+    except KeyboardInterrupt:
+        logging.info("绋嬪簭琚腑鏂紝閫�鍑�")

--
Gitblit v1.9.1