diff options
Diffstat (limited to 'QueryServer.py')
-rwxr-xr-x | QueryServer.py | 184 |
1 files changed, 99 insertions, 85 deletions
diff --git a/QueryServer.py b/QueryServer.py index fb2efd1..9227e5a 100755 --- a/QueryServer.py +++ b/QueryServer.py @@ -6,35 +6,33 @@ import time CACHE_TTL = 15 sourcequery = [ - 50, # HL Opposing Force - 240, # CS:S - 320, # HL2 DM - 440, # TF2 - 550, # L4D2 - 630, # AlienSwarm - 730, # CS:GO - 4000, # Garrys Mod - 107410, # ARMA III - # 221100, # DayZ - 252490, # Rust - 282440, # Quake Live - 328070, # Reflex - 346110 # ARK: Survival Evolved - ] -sourcequeryinc = [ - 107410, # ARMA III - 346110 # ARK: Survival Evolved - ] + 50, # HL Opposing Force + 240, # CS:S + 320, # HL2 DM + 440, # TF2 + 550, # L4D2 + 630, # AlienSwarm + 730, # CS:GO + 4000, # Garrys Mod + 107410, # ARMA III + # 221100, # DayZ + 252490, # Rust + 282440, # Quake Live + 328070, # Reflex + 346110, # ARK: Survival Evolved +] +sourcequeryinc = [107410, 346110] # ARMA III # ARK: Survival Evolved import json import socket import struct from SteamAPI import SteamAPI + if CACHE_TTL > 0: from Caching import Caching -class QueryServer(): +class QueryServer: def QueryServer(ip, port, gameid): """Query a supported server. @@ -45,23 +43,27 @@ class QueryServer(): Returns: dict() with parsed server values""" - port = int(port) + port = int(port) gameid = int(gameid) if CACHE_TTL > 0: - cache = Caching.readCache('server', '%s-%s-%s' % (str(gameid), ip, str(port)), CACHE_TTL) + cache = Caching.readCache( + "server", "%s-%s-%s" % (str(gameid), ip, str(port)), CACHE_TTL + ) if cache: return json.loads(cache) socket.setdefaulttimeout(5) if int(gameid) in sourcequery: - print('Querying server...') + print("Querying server...") serverdata = QueryServer._querySourceServer(ip, port, gameid) if CACHE_TTL > 0: serialized = json.dumps(serverdata) - Caching.writeCache('server', '%s-%s-%s' % (str(gameid), ip, str(port)), serialized) + Caching.writeCache( + "server", "%s-%s-%s" % (str(gameid), ip, str(port)), serialized + ) return serverdata @@ -78,15 +80,15 @@ class QueryServer(): message = None try: - conn.connect( (ip, port) ) - conn.sendall( b'\xFF\xFF\xFF\xFF\x54' + b'Source Engine Query' + b'\x00' ) + conn.connect((ip, port)) + conn.sendall(b"\xFF\xFF\xFF\xFF\x54" + b"Source Engine Query" + b"\x00") message = conn.recv(4096) - conn.sendall( b'\xFF\xFF\xFF\xFF\x55\xFF\xFF\xFF\xFF' ) + conn.sendall(b"\xFF\xFF\xFF\xFF\x55\xFF\xFF\xFF\xFF") challenge = conn.recv(1024)[5:] - conn.sendall( b'\xFF\xFF\xFF\xFF\x55' + challenge ) + conn.sendall(b"\xFF\xFF\xFF\xFF\x55" + challenge) playerdata = conn.recv(8192) except Exception as e: - print('Exception in SourceQuery connection:', e) + print("Exception in SourceQuery connection:", e) if not message: return None finally: @@ -95,103 +97,115 @@ class QueryServer(): data = {} latency = time.time() - starttime - data['latency'] = int(latency * 1000) + data["latency"] = int(latency * 1000) # [0]-[3] -> 4*\xFF - data['header'] = chr(message[4]) - data['protocol'] = chr(message[5]) + data["header"] = chr(message[4]) + data["protocol"] = chr(message[5]) message = message[6:] # Servername - nullterm = message.index(b'\0') - data['name'] = message[:nullterm] - message = message[nullterm+1:] + nullterm = message.index(b"\0") + data["name"] = message[:nullterm] + message = message[nullterm + 1 :] # Mapname - nullterm = message.index(b'\0') - data['map'] = message[:nullterm] - message = message[nullterm+1:] + nullterm = message.index(b"\0") + data["map"] = message[:nullterm] + message = message[nullterm + 1 :] # Folder - nullterm = message.index(b'\0') - data['folder'] = message[:nullterm] - message = message[nullterm+1:] + nullterm = message.index(b"\0") + data["folder"] = message[:nullterm] + message = message[nullterm + 1 :] # Game - nullterm = message.index(b'\0') - data['game'] = message[:nullterm] - message = message[nullterm+1:] - - data['gameid'] = (message[1] << 8) + message[0] - data['players'] = message[2] - data['playersmax'] = message[3] - data['bots'] = message[4] - data['servertype'] = chr(message[5]) # dedicated/local/proxy(tv) - data['enviroment'] = chr(message[6]) # windows/linux/mac - data['visibility'] = message[7] # 0public 1private - data['vac'] = message[8] + nullterm = message.index(b"\0") + data["game"] = message[:nullterm] + message = message[nullterm + 1 :] + + data["gameid"] = (message[1] << 8) + message[0] + data["players"] = message[2] + data["playersmax"] = message[3] + data["bots"] = message[4] + data["servertype"] = chr(message[5]) # dedicated/local/proxy(tv) + data["enviroment"] = chr(message[6]) # windows/linux/mac + data["visibility"] = message[7] # 0public 1private + data["vac"] = message[8] message = message[9:] # Game - nullterm = message.index(b'\0') - data['gameversion'] = message[:nullterm] - message = message[nullterm+1:] + nullterm = message.index(b"\0") + data["gameversion"] = message[:nullterm] + message = message[nullterm + 1 :] extradataflag = message[0] message = message[1:] if extradataflag & 0x80: - data['port'] = (message[1] << 8) + message[0] + data["port"] = (message[1] << 8) + message[0] message = message[2:] if extradataflag & 0x10: - data['steamid'] = (message[7] << 56) + (message[6] << 48) + \ - (message[5] << 40) + (message[4] << 32) + \ - (message[3] << 24) + (message[2] << 16) + \ - (message[1] << 8) + (message[0]) + data["steamid"] = ( + (message[7] << 56) + + (message[6] << 48) + + (message[5] << 40) + + (message[4] << 32) + + (message[3] << 24) + + (message[2] << 16) + + (message[1] << 8) + + (message[0]) + ) message = message[8:] if extradataflag & 0x40: - data['sourcetvport'] = (message[1] << 8) + message[0] + data["sourcetvport"] = (message[1] << 8) + message[0] message = message[2:] - nullterm = message.index(b'\0') - data['sourcetvname'] = message[:nullterm] - message = message[nullterm+1:] + nullterm = message.index(b"\0") + data["sourcetvname"] = message[:nullterm] + message = message[nullterm + 1 :] if extradataflag & 0x20: - nullterm = message.index(b'\0') - data['keywords'] = message[:nullterm] - message = message[nullterm+1:] + nullterm = message.index(b"\0") + data["keywords"] = message[:nullterm] + message = message[nullterm + 1 :] if extradataflag & 0x01: - data['sgameid'] = (message[7] << 56) + (message[6] << 48) + \ - (message[5] << 40) + (message[4] << 32) + \ - (message[3] << 24) + (message[2] << 16) + \ - (message[1] << 8) + (message[0]) + data["sgameid"] = ( + (message[7] << 56) + + (message[6] << 48) + + (message[5] << 40) + + (message[4] << 32) + + (message[3] << 24) + + (message[2] << 16) + + (message[1] << 8) + + (message[0]) + ) message = message[8:] - if playerdata and playerdata[4] == ord('D'): + if playerdata and playerdata[4] == ord("D"): players = [] - data['player_info'] = players + data["player_info"] = players number = playerdata[5] playerdata = playerdata[6:] index = 0 while index < number and playerdata: player = dict() - player['index'] = playerdata[0] + player["index"] = playerdata[0] - nullterm = playerdata.index(b'\0', 1) + nullterm = playerdata.index(b"\0", 1) player_name = playerdata[1:nullterm] - player['name'] = player_name.decode('utf-8', errors='replace') - playerdata = playerdata[nullterm+1:] + player["name"] = player_name.decode("utf-8", errors="replace") + playerdata = playerdata[nullterm + 1 :] - playerscore = int(struct.unpack('i', playerdata[0:4])[0]) - player['score'] = playerscore + playerscore = int(struct.unpack("i", playerdata[0:4])[0]) + player["score"] = playerscore playerdata = playerdata[4:] - duration = int(struct.unpack('f', playerdata[0:4])[0]) - player['duration'] = duration + duration = int(struct.unpack("f", playerdata[0:4])[0]) + player["duration"] = duration playerdata = playerdata[4:] players.append(player) @@ -201,14 +215,14 @@ class QueryServer(): for key, value in data.items(): if isinstance(value, bytes): try: - value = value.decode('utf-8', errors='replace') + value = value.decode("utf-8", errors="replace") data[key] = value except UnicodeDecodeError: data[key] = "UTF8 Error" pass return data + if __name__ == "__main__": # TODO(andre): Maybe run our tests here? - print('This is a module.') - + print("This is a module.") |