コード例 #1
0
class PGoApi:
    def __init__(self,
                 provider=None,
                 oauth2_refresh_token=None,
                 username=None,
                 password=None,
                 position_lat=None,
                 position_lng=None,
                 position_alt=None,
                 proxy_config=None,
                 device_info=None):
        self.set_logger()
        self.log.info('%s v%s - %s', __title__, __version__, __copyright__)

        self._auth_provider = None
        if provider is not None and (
            (username is not None and password is not None) or
            (oauth2_refresh_token is not None)):
            self.set_authentication(provider, oauth2_refresh_token, username,
                                    password, proxy_config)

        self.set_api_endpoint("pgorelease.nianticlabs.com/plfe")

        self._position_lat = position_lat
        self._position_lng = position_lng
        self._position_alt = position_alt

        self._signature_lib = None
        self._hash_lib = None

        self._session = requests.session()
        self._session.headers.update({'User-Agent': 'Niantic App'})
        self._session.verify = True

        if proxy_config is not None:
            self._session.proxies = proxy_config

        self.device_info = device_info

    def set_logger(self, logger=None):
        self.log = logger or logging.getLogger(__name__)

    def set_authentication(self,
                           provider=None,
                           oauth2_refresh_token=None,
                           username=None,
                           password=None,
                           proxy_config=None):
        if provider == 'ptc':
            self._auth_provider = AuthPtc()
        elif provider == 'google':
            self._auth_provider = AuthGoogle()
        elif provider is None:
            self._auth_provider = None
        else:
            raise AuthException(
                "Invalid authentication provider - only ptc/google available.")

        self.log.debug('Auth provider: %s', provider)

        if proxy_config is not None:
            self._auth_provider.set_proxy(proxy_config)

        if oauth2_refresh_token is not None:
            self._auth_provider.set_refresh_token(oauth2_refresh_token)
        elif username is not None and password is not None:
            if not self._auth_provider.user_login(username, password):
                raise AuthException("User login failed!")
        else:
            raise AuthException(
                "Invalid Credential Input - Please provide username/password or an oauth2 refresh token"
            )

    def get_position(self):
        return (self._position_lat, self._position_lng, self._position_alt)

    def set_position(self, lat, lng, alt=None):
        self.log.debug('Set Position - Lat: %s Long: %s Alt: %s', lat, lng,
                       alt)

        self._position_lat = lat
        self._position_lng = lng
        self._position_alt = alt

    def set_proxy(self, proxy_config):
        self._session.proxies = proxy_config

    def get_api_endpoint(self):
        return self._api_endpoint

    def set_api_endpoint(self, api_url):
        if api_url.startswith("https"):
            self._api_endpoint = api_url
        else:
            self._api_endpoint = parse_api_endpoint(api_url)

    def get_auth_provider(self):
        return self._auth_provider

    def create_request(self):
        request = PGoApiRequest(self, self._position_lat, self._position_lng,
                                self._position_alt, self.device_info)
        return request

    def activate_signature(self, signature_lib_path=None, hash_lib_path=None):
        if signature_lib_path: self.set_signature_lib(signature_lib_path)
        if hash_lib_path: self.set_hash_lib(hash_lib_path)

    def set_signature_lib(self, signature_lib_path):
        self._signature_lib = signature_lib_path

    def set_hash_lib(self, hash_lib_path):
        self._hash_lib = hash_lib_path

    def get_signature_lib(self):
        return self._signature_lib

    def get_hash_lib(self):
        return self._hash_lib

    def __getattr__(self, func):
        def function(**kwargs):
            request = self.create_request()
            getattr(request, func)(_call_direct=True, **kwargs)
            return request.call()

        if func.upper() in RequestType.keys():
            return function
        else:
            raise AttributeError

    def app_simulation_login(self):
        self.log.info('Starting RPC login sequence (app simulation)')

        # making a standard call, like it is also done by the client
        request = self.create_request()

        request.get_player()
        request.get_hatched_eggs()
        request.get_inventory()
        request.check_awarded_badges()
        request.download_settings(
            hash="54b359c97e46900f87211ef6e6dd0b7f2a3ea1f5")

        response = request.call()

        self.log.info('Finished RPC login sequence (app simulation)')

        return response

    """
    The login function is not needed anymore but still in the code for backward compatibility"
    """

    def login(self,
              provider,
              username,
              password,
              lat=None,
              lng=None,
              alt=None,
              app_simulation=True):

        if lat and lng:
            self._position_lat = lat
            self._position_lng = lng
        if alt:
            self._position_alt = alt

        try:
            self.set_authentication(provider,
                                    username=username,
                                    password=password)
        except AuthException as e:
            self.log.error('Login process failed: %s', e)
            return False

        if app_simulation:
            response = self.app_simulation_login()
        else:
            self.log.info('Starting minimal RPC login sequence')
            response = self.get_player()
            self.log.info('Finished minimal RPC login sequence')

        if not response:
            self.log.info('Login failed!')
            return False

        self.log.info('Login process completed')

        return True
