Add VPN configuration tools and agent documentation
Created comprehensive VPN setup tooling for Peaceful Spirit L2TP/IPsec connection and enhanced agent documentation framework. VPN Configuration (PST-NW-VPN): - Setup-PST-L2TP-VPN.ps1: Automated L2TP/IPsec setup with split-tunnel and DNS - Connect-PST-VPN.ps1: Connection helper with PPP adapter detection, DNS (192.168.0.2), and route config (192.168.0.0/24) - Connect-PST-VPN-Standalone.ps1: Self-contained connection script for remote deployment - Fix-PST-VPN-Auth.ps1: Authentication troubleshooting for CHAP/MSChapv2 - Diagnose-VPN-Interface.ps1: Comprehensive VPN interface and routing diagnostic - Quick-Test-VPN.ps1: Fast connectivity verification (DNS/router/routes) - Add-PST-VPN-Route-Manual.ps1: Manual route configuration helper - vpn-connect.bat, vpn-disconnect.bat: Simple batch file shortcuts - OpenVPN config files (Windows-compatible, abandoned for L2TP) Key VPN Implementation Details: - L2TP creates PPP adapter with connection name as interface description - UniFi auto-configures DNS (192.168.0.2) but requires manual route to 192.168.0.0/24 - Split-tunnel enabled (only remote traffic through VPN) - All-user connection for pre-login auto-connect via scheduled task - Authentication: CHAP + MSChapv2 for UniFi compatibility Agent Documentation: - AGENT_QUICK_REFERENCE.md: Quick reference for all specialized agents - documentation-squire.md: Documentation and task management specialist agent - Updated all agent markdown files with standardized formatting Project Organization: - Moved conversation logs to dedicated directories (guru-connect-conversation-logs, guru-rmm-conversation-logs) - Cleaned up old session JSONL files from projects/msp-tools/ - Added guru-connect infrastructure (agent, dashboard, proto, scripts, .gitea workflows) - Added guru-rmm server components and deployment configs Technical Notes: - VPN IP pool: 192.168.4.x (client gets 192.168.4.6) - Remote network: 192.168.0.0/24 (router at 192.168.0.10) - PSK: rrClvnmUeXEFo90Ol+z7tfsAZHeSK6w7 - Credentials: pst-admin / 24Hearts$ Files: 15 VPN scripts, 2 agent docs, conversation log reorganization, guru-connect/guru-rmm infrastructure additions Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
102
projects/msp-tools/guru-connect/agent/src/capture/mod.rs
Normal file
102
projects/msp-tools/guru-connect/agent/src/capture/mod.rs
Normal file
@@ -0,0 +1,102 @@
|
||||
//! Screen capture module
|
||||
//!
|
||||
//! Provides DXGI Desktop Duplication for high-performance screen capture on Windows 8+,
|
||||
//! with GDI fallback for legacy systems or edge cases.
|
||||
|
||||
#[cfg(windows)]
|
||||
mod dxgi;
|
||||
#[cfg(windows)]
|
||||
mod gdi;
|
||||
mod display;
|
||||
|
||||
pub use display::{Display, DisplayInfo};
|
||||
|
||||
use anyhow::Result;
|
||||
use std::time::Instant;
|
||||
|
||||
/// Captured frame data
|
||||
#[derive(Debug)]
|
||||
pub struct CapturedFrame {
|
||||
/// Frame width in pixels
|
||||
pub width: u32,
|
||||
|
||||
/// Frame height in pixels
|
||||
pub height: u32,
|
||||
|
||||
/// Raw BGRA pixel data (4 bytes per pixel)
|
||||
pub data: Vec<u8>,
|
||||
|
||||
/// Timestamp when frame was captured
|
||||
pub timestamp: Instant,
|
||||
|
||||
/// Display ID this frame is from
|
||||
pub display_id: u32,
|
||||
|
||||
/// Regions that changed since last frame (if available)
|
||||
pub dirty_rects: Option<Vec<DirtyRect>>,
|
||||
}
|
||||
|
||||
/// Rectangular region that changed
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DirtyRect {
|
||||
pub x: u32,
|
||||
pub y: u32,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
/// Screen capturer trait
|
||||
pub trait Capturer: Send {
|
||||
/// Capture the next frame
|
||||
///
|
||||
/// Returns None if no new frame is available (screen unchanged)
|
||||
fn capture(&mut self) -> Result<Option<CapturedFrame>>;
|
||||
|
||||
/// Get the current display info
|
||||
fn display(&self) -> &Display;
|
||||
|
||||
/// Check if capturer is still valid (display may have changed)
|
||||
fn is_valid(&self) -> bool;
|
||||
}
|
||||
|
||||
/// Create a capturer for the specified display
|
||||
#[cfg(windows)]
|
||||
pub fn create_capturer(display: Display, use_dxgi: bool, gdi_fallback: bool) -> Result<Box<dyn Capturer>> {
|
||||
if use_dxgi {
|
||||
match dxgi::DxgiCapturer::new(display.clone()) {
|
||||
Ok(capturer) => {
|
||||
tracing::info!("Using DXGI Desktop Duplication for capture");
|
||||
return Ok(Box::new(capturer));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!("DXGI capture failed: {}, trying fallback", e);
|
||||
if !gdi_fallback {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GDI fallback
|
||||
tracing::info!("Using GDI for capture");
|
||||
Ok(Box::new(gdi::GdiCapturer::new(display)?))
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn create_capturer(_display: Display, _use_dxgi: bool, _gdi_fallback: bool) -> Result<Box<dyn Capturer>> {
|
||||
anyhow::bail!("Screen capture only supported on Windows")
|
||||
}
|
||||
|
||||
/// Get all available displays
|
||||
pub fn enumerate_displays() -> Result<Vec<Display>> {
|
||||
display::enumerate_displays()
|
||||
}
|
||||
|
||||
/// Get the primary display
|
||||
pub fn primary_display() -> Result<Display> {
|
||||
let displays = enumerate_displays()?;
|
||||
displays
|
||||
.into_iter()
|
||||
.find(|d| d.is_primary)
|
||||
.ok_or_else(|| anyhow::anyhow!("No primary display found"))
|
||||
}
|
||||
Reference in New Issue
Block a user