dot-browser is the asking half of
dot-server-query: a query client and a
list model. That addon has answered queries since the day it was written, and
until this one nothing in the family had ever asked one anything.
Requires dot-core. dot-server-query is what it asks and is not a
dependency — the wire format is implemented here and no class from it is named.
Usage
var browser := DotBrowser.new()
browser.add_source(DotBrowserSourceList.of(PackedStringArray([
"eu1.example.com:27015",
"127.0.0.1:27016",
])))
browser.entry_updated.connect(func(entry: DotBrowserEntry) -> void:
table.redraw(entry))
add_child(browser)
await browser.refresh()
for entry in browser.filtered():
print(entry.describe())
# 127.0.0.1:27016 A dot server dm_atrium 8/32 14 ms
Asking one server everything, for the panel behind a clicked row:
await browser.query(entry.target, PackedStringArray(["info", "players", "rules"]))
Sources
A browser knows how to ask a server what it is. It does not know which servers exist — that is a different problem with a different answer per deployment.
DotBrowserSourceList |
Addresses typed in, or a JSON file you ship. |
DotBrowserSourceBackbone |
A community’s listing on the TMC backbone, read through a duck-typed client. |
| your own | Subclass DotBrowserSource and return targets. |
A source produces addresses, never player counts. What a server is, is what it says when asked: a listing that has not heard from a server in ten minutes still lists it, and the player clicking it wants to know that before connecting.
Three bugs it exists to not have
Every game that ships a server browser writes this, usually the A2S half, and usually with the same three:
- The player count is humans plus bots. A2S has always written it that way, so a browser showing it presents a server with eight bots as an eight-player server.
- Multi-packet responses get stitched together wrong. A socket refreshing two hundred servers receives replies interleaved, and a fragment of one response mixed into another produces bytes that parse and are wrong.
- Refreshing hangs. Two hundred concurrent queries is a fan-out, and GDScript has two obvious spellings for that and both are broken.
In a browser build
A web page cannot open a UDP socket, so it can never speak A2S. dot-server-query
serves DQP as plain JSON over a WebSocket for exactly this, and Protocol.AUTO
picks it when the platform has no UDP — asking about the capability, not the
platform name.
The wire format is a second implementation on purpose
Only dot-core may be a hard dependency. The self-test checks this
implementation against bytes dot-server-query’s own encoder produced, rather
than against itself.
