ProcessCommand chose the MSG record size by testing "ulLength % 28 == 0"
before "% 48 == 0". The two sizes' least common multiple is 336 (7*48 =
12*28), so a 48-byte batch whose record count is a multiple of 7 was
misclassified as 28-byte MSG32 records, shifting every field and garbling
(or silently dropping) injected input.
Check "% 48 == 0" first. The modern controller always emits 48-byte MSG64;
the 28-byte MSG32 path is legacy 32-bit-controller compatibility and is only
reached when 48 does not divide evenly. This is the first feature (MCP
remote_keyboard "type", and the upcoming remote_mouse drag) to emit
multi-record batches, which is what made the latent bug reachable.
Co-Authored-By: deepseek-v4-pro
Replacing the old connection on a duplicate login made the client
reconnect in a tight loop. Instead, park the new connection in a standby
list keyed by clientID and promote it into the main host list only after
the old connection is removed by heartbeat timeout or disconnect.
Fix heartbeat attribution so a parked standby refreshes its own
last-heartbeat time rather than the main connection's, otherwise the main
never times out and the standby can never take over. Gate the offline
notification on an actual removal with no promoted standby to avoid a
spurious "host offline" when takeover happens. Skip promoting a standby
already marked removed, and reuse the normal login sign/settings path when
a standby is promoted.
Co-Authored-By: deepseek-v4-pro
Two changes to reduce unnecessary CScreenSpy restarts when connecting:
1. Client (ScreenManager.cpp): Initialize CScreenSpy with bitrate from
the locally-saved quality profile, so CMD_QUALITY_LEVEL arriving from
the server (same bitrate as default) hits SetBitRate(3000)==3000 and
skips the restart instead of comparing against the hard-coded 0.
Also fixes QualityLevel init to use the already-computed `quality`
variable (which honours the QUALITY_DISABLED override when algo!=NUL)
rather than re-reading the cfg key a second time.
2. Server (ScreenSpyDlg.cpp): Only send CMD_SCREEN_SIZE strategy=2 when
the session is in QUALITY_ADAPTIVE mode and a cached maxWidth exists.
Fixed quality levels already carry resolution via CMD_QUALITY_PROFILES,
so unconditionally sending CMD_SCREEN_SIZE caused a second restart when
the screen spy was still rebuilding from the first one.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Server: clamp web session adaptive quality to H264-only levels (>=Good) in EvaluateQuality and ApplyQualityLevel; Ultra/High (DIFF/RGB565) caused the browser to freeze ~1 min into a session
- Server: move session-type detection to the top of ScreenSpyDlg::OnInitDialog and skip SetWindowPlacement/EnterFullScreen for hidden web sessions, eliminating the MFC dialog flash on web-triggered opens
- Linux client: default QualityLevel from QUALITY_ADAPTIVE to QUALITY_GOOD to match Windows/macOS so the server's adaptive controller doesn't auto-upgrade to non-H264 algorithms
- Web: clear the floating quick-action toolbar on fullscreen exit so its row of buttons (RDP reset / Mouse / Close) doesn't stay pinned to the top of the page
- Web: route F11 to the remote in control mode instead of toggling local fullscreen
- Web: route Esc to the remote in control mode via the Keyboard Lock API instead of exiting native fullscreen