From a7702c80509e7fe7d99998f7fb79336404fedfe6 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Mon, 4 Nov 2024 16:13:31 +0000 Subject: [PATCH] add functional option WithLoginTimeout use it to set the login timeout --- README.md | 10 ++++++++++ q3rcon.go | 17 +++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 43064ee..bb267d4 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/q3rcon.go b/q3rcon.go index 16cf960..13e68cc 100644 --- a/q3rcon.go +++ b/q3rcon.go @@ -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: