def request(self, endpoint, subrequests, player_position): if not self._auth_provider or self._auth_provider.is_login() is False: raise NotLoggedInException() request_proto = self._build_main_request(subrequests, player_position) response = self._make_rpc(endpoint, request_proto) response_dict = self._parse_main_response(response, subrequests) self.check_authentication(response_dict) # some response validations if isinstance(response_dict, dict): status_code = response_dict.get('status_code', None) if status_code == 102: raise AuthTokenExpiredException() elif status_code == 52: raise ServerSideRequestThrottlingException("Request throttled by server... slow down man") elif status_code == 53: api_url = response_dict.get('api_url', None) if api_url is not None: exception = ServerApiEndpointRedirectException() exception.set_redirected_endpoint(api_url) raise exception else: raise UnexpectedResponseException() return response_dict
def _parse_main_response(self, response_raw, subrequests): self.log.debug('Parsing main RPC response...') if response_raw.status_code == 403: raise ServerSideAccessForbiddenException("Seems your IP Address is banned or something else went badly wrong...") elif response_raw.status_code == 502: raise ServerBusyOrOfflineException("502: Bad Gateway") elif response_raw.status_code != 200: error = 'Unexpected HTTP server response - needs 200 got {}'.format(response_raw.status_code) self.log.warning(error) self.log.debug('HTTP output: \n%s', response_raw.content.decode('utf-8')) raise UnexpectedResponseException(error) if response_raw.content is None: self.log.warning('Empty server response!') return False response_proto = ResponseEnvelope() try: response_proto.ParseFromString(response_raw.content) except message.DecodeError as e: self.log.warning('Could not parse response: %s', e) return False self.log.debug('Protobuf structure of rpc response:\n\r%s', response_proto) try: self.log.debug('Decode raw over protoc (protoc has to be in your PATH):\n\r%s', self.decode_raw(response_raw.content).decode('utf-8')) except: self.log.debug('Error during protoc parsing - ignored.') response_proto_dict = protobuf_to_dict(response_proto) response_proto_dict = self._parse_sub_responses(response_proto, subrequests, response_proto_dict) return response_proto_dict
def _parse_main_response(self, response_raw, subrequests, use_dict=True): self.log.debug('Parsing main RPC response...') if response_raw.status_code == 400: raise BadRequestException("400: Bad Request") if response_raw.status_code == 403: raise NianticIPBannedException( "Seems your IP Address is banned or something else went badly wrong..." ) elif response_raw.status_code in (502, 503, 504): raise NianticOfflineException('{} Server Error'.format( response_raw.status_code)) elif response_raw.status_code != 200: error = 'Unexpected HTTP server response - needs 200 got {}'.format( response_raw.status_code) self.log.warning(error) self.log.debug('HTTP output: \n%s', response_raw.content.decode('utf-8')) raise UnexpectedResponseException(error) if not response_raw.content: self.log.warning('Empty server response!') raise MalformedNianticResponseException('Empty server response!') response_proto = ResponseEnvelope() try: response_proto.ParseFromString(response_raw.content) except message.DecodeError as e: self.log.error('Could not parse response: %s', e) raise MalformedNianticResponseException( 'Could not decode response.') self.log.debug('Protobuf structure of rpc response:\n\r%s', response_proto) try: self.log.debug( 'Decode raw over protoc (protoc has to be in your PATH):\n\r%s', self.decode_raw(response_raw.content).decode('utf-8')) except Exception: self.log.debug('Error during protoc parsing - ignored.') if use_dict: response_proto_dict = protobuf_to_dict(response_proto) if 'returns' in response_proto_dict: del response_proto_dict['returns'] else: response_proto_dict = {'envelope': response_proto} if not response_proto_dict: raise MalformedNianticResponseException( 'Could not convert protobuf to dict.') response_proto_dict = self._parse_sub_responses( response_proto, subrequests, response_proto_dict, use_dict) #It can't be done before if not use_dict: del response_proto_dict['envelope'].returns[:] return response_proto_dict