Example #1
0
    def _send_request(self, action, params):
        medium = self.medium

        if isinstance(medium, MobileWebAuth):
            if not medium.complete:
                raise SteamAuthenticatorError("MobileWebAuth instance not logged in")

            params['access_token'] = medium.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 medium.logged_on:
                raise SteamAuthenticatorError("SteamClient instance not logged in")

            resp = medium.unified_messages.send_and_wait("TwoFactor.%s#1" % action,
                                                         params, timeout=10)
            if resp is None:
                raise SteamAuthenticatorError("Failed to add authenticator. Request timeout")

            resp = proto_to_dict(resp)

            if action == 'AddAuthenticator':
                for key in ['shared_secret', 'identity_secret', 'secret_1']:
                    resp[key] = b64encode(resp[key])

        return resp
Example #2
0
    def get_change_number(self, appids=None):
        if not appids:
            appids = []
        else:
            appids = [appids]

        packageids = []

        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').rstrip('\x00'))['appinfo']
            app['sha'] = hexlify(app['sha'])
        for pkg in resp.get('packages', []):
            pkg['appinfo'] = vdf.binary_loads(pkg.pop('buffer')[4:])[str(
                pkg['packageid'])]
            pkg['sha'] = hexlify(pkg['sha'])

        return resp['apps'][0]['change_number']
Example #3
0
    def _send_request(self, action, params):
        medium = self.medium

        if isinstance(medium, MobileWebAuth):
            if not medium.complete:
                raise SteamAuthenticatorError("MobileWebAuth instance not logged in")

            params['access_token'] = medium.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 medium.logged_on:
                raise SteamAuthenticatorError("SteamClient instance not logged in")

            resp = medium.unified_messages.send_and_wait("TwoFactor.%s#1" % action,
                                                         params, timeout=10)
            if resp is None:
                raise SteamAuthenticatorError("Failed to add authenticator. Request timeout")

            resp = proto_to_dict(resp)

            if action == 'AddAuthenticator':
                for key in ['shared_secret', 'identity_secret', 'secret_1']:
                    resp[key] = b64encode(resp[key])

        return resp
Example #4
0
    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']
Example #5
0
    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:`.UnifiedMessageError`


        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, error = self._um.send_and_wait("GameServers.GetServerList#1",
                                             {
                                              "filter": filter_text,
                                              "limit": max_servers,
                                             },
                                             timeout=20,
                                             )

        if error:
            raise error
        if resp is None:
            return None

        resp = proto_to_dict(resp)

        if not resp:
            return []
        else:
            for server in resp['servers']:
                server['steamid'] = SteamID(server['steamid'])

            return resp['servers']
Example #6
0
 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 {}
Example #7
0
 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 {}
Example #8
0
    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']
Example #9
0
    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']
Example #10
0
    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
        }

        ut.proto_fill_from_dict(self.msg, DATA)

        RESULT = ut.proto_to_dict(self.msg)

        self.assertEqual(DATA, RESULT)
Example #11
0
    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
                }

        ut.proto_fill_from_dict(self.msg, DATA)

        RESULT = ut.proto_to_dict(self.msg)

        self.assertEqual(DATA, RESULT)
Example #12
0
    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
Example #13
0
    def get_product_info(self, appids=[], packageids=[]):
        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
Example #14
0
 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 {}
Example #15
0
 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 {}