示例#1
0
	def connectToServer(self, hostname, port, username, password, arena='#master'):
		"""Connect to a server using the Subspace protocol.
		
		hostname and port specify the hostname/IP address and port of the server to connect to.  username is
		the user to connect as.  password is the combined password and SMod+ password
		seperated by an asterisk.  For example, 'bot_password*smod_password'. Arena
		is the name of the arena to join upon entering the zone."""
		CoreStack.connectToServer(self, hostname, port)
		self._queueSyncRequest()
		self.flushOutboundQueues()
		self.__queueLoginPacket(username, password)
		self.flushOutboundQueues()
		self.arena = arena
		self.__connected = True
		self.__last_pos_update_sent_tick = GetTickCountHs()
示例#2
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))
示例#3
0
	def __init__(self, owners_list=None, description=None, debug=False):
		"""Initialize the CoreStack class. If debug is set debugging messages will be displayed."""
		CoreStack.__init__(self, debug)
		self.__debug = debug
		self.__players_by_pid = {} # pid : Player
		self.__players_by_name = {} # name: Player
		
		self.__event_list = []
		
		# make the argument into a list if it isnt, xxx, maybe there is a cleaner way to do this
		if type(owners_list) == type(''):
			owners_list = [owners_list]
		self.__owners_list = owners_list
		
		# generate a valid mid
		hash_string = os.name + sys.platform + socket.getfqdn()
		self.machine_id, self.permission_id = struct.unpack_from('II', hashlib.md5(hash_string).digest())
		self.machine_id = self.__makeValidMachineID(self.machine_id)
		
		self.players_here = []
		self.__players_by_name = {}
		self.__players_by_pid = {}
			
		self.__last_event_generated = None
		
		self.pid = None
		self.name = None
		
		self.__cmd_about_description = description
		
		self.arena = None
		
		self.__command_dict = {}
		
		# the ships position data
		self.ship = None
		self.x_pos = 512 * 16
		self.y_pos = 512 * 16
		self.x_vel = 0
		self.y_vel = 0
		self.status = 0
		self.bounty = 0
		self.energy = 0
		self.rotation = 0
			
		self.__timer_list = [] # Timer()
		self.__next_timer_id = 0
		self.__last_timer_expire_tick = GetTickCountHs()
		
		self.__command_die_id = self.registerCommand('!die', 'Stop the bot', owners_list)
		self.__command_help_id = self.registerCommand('!help', 'Show help', None)
		if description:
			self.__command_about_id = self.registerCommand('!about', 'Show information about the bot', None)
		
		#: Event preprocessors can return a new event to pass on to the bot, or None if no event should be generated
		self.__event_preprocessors = {
			EVENT_ENTER : self.__eventEnterPreprocessor,
			EVENT_LEAVE : self.__eventLeavePreprocessor,
			EVENT_TICK :  self.__eventTickPreprocessor,
			EVENT_CHANGE: self.__eventChangePreprocessor,
			EVENT_DISCONNECT : self.__eventDisconnectPreprocessor,
			EVENT_COMMAND : self.__eventCommandPreprocessor,
			EVENT_ARENA_LIST : self.__eventArenaListPreprocessor,
		}
			
		# event post processors
		self.__event_postprocessors = {
			# empty for now
		}
		
		# setup the appropriate handlers
		self.__packet_handlers = {
			0x03 : self.__handlePlayerEnteredPacket,
			0x04 : self.__handlePlayerLeftPacket,
			0x05 : self.__handleLargePositionUpdatePacket,
			0x06 : self.__handleKillPacket,
			0x07 : self.__handleMessagePacket,
			0x0A : self.__handleLoginResponsePacket,
			0x0B : self.__handleGoalPacket,
			0x0D : self.__handleFreqchangePacket,
			0x1C : self.__handleShipChangePacketSelf,
			0x1D : self.__handleShipchangePacket,
			0x27 : self.__handlePositionUpdateRequest,
			0x28 : self.__handleSmallPositionUpdatePacket,
			0x2F : self.__handleArenaListPacket,
			0x31 : self.__handleLoginPacket,
		}