Previous commit (6d587a8) used DEFAULT_SETTINGS, which is the lowest
priority — user config (RustDesk2.toml) wins. The user complained that
'Enable keyboard/mouse' and 'Enable clipboard' were 'default on', which
turned out to be old config values from a previous build session.
OVERWRITE_SETTINGS is the highest priority — user cannot override it from
the UI. This is the right mechanism for security/billing policy:
- enable-keyboard, enable-clipboard: user said 'default on is wrong'
- enable-file-transfer: server bandwidth killer (1 GB upload = 2 GB)
- enable-tunnel: server-as-jump-host risk
- enable-record-session, enable-camera, enable-audio: rare-use, default-off
The 2 NAT-punch force-on options (enable-udp-punch, enable-ipv6-punch)
are unchanged — they live in OVERWRITE_LOCAL_SETTINGS, which is also
highest priority but for local-only options (UDP punch is per-machine).
Custom fork feature: surface NAT-punch result to the user so they know
whether the connection is going through their 21117 server (relay) or
directly between the two machines (P2P).
Three changes:
1. flutter/lib/common/shared_state.dart: add ConnectionType.isP2P getter
(true = direct, false = relay) and a top-level isDirectConnection(peerId)
helper that returns true when state is unknown (so UI doesn't briefly
grey out before the connection establishes).
2. flutter/lib/desktop/widgets/punch_status_banner.dart (new): a small
Positioned banner at the top of the connection page.
- P2P success: green ⚡ banner: 'P2P 直连成功 — 走的是两台机器之间的网络,可放心传文件'
- Relay fallback: orange ⚠ banner: '中继模式 — 视频/控制走服务器 21117 中转,请勿传大文件'
The banner is reactive (Obx on ConnectionType.direct Rx<String>).
3. flutter/lib/common/widgets/toolbar.dart: wrap the 'Transfer file' and
'TCP tunneling' menu items' onPressed with an isDirectConnection() guard.
On relay mode, the menu still shows but the click is intercepted with a
toast explaining why the action is blocked.
4. flutter/lib/desktop/pages/remote_page.dart: add the banner via
Positioned(top: 0, left: 0, right: 0) at the end of bodyWidget's Stack.
Why this matters: user has 4 users on 5 Mbps server (114.55.133.123).
When NAT punch fails and the session goes through relay, file transfers
would saturate the server bandwidth. Showing the relay state + blocking
the file-transfer menu protects the server without requiring the user
to remember the technical detail.
For 4 users on 5 Mbps server (114.55.133.123) where file transfers were saturating bandwidth:
Turn OFF by default (users can still flip on per-session):
- enable-file-transfer: THE KILLER (1 GB upload = 2 GB server bandwidth)
- enable-clipboard: 50 kbps + privacy
- enable-keyboard: only needed for typing-on-remote
- enable-tunnel: prevents using server as jump host
- enable-record-session: only when explicitly recording
- enable-camera: 500 kbps; rarely used for support
- enable-audio: (already in c94a72a)
Force ON (overrides RustDesk's conservative default for self-hosted servers):
- enable-udp-punch, enable-ipv6-punch: src/common.rs:1107 turns these off
when rendezvous server is non-public. That's a safety measure meant for
untrusted public servers, but our self-hosted server is fully trusted.
Force-enabling boosts P2P success rate → less relay (21117) traffic →
less server bandwidth.
RustDesk's read_custom_client() at src/common.rs:2191 expects base64-decoded
ed25519-signed content, not plain JSON. Our custom.txt (plain JSON) fails the
decode64 check and returns early, so DEFAULT_SETTINGS stays empty.
Fix: inject 'enable-audio' = 'N' directly into DEFAULT_SETTINGS at the end of
load_custom_client(), outside the read_custom_client() call. entry().or_insert()
preserves the priority chain (OVERWRITE_SETTINGS → CONFIG2 → DEFAULT_SETTINGS),
so the user can still flip the option on in Settings.
Verified with debug eprintln that DEFAULT_SETTINGS.get("enable-audio") returns
Some("N") at startup. UI now shows 'Enable audio' unchecked in Settings →
Permissions.
- Added flutter/macos/Runner/custom.txt with default-settings.enable-audio=N
- Added custom.txt to Xcode Copy Bundle Resources (PBXResourcesBuildPhase)
- RustDesk's load_custom_client() reads this file and injects into DEFAULT_SETTINGS
- Users can still toggle 'Enable audio' in Settings; this just flips the default
This addresses the user's request to disable all 4 audio behaviors by default
(play remote sound, hear remote mic, voice call, capture host audio), all of
which share the single 'enable-audio' option.
- BUILD.md: complete build instructions for macOS desktop (Xcode 26.5,
Flutter 3.44, Dart 3.12, VCPKG, all patches explained)
- res/post-build-mac.sh: re-sign + install to /Applications + create dmg,
run after every 'flutter build macos --release'
Key issues documented in BUILD.md:
* Re-signing is mandatory (codesign --force --deep -s -)
* Use hdiutil for dmg, not create-dmg (macos-alias is x86_64 broken)
* libclang must be arm64 (use Xcode CLT, not homebrew llvm)
* EXCLUDED_ARCHS=x86_64 for arm64-only Rust dylib