Compare commits

..

No commits in common. "9db0f9f9237c9979df2d2e322526ebe042f6c6a9" and "07cae8959ad9325b8de740ae8719182f93a3e4a5" have entirely different histories.

2 changed files with 90 additions and 71 deletions

84
cli/entry.go Normal file
View file

@ -0,0 +1,84 @@
package cli
import (
"bufio"
"fmt"
"io"
"log"
"os"
"strings"
"github.com/hamburghammer/rcon"
)
// Start a interactive connection. Uses the given reader and writer to inteact with the created connection.
func Start(hostPort string, password string, in io.Reader, out io.Writer) {
remoteConsole, err := rcon.Dial(hostPort, password)
if err != nil {
log.Fatal("Failed to connect to RCON server", err)
}
defer remoteConsole.Close()
scanner := bufio.NewScanner(in)
out.Write([]byte("To quit the session type 'exit'.\n"))
out.Write([]byte("> "))
for scanner.Scan() {
cmd := scanner.Text()
if cmd == "exit" {
return
}
reqID, err := remoteConsole.Write(cmd)
if err != nil {
fmt.Fprintln(os.Stderr, "Failed to send command:", err.Error())
continue
}
resp, respID, err := remoteConsole.Read()
if err != nil {
if err == io.EOF {
return
}
fmt.Fprintln(os.Stderr, "Failed to read command:", err.Error())
continue
}
if reqID != respID {
fmt.Fprintln(out, "Weird. This response is for another request.")
}
fmt.Fprintln(out, resp)
out.Write([]byte("> "))
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading standard input:", err)
}
}
// Execute runs the given command against the remote console and writes the response into the writer.
func Execute(hostPort string, password string, out io.Writer, command ...string) {
remoteConsole, err := rcon.Dial(hostPort, password)
if err != nil {
log.Fatal("Failed to connect to RCON server", err)
}
defer remoteConsole.Close()
preparedCmd := strings.Join(command, " ")
reqID, err := remoteConsole.Write(preparedCmd)
resp, respID, err := remoteConsole.Read()
if err != nil {
if err == io.EOF {
return
}
fmt.Fprintln(os.Stderr, "Failed to read command:", err.Error())
return
}
if reqID != respID {
fmt.Fprintln(out, "Weird. This response is for another request.")
}
fmt.Fprintln(out, resp)
}

77
main.go
View file

@ -1,15 +1,11 @@
package main package main
import ( import (
"bufio"
"errors"
"fmt" "fmt"
"io"
"net" "net"
"os" "os"
"strings"
"github.com/hamburghammer/rcon" "github.com/itzg/rcon-cli/cli"
flags "github.com/spf13/pflag" flags "github.com/spf13/pflag"
) )
@ -38,11 +34,7 @@ func main() {
return return
} }
err := run(strings.Join(commands, " ")) run(commands...)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
} }
func parseArgs(args []string) ([]string, error) { func parseArgs(args []string) ([]string, error) {
@ -78,25 +70,14 @@ func loadEnvIfNotSet() {
} }
} }
func run(cmd string) error { func run(args ...string) {
hostPort := net.JoinHostPort(host, port) hostPort := net.JoinHostPort(host, port)
remoteConsole, err := rcon.Dial(hostPort, password)
if err != nil {
return fmt.Errorf("failed to connect to RCON server: %w", err)
}
defer remoteConsole.Close()
if len(cmd) == 0 { if len(args) == 0 {
err = executeInteractive(remoteConsole) cli.Start(hostPort, password, os.Stdin, os.Stdout)
} else { } else {
resp, err := execute(cmd, remoteConsole) cli.Execute(hostPort, password, os.Stdout, args...)
if err != nil {
return err
}
fmt.Println(resp)
} }
return err
} }
func printHelp() { func printHelp() {
@ -119,49 +100,3 @@ EXAMPLES:
%sPORT=25575 rcon-cli stop %sPORT=25575 rcon-cli stop
`, envVarPrefix, envVarPrefix) `, envVarPrefix, envVarPrefix)
} }
func executeInteractive(remoteConsole *rcon.RemoteConsole) error {
scanner := bufio.NewScanner(os.Stdin)
fmt.Println("To quit the session type 'exit'.")
for scanner.Scan() {
fmt.Print("> ")
cmd := scanner.Text()
if cmd == "exit" {
return nil
}
resp, err := execute(cmd, remoteConsole)
if err != nil {
return err
}
fmt.Println(resp)
}
if err := scanner.Err(); err != nil {
return fmt.Errorf("reading standard input: %w", err)
}
return nil
}
func execute(cmd string, remoteConsole *rcon.RemoteConsole) (string, error) {
resp := ""
reqID, err := remoteConsole.Write(cmd)
if err != nil {
return resp, fmt.Errorf("failed to send command: %w", err)
}
resp, respID, err := remoteConsole.Read()
if err != nil {
if err == io.EOF {
return resp, nil
}
return resp, fmt.Errorf("failed to read command: %w", err)
}
if reqID != respID {
return resp, errors.New("the response id didn't match the request id")
}
return resp, nil
}