Exemplo n.º 1
0
	def waitForEvent(self):
		"""Wait for an event.
		
		A GameEvent class instance is returned, and its type can be found in GameEvent.type.
		The type will be one of EVENT_Xxx.  If the bot is disconnected None will be returned."""
		
		#give the core the chance to post process the last event generated
		if self.__last_event_generated is not None:
			postprocessor = self.__event_postprocessors.get(self.__last_event_generated.type, None)
			if postprocessor:
				postprocessor(self.__last_event_generated)
			self.__last_event_generated = None
			
		if self.__connected is False:
			return None
		
		#xxx make sure large event lists dont starve the core, and i/o should probably be done between events...
		while True:
			if len(self.__event_list) > 0:
				# give the core the chance to preprocess events, this is needed
				# because if the changes were made immediately when the event was received (as opposed to when the packet is removed from queue for processing)
				# the core's view of the game state might be incorrect
				event =  self.__event_list.pop(0)
				preprocessor = self.__event_preprocessors.get(event.type, None)
				if preprocessor:
					event = preprocessor(event)
				if event is None: continue
				self.__last_event_generated = event
				return event
				
			# there are no more bot-level events to process, so call the core's
			# own wait for event handler
			event = CoreStack.waitForEvent(self)
			if event.type == SubspaceCoreStack.EVENT_GAME_PACKET_RECEIVED:
				try:
					game_type, = struct.unpack_from("<B", event.packet)
					handler = self.__packet_handlers.get(game_type, None)
					if handler:
						handler(event.packet)
						
				except (IndexError, struct.error):
					if game_type:
						print 'Structure error in SubspaceBot packet handler: %02X' % game_type
						print event.packet.encode('hex')
						
			# map core stack events to game stack events
			elif event.type == SubspaceCoreStack.EVENT_TICK:
				self.__addPendingEvent(GameEvent(EVENT_TICK))
			elif event.type == SubspaceCoreStack.EVENT_DISCONNECT:
				self.__addPendingEvent(GameEvent(EVENT_DISCONNECT))