コード例 #2
0
class PGoApi:
    def __init__(self,
                 provider=None,
                 oauth2_refresh_token=None,
                 username=None,
                 password=None,
                 position_lat=None,
                 position_lng=None,
                 position_alt=None,
                 proxy_config=None,
                 device_info=None):
        self.set_logger()
        self.log.info('%s v%s - %s', __title__, __version__, __copyright__)

        self._auth_provider = None
        if provider is not None and (
            (username is not None and password is not None) or
            (oauth2_refresh_token is not None)):
            self.set_authentication(provider, oauth2_refresh_token, username,
                                    password, proxy_config)

        self.set_api_endpoint("pgorelease.nianticlabs.com/plfe")

        self._position_lat = position_lat
        self._position_lng = position_lng
        self._position_alt = position_alt

        self._hash_server_token = None

        self._session = requests.session()
        self._session.headers.update({'User-Agent': 'Niantic App'})
        self._session.verify = True

        if proxy_config is not None:
            self._session.proxies = proxy_config

        self.device_info = device_info

    def set_logger(self, logger=None):
        self.log = logger or logging.getLogger(__name__)

    @staticmethod
    def get_api_version():
        return 9100

    def set_authentication(self,
                           provider=None,
                           oauth2_refresh_token=None,
                           username=None,
                           password=None,
                           proxy_config=None,
                           user_agent=None,
                           timeout=None):
        if provider == 'ptc':
            self._auth_provider = AuthPtc(user_agent=user_agent,
                                          timeout=timeout)
        elif provider == 'google':
            self._auth_provider = AuthGoogle()
        elif provider is None:
            self._auth_provider = None
        else:
            raise InvalidCredentialsException(
                "Invalid authentication provider - only ptc/google available.")

        self.log.debug('Auth provider: {}'.format(provider))

        if proxy_config:
            self._auth_provider.set_proxy(proxy_config)

        if oauth2_refresh_token is not None:
            self._auth_provider.set_refresh_token(oauth2_refresh_token)
        elif username and password:
            if not self._auth_provider.user_login(username, password):
                raise AuthException("User login failed!")
        else:
            raise InvalidCredentialsException(
                "Invalid Credential Input - Please provide username/password or an oauth2 refresh token"
            )

    def get_position(self):
        return (self._position_lat, self._position_lng, self._position_alt)

    def set_position(self, lat, lng, alt=None):
        self.log.debug('Set Position - Lat: %s Long: %s Alt: %s', lat, lng,
                       alt)

        self._position_lat = lat
        self._position_lng = lng
        self._position_alt = alt

    def set_proxy(self, proxy_config):
        self._session.proxies = proxy_config

    def get_api_endpoint(self):
        return self._api_endpoint

    def set_api_endpoint(self, api_url):
        if api_url.startswith("https"):
            self._api_endpoint = api_url
        else:
            self._api_endpoint = parse_api_endpoint(api_url)

    def get_auth_provider(self):
        return self._auth_provider

    def create_request(self):
        request = PGoApiRequest(self, self._position_lat, self._position_lng,
                                self._position_alt, self.device_info)
        return request

    def activate_hash_server(self, hash_server_token):
        self._hash_server_token = hash_server_token

    def get_hash_server_token(self):
        return self._hash_server_token

    def __getattr__(self, func):
        def function(**kwargs):
            request = self.create_request()
            getattr(request, func)(_call_direct=True, **kwargs)
            return request.call()

        if func.upper() in RequestType.keys():
            return function
        else:
            raise AttributeError

    def app_simulation_login(self):
        self.log.info('Starting RPC login sequence (iOS app simulation)')

        # Send empty initial request
        request = self.create_request()
        response = request.call()

        time.sleep(1.5)

        # Send GET_PLAYER only
        request = self.create_request()
        request.get_player(player_locale={
            'country': 'US',
            'language': 'en',
            'timezone': 'America/Chicago'
        })
        response = request.call()

        if response.get('responses', {}).get('GET_PLAYER',
                                             {}).get('banned', False):
            raise BannedAccountException

        time.sleep(1.5)

        request = self.create_request()
        request.download_remote_config_version(
            platform=1, app_version=self.get_api_version())
        request.check_challenge()
        request.get_hatched_eggs()
        request.get_inventory()
        request.check_awarded_badges()
        request.download_settings()
        response = request.call()

        self.log.info('Finished RPC login sequence (iOS app simulation)')

        return response

    """
    The login function is not needed anymore but still in the code for backward compatibility"
    """

    def login(self,
              provider,
              username,
              password,
              lat=None,
              lng=None,
              alt=None,
              app_simulation=True):

        if lat and lng:
            self._position_lat = lat
            self._position_lng = lng
        if alt:
            self._position_alt = alt

        try:
            self.set_authentication(provider,
                                    username=username,
                                    password=password)
        except AuthException as e:
            self.log.error('Login process failed: %s', e)
            return False

        if app_simulation:
            response = self.app_simulation_login()
        else:
            self.log.info('Starting minimal RPC login sequence')
            response = self.get_player()
            self.log.info('Finished minimal RPC login sequence')

        if not response:
            self.log.info('Login failed!')
            return False

        self.log.info('Login process completed')

        return True
コード例 #3
0
ファイル: pgoapi.py プロジェクト: jeafke/pgoapi
class PGoApi:

    def __init__(self, provider=None, oauth2_refresh_token=None, username=None, password=None, position_lat=None, position_lng=None, position_alt=None, proxy_config=None, device_info=None):
        self.set_logger()
        self.log.info('%s v%s - %s', __title__, __version__, __copyright__)

        self._auth_provider = None
        if provider is not None and ((username is not None and password is not None) or (oauth2_refresh_token is not None)):
            self.set_authentication(provider, oauth2_refresh_token, username, password, proxy_config)

        self.set_api_endpoint("pgorelease.nianticlabs.com/plfe")

        self._position_lat = position_lat
        self._position_lng = position_lng
        self._position_alt = position_alt

        self._signature_lib = None
        self._hash_lib = None

        self._session = requests.session()
        self._session.headers.update({'User-Agent': 'Niantic App'})
        self._session.verify = True

        if proxy_config is not None:
            self._session.proxies = proxy_config

        self.device_info = device_info

    def set_logger(self, logger=None):
        self.log = logger or logging.getLogger(__name__)

    def set_authentication(self, provider=None, oauth2_refresh_token=None, username=None, password=None, proxy_config=None):
        if provider == 'ptc':
            self._auth_provider = AuthPtc()
        elif provider == 'google':
            self._auth_provider = AuthGoogle()
        elif provider is None:
            self._auth_provider = None
        else:
            raise AuthException("Invalid authentication provider - only ptc/google available.")

        self.log.debug('Auth provider: %s', provider)

        if proxy_config is not None:
            self._auth_provider.set_proxy(proxy_config)

        if oauth2_refresh_token is not None:
            self._auth_provider.set_refresh_token(oauth2_refresh_token)
        elif username is not None and password is not None:
            if not self._auth_provider.user_login(username, password):
                raise AuthException("User login failed!")
        else:
            raise AuthException("Invalid Credential Input - Please provide username/password or an oauth2 refresh token")

    def get_position(self):
        return (self._position_lat, self._position_lng, self._position_alt)

    def set_position(self, lat, lng, alt=None):
        self.log.debug('Set Position - Lat: %s Long: %s Alt: %s', lat, lng, alt)

        self._position_lat = lat
        self._position_lng = lng
        self._position_alt = alt

    def set_proxy(self, proxy_config):
        self._session.proxies = proxy_config

    def get_api_endpoint(self):
        return self._api_endpoint

    def set_api_endpoint(self, api_url):
        if api_url.startswith("https"):
            self._api_endpoint = api_url
        else:
            self._api_endpoint = parse_api_endpoint(api_url)

    def get_auth_provider(self):
        return self._auth_provider

    def create_request(self):
        request = PGoApiRequest(self, self._position_lat, self._position_lng,
                                self._position_alt, self.device_info)
        return request

    def activate_signature(self, signature_lib_path=None, hash_lib_path=None):
        if signature_lib_path: self.set_signature_lib(signature_lib_path)
        if hash_lib_path: self.set_hash_lib(hash_lib_path)

    def set_signature_lib(self, signature_lib_path):
        self._signature_lib = signature_lib_path

    def set_hash_lib(self, hash_lib_path):
        self._hash_lib = hash_lib_path

    def get_signature_lib(self):
        return self._signature_lib

    def get_hash_lib(self):
        return self._hash_lib

    def __getattr__(self, func):
        def function(**kwargs):
            request = self.create_request()
            getattr(request, func)(_call_direct=True, **kwargs )
            return request.call()

        if func.upper() in RequestType.keys():
            return function
        else:
            raise AttributeError

    def app_simulation_login(self):
        self.log.info('Starting RPC login sequence (iOS app simulation)')

        # Send empty initial request
        request = self.create_request()
        response = request.call()
        time.sleep(1.172)

        request = self.create_request()
        response = request.call()
        time.sleep(1.304)
        

        # Send GET_PLAYER only
        request = self.create_request()
        request.get_player(player_locale = {'country': 'US', 'language': 'en', 'timezone': 'America/Denver'})
        response = request.call()
        
        if response.get('responses', {}).get('GET_PLAYER', {}).get('banned', False):
            raise BannedAccount()

        time.sleep(1.356)

        request = self.create_request()
        request.download_remote_config_version(platform=1, app_version=4500)
        request.check_challenge()
        request.get_hatched_eggs()
        request.get_inventory()
        request.check_awarded_badges()
        request.download_settings()
        response = request.call()
        time.sleep(1.072)

        responses = response.get('responses', {})
        download_hash = responses.get('DOWNLOAD_SETTINGS', {}).get('hash')
        inventory = responses.get('GET_INVENTORY', {}).get('inventory_delta', {})
        timestamp = inventory.get('new_timestamp_ms')
        player_level = None
        for item in inventory.get('inventory_items', []):
            player_stats = item.get('inventory_item_data', {}).get('player_stats', {})
            if player_stats:
                player_level = player_stats.get('level')
                break

        request = self.create_request()
        request.get_asset_digest(platform=1, app_version=4500)
        request.check_challenge()
        request.get_hatched_eggs()
        request.get_inventory(last_timestamp_ms=timestamp)
        request.check_awarded_badges()
        request.download_settings(hash=download_hash)
        response = request.call()
        time.sleep(1.709)

        timestamp = response.get('responses', {}).get('GET_INVENTORY', {}).get('inventory_delta', {}).get('new_timestamp_ms')
        request = self.create_request()
        request.get_player_profile()
        request.check_challenge()
        request.get_hatched_eggs()
        request.get_inventory(last_timestamp_ms=timestamp)
        request.check_awarded_badges()
        request.download_settings(hash=download_hash)
        request.get_buddy_walked()
        response = request.call()
        time.sleep(1.326)

        timestamp = response.get('responses', {}).get('GET_INVENTORY', {}).get('inventory_delta', {}).get('new_timestamp_ms')
        request = self.create_request()
        request.level_up_rewards(level=player_level)
        request.check_challenge()
        request.get_hatched_eggs()
        request.get_inventory(last_timestamp_ms=timestamp)
        request.check_awarded_badges()
        request.download_settings(hash=download_hash)
        request.get_buddy_walked()
        response = request.call()

        self.log.info('Finished RPC login sequence (iOS app simulation)')

        return response

    """
    The login function is not needed anymore but still in the code for backward compatibility"
    """
    def login(self, provider, username, password, lat=None, lng=None, alt=None, app_simulation=True):

        if lat and lng:
            self._position_lat = lat
            self._position_lng = lng
        if alt:
            self._position_alt = alt

        try:
            self.set_authentication(provider, username=username, password=password, proxy_config=self._session.proxies)
        except AuthException as e:
            self.log.error('Login process failed: %s', e)
            return False

        if app_simulation:
            response = self.app_simulation_login()
        else:
            self.log.info('Starting minimal RPC login sequence')
            response = self.get_player()
            self.log.info('Finished minimal RPC login sequence')

        if not response:
            self.log.info('Login failed!')
            return False

        challenge_url = response.get('responses', {}).get('CHECK_CHALLENGE', {}).get('challenge_url', ' ')
        if challenge_url != ' ':
            self.log.error('CAPCHA required: ' + challenge_url)
            return challenge_url

        self.log.info('Login process completed')

        return True
コード例 #4
0
ファイル: pgoapi.py プロジェクト: ohc192/pgoapi
class PGoApi:

    def __init__(self, provider=None, oauth2_refresh_token=None, username=None, password=None, position_lat=None, position_lng=None, position_alt=None, proxy_config=None,interface_bind=None):
        self.set_logger()
        self.log.info('%s v%s - %s', __title__, __version__, __copyright__)
        self._auth_provider = None
        if provider is not None and ((username is not None and password is not None) or (oauth2_refresh_token is not None)):
            self.set_authentication(provider, oauth2_refresh_token, username, password, proxy_config)

        self.set_api_endpoint("pgorelease.nianticlabs.com/plfe")

        self._position_lat = position_lat
        self._position_lng = position_lng
        self._position_alt = position_alt
        self._interface_bind = interface_bind

        self._signature_lib = None

        self._session = requests.session()
        if self._interface_bind is not None:
            print('inside pgoapi init,ip is set.. using %s for IP' % self._interface_bind)    
            self._session.mount('http://', source.SourceAddressAdapter(self._interface_bind))
            self._session.mount('https://', source.SourceAddressAdapter(self._interface_bind))
        self._session.headers.update({'User-Agent': 'Niantic App'})
        self._session.verify = True
      

        if proxy_config is not None:
            self._session.proxies = proxy_config

    def set_logger(self, logger=None):
        self.log = logger or logging.getLogger(__name__)

    def set_authentication(self, provider=None, oauth2_refresh_token=None, username=None, password=None, proxy_config=None):
        if provider == 'ptc':
            self._auth_provider = AuthPtc()
        elif provider == 'google':
            self._auth_provider = AuthGoogle()
        elif provider is None:
            self._auth_provider = None
        else:
            raise AuthException("Invalid authentication provider - only ptc/google available.")

        self.log.debug('Auth provider: %s', provider)

        if proxy_config is not None:
            self._auth_provider.set_proxy(proxy_config)

        if oauth2_refresh_token is not None:
            self._auth_provider.set_refresh_token(oauth2_refresh_token)
        elif username is not None and password is not None:
            if not self._auth_provider.user_login(username, password):
                raise AuthException("User login failed!")
        else:
            raise AuthException("Invalid Credential Input - Please provide username/password or an oauth2 refresh token")

    def get_position(self):
        return (self._position_lat, self._position_lng, self._position_alt)

    def set_position(self, lat, lng, alt):
        self.log.debug('Set Position - Lat: %s Long: %s Alt: %s', lat, lng, alt)

        self._position_lat = lat
        self._position_lng = lng
        self._position_alt = alt

    def set_proxy(self, proxy_config):
        self._session.proxies = proxy_config

    def get_api_endpoint(self):
        return self._api_endpoint


    def set_srcinterface(self,iface):
        self.log.info('Set interface ip inside pgoapi: %s', iface)        
        self._interface_bind = iface
        
    def get_srcinterface(self):
        return (self._interface_bind)
        
    def set_api_endpoint(self, api_url):
        self.log.info('Set api endpoint: %s', api_url)                        
        if api_url.startswith("https"):
            self._api_endpoint = api_url
        else:
            self._api_endpoint = parse_api_endpoint(api_url)

    def get_auth_provider(self):
        return self._auth_provider

    def create_request(self):
        request = PGoApiRequest(self, self._position_lat, self._position_lng,
                                self._position_alt)
        return request

    def activate_signature(self, lib_path):
        self._signature_lib = lib_path

    def get_signature_lib(self):
        return self._signature_lib

    def __getattr__(self, func):
        def function(**kwargs):
            request = self.create_request()
            getattr(request, func)(_call_direct=True, **kwargs )
            return request.call()

        if func.upper() in RequestType.keys():
            return function
        else:
            raise AttributeError

    def app_simulation_login(self):
        self.log.info('Starting RPC login sequence (app simulation)')

        # making a standard call, like it is also done by the client
        request = self.create_request()

        request.get_player()
        request.get_hatched_eggs()
        request.get_inventory()
        request.check_awarded_badges()
        request.download_settings(hash="54b359c97e46900f87211ef6e6dd0b7f2a3ea1f5")

        response = request.call()

        self.log.info('Finished RPC login sequence (app simulation)')

        return response

    """
    The login function is not needed anymore but still in the code for backward compatibility"
    """
    def login(self, provider, username, password, lat=None, lng=None, alt=None, app_simulation=True):

        if lat is not None and lng is not None and alt is not None:
            self._position_lat = lat
            self._position_lng = lng
            self._position_alt = alt

        try:
            self.set_authentication(provider, username=username, password=password)
        except AuthException as e:
            self.log.error('Login process failed: %s', e)
            return False

        if app_simulation:
            response = self.app_simulation_login()
        else:
            self.log.info('Starting minimal RPC login sequence')
            response = self.get_player()
            self.log.info('Finished minimal RPC login sequence')

        if not response:
            self.log.info('Login failed!')
            return False

        self.log.info('Login process completed')

        return True
