# 项目结构和调用时序 ## 目录结构 | 路径 | 职责 | | --- | --- | | `pyxray/cli.py` | 命令行入口。默认启动 Web。 | | `pyxray/web/server.py` | 创建 Flask app,注册各 API 和生命周期清理。 | | `pyxray/web/dashboard.py` | 渲染首页。 | | `pyxray/web/jobs.py` | 内存任务表,当前用于下载任务轮询。 | | `pyxray/web/nodes.py` | 节点 API。 | | `pyxray/web/xray_assets.py` | Xray 资源下载 API。 | | `pyxray/web/xray_config.py` | 配置保存和生成 API。 | | `pyxray/web/xray_service.py` | Xray 启停和日志 API。 | | `pyxray/web/templates/` | Jinja 页面和配置表单。 | | `pyxray/web/static/` | 前端 JS/CSS。 | | `pyxray/libs/nodes/` | 节点链接解析、标准化、TOML 存储。 | | `pyxray/libs/xray_assets.py` | 下载和检查 `xray`、`geoip.dat`、`geosite.dat`。 | | `pyxray/libs/xray_asset_settings.py` | `download.toml` 读写。 | | `pyxray/libs/xray_config/` | Xray JSON、透明代理脚本、TinyTun 配置和设置存储。 | | `pyxray/libs/xray_runtime.py` | Xray 子进程管理、端口检查、日志转发。 | | `pyxray/libs/xray_transparent_runtime.py` | 透明代理脚本执行、回滚、本地 CIDR watcher。 | | `tests/` | 单元测试和 Web API 测试。 | | `docs/` | 使用和配置文档。 | | `scripts/build.sh` | Docker 镜像构建脚本。 | | `compose.yaml` | Docker 透明代理部署。 | ## 数据文件 | 文件 | 创建方 | 读写时机 | | --- | --- | --- | | `nodes.toml` | `NodeStore` | 导入、选择、删除节点。 | | `settings.toml` | `XrayConfigSettingsStore` | 保存配置页设置、生成配置、启动 Xray。 | | `download.toml` | `XrayAssetSettingsStore` | 保存下载页设置、启动下载任务。 | | `config.json` | `generate_current_xray_config` | 生成配置、启动 Xray 前。 | | `xray.log` | `XrayServiceManager` / `TransparentRuntime` | 启停 Xray、转发 Xray 输出、透明代理脚本日志。 | | `transparent/*` | `write_transparent_rule_files` | 生成配置、启动 Xray 前。 | ## Web App 装配 ```mermaid flowchart TD CLI[pyxray cli] --> RunWeb[run_web] RunWeb --> CreateApp[create_app] CreateApp --> Jobs[init_job_store] CreateApp --> Assets[register_xray_assets] CreateApp --> Nodes[register_nodes] CreateApp --> Config[register_xray_config] CreateApp --> Service[register_xray_service] CreateApp --> Lifecycle[_bind_xray_lifecycle] CreateApp --> Dashboard[register_dashboard] ``` ## 首页渲染 ```mermaid sequenceDiagram participant B as Browser participant D as dashboard.index participant A as AssetSettingsStore participant N as NodeManager participant C as XrayConfigSettingsStore participant S as XrayServiceManager B->>D: GET / D->>A: load download.toml D->>N: list_nodes + selected_id D->>C: load settings.toml D->>S: status D-->>B: render index.html ``` ## 资源下载 ```mermaid sequenceDiagram participant B as Browser participant API as /api/xray/assets/ensure participant Store as XrayAssetSettingsStore participant Jobs as JobStore participant Worker as _run_asset_job participant Assets as ensure_xray_assets B->>API: POST form API->>Store: save download.toml API->>Jobs: start worker API-->>B: job_id Worker->>Assets: check/download/extract Worker->>Jobs: update steps/status B->>Jobs: GET job status Jobs-->>B: progress/result ``` ## 节点导入和选择 ```mermaid sequenceDiagram participant B as Browser participant API as nodes API participant M as NodeManager participant P as parse_node_link participant S as NodeStore B->>API: POST /api/nodes/import API->>M: import_links M->>P: parse + normalize M->>S: save nodes.toml API-->>B: import results B->>API: POST /api/nodes/select API->>M: select_node M->>S: save selected_id API-->>B: selected node ``` ## 配置生成 ```mermaid sequenceDiagram participant B as Browser participant API as /api/xray/config/generate participant N as NodeManager participant S as SettingsStore participant G as generate_xray_config participant T as write_transparent_rule_files participant U as write_tinytun_config_file participant FS as data directory B->>API: POST generate API->>N: get_selected_node API->>S: load settings.toml API->>G: node + settings G-->>API: config dict API->>FS: write config.json API->>T: write transparent scripts API->>U: write tinytun.yaml if needed API-->>B: config + paths ``` ## 启动 Xray 和透明代理 ```mermaid sequenceDiagram participant B as Browser participant API as /api/xray/service/start participant G as generate_current_xray_config participant X as XrayServiceManager participant R as TransparentRuntime participant OS as Host network B->>API: POST start API->>G: regenerate config and scripts API->>X: status API->>X: start xray X->>X: check inbound ports X->>OS: Popen xray run -config config.json X->>X: forward stdout/stderr to xray.log API->>R: setup settings R->>R: cleanup old rules best-effort R->>OS: run ip-forward script R->>OS: run iptables setup, fallback nft R->>OS: run resolv setup R->>R: start local CIDR watcher API-->>B: running status ``` ## 停止和清理 ```mermaid sequenceDiagram participant B as Browser participant API as /api/xray/service/stop participant X as XrayServiceManager participant R as TransparentRuntime participant OS as Host network B->>API: POST stop API->>X: stop X->>R: before_stop cleanup R->>R: stop local CIDR watcher R->>OS: run resolv cleanup R->>OS: run transparent backend cleanup X->>OS: terminate xray process API-->>B: stopped status ``` ## Docker 透明代理部署 ```mermaid flowchart TD Compose["docker compose"] --> Container["pyxray container"] Container --> HostNet["host network namespace"] Container --> ConfigVol["data volume mounted to config"] Container --> Resolv["resolv.conf bind mount"] Container --> Modules["lib modules read-only mount"] HostNet --> XrayPorts["Xray listens on host ports"] HostNet --> Rules["iptables nft ip rule affect host"] Resolv --> DNS["host DNS hijack when enabled"] ``` 关键点: | Compose 配置 | 原因 | | --- | --- | | `network_mode: host` | Xray 端口和透明代理规则直接作用于宿主机。 | | `privileged: true` | 允许改防火墙、策略路由、procfs。 | | `./data:/config` | 容器重建后状态不丢。 | | `/etc/resolv.conf:/etc/resolv.conf` | redirect DNS 劫持修改宿主机 DNS。 | | `/lib/modules:/lib/modules:ro` | 读取宿主机内核模块信息。 | ## 修改建议 | 目标 | 优先修改位置 | | --- | --- | | 增加节点协议 | `pyxray/libs/nodes/parsers/`、`pyxray/libs/xray_config/outbound.py`。 | | 增加配置字段 | `settings.py`、`store.py`、配置模板、`generator.py`。 | | 改 Web API | `pyxray/web/*.py`。 | | 改配置生成 | `pyxray/libs/xray_config/generator.py`。 | | 改透明代理规则 | `transparent_rules.py`。 | | 改规则执行/回滚 | `xray_transparent_runtime.py`。 | | 改 Docker 部署 | `Dockerfile`、`compose.yaml`、`scripts/build.sh`。 |