5 Commits

Author SHA1 Message Date
a7702c8050 add functional option WithLoginTimeout
use it to set the login timeout
2024-11-04 16:13:31 +00:00
08af9d3388 fix -p flag usage message 2024-11-04 15:30:03 +00:00
46d3e3fa4a left align example snippets 2024-11-04 15:10:12 +00:00
07ffd98e7a remove Logging highlight 2024-11-04 15:05:57 +00:00
bc373e72ae add your own implementation section 2024-11-04 15:05:13 +00:00
3 changed files with 40 additions and 17 deletions

View File

@@ -52,6 +52,16 @@ func main() {
}
```
#### `WithLoginTimeout(timeout time.Duration)`
If the server was just started or is currently performing a long operation like map rotating then it's possible to receive empty rcon responses. In which case you'll want to retry login. Use this functional option to set the max timeout for logins, it defaults to 5 seconds. For example:
```go
rcon, err := q3rcon.New(
host, port, password,
q3rcon.WithLoginTimeout(2*time.Second))
```
#### `WithDefaultTimeout(timeout time.Duration)`
You may want to change the default timeout if some of your responses are getting mixed together (stability can depend on connection to the server). For example, on LAN I can leave the default at 20ms, when connecting remotely I normally increase this to 50ms.
@@ -59,9 +69,9 @@ You may want to change the default timeout if some of your responses are getting
For example:
```go
rcon, err := q3rcon.New(
host, port, password,
q3rcon.WithDefaultTimeout(50*time.Millisecond))
rcon, err := q3rcon.New(
host, port, password,
q3rcon.WithDefaultTimeout(50*time.Millisecond))
```
#### `WithTimeouts(timeouts map[string]time.Duration)`
@@ -69,14 +79,14 @@ For example:
Perhaps there are some requests that take a long time to receive a response but you want the whole response in one chunk. Pass a timeouts map, for example:
```go
timeouts := map[string]time.Duration{
"map_rotate": 1200 * time.Millisecond,
"map_restart": 1200 * time.Millisecond,
}
timeouts := map[string]time.Duration{
"map_rotate": 1200 * time.Millisecond,
"map_restart": 1200 * time.Millisecond,
}
rcon, err := q3rcon.New(
host, port, password,
q3rcon.WithTimeouts(timeouts))
rcon, err := q3rcon.New(
host, port, password,
q3rcon.WithTimeouts(timeouts))
```
## Command line
@@ -103,7 +113,11 @@ q3rcon -h=localhost -p=30000 -P="rconpassword" -i
If interactive mode is enabled, any arguments sent on the command line will be ignored.
## `Logging`
## Your own implementation
I've separated the q3rcon package from the CLI precisely so that you can write your own implementation, since I don't know the target game or it's commands. For example, in my case I've added terminal colouring and reformatted some of the command responses.
## Logging
Log level may be set by passing the `-l` flag with a number from 0 up to 6 where

View File

@@ -28,8 +28,8 @@ func main() {
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(&password, "password", "", "hostname of the server")
flag.StringVar(&password, "P", "", "hostname of the server (shorthand)")
flag.StringVar(&password, "password", "", "rcon password")
flag.StringVar(&password, "P", "", "rcon password (shorthand)")
flag.BoolVar(&interactive, "interactive", false, "run in interactive mode")
flag.BoolVar(&interactive, "i", false, "run in interactive mode")

View File

@@ -12,13 +12,21 @@ import (
// Option is a functional option type that allows us to configure the VbanTxt.
type Option func(*Rcon)
// WithLoginTimeout is a functional option to set the login timeout
func WithLoginTimeout(timeout time.Duration) Option {
return func(rcon *Rcon) {
rcon.loginTimeout = timeout
}
}
// WithDefaultTimeout is a functional option to set the default response timeout
func WithDefaultTimeout(timeout time.Duration) Option {
return func(rcon *Rcon) {
rcon.defaultTimeout = timeout
}
}
// WithTimeouts is a functional option to set the timeouts for responses
// WithTimeouts is a functional option to set the timeouts for responses per command
func WithTimeouts(timeouts map[string]time.Duration) Option {
return func(rcon *Rcon) {
rcon.timeouts = timeouts
@@ -30,6 +38,7 @@ type Rcon struct {
request packet.Request
response packet.Response
loginTimeout time.Duration
defaultTimeout time.Duration
timeouts map[string]time.Duration
@@ -50,6 +59,7 @@ func New(host string, port int, password string, options ...Option) (*Rcon, erro
conn: conn,
request: packet.NewRequest(password),
resp: make(chan string),
loginTimeout: 5 * time.Second,
defaultTimeout: 20 * time.Millisecond,
timeouts: make(map[string]time.Duration),
}
@@ -58,8 +68,7 @@ func New(host string, port int, password string, options ...Option) (*Rcon, erro
o(r)
}
err = r.Login()
if err != nil {
if err = r.Login(); err != nil {
return nil, err
}
@@ -67,7 +76,7 @@ func New(host string, port int, password string, options ...Option) (*Rcon, erro
}
func (r Rcon) Login() error {
timeout := time.After(2 * time.Second)
timeout := time.After(r.loginTimeout)
for {
select {
case <-timeout: