def get_product_info(self, appids=[], packageids=[]): try: resp = self.steam.send_job_and_wait(MsgProto(EMsg.ClientPICSProductInfoRequest), { 'apps': map(lambda x: {'appid': x}, appids), 'packages': map(lambda x: {'packageid': x}, packageids), }, timeout=10 ) if not resp: return {} resp = proto_to_dict(resp) for app in resp.get('apps', []): app['appinfo'] = vdf.loads( app.pop('buffer')[:-1].decode('utf-8', 'replace'))['appinfo'] app['sha'] = hexlify(app['sha']).decode('utf-8') for pkg in resp.get('packages', []): pkg['appinfo'] = vdf.binary_loads(pkg.pop('buffer')[4:])[ str(pkg['packageid'])] pkg['sha'] = hexlify(pkg['sha']).decode('utf-8') return resp except Exception as e: print('get_product_info() exception: ' + str(e)) return {}
def query(self, filter_text, max_servers=10, timeout=30, **kw): r""" Query game servers https://developer.valvesoftware.com/wiki/Master_Server_Query_Protocol .. note:: When specifying ``filter_text`` use *raw strings* otherwise python won't treat backslashes as literal characters (e.g. ``query(r'\appid\730\white\1')``) :param filter_text: filter for servers :type filter_text: str :param max_servers: (optional) number of servers to return :type max_servers: int :param timeout: (optional) timeout for request in seconds :type timeout: int :param app_id: (optional) app id :type app_id: int :param geo_location_ip: (optional) ip (e.g. '1.2.3.4') :type geo_location_ip: str :returns: list of servers, see below. (``None`` is returned steam doesn't respond) :rtype: :class:`list`, :class:`None` Sample response: .. code:: python [{'auth_players': 0, 'server_ip': '1.2.3.4', 'query_port': 27015}, {'auth_players': 6, 'server_ip': '1:2:3:4::5', 'query_port': 27016}, ... ] """ if 'geo_location_ip' in kw: kw['geo_location_ip'] = ip4_to_int(kw['geo_location_ip']) kw['filter_text'] = filter_text kw['max_servers'] = max_servers resp = self._s.send_job_and_wait( MsgProto(EMsg.ClientGMSServerQuery), kw, timeout=timeout, ) if resp is None: return None resp = proto_to_dict(resp) for server in resp['servers']: server.pop('deprecated_server_ip', None) # no point returning this if 'v4' in server['server_ip']: server['server_ip'] = ip4_from_int(server['server_ip']['v4']) else: server['server_ip'] = ip6_from_bytes(server['server_ip']['v6']) return resp['servers']
def get_product_changes(self, since_change_number): resp = self.steam.send_job_and_wait(MsgProto( EMsg.ClientPICSChangesSinceRequest), { 'since_change_number': since_change_number, 'send_app_info_changes': True, 'send_package_info_changes': True, }, timeout=10) return proto_to_dict(resp) or {}
def get_product_changes(self, since_change_number): try: resp = self.steam.send_job_and_wait(MsgProto(EMsg.ClientPICSChangesSinceRequest), { 'since_change_number': since_change_number, 'send_app_info_changes': True, 'send_package_info_changes': True, }, timeout=10 ) return proto_to_dict(resp) or {} except Exception as e: print('get_product_changes() exception: ' + str(e)) return {}
def test_proto_from_dict_to_dict(self): DATA = { 'buffers': [{ 'data': b'some data', 'flags': [{ 'flag': True }, { 'flag': False }, { 'flag': False }] }, { 'data': b'\x01\x02\x03\x04', 'flags': [{ 'flag': False }, { 'flag': True }, { 'flag': True }] }], 'list_number32': [ 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864, 268435456, 1073741824 ], 'list_number64': [ 4, 64, 1024, 16384, 262144, 1125899906842624, 18014398509481984, 288230376151711744, 4611686018427387904 ], 'messages': [{ 'text': 'test string' }, { 'text': 'another one' }, { 'text': 'third' }], 'number32': 16777216, 'number64': 72057594037927936 } utp.proto_fill_from_dict(self.msg, DATA) RESULT = utp.proto_to_dict(self.msg) self.assertEqual(DATA, RESULT)
def _send_request(self, action, params): backend = self.backend if isinstance(backend, MobileWebAuth): if not backend.logged_on: raise SteamAuthenticatorError( "MobileWebAuth instance not logged in") params['access_token'] = backend.oauth_token params['http_timeout'] = 10 try: resp = webapi.post('ITwoFactorService', action, 1, params=params) except requests.exceptions.RequestException as exp: raise SteamAuthenticatorError("Error adding via WebAPI: %s" % str(exp)) resp = resp['response'] else: if not backend.logged_on: raise SteamAuthenticatorError( "SteamClient instance not logged in") resp = backend.send_um_and_wait("TwoFactor.%s#1" % action, params, timeout=10) if resp is None: raise SteamAuthenticatorError("Failed. Request timeout") if resp.header.eresult != EResult.OK: raise SteamAuthenticatorError( "Failed: %s (%s)" % str(resp.header.error_message, repr(resp.header.eresult))) resp = proto_to_dict(resp.body) if action == 'AddAuthenticator': for key in ['shared_secret', 'identity_secret', 'secret_1']: resp[key] = b64encode(resp[key]).decode('ascii') return resp
def get_player_count(self, appid): resp = self.steam.send_job_and_wait(MsgProto( EMsg.ClientGetNumberOfCurrentPlayersDP), {'appid': appid}, timeout=10) return proto_to_dict(resp) or {}
def get_server_list(self, filter_text, max_servers=10, timeout=20): """ Get list of servers. Works similiarly to :meth:`query`, but the response has more details. :param filter_text: filter for servers :type filter_text: str :param max_servers: (optional) number of servers to return :type max_servers: int :param timeout: (optional) timeout for request in seconds :type timeout: int :returns: list of servers, see below. (``None`` is returned steam doesn't respond) :rtype: :class:`list`, :class:`None` :raises: :class:`.SteamError` Sample response: .. code:: python [{'addr': '1.2.3.4:27067', 'appid': 730, 'bots': 0, 'dedicated': True, 'gamedir': 'csgo', 'gameport': 27067, 'gametype': 'valve_ds,empty,secure', 'map': 'de_dust2', 'max_players': 10, 'name': 'Valve CS:GO Asia Server (srcdsXXX.XXX.XXX)', 'os': 'l', 'players': 0, 'product': 'csgo', 'region': 5, 'secure': True, 'steamid': SteamID(id=3279818759, type='AnonGameServer', universe='Public', instance=7011), 'version': '1.35.4.0'} ] """ resp = self._s.send_um_and_wait( "GameServers.GetServerList#1", { "filter": filter_text, "limit": max_servers, }, timeout=20, ) if resp is None: return None if resp.header.eresult != EResult.OK: raise SteamError(resp.header.error_message, resp.header.eresult) resp = proto_to_dict(resp.body) if not resp: return [] else: for server in resp['servers']: server['steamid'] = SteamID(server['steamid']) return resp['servers']