Go client library for Valve's A2S UDP server query protocol.
The package can query Source Engine compatible game servers for:
- general server information via
A2S_INFO - server rules via
A2S_RULES - Arma 3 Server Browser Protocol v3 and DayZ Server Browser Protocol v2 data
embedded in
A2S_RULES
It handles challenge responses and Source Engine split-packet responses internally.
Install
Requires Go 1.24 or newer.
go get fakehacker.cc/a2s@latest
For direct VCS downloads, Go may need permission to use Fossil for this module:
go env -w GOVCS=fakehacker.cc:fossil,public:git|hg,private:all
You can also set GOVCS only for one command:
GOVCS=fakehacker.cc:fossil go get fakehacker.cc/a2s@latest
Usage
package main
import (
"context"
"fmt"
"log"
"time"
"fakehacker.cc/a2s"
)
func main() {
client, err := a2s.NewClient(a2s.WithTimeout(5 * time.Second))
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
info, err := client.Info(ctx, "192.0.2.10:27016")
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s on %s: %d/%d players\n",
info.Name,
info.Map,
info.Players,
info.MaxPlayers,
)
}
Query rules:
rules, err := client.Rules(ctx, "192.0.2.10:27016")
if err != nil {
log.Fatal(err)
}
fmt.Println(rules.Raw["sv_cheats"])
Query Arma 3 or DayZ server-browser data:
browser, err := client.ServerBrowserRules(ctx, "192.0.2.10:27016")
if err != nil {
log.Fatal(err)
}
switch browser.Game {
case a2s.ServerBrowserGameArma3:
fmt.Println("Arma 3 mods:", len(browser.Mods))
case a2s.ServerBrowserGameDayZ:
fmt.Println("DayZ island:", browser.Island)
}
Use the game-specific helpers when you want a type check:
arma3, err := client.Arma3Rules(ctx, "192.0.2.10:27016")
if err != nil {
log.Fatal(err)
}
dayz, err := client.DayZRules(ctx, "192.0.2.10:27016")
if err != nil {
log.Fatal(err)
}
fmt.Println(len(arma3.Mods), dayz.Island)
Addresses must use the server query port, not necessarily the game port.
For DayZ, the query port is usually the game port plus 24648; for example,
game port 2302 uses query port 27016.
Client Options
client, err := a2s.NewClient(
a2s.WithTimeout(5*time.Second),
a2s.WithBufferSize(65536),
)
if err != nil {
log.Fatal(err)
}
Defaults:
- timeout: 3 seconds
- buffer size: 65536 bytes
Invalid option values return OptionError.
Client is safe for concurrent use. Each query opens and closes its own UDP
connection.
Errors
Errors are returned as package-specific types and support errors.Is and
errors.As.
info, err := client.Info(ctx, addr)
if err != nil {
var queryErr *a2s.QueryError
if errors.As(err, &queryErr) {
log.Printf("query=%s operation=%s", queryErr.Query, queryErr.Operation)
}
if errors.Is(err, a2s.ErrGoldSourceResponse) {
log.Printf("server returned unsupported GoldSource response")
}
return
}
_ = info
Common error types include:
QueryErrorOptionErrorDialErrorChallengeErrorNetworkErrorParseErrorReadErrorUnsupportedResponseErrorUnexpectedResponseTypeErrorPacketTooShortErrorInvalidHeaderErrorMultiPacketErrorNoServerBrowserPayloadErrorServerBrowserUnsupportedVersionErrorServerBrowserUnexpectedGameErrorServerBrowserInvalidPageErrorServerBrowserInvalidEscapeError
Supported Response Details
A2S_INFO parsing includes the optional EDF fields:
- game port
- Steam ID
- spectator port and name
- tags
- full game ID
When the full game ID is present, the low 24 bits are used to correct AppIDs that do not fit in the 16-bit base response field, such as DayZ.
A2S_RULES parsing includes ordinary rule key-value pairs and the nested
server-browser payload used by Arma 3 and DayZ. The nested payload is split into
binary pages, escaped for transport through Steam rules, and decoded into
ServerBrowserRules.
Arma 3 server-browser parsing includes:
- protocol version and flags
- DLC bitmask and hashes
- difficulty settings
- Workshop mods
- creator DLC
- accepted signatures
DayZ server-browser parsing includes:
- protocol version and flags
- DLC bitmask and hashes
- Workshop mods
- accepted signatures
- server description
- DayZ ordinary rule fields such as island, platform, build, and client port
Development
Run the test suite:
go test ./...
Run race-enabled tests:
go test -race ./...
Format check:
gofmt -l .
Protocol reference notes live in doc/server_queries.md; DayZ-specific notes
live in doc/dayz.md.