コード例 #5
0
ファイル: pgoapi.py プロジェクト: Devilkk/pgoapi
class PGoApi:

    def __init__(self, provider=None, oauth2_refresh_token=None, username=None, password=None, position_lat=None, position_lng=None, position_alt=None, proxy_config=None, device_info=None):
        self.set_logger()
        self.log.info('%s v%s - %s', __title__, __version__, __copyright__)

        self._auth_provider = None
        if provider is not None and ((username is not None and password is not None) or (oauth2_refresh_token is not None)):
            self.set_authentication(provider, oauth2_refresh_token, username, password, proxy_config)

        self.set_api_endpoint("pgorelease.nianticlabs.com/plfe")

        self._position_lat = position_lat
        self._position_lng = position_lng
        self._position_alt = position_alt

        self._hash_server_token = None

        self._session = requests.session()
        self._session.headers.update({'User-Agent': 'Niantic App'})
        self._session.verify = True

        if proxy_config is not None:
            self._session.proxies = proxy_config

        self.device_info = device_info

    def set_logger(self, logger=None):
        self.log = logger or logging.getLogger(__name__)

    @staticmethod
    def get_api_version():
        return 9100

    def set_authentication(self, provider=None, oauth2_refresh_token=None, username=None, password=None, proxy_config=None, user_agent=None, timeout=None):
        if provider == 'ptc':
            self._auth_provider = AuthPtc(user_agent=user_agent, timeout=timeout)
        elif provider == 'google':
            self._auth_provider = AuthGoogle()
        elif provider is None:
            self._auth_provider = None
        else:
            raise InvalidCredentialsException("Invalid authentication provider - only ptc/google available.")

        self.log.debug('Auth provider: {}'.format(provider))

        if proxy_config:
            self._auth_provider.set_proxy(proxy_config)

        if oauth2_refresh_token is not None:
            self._auth_provider.set_refresh_token(oauth2_refresh_token)
        elif username and password:
            if not self._auth_provider.user_login(username, password):
                raise AuthException("User login failed!")
        else:
            raise InvalidCredentialsException("Invalid Credential Input - Please provide username/password or an oauth2 refresh token")

    def get_position(self):
        return (self._position_lat, self._position_lng, self._position_alt)

    def set_position(self, lat, lng, alt=None):
        self.log.debug('Set Position - Lat: %s Long: %s Alt: %s', lat, lng, alt)

        self._position_lat = lat
        self._position_lng = lng
        self._position_alt = alt

    def set_proxy(self, proxy_config):
        self._session.proxies = proxy_config

    def get_api_endpoint(self):
        return self._api_endpoint

    def set_api_endpoint(self, api_url):
        if api_url.startswith("https"):
            self._api_endpoint = api_url
        else:
            self._api_endpoint = parse_api_endpoint(api_url)

    def get_auth_provider(self):
        return self._auth_provider

    def create_request(self):
        request = PGoApiRequest(self, self._position_lat, self._position_lng,
                                self._position_alt, self.device_info)
        return request

    def activate_hash_server(self, hash_server_token):
        self._hash_server_token = hash_server_token

    def get_hash_server_token(self):
        return self._hash_server_token

    def __getattr__(self, func):
        def function(**kwargs):
            request = self.create_request()
            getattr(request, func)(_call_direct=True, **kwargs )
            return request.call()

        if func.upper() in RequestType.keys():
            return function
        else:
            raise AttributeError

    def app_simulation_login(self):
        self.log.info('Starting RPC login sequence (iOS app simulation)')

        # Send empty initial request
        request = self.create_request()
        response = request.call()
        
        time.sleep(1.5)
        
        # Send GET_PLAYER only
        request = self.create_request()
        request.get_player(player_locale = {'country': 'US', 'language': 'en', 'timezone': 'America/Chicago'})
        response = request.call()

        if response.get('responses', {}).get('GET_PLAYER', {}).get('banned', False):
            raise BannedAccountException

        time.sleep(1.5)

        request = self.create_request()
        request.download_remote_config_version(platform=1, app_version=self.get_api_version())
        request.check_challenge()
        request.get_hatched_eggs()
        request.get_inventory()
        request.check_awarded_badges()
        request.download_settings()
        response = request.call()

        self.log.info('Finished RPC login sequence (iOS app simulation)')

        return response

    """
    The login function is not needed anymore but still in the code for backward compatibility"
    """
    def login(self, provider, username, password, lat=None, lng=None, alt=None, app_simulation=True):

        if lat and lng:
            self._position_lat = lat
            self._position_lng = lng
        if alt:
            self._position_alt = alt

        try:
            self.set_authentication(provider, username=username, password=password)
        except AuthException as e:
            self.log.error('Login process failed: %s', e)
            return False

        if app_simulation:
            response = self.app_simulation_login()
        else:
            self.log.info('Starting minimal RPC login sequence')
            response = self.get_player()
            self.log.info('Finished minimal RPC login sequence')

        if not response:
            self.log.info('Login failed!')
            return False

        self.log.info('Login process completed')

        return True