internal/gui: wire StartEngine/StopEngine to internal/engine
Build / test (push) Failing after 30s
Build / build-windows (push) Has been skipped

Replaces the stub flag-toggle with a real engine.Engine. GetStatus
now reports the engine's actual state machine value. Stats remain
randomised in P2.1 — real bytes-counters land in P2.4 with the tray
UI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-01 20:05:51 +03:00
parent bbe88b0f70
commit 8ceb7775d7
+46 -16
View File
@@ -11,6 +11,7 @@ import (
"time" "time"
"git.okcu.io/root/drover-go/internal/checker" "git.okcu.io/root/drover-go/internal/checker"
"git.okcu.io/root/drover-go/internal/engine"
"github.com/wailsapp/wails/v2/pkg/runtime" "github.com/wailsapp/wails/v2/pkg/runtime"
) )
@@ -26,7 +27,7 @@ type App struct {
version string version string
mu sync.Mutex mu sync.Mutex
running bool eng *engine.Engine
startedAt time.Time startedAt time.Time
// muCheck guards cancelCheck and checkDone. // muCheck guards cancelCheck and checkDone.
@@ -172,46 +173,75 @@ func (a *App) CancelCheck() {
} }
} }
// StartEngine flips the proxy on. In the stub we just toggle the flag and // StartEngine initializes and brings up the engine with the given config.
// note the start time so GetStats can produce a believable uptime. func (a *App) StartEngine(cfg Config) error {
func (a *App) StartEngine() error {
a.mu.Lock() a.mu.Lock()
defer a.mu.Unlock() defer a.mu.Unlock()
a.running = true if a.eng != nil && a.eng.Status() == engine.StatusActive {
return nil
}
e, err := engine.New(engine.Config{
ProxyAddr: fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),
UseAuth: cfg.Auth,
Login: cfg.Login,
Password: cfg.Password,
Targets: []string{"Discord.exe", "DiscordCanary.exe", "DiscordPTB.exe", "Update.exe"},
})
if err != nil {
runtime.EventsEmit(a.ctx, "engine:status", map[string]any{"running": false, "error": err.Error()})
return err
}
if err := e.Start(a.ctx); err != nil {
runtime.EventsEmit(a.ctx, "engine:status", map[string]any{"running": false, "error": err.Error()})
return err
}
a.eng = e
a.startedAt = time.Now() a.startedAt = time.Now()
runtime.EventsEmit(a.ctx, "engine:status", map[string]any{"running": true}) runtime.EventsEmit(a.ctx, "engine:status", map[string]any{"running": true})
return nil return nil
} }
// StopEngine turns the proxy off. // StopEngine shuts down the engine.
func (a *App) StopEngine() error { func (a *App) StopEngine() error {
a.mu.Lock() a.mu.Lock()
defer a.mu.Unlock() defer a.mu.Unlock()
a.running = false if a.eng == nil {
return nil
}
err := a.eng.Stop()
a.eng = nil
runtime.EventsEmit(a.ctx, "engine:status", map[string]any{"running": false}) runtime.EventsEmit(a.ctx, "engine:status", map[string]any{"running": false})
return nil return err
} }
// GetStatus is read by the frontend on first paint to know whether to // GetStatus returns the current engine state and uptime.
// show "Idle" or "Active".
func (a *App) GetStatus() map[string]any { func (a *App) GetStatus() map[string]any {
a.mu.Lock() a.mu.Lock()
defer a.mu.Unlock() defer a.mu.Unlock()
return map[string]any{ running := a.eng != nil && a.eng.Status() == engine.StatusActive
"running": a.running, res := map[string]any{
"running": running,
"uptimeS": int(time.Since(a.startedAt).Seconds()), "uptimeS": int(time.Since(a.startedAt).Seconds()),
} }
if a.eng != nil {
res["state"] = string(a.eng.Status())
if err := a.eng.LastError(); err != nil {
res["error"] = err.Error()
}
}
return res
} }
// statsLoop emits a stats event every second when the engine is running. // statsLoop emits a stats event every second when the engine is active.
// Numbers are random but stable enough to look real. // Numbers are random but stable enough to look real. P2.4 will replace
// with real counters from engine.Engine.
func (a *App) statsLoop() { func (a *App) statsLoop() {
r := rand.New(rand.NewSource(time.Now().UnixNano())) r := rand.New(rand.NewSource(time.Now().UnixNano()))
tick := time.NewTicker(time.Second) tick := time.NewTicker(time.Second)
defer tick.Stop() defer tick.Stop()
for range tick.C { for range tick.C {
a.mu.Lock() a.mu.Lock()
if !a.running || a.ctx == nil { if a.eng == nil || a.eng.Status() != engine.StatusActive || a.ctx == nil {
a.mu.Unlock() a.mu.Unlock()
continue continue
} }
@@ -222,7 +252,7 @@ func (a *App) statsLoop() {
"up": r.Intn(50_000) + 5_000, // bytes/sec out "up": r.Intn(50_000) + 5_000, // bytes/sec out
"down": r.Intn(500_000) + 50_000, // bytes/sec in "down": r.Intn(500_000) + 50_000, // bytes/sec in
"tcp": r.Intn(8) + 1, "tcp": r.Intn(8) + 1,
"udp": r.Intn(5) + 1, "udp": 0, // P2.1 scope: no UDP yet
"uptimeS": uptime, "uptimeS": uptime,
}) })
} }