async def get_map_details( self, map, game_mode, server_name, server_comment, is_private, max_players, max_specs, players, server_login ): """ Get records for specific map instance. :param map: Map instance. :param game_mode: Game mode, either 'Rounds' or 'TA'. :param server_name: Name of server :param server_comment: Comment :param is_private: Is server hidden from lists? :param max_players: Maximum number of players. :param max_specs: Maximum of spectators. :param players: List with players, raw from gbx command!!!!! :type map: pyplanet.apps.core.maniaplanet.models.map.Map :return: Record list. """ if not self.session_id: await self.authenticate() if not self.session_id: raise DedimaniaTransportException('Dedimania not authenticated!') def is_spectator(player): return bool(player['SpectatorStatus'] % 10) player_list = [ {'Login': p['Login'], 'IsSpec': is_spectator(p)} for p in players if p['Login'] != server_login ] num_specs = sum(p['IsSpec'] for p in player_list) num_players = len(player_list) - num_specs mode = self.mode_to_dedi_mode(game_mode) if not mode: raise DedimaniaNotSupportedException('Mode is not supported!') result = await self.multicall( ('dedimania.GetChallengeRecords', self.session_id, { 'UId': map.uid, 'Name': map.name, 'Environment': map.environment, 'Author': map.author_login, 'NbCheckpoints': map.num_checkpoints, 'NbLaps': map.num_laps, }, mode, { 'SrvName': server_name, 'Comment': server_comment, 'Private': is_private, 'NumPlayers': num_players, 'MaxPlayers': max_players, 'NumSpecs': num_specs, 'MaxSpecs': max_specs }, player_list) ) if not result or not isinstance(result, list): raise DedimaniaTransportException('Result seems to be empty!') result = result[0][0] if not result: raise DedimaniaTransportException('Result seems to be empty!') allowed_modes = result['AllowedGameModes'] server_max_rank = result['ServerMaxRank'] response_players = result['Players'] raw_records = result['Records'] records = [ DedimaniaRecord(r['Login'], r['NickName'], r['Best'], r['Rank'], r['MaxRank'], r['Checks'], r['Vote']) for r in raw_records ] return server_max_rank, allowed_modes, response_players, records or []
async def set_map_times(self, map, game_mode, records, v_replay=None, v_replay_checks=None, ghost_replay=None): mode = self.mode_to_dedi_mode(game_mode) if not mode: raise DedimaniaNotSupportedException('Mode is not supported!') if not self.session_id: raise DedimaniaTransportException('Dedimania not authenticated!') times = [{ 'Login': r.login, 'Best': r.score, 'Checks': ','.join([str(c) for c in r.cps]), } for r in records if r.updated] replays = { 'VReplay': v_replay or None, 'VReplayChecks': v_replay_checks or '', 'Top1GReplay': ghost_replay or '' } if not replays['VReplay']: # Nothing to update! logger.debug('Dedimania end map, nothing new to update! Skipping set times call!') return result = await self.multicall( ('dedimania.SetChallengeTimes', self.session_id, { 'UId': map.uid, 'Name': map.name, 'Environment': map.environment, 'Author': map.author_login, 'NbCheckpoints': map.num_checkpoints, 'NbLaps': map.num_laps, }, mode, times, replays) ) try: return bool(isinstance(result[0][0]['Records'], list)) except Exception as e: logger.error('Sending times to dedimania failed. Info: {}'.format(result)) return False
async def execute(self, method, *args): payload = dumps(args, methodname=method, allow_none=True) body = gzip.compress(payload.encode('utf8')) try: res = await self.loop.run_in_executor(None, self.__request, body) data, _ = loads(res.text, use_datetime=True) if isinstance(data, (tuple, list)) and len(data) > 0 and len(data[0]) > 0: if isinstance(data[0][0], dict) and 'faultCode' in data[0][0]: raise DedimaniaFault(faultCode=data[0][0]['faultCode'], faultString=data[0][0]['faultString']) self.retries = 0 return data[0] raise DedimaniaTransportException('Invalid response from dedimania!') except (ConnectionError, ReadTimeout, ConnectionRefusedError, requests.exceptions.ConnectionError) as e: raise DedimaniaTransportException(e) from e except ConnectTimeout as e: raise DedimaniaTransportException(e) from e except DedimaniaTransportException: # Try to setup new session. self.retries += 1 if self.retries > 5: raise DedimaniaTransportException('Dedimania didn\'t gave the right answer after few retries!') self.client = requests.session() try: await self.authenticate() return await self.execute(method, *args) except Exception as e: logger.error('XML-RPC Fault retrieved from Dedimania: {}'.format(str(e))) handle_exception(e, __name__, 'execute') raise DedimaniaTransportException('Could not retrieve data from dedimania!') except DedimaniaFault as e: if 'Bad SessionId' in e.faultString or ('SessionId' in e.faultString and 'not found' in e.faultString): try: self.retries += 1 if self.retries > 5: raise DedimaniaTransportException('Max retries reached for reauthenticating with dedimania!') # Save original session ID. original_session_id = '{}'.format(self.session_id) # Reauthenticate await self.authenticate() # Replace session_id in args. if len(args) > 0 and len(args[0]) > 0 and isinstance(args[0][0], dict) and 'params' in args[0][0]: new_params = list(args[0][0]['params']) if (new_params and isinstance(new_params[0], str) and new_params[0] == original_session_id): new_params[0] = self.session_id args[0][0]['params'] = tuple(new_params) # Try again. return await self.execute(method, *args) except: return logger.error('XML-RPC Fault retrieved from Dedimania: {}'.format(str(e))) handle_exception(e, __name__, 'execute', extra_data={ 'dedimania_retries': self.retries, }) raise DedimaniaTransportException('Could not retrieve data from dedimania!')
async def execute(self, method, *args): payload = dumps(args, methodname=method, allow_none=True) body = gzip.compress(payload.encode('utf8')) try: res = await self.loop.run_in_executor(None, self.__request, body) data, _ = loads(res.text, use_datetime=True) if isinstance( data, (tuple, list)) and len(data) > 0 and len(data[0]) > 0: if isinstance(data[0][0], dict) and 'faultCode' in data[0][0]: raise DedimaniaFault(faultCode=data[0][0]['faultCode'], faultString=data[0][0]['faultString']) self.retries = 0 return data[0] raise DedimaniaTransportException( 'Invalid response from dedimania!') except (ConnectionError, ReadTimeout) as e: raise DedimaniaTransportException(e) from e except ConnectTimeout as e: raise DedimaniaTransportException(e) from e except DedimaniaTransportException: # Try to setup new session. self.retries += 1 if self.retries > 5: raise DedimaniaTransportException( 'Dedimania didn\'t gave the right answer after few retries!' ) self.client = requests.session() try: await self.authenticate() return await self.execute(method, *args) except Exception as e: logger.error( 'XML-RPC Fault retrieved from Dedimania: {}'.format( str(e))) handle_exception(e, __name__, 'execute') raise DedimaniaTransportException( 'Could not retrieve data from dedimania!') except DedimaniaFault as e: if 'Bad SessionId' in e.faultString: try: self.retries += 1 if self.retries > 5: raise DedimaniaTransportException( 'Max retries reached for reauthenticating with dedimania!' ) await self.authenticate() return await self.execute(method, *args) except: return logger.error('XML-RPC Fault retrieved from Dedimania: {}'.format( str(e))) handle_exception(e, __name__, 'execute') raise DedimaniaTransportException( 'Could not retrieve data from dedimania!')