Example #1
0
	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 []
Example #2
0
	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
Example #3
0
	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!')
Example #4
0
 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!')