feat: Add WebSocket RCON client to companion agent
All checks were successful
Test Asgard Runner / test (push) Successful in 3s
All checks were successful
Test Asgard Runner / test (push) Successful in 3s
Wire gorilla/websocket into the Go companion agent to send arbitrary console commands (e.g. oxide.reload BetterLoot) to the Rust Dedicated Server's WebRCON endpoint. Adds RCON_PORT and RCON_PASSWORD env vars, a new "command" action on the existing cmd.server NATS subject, and the internal/rcon package that handles the JSON-over-WebSocket protocol. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/vigilcyber/corrosion-companion/internal/filemanager"
|
||||
"github.com/vigilcyber/corrosion-companion/internal/files"
|
||||
"github.com/vigilcyber/corrosion-companion/internal/process"
|
||||
"github.com/vigilcyber/corrosion-companion/internal/rcon"
|
||||
"github.com/vigilcyber/corrosion-companion/internal/update"
|
||||
)
|
||||
|
||||
@@ -25,6 +26,8 @@ type DaemonConfig struct {
|
||||
GameServerArgs string
|
||||
Version string
|
||||
InstallDir string
|
||||
RconPort int
|
||||
RconPassword string
|
||||
}
|
||||
|
||||
// Daemon manages the companion agent's main operations
|
||||
@@ -155,7 +158,8 @@ func (d *Daemon) subscribeServerCommands() error {
|
||||
|
||||
sub, err := d.nc.Subscribe(subject, func(msg *nats.Msg) {
|
||||
var cmd struct {
|
||||
Action string `json:"action"`
|
||||
Action string `json:"action"`
|
||||
Command string `json:"command"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(msg.Data, &cmd); err != nil {
|
||||
@@ -174,6 +178,24 @@ func (d *Daemon) subscribeServerCommands() error {
|
||||
err = d.gameServer.Stop()
|
||||
case "restart":
|
||||
err = d.gameServer.Restart()
|
||||
case "command":
|
||||
if cmd.Command == "" {
|
||||
d.respondError(msg, "invalid_command", "command field is required")
|
||||
return
|
||||
}
|
||||
result, rconErr := rcon.SendCommand(d.cfg.RconPort, d.cfg.RconPassword, cmd.Command)
|
||||
if rconErr != nil {
|
||||
log.Printf("RCON command failed: %v", rconErr)
|
||||
d.respondError(msg, "rcon_failed", rconErr.Error())
|
||||
} else {
|
||||
d.respondSuccess(msg, map[string]interface{}{
|
||||
"action": "command",
|
||||
"command": cmd.Command,
|
||||
"response": result,
|
||||
"status": "success",
|
||||
})
|
||||
}
|
||||
return
|
||||
default:
|
||||
err = fmt.Errorf("unknown action: %s", cmd.Action)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user