|
| 1 | +# Architecture |
| 2 | + |
| 3 | +## Core Integration |
| 4 | + |
| 5 | +The Go proxy core in `core/` operates in two modes. |
| 6 | + |
| 7 | +Android lib mode: |
| 8 | + |
| 9 | +- Go core is compiled as a C shared library, `libclash.so`, through `go build -buildmode=c-shared` with CGO. |
| 10 | +- Flutter calls it via FFI through the `service` plugin. |
| 11 | +- Dart-side implementation: `lib/core/lib.dart` (`CoreLib`). |
| 12 | + |
| 13 | +Desktop core mode: |
| 14 | + |
| 15 | +- Go core runs as a separate process with `CGO_ENABLED=0`. |
| 16 | +- Flutter communicates via JSON over socket, using a Unix socket on macOS/Linux and TCP on Windows. |
| 17 | +- Dart-side implementation: `lib/core/service.dart` (`CoreService`). |
| 18 | + |
| 19 | +`lib/core/controller.dart` (`CoreController`) selects the implementation based on platform. `lib/core/interface.dart` defines the shared `CoreHandlerInterface`. |
| 20 | + |
| 21 | +Key Go core files: |
| 22 | + |
| 23 | +- `core/hub.go`: handler functions. |
| 24 | +- `core/action.go`: dispatch. |
| 25 | +- `core/lib.go`: CGO exports. |
| 26 | +- `core/server.go`: socket server. |
| 27 | + |
| 28 | +## State Management |
| 29 | + |
| 30 | +Provider files in `lib/providers/`: |
| 31 | + |
| 32 | +- `app.dart`: runtime/UI state, logs, traffic, delays, loading, navigation. |
| 33 | +- `config.dart`: persistent config providers, app settings, theme, VPN, proxy style. |
| 34 | +- `state.dart`: derived/computed providers, navigation, proxy, tray, color scheme. |
| 35 | +- `action.dart`: business logic notifiers, setup, backup, core lifecycle, proxy selection. |
| 36 | +- `database.dart`: Drift database provider wrappers. |
| 37 | + |
| 38 | +`globalState` in `lib/state.dart` is a singleton holding app lifecycle, timers, theme, and start/stop state. Providers are generated into `lib/providers/generated/`. |
| 39 | + |
| 40 | +## Database |
| 41 | + |
| 42 | +The app uses Drift/SQLite in `lib/database/`. Current schema version is 2. |
| 43 | + |
| 44 | +Tables: |
| 45 | + |
| 46 | +- `Profiles` |
| 47 | +- `Scripts` |
| 48 | +- `Rules` |
| 49 | +- `ProfileRuleLinks` (`profile_rule_mapping`) |
| 50 | +- `ProxyGroups` |
| 51 | +- `IconRecords` (`icon_records`) |
| 52 | + |
| 53 | +Rule scenes distinguish global added rules, profile added rules, profile custom rules, and disabled links. Rule and proxy-group ordering use fractional indexing. |
| 54 | + |
| 55 | +Generated Drift output lives in `lib/database/generated/database.g.dart`. After schema changes, run code generation and add or update focused database tests under `test/database/` when converter or migration behavior changes. |
| 56 | + |
| 57 | +## Manager Stack |
| 58 | + |
| 59 | +Managers are nested `InheritedWidget`/`StatefulWidget` components in `lib/application.dart`: |
| 60 | + |
| 61 | +```text |
| 62 | +AppEnvManager > StatusManager > ThemeManager |
| 63 | + > [Desktop: WindowManager > TrayManager > HotKeyManager > ProxyManager] |
| 64 | + > ConnectivityManager > CoreManager > AppStateManager |
| 65 | + > [Mobile: AndroidManager > VpnManager | Desktop: WindowHeaderContainer] |
| 66 | +``` |
| 67 | + |
| 68 | +Each manager in `lib/manager/` handles a specific platform concern. Desktop-only managers are conditionally inserted. |
| 69 | + |
| 70 | +## Core Controller and Actions |
| 71 | + |
| 72 | +`lib/core/controller.dart` (`CoreController`) is a singleton facade over `CoreHandlerInterface`. Public methods delegate to the platform-specific interface, either Android FFI or desktop socket. It has an `@visibleForTesting` constructor and `resetInstance()` for test injection. |
| 73 | + |
| 74 | +Business logic lives in Riverpod notifier classes in `lib/providers/action.dart`: |
| 75 | + |
| 76 | +- `CommonAction`: update check and common UI operations. |
| 77 | +- `SetupAction`: config setup and TUN management. |
| 78 | +- `BackupAction`: backup/restore with WebDAV sync. |
| 79 | +- `CoreAction`: core lifecycle, init, connect, restart, shutdown. |
| 80 | +- `SystemAction`: system integration, tray, exit, brightness. |
| 81 | +- `StoreAction`: profile storage operations. |
| 82 | +- `ThemeAction`: theme state updates. |
| 83 | +- `ProxiesAction`: group management and proxy selection. |
| 84 | +- `ProfilesAction`: profile CRUD, auto-update, import. |
| 85 | + |
| 86 | +## Platform Managers |
| 87 | + |
| 88 | +Desktop: |
| 89 | + |
| 90 | +- `WindowManager` |
| 91 | +- `TrayManager` |
| 92 | +- `HotKeyManager` |
| 93 | +- `ProxyManager` |
| 94 | + |
| 95 | +Mobile: |
| 96 | + |
| 97 | +- `AndroidManager` |
| 98 | +- `TileManager` |
| 99 | +- `VpnManager` |
| 100 | + |
| 101 | +Shared: |
| 102 | + |
| 103 | +- `ConnectivityManager` |
| 104 | +- `CoreManager` |
| 105 | +- `AppStateManager` |
| 106 | +- `StatusManager` |
| 107 | +- `ThemeManager` |
| 108 | + |
| 109 | +## Build System |
| 110 | + |
| 111 | +`setup.dart` is the release build orchestrator: |
| 112 | + |
| 113 | +1. On Windows, pre-builds Go core via `dart run build_tool windows` and reads `core_sha256.json`. |
| 114 | +2. Writes `env.json` (`APP_ENV`). |
| 115 | +3. Passes SHA256 as `--dart-define=CORE_SHA256=$val`, embedded at compile time for Windows. |
| 116 | +4. Activates `flutter_distributor` for packaging. |
| 117 | + |
| 118 | +Go core building is handled by `build_tool`, a standalone Dart CLI in `plugins/setup/buildkit/build_tool/`. |
| 119 | + |
| 120 | +Platform build hooks inside `flutter build` trigger `build_tool` automatically: |
| 121 | + |
| 122 | +- macOS: podspec script phase, `build_pod.sh`, `build_tool macos`. |
| 123 | +- Linux: CMake include, `buildkit/cmake/buildkit.cmake`, `build_tool linux`. |
| 124 | +- Windows: CMake include, `buildkit/cmake/buildkit.cmake`, `build_tool windows`. Debug passes `--dev` via `CMAKE_BUILD_TYPE`. |
| 125 | +- Android: Gradle include, `buildkit/gradle/plugin.gradle`, `build_tool android`. |
| 126 | + |
| 127 | +Windows helper auth: |
| 128 | + |
| 129 | +- Release: Core SHA256 is embedded in both the Flutter app and the Rust helper. The app pings the helper and verifies the token matches. |
| 130 | +- Debug: The Rust helper skips token verification when built in debug mode, so `flutter run` works without the SHA256 flow. |
| 131 | + |
| 132 | +`plugins/setup/` is an FFI plugin that exists only as a build harness. It carries no Dart API, only platform build hooks that trigger Go compilation. Windows builds also compile a Rust helper in `services/helper/` through `RustBuilder`. |
| 133 | + |
| 134 | +Build configuration defaults live in `build_tool/lib/src/options.dart` and can be overridden via `build_config.yaml`. |
| 135 | + |
| 136 | +Architecture detection is automatic. The `--description` flag passed to `flutter_distributor` adds arch suffixes to artifact names, such as `FlClash-0.8.93-macos-arm64.dmg`. |
| 137 | + |
| 138 | +## Local Plugins |
| 139 | + |
| 140 | +- `setup`: build harness FFI plugin. |
| 141 | +- `proxy`: system proxy configuration. |
| 142 | +- `rust_api`: Flutter Rust Bridge FFI plugin. |
| 143 | +- `tray_manager`: system tray fork/customization. |
| 144 | +- `wifi_ssid`: Wi-Fi SSID detection. |
| 145 | +- `window_ext`: window extensions. |
| 146 | +- `flutter_distributor`: app packaging/distribution. |
| 147 | + |
| 148 | +## Rust Helper Service |
| 149 | + |
| 150 | +`services/helper/` is a Windows-only privileged helper for starting the core as admin and managing TUN. It is built with: |
| 151 | + |
| 152 | +```bash |
| 153 | +cargo build --release --features windows-service |
| 154 | +``` |
| 155 | + |
| 156 | +It uses token-based auth with the Flutter app. |
0 commit comments