//go:build windows package main import ( "context" "fmt" "log" "os" "os/signal" "syscall" "time" "git.okcu.io/root/drover-go/internal/engine" ) // runProxy is the body of the `drover proxy` subcommand. It builds an // engine.Engine from the supplied flags, calls Start, and blocks until // the process receives SIGINT (Ctrl+C) or SIGTERM. On signal, it // gracefully Stops the engine and exits. // // All output is mirrored to stderr (visible when launched from a // console session) AND %LOCALAPPDATA%\Drover\debug.log. setupDebugLog // in main.go has already wired the log package to write to both. func runProxy(parent context.Context, host string, port int, auth bool, login, password string) error { if host == "" || port == 0 { return fmt.Errorf("--host and --port are required") } ctx, cancel := signal.NotifyContext(parent, os.Interrupt, syscall.SIGTERM) defer cancel() cfg := engine.Config{ ProxyAddr: fmt.Sprintf("%s:%d", host, port), UseAuth: auth, Login: login, Password: password, Targets: []string{"Discord.exe", "DiscordCanary.exe", "DiscordPTB.exe", "Update.exe"}, } log.Printf("proxy: building engine (proxy=%s auth=%v targets=%v)", cfg.ProxyAddr, cfg.UseAuth, cfg.Targets) e, err := engine.New(cfg) if err != nil { return fmt.Errorf("engine.New: %w", err) } startCtx, startCancel := context.WithTimeout(ctx, 15*time.Second) defer startCancel() if err := e.Start(startCtx); err != nil { log.Printf("proxy: Start failed: %v", err) return fmt.Errorf("engine.Start: %w", err) } log.Printf("proxy: engine status=%s — press Ctrl+C to stop", e.Status()) // Periodic status ping so the user sees the engine is alive. statusTk := time.NewTicker(10 * time.Second) defer statusTk.Stop() for { select { case <-ctx.Done(): log.Printf("proxy: signal received, shutting down") if err := e.Stop(); err != nil { log.Printf("proxy: Stop returned: %v", err) } log.Printf("proxy: bye") return nil case <-statusTk.C: if le := e.LastError(); le != nil { log.Printf("proxy: heartbeat status=%s lastErr=%v", e.Status(), le) } else { log.Printf("proxy: heartbeat status=%s", e.Status()) } if e.Status() == engine.StatusFailed { log.Printf("proxy: engine entered Failed state, exiting") _ = e.Stop() return fmt.Errorf("engine failed: %v", e.LastError()) } } } }