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', 'server_port': 27015}, {'auth_players': 6, 'server_ip': '1.2.3.4', 'server_port': 27016}, ... ] """ if 'geo_location_ip' in kw: kw['geo_location_ip'] = ip_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['server_ip'] = ip_from_int(server['server_ip']) return resp['servers']
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', 'server_port': 27015}, {'auth_players': 6, 'server_ip': '1.2.3.4', 'server_port': 27016}, ... ] """ if 'geo_location_ip' in kw: kw['geo_location_ip'] = ip_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['server_ip'] = ip_from_int(server['server_ip']) return resp['servers']
def login(self, username, password='', login_key=None, auth_code=None, two_factor_code=None, login_id=None): """Login as a specific user :param username: username :type username: :class:`str` :param password: password :type password: :class:`str` :param login_key: login key, instead of password :type login_key: :class:`str` :param auth_code: email authentication code :type auth_code: :class:`str` :param two_factor_code: 2FA authentication code :type two_factor_code: :class:`str` :param login_id: number used for identifying logon session :type login_id: :class:`int` :return: logon result, see `CMsgClientLogonResponse.eresult <https://github.com/ValvePython/steam/blob/513c68ca081dc9409df932ad86c66100164380a6/protobufs/steammessages_clientserver.proto#L95-L118>`_ :rtype: :class:`.EResult` .. note:: Failure to login will result in the server dropping the connection, ``error`` event is fired ``auth_code_required`` event is fired when 2FA or Email code is needed. Here is example code of how to handle the situation. .. code:: python @steamclient.on(steamclient.EVENT_AUTH_CODE_REQUIRED) def auth_code_prompt(is_2fa, code_mismatch): if is_2fa: code = input("Enter 2FA Code: ") steamclient.login(username, password, two_factor_code=code) else: code = input("Enter Email Code: ") steamclient.login(username, password, auth_code=code) Codes are required every time a user logins if sentry is not setup. See :meth:`set_credential_location` """ self._LOG.debug("Attempting login") eresult = self._pre_login() if eresult != EResult.OK: return eresult self.username = username message = MsgProto(EMsg.ClientLogon) message.header.steamid = SteamID(type='Individual', universe='Public') message.body.protocol_version = 65580 message.body.client_package_version = 1561159470 message.body.client_os_type = EOSType.Windows10 message.body.client_language = "english" message.body.should_remember_password = True message.body.supports_rate_limit_response = True message.body.chat_mode = self.chat_mode if login_id is None: message.body.obfuscated_private_ip.v4 = ip_to_int( self.connection.local_address) ^ 0xF00DBAAD else: message.body.obfuscated_private_ip.v4 = login_id message.body.account_name = username if login_key: message.body.login_key = login_key else: message.body.password = password sentry = self.get_sentry(username) if sentry is None: message.body.eresult_sentryfile = EResult.FileNotFound else: message.body.eresult_sentryfile = EResult.OK message.body.sha_sentryfile = sha1_hash(sentry) if auth_code: message.body.auth_code = auth_code if two_factor_code: message.body.two_factor_code = two_factor_code self.send(message) resp = self.wait_msg(EMsg.ClientLogOnResponse, timeout=30) if resp and resp.body.eresult == EResult.OK: self.sleep(0.5) return EResult(resp.body.eresult) if resp else EResult.Fail
def test_ip_to_int(self): self.assertEqual(ut.ip_to_int('0.0.0.0'), 0) self.assertEqual(ut.ip_to_int('12.34.56.78'), 203569230) self.assertEqual(ut.ip_to_int('255.255.255.255'), 4294967295)