cs16-dm-server: CS 1.6 deathmatch server in Docker
One-command setup (SteamCMD + pinned, checksum-verified ReHLDS / ReGameDLL / Metamod-R / AMXX / ReAPI / ReUnion / CSDM-ReAPI / YaPB / GunGame), .env settings, ./cs menu (map, DM/GunGame mode, bots, kill counter, restart, update), own plugins (extras, rtv, mode switch), all-time kill counter, watchdog + nightly backup, docs for admins and players. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
commit
7e9cbee14d
33 files changed
+1890
No files matched your search
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Asks a CS 1.6 / GoldSrc server for its info (A2S_INFO), like the in-game server browser does.
|
||||
python3 tools/hlq.py info <host> <port>
|
||||
Prints: name | map | players x/y (bots n) | password yes/no. Exit code 1 when there's no answer.
|
||||
Works against any address (LAN, VPN, a playit tunnel), so it also tests the way in from outside."""
|
||||
import socket, sys
|
||||
|
||||
H = b"\xff\xff\xff\xff"
|
||||
|
||||
|
||||
def info(host, port, timeout=4):
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s.settimeout(timeout)
|
||||
q = H + b"TSource Engine Query\x00"
|
||||
s.sendto(q, (host, port))
|
||||
d = s.recvfrom(65535)[0]
|
||||
if d[4:5] == b"A": # newer servers answer with a challenge first: ask again with it
|
||||
s.sendto(q + d[5:9], (host, port))
|
||||
d = s.recvfrom(65535)[0]
|
||||
if d[4:5] != b"I":
|
||||
raise ValueError("unexpected reply type %r" % d[4:5])
|
||||
name, mp, folder, game, rest = d[6:].split(b"\x00", 4)
|
||||
players, maxp, bots, pw = rest[2], rest[3], rest[4], rest[7]
|
||||
return (f"{name.decode(errors='replace')} | map {mp.decode()} | players {players}/{maxp} (bots {bots})"
|
||||
f" | password {'yes' if pw else 'no'}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 4 or sys.argv[1] != "info":
|
||||
sys.exit(__doc__)
|
||||
try:
|
||||
print("A2S_INFO ok:", info(sys.argv[2], int(sys.argv[3])))
|
||||
except (OSError, ValueError) as e:
|
||||
print("no answer:", e)
|
||||
sys.exit(1)
|
||||
Reference in new issue
Block a user