Git project: WoozyMasta/a2s
License: MIT
Powerful command-line utility and Go toolkit for working with Steam A2S game servers. Query server information, players, and rules; build A2S servers and cached UDP proxies; and handle Arma 3 and DayZ Server Browser Protocol responses.
A2S_INFO, A2S_PLAYER, and A2S_RULES.A2S_SERVERQUERY_GETCHALLENGE and A2A_PING requests exposed by the Go API.A2S_RULES, with automatic detection,
explicit layouts and native A2S fallback.cmd/a2s:
CLI for queries, diagnostics and cached proxy operation;pkg/a2s:
context-aware A2S client and transport-independent codecs;pkg/a2s/server:
UDP A2S server runtime with challenges and packetization;pkg/a2s/proxy:
reusable cache, polling, relay, and rate-limit components;pkg/a3sb:
typed Arma 3 and DayZ Server Browser Protocol parser and codec;pkg/keywords:
typed parsers for Arma 3 and DayZ A2S_INFO keywords;pkg/appid:
curated Steam AppID registry for A2S-compatible games.go get github.com/woozymasta/a2s
Download the latest CLI release for your platform:
| Arch/OS | macOS | Linux | Windows |
|---|---|---|---|
| AMD64 | a2s-darwin-amd64 | a2s-linux-amd64 | a2s-windows-amd64 |
| ARM64 | a2s-darwin-arm64 | a2s-linux-arm64 | a2s-windows-arm64 |
Download the latest release with curl in Bash:
case "$(uname -s)" in
Linux*) OS=linux;;
Darwin*) OS=darwin;;
MINGW*|MSYS*|CYGWIN*) OS=windows; EXT=.exe;;
*) exit 1;;
esac
case "$(uname -m)" in
x86_64|amd64) ARCH=amd64;;
aarch64|arm64) ARCH=arm64;;
*) exit 1;;
esac
BIN="./a2s$EXT"
curl -#SfLo "$BIN" \
"https://github.com/WoozyMasta/a2s/releases/latest/download/a2s-$OS-$ARCH$EXT"
chmod +x "$BIN"
"$BIN" -h && "$BIN" -v
Prebuilt images are available from GitHub Container Registry and Docker Hub:
ghcr.io/woozymasta/a2s:latestdocker.io/woozymasta/a2s:latestExample using a container image:
docker pull ghcr.io/woozymasta/a2s:latest
docker run --rm -ti \
-e A2S_TIMEOUT=3s \
-e A2S_BUFFER_SIZE=8192 \
ghcr.io/woozymasta/a2s:latest info host:port
The CLI queries A2S servers, formats responses, and runs a cached proxy. See the CLI reference for all commands, options, defaults, environment variables, and generated examples.
info: query server metadata;players: list current players;rules: query native A2S or A3SB rules;all: query metadata, rules, and players together;ping: measure repeated query response times;proxy: expose a cached UDP endpoint for an upstream server.# Query server metadata.
a2s info 127.0.0.1:27015
# Export all responses as one JSON document.
a2s all 127.0.0.1:27015 --format json | jq
# Parse Arma 3 server-browser rules explicitly.
a2s rules 127.0.0.1:2303 --game arma3
# Print only ping values for five queries.
a2s ping 127.0.0.1:27015 --ping-count 5 --compact
# Cache an upstream server on a local UDP endpoint.
a2s proxy 127.0.0.1:27015 --listen :27016
The Go packages cover both sides of the protocol: querying existing servers and serving or proxying A2S responses. For the complete public API, see the Go module documentation. The examples below show the main building blocks.
Use pkg/a2s for standard server queries.
ctx := context.Background()
client, err := a2s.New("127.0.0.1", 27015, a2s.WithTimeout(3*time.Second))
if err != nil {
panic(err)
}
defer client.Close()
info, err := client.GetInfo(ctx)
if err != nil {
panic(err)
}
_ = info
Wrap an existing a2s.Client with pkg/a3sb
for Arma 3 and DayZ rules:
a3sClient := &a3sb.Client{Client: client}
rules, err := a3sClient.GetRules(ctx, 0) // Automatic classification.
if err != nil {
panic(err)
}
_ = rules
// Explicit layout: a3sClient.GetRules(ctx, appid.DayZ)
Use pkg/a2s/server to publish your own server data:
implement a Handler and pass it to server.New.
The server handles UDP transport, challenge validation,
and response packetization.
handler := server.HandlerFunc(func(
_ context.Context,
request *server.Request,
) (server.Response, error) {
if request.Query.Type != a2s.InfoRequest {
return nil, server.ErrDrop
}
return server.InfoResponse{Info: a2s.Info{
Format: a2s.InfoFormat(a2s.ResponseInfo),
Name: "Example A2S server",
}}, nil
})
srv, err := server.New(handler)
if err != nil {
panic(err)
}
conn, err := net.ListenPacket("udp", ":27015")
if err != nil {
panic(err)
}
defer conn.Close()
go srv.Serve(conn)
defer srv.Shutdown(context.Background())
Use pkg/a2s/proxy with pkg/a2s/server
to serve cached responses and relay uncached queries.
Use a Poller to refresh selected cache entries from the upstream client.
cache, _ := proxy.NewCache([]a2s.QueryType{
a2s.InfoRequest, a2s.RulesRequest,
})
handler, _ := proxy.NewHandler(cache, upstream, proxy.HandlerConfig{
ChallengeProvider: provider,
LocalPing: true,
})
srv, _ := server.New(handler, server.WithChallengeProvider(provider))
Run a Poller to refresh the cache and serve srv on a UDP PacketConn.
For a deeper understanding of the protocols used, refer to the official documentation:
During development, the functionality of a2s was thoroughly tested
across a diverse range of popular games
that utilize the Steam server query protocols.
The implementation has been tested against servers from these games:
Your support is greatly appreciated!
Content type
Image
Digest
sha256:6e789d694…
Size
2.8 MB
Last updated
2 days ago
docker pull woozymasta/a2s