Interacting with Source Servers¶
Source provides the “A2S” protocol for querying game servers. This protocol
is used by the Steam and in-game server browsers to list information about
servers such as their name, player count and whether or not they’re password
protected. valve.source.a2s
provides a client implementation of
A2S.
-
class
valve.source.a2s.
ServerQuerier
(address, timeout=5.0)¶ Implements the A2S Source server query protocol.
https://developer.valvesoftware.com/wiki/Server_queries
Note
Instantiating this class creates a socket. Be sure to close the querier once finished with it. See
valve.source.BaseQuerier
.-
info
()¶ Retreive information about the server state
This returns the response from the server which implements
__getitem__
for accessing response fields. For example:with ServerQuerier(...) as server: print(server.info()["server_name"])
The following fields are available on the response:
Field Description response_type Always 0x49
server_name The name of the server map The name of the map being ran by the server folder The gamedir if the modification being ran by the server. E.g. tf
,cstrike
,csgo
.game A string identifying the game being ran by the server app_id The numeric application ID of the game ran by the server. Note that this is the app ID of the client, not the server. For example, for Team Fortress 2 440
is returned instead of232250
which is the ID of the server software.player_count Number of players currently connected. See players()
for caveats about the accuracy of this field.max_players The number of player slots available. Note that player_count
may exceed this value under certain circumstances. Seeplayers()
.bot_count The number of AI players present server_type A util.ServerType
instance representing the type of server. E.g. Dedicated, non-dedicated or Source TV relay.platform A util.Platform
instances represneting the platform the server is running on. E.g. Windows, Linux or Mac OS X.password_protected Whether or not a password is required to connect to the server. vac_enabled Whether or not Valve anti-cheat (VAC) is enabled version The version string of the server software Currently the extra data field (EDF) is not supported.
-
ping
()¶ Ping the server, returning the round-trip latency in milliseconds
The A2A_PING request is deprecated so this actually sends a A2S_INFO request and times that. The time difference between the two should be negligble.
-
players
()¶ Retrive a list of all players connected to the server
The following fields are available on the response:
Field Description response_type Always 0x44
player_count The number of players listed players A list of player entries The
players
field is a list that containsplayer_count
number ofmessages.PlayerEntry
instances which have the same interface as the top-level response object that is returned.The following fields are available on each player entry:
Field Description name The name of the player score Player’s score at the time of the request. What this relates to is dependant on the gamemode of the server. duration Number of seconds the player has been connected as a float Note
Under certain circumstances, some servers may return a player list which contains empty
name
fields. This can lead toplayer_count
being misleading.Filtering out players with empty names may yield a more accurate enumeration of players:
with ServerQuerier(...) as query: players = [] for player in query.players()["players"]: if player["name"]: players.append(player) player_count = len(players)
-
rules
()¶ Retreive the server’s game mode configuration
This method allows you capture a subset of a server’s console variables (often referred to as ‘cvars’,) specifically those which have the
FCVAR_NOTIFY
flag set on them. These cvars are used to indicate game mode’s configuration, such as the gravity setting for the map or whether friendly fire is enabled or not.The following fields are available on the response:
Field Description response_type Always 0x56
rule_count The number of rules rules A dictionary mapping rule names to their corresponding string value
-
Example¶
In this example we will query a server, printing out it’s name and the number of players currently conected. Then we’ll print out all the players sorted score-decesending.
import valve.source.a2s
SERVER_ADDRESS = (..., ...)
with valve.source.a2s.ServerQuerier(SERVER_ADDRESS) as server:
info = server.info()
players = server.players()
print("{player_count}/{max_players} {server_name}".format(**info))
for player in sorted(players["players"],
key=lambda p: p["score"], reverse=True):
print("{score} {name}".format(**player))
Queriers and Exceptions¶
Both valve.source.a2s.ServerQuerier
and
valve.source.master_server.MasterServerQuerier
are based on a
common querier interface. They also raise similar exceptions. All of these
live in the valve.source
module.
-
class
valve.source.
BaseQuerier
(address, timeout=5.0)¶ Base class for implementing source server queriers.
When an instance of this class is initialised a socket is created. It’s important that, once a querier is to be discarded, the associated socket be closed via
close()
. For example:querier = valve.source.BaseQuerier(('...', 27015)) try: querier.request(...) finally: querier.close()
When server queriers are used as context managers, the socket will be cleaned up automatically. Hence it’s preferably to use the with statement over the try-finally pattern described above:
with valve.source.BaseQuerier(('...', 27015)) as querier: querier.request(...)
Once a querier has been closed, any attempts to make additional requests will result in a
QuerierClosedError
to be raised.Variables: - host – Host requests will be sent to.
- port – Port number requests will be sent to.
- timeout – How long to wait for a response to a request.
-
close
()¶ Close the querier’s socket.
It is safe to call this multiple times.
-
get_response
()¶ Wait for a response to a request.
Raises: - NoResponseError – If the configured
timeout
is reached before a response is received. - QuerierClosedError – If the querier has been closed.
Returns: The raw response as a
bytes
.- NoResponseError – If the configured
-
request
(*request)¶ Issue a request.
The given request segments will be encoded and combined to form the final message that is sent to the configured address.
Parameters: request (valve.source.messages.Message) – Request message segments. Raises: QuerierClosedError – If the querier has been closed.
-
exception
valve.source.
NoResponseError
¶ Raised when a server querier doesn’t receive a response.
-
exception
valve.source.
QuerierClosedError
¶ Raised when attempting to use a querier after it’s closed.
Identifying Server Platforms¶
valve.source.util
provides a handful of utility classes which are
used when querying Source servers.
-
class
valve.source.util.
Platform
(value)¶ A Source server platform identifier
This class provides utilities for representing Source server platforms as returned from a A2S_INFO request. Each platform is ultimately represented by one of the following integers:
ID Platform 76 Linux 108 Linux 109 Mac OS X 111 Mac OS X 119 Windows Note
Starbound uses 76 instead of 108 for Linux in the old GoldSource style.
-
__eq__
(other)¶ Check for equality between two platforms
If
other
is not a Platform instance then an attempt is made to convert it to one using same approach as__init__()
. This means platforms can be compared against integers and strings. For example:>>>Platform(108) == "linux" True >>>Platform(109) == 109 True >>>Platform(119) == "w" True
Despite the fact there are two numerical identifers for Mac (109 and 111) comparing either of them together will yield
True
.>>>Platform(109) == Platform(111) True
-
__init__
(value)¶ Initialise the platform identifier
The given
value
will be mapped to a numeric identifier. If the value is already an integer it must then it must exist in the table above else ValueError is returned.If
value
is a one character long string then it’s ordinal value as given byord()
is used. Alternately the string can be either of the following:- Linux
- Mac OS X
- Windows
-
__weakref__
¶ list of weak references to the object (if defined)
-
os_name
¶ Convenience mapping to names returned by
os.name
-
-
class
valve.source.util.
ServerType
(value)¶ A Source server platform identifier
This class provides utilities for representing Source server types as returned from a A2S_INFO request. Each server type is ultimately represented by one of the following integers:
ID Server type 68 Dedicated 100 Dedicated 108 Non-dedicated 112 SourceTV Note
Starbound uses 68 instead of 100 for a dedicated server in the old GoldSource style.
-
__eq__
(other)¶ Check for equality between two server types
If
other
is not a ServerType instance then an attempt is made to convert it to one using same approach as__init__()
. This means server types can be compared against integers and strings. For example:>>>Server(100) == "dedicated" True >>>Platform(108) == 108 True >>>Platform(112) == "p" True
-
__init__
(value)¶ Initialise the server type identifier
The given
value
will be mapped to a numeric identifier. If the value is already an integer it must then it must exist in the table above else ValueError is returned.If
value
is a one character long string then it’s ordinal value as given byord()
is used. Alternately the string can be either of the following:- Dedicated
- Non-Dedicated
- SourceTV
-
__weakref__
¶ list of weak references to the object (if defined)
-