diff --git a/cmd/q3rcon/main.go b/cmd/q3rcon/main.go index c9c765c..8058e31 100644 --- a/cmd/q3rcon/main.go +++ b/cmd/q3rcon/main.go @@ -2,7 +2,6 @@ package main import ( "bufio" - "errors" "flag" "fmt" "io" @@ -15,28 +14,26 @@ import ( log "github.com/sirupsen/logrus" ) -var interactive bool - -func exit(err error) { +func exitOnError(err error) { _, _ = fmt.Fprintf(os.Stderr, "Error: %s\n", err) - flag.Usage() os.Exit(1) } func main() { var ( - host string - port int - rconpass string - loglevel int + host string + port int + rconpass string + interactive bool + loglevel int ) - flag.StringVar(&host, "host", "localhost", "hostname of the server") - flag.StringVar(&host, "h", "localhost", "hostname of the server (shorthand)") - flag.IntVar(&port, "port", 28960, "port of the server") - flag.IntVar(&port, "p", 28960, "port of the server (shorthand)") - flag.StringVar(&rconpass, "rconpass", "", "rcon password") - flag.StringVar(&rconpass, "r", "", "rcon password (shorthand)") + flag.StringVar(&host, "host", "localhost", "hostname of the gameserver") + flag.StringVar(&host, "h", "localhost", "hostname of the gameserver (shorthand)") + flag.IntVar(&port, "port", 28960, "port on which the gameserver resides, default is 28960") + flag.IntVar(&port, "p", 28960, "port on which the gameserver resides, default is 28960 (shorthand)") + flag.StringVar(&rconpass, "rconpass", os.Getenv("RCON_PASS"), "rcon password of the gameserver") + flag.StringVar(&rconpass, "r", os.Getenv("RCON_PASS"), "rcon password of the gameserver (shorthand)") flag.BoolVar(&interactive, "interactive", false, "run in interactive mode") flag.BoolVar(&interactive, "i", false, "run in interactive mode") @@ -49,33 +46,29 @@ func main() { log.SetLevel(log.Level(loglevel)) } + if port < 1024 || port > 65535 { + exitOnError(fmt.Errorf("invalid port value, got: (%d) expected: in range 1024-65535", port)) + } + + if len(rconpass) < 8 { + exitOnError(fmt.Errorf("invalid rcon password, got: (%s) expected: at least 8 characters", rconpass)) + } + rcon, err := connectRcon(host, port, rconpass) if err != nil { - log.Fatal(err) + exitOnError(err) } defer rcon.Close() - if interactive { - fmt.Printf("Enter 'Q' to exit.\n>> ") - err := interactiveMode(rcon, os.Stdin) - if err != nil { - log.Fatal(err) - } + if !interactive { + runCommands(flag.Args(), rcon) return } - if len(flag.Args()) == 0 { - err = errors.New("no rcon commands passed") - exit(err) - } - - for _, arg := range flag.Args() { - resp, err := rcon.Send(arg) - if err != nil { - log.Error(err) - continue - } - fmt.Print(resp) + fmt.Printf("Enter 'Q' to exit.\n>> ") + err = interactiveMode(rcon, os.Stdin) + if err != nil { + exitOnError(err) } } @@ -87,6 +80,23 @@ func connectRcon(host string, port int, password string) (*q3rcon.Rcon, error) { return rcon, nil } +// runCommands runs the commands given in the flag.Args slice. +// If no commands are given, it defaults to running the "status" command. +func runCommands(commands []string, rcon *q3rcon.Rcon) { + if len(commands) == 0 { + commands = append(commands, "status") + } + + for _, cmd := range commands { + resp, err := rcon.Send(cmd) + if err != nil { + log.Error(err) + continue + } + fmt.Print(resp) + } +} + // interactiveMode continuously reads from input until a quit signal is given. func interactiveMode(rcon *q3rcon.Rcon, input io.Reader) error { scanner := bufio.NewScanner(input) @@ -103,6 +113,7 @@ func interactiveMode(rcon *q3rcon.Rcon, input io.Reader) error { } fmt.Printf("%s>> ", resp) } + if scanner.Err() != nil { return scanner.Err() } diff --git a/go.mod b/go.mod index 4173232..26185a9 100644 --- a/go.mod +++ b/go.mod @@ -2,13 +2,6 @@ module github.com/onyx-and-iris/q3rcon go 1.23.0 -require ( - github.com/fatih/color v1.18.0 - github.com/sirupsen/logrus v1.9.3 -) +require github.com/sirupsen/logrus v1.9.3 -require ( - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - golang.org/x/sys v0.25.0 // indirect -) +require golang.org/x/sys v0.25.0 // indirect diff --git a/go.sum b/go.sum index 3b57f37..68f5093 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -16,8 +9,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=