示例#1
0
文件: TestTCP.py 项目: czorn/Modifire
class Client():
    
    def __init__(self):
        self.cManager = QueuedConnectionManager()
        self.tcpWriter = ConnectionWriter(self.cManager,0)
        self.tcpReader = QueuedConnectionReader(self.cManager, 0)
        taskMgr.add(self.tskReaderPolling,"Poll the connection reader",-40)
        
        # This fails
        self.conn = self.cManager.openTCPClientConnection(IP_ADDR, PORT, 1000)
        if self.conn:
            print 'Successful connection to', IP_ADDR, ':', PORT
            self.tcpReader.addConnection(self.conn)
            
            self.SendPacket()
            
    def SendPacket(self):
        dg = PyDatagram()
        dg.addUint8(5)
        self.tcpWriter.send(dg, self.conn)
            
    def tskReaderPolling(self, task):
        if self.tcpReader.dataAvailable():
            datagram = NetDatagram()
            if self.tcpReader.getData(datagram):
                print 'client got data'
        return task.cont
class Client(DirectObject):
    def __init__(self):
        self.cManager = QueuedConnectionManager()
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager,0)
        self.connection = None #Connection with the server
        
    def connectToServer(self, ip_address="192.168.1.110", port_address=9099):
        #How long to wait until we give up connecting
        timeout = 3000 # 3 seconds
        self.connection = self.cManager.openTCPClientConnection(ip_address,port_address,timeout)
        if self.connection:
            self.cReader.addConnection(self.connection) #Retrieve message from Server
            return True #We connected
        return False #We couldn't succeed
    
    def processMsgData(self, dataGram):
        iterator = PyDatagramIterator(dataGram)
        msgID = iterator.getUint8()
        if msgID == PRINT_MESSAGE:
            msg = iterator.getString()
            print msg
    
    def recieveMessage(self):
        datagram = NetDatagram() #Needed to store the message or data recieved
        if self.cReader.getData(datagram):
            self.processMsgData(datagram)
            
    
    '''
    Closes the connection with the server
    '''
    def disconnectServer(self):
        self.cManager.closeConnection(self.connection)
示例#3
0
class Client(DirectObject): 
    def __init__( self ): 
        print "Initializing client test" 
        
        self.port = 9099
        self.ip_address = "142.157.150.72" 
        self.timeout = 3000             # 3 seconds to timeout 
        
        self.cManager = QueuedConnectionManager() 
        self.cListener = QueuedConnectionListener(self.cManager, 0) 
        self.cReader = QueuedConnectionReader(self.cManager, 0) 
        self.cWriter = ConnectionWriter(self.cManager,0) 
        
        self.Connection = self.cManager.openTCPClientConnection(self.ip_address, self.port, self.timeout) 
        if self.Connection: 
            taskMgr.add(self.tskReaderPolling,"read the connection listener",-40) 
            # this tells the client to listen for datagrams sent by the server 
            
            print "Connected to Server" 
            self.cReader.addConnection(self.Connection) 
            PRINT_MESSAGE = 1 
            myPyDatagram = PyDatagram() 
            myPyDatagram.addUint8(100) 
            # adds an unsigned integer to your datagram 
            myPyDatagram.addString("first string of text") 
            # adds a string to your datagram 
            myPyDatagram.addString("second string of text") 
            # adds a second string to your datagram 
            self.cWriter.send(myPyDatagram, self.Connection) 
            # fires it off to the server 
            
            #self.cManager.closeConnection(self.Connection) 
            #print "Disconnected from Server" 
            # uncomment the above 2 lines if you want the client to 
            # automatically disconnect.  Or you can just 
            # hit CTRL-C twice when it's running to kill it 
            # in windows, I don't know how to kill it in linux 
        else: 
            print "Not connected to Server" 
        
    def tskReaderPolling(self, task): 
        if self.cReader.dataAvailable(): 
            datagram=PyDatagram()  
            if self.cReader.getData(datagram): 
                self.processServerMessage(datagram) 
        return Task.cont        
    
    def processServerMessage(self, netDatagram): 
        myIterator = PyDatagramIterator(netDatagram) 
        print myIterator.getString() 
示例#4
0
文件: TestTCP.py 项目: czorn/Modifire
class Server():
    
    def __init__(self):
        self.cManager = QueuedConnectionManager()
        self.tcpSocket = self.cManager.openTCPServerRendezvous(PORT, 1000)
        self.tcpWriter = ConnectionWriter(self.cManager,0)
        self.tcpListener = QueuedConnectionListener(self.cManager, 0)
        self.tcpListener.addConnection(self.tcpSocket)
        self.tcpReader = QueuedConnectionReader(self.cManager, 0)
        
        taskMgr.add(self.tskListenerPolling,"Poll the connection listener",-39)
        taskMgr.add(self.tskReaderPolling,"Poll the connection reader",-40)
        
    def SendPacket(self):
        dg = PyDatagram()
        dg.addUint8(5)
        self.tcpWriter.send(dg, self.conn)
        
    def tskReaderPolling(self, task):
        if self.tcpReader.dataAvailable():
            datagram = NetDatagram()
            if self.tcpReader.getData(datagram):
                print 'server got data'
                self.SendPacket()
        return task.cont
    
    def tskListenerPolling(self, task):
        if self.tcpListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            newConnection = PointerToConnection()
        
            if self.tcpListener.getNewConnection(rendezvous, netAddress, newConnection):
                newConnection = newConnection.p()
                self.tcpReader.addConnection(newConnection)
                self.conn = newConnection
                print self.conn.getAddress().getPort()
        return task.cont
示例#5
0
class Client:
    def __init__(self, showbase, host, port, timeout=3000, compress=False):
        self.showbase = showbase
        self.host = host
        self.port = port
        self.timeout = timeout
        self.compress = compress

        self.cManager = QueuedConnectionManager()
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager, 0)

        # By default, we are not connected
        self.connected = False

        self.passedData = []

        self.connect(self.host, self.port, self.timeout)

        self.startPolling()

    def startPolling(self):
        self.showbase.taskMgr.add(self.tskDisconnectPolling,
                                  "clientDisconnectTask", -39)

    def connect(self, host, port, timeout=3000):
        # Connect to our host's socket
        self.myConnection = self.cManager.openTCPClientConnection(
            host, port, timeout)
        if self.myConnection:
            self.cReader.addConnection(
                self.myConnection)  # receive messages from server
            self.connected = True  # Let us know that we're connected

    def getConnected(self):
        # Check whether we are connected or not
        return self.connected

    def tskDisconnectPolling(self, task):
        while self.cManager.resetConnectionAvailable() == True:
            connPointer = PointerToConnection()
            self.cManager.getResetConnection(connPointer)
            connection = connPointer.p()

            # Remove the connection we just found to be "reset" or "disconnected"
            self.cReader.removeConnection(connection)

            # Let us know that we are not connected
            self.connected = False

        return Task.cont

    def processData(self, netDatagram):
        myIterator = PyDatagramIterator(netDatagram)
        return self.decode(myIterator.getString())

    def encode(self, data, compress=False):
        # encode(and possibly compress) the data with rencode
        return rencode.dumps(data, compress)

    def decode(self, data):
        # decode(and possibly decompress) the data with rencode
        return rencode.loads(data)

    def sendData(self, data):
        myPyDatagram = PyDatagram()
        myPyDatagram.addString(self.encode(data, self.compress))
        self.cWriter.send(myPyDatagram, self.myConnection)

    def passData(self, data):
        self.passedData.append(data)

    def getData(self):
        data = []
        for passed in self.passedData:
            data.append(passed)
            self.passedData.remove(passed)
        while self.cReader.dataAvailable():
            datagram = NetDatagram()
            if self.cReader.getData(datagram):
                data.append(self.processData(datagram))
        return data
示例#6
0
class LoginServer:
	def __init__(self, port, backlog=1000, compress=False):
		self.port = port
		self.backlog = backlog
		self.compress = compress

		self.cManager = QueuedConnectionManager()
		self.cListener = QueuedConnectionListener(self.cManager, 0)
		self.cReader = QueuedConnectionReader(self.cManager, 0)
		self.cWriter = ConnectionWriter(self.cManager,0)
		
		self.db = DataBase()
		# This is for pre-login
		self.tempConnections = []
		# This is for authed clients
		self.activeConnections = []
		
		# Temp user dict
		self.clients={}
		
		self.connect(self.port, self.backlog)
		self.startPolling()

	def connect(self, port, backlog=1000):
		# Bind to our socket
		tcpSocket = self.cManager.openTCPServerRendezvous(port, backlog)
		self.cListener.addConnection(tcpSocket)

	def startPolling(self):
		taskMgr.add(self.tskListenerPolling, "serverListenTask", -40)
		taskMgr.add(self.tskDisconnectPolling, "serverDisconnectTask", -39)

	def tskListenerPolling(self, task):
		if self.cListener.newConnectionAvailable():
			rendezvous = PointerToConnection()
			netAddress = NetAddress()
			newConnection = PointerToConnection()

			if self.cListener.getNewConnection(rendezvous, netAddress, newConnection):
				newConnection = newConnection.p()
				self.tempConnections.append(newConnection) # Lets add it to a temp list first.
				self.cReader.addConnection(newConnection)     # Begin reading connection
				
				# Make the temp place holder then add to temp, under dataget check the temp list, if something ther do
				# auth and then add to the active
		return Task.cont

	def tskDisconnectPolling(self, task):
		while self.cManager.resetConnectionAvailable() == True:
			print "disconnect"
			connPointer = PointerToConnection()
			self.cManager.getResetConnection(connPointer)
			connection = connPointer.p()
			
			# Remove the connection we just found to be "reset" or "disconnected"
			self.cReader.removeConnection(connection)
			# Remove the connection we just found to be "reset" or "disconnected"
			self.cReader.removeConnection(connection)
			for u in range(len(self.clients)):
				if self.clients[u]['connection']==connection:
					del self.clients[u]
					break
			
			# Loop through the activeConnections till we find the connection we just deleted
			# and remove it from our activeConnections list
			for c in range(0, len(self.activeConnections)):
				if self.activeConnections[c] == connection:
					del self.activeConnections[c]
					break
					
		return Task.cont

	def broadcastData(self, data):
		# Broadcast data out to all activeConnections
		for con in self.activeConnections:
			self.sendData(data, con)

	def processData(self, netDatagram):
		myIterator = PyDatagramIterator(netDatagram)
		return self.decode(myIterator.getString())

	def getClients(self):
		# return a list of all activeConnections
		return self.activeConnections

	def encode(self, data, compress=False):
		# encode(and possibly compress) the data with rencode
		return rencode.dumps(data, compress)

	def decode(self, data):
		# decode(and possibly decompress) the data with rencode
		return rencode.loads(data)

	def sendData(self, data, con):
		myPyDatagram = PyDatagram()
		myPyDatagram.addString(self.encode(data, self.compress))
		self.cWriter.send(myPyDatagram, con)
		
	# This will check and do the logins.
	def auth(self, datagram): 
		# If in login state.
		clientIp = datagram.getAddress() # This is the ip :P
		clientCon = datagram.getConnection() # This is the connection data. used to send the shit.
		package=self.processData(datagram)
		print "SERVER: ",package
		valid_packet=False
		if len(package)==2:
			# if login request is send reply
			# Should add a checker like in the db something like isLogged(0 or 1)
			# If found then say no for client
			user_found=False
			if package[0]=='login_request':
				valid_packet=True
				print "Try login"
				for u in range(len(self.clients)):
					if self.clients[u]['name']==package[1][0]:
						print "User already exists"
						user_found=True
						data = {}
						data[0] = "error"
						data[1] = "User already logged in"
						self.sendData(data,clientCon)
						break
						# send something back to the client saying to change username
				if not user_found:
					username=package[1][0]
					password=package[1][1]
					self.db.Client_getLogin(username, password)
					if self.db.login_valid:
						# Add the user
						new_user={}
						new_user['name']=package[1][0]
						new_user['connection']=clientCon
						new_user['ready']=False
						new_user['new_dest']=False
						new_user['new_spell']=False
						self.clients[len(self.clients)]=new_user
							# Send back the valid check.
						data={}
						data[0]='login_valid' # If client gets this the client should switch to main_menu.
						data[1]={}
						data[1][0]=self.db.status
						data[1][1]=len(self.clients)-1 # This is part of the old 'which' packet
						self.sendData(data, clientCon)
					
						# Move client to the self.activeConnections list.
						self.activeConnections.append(clientCon)
						print "HERE IS ACTIVE: ", self.activeConnections
						self.tempConnections.remove(clientCon)
						print "HERE IS TEMP", self.tempConnections
					
				else:
					status = self.db.status
					data={}
					data[0]='db_reply'
					data[1]=status
					self.sendData(data, clientCon)
			if not valid_packet:
				data = {}
				data[0] = "error"
				data[1] = "Wrong Packet"
				self.sendData(data, clientCon)
				print "Login Packet not correct"
				
		else:
			print "Data in packet wrong size"

	def getData(self):
		data = []
		while self.cReader.dataAvailable():
			datagram = NetDatagram()  # catch the incoming data in this instance
			# Check the return value; if we were threaded, someone else could have
			# snagged this data before we did
			if self.cReader.getData(datagram):
				
				if datagram.getConnection() in self.tempConnections:
					print "Check Auth!"
					self.auth(datagram)
					print "Auth Done!"
					# in auth def or after the connection will be moved to self.activeConnections
					# and then removed from the temp list
					break
				# Check if the data rechieved is from a valid client.
				elif datagram.getConnection() in self.activeConnections:
					appendage={}
					appendage[0]=self.processData(datagram)
					appendage[1]=datagram.getConnection()
					data.append(appendage)
					
				
		return data
示例#7
0
class Client:
    def __init__(self, host, port, timeout=3000, compress=False):
        self.host = host
        self.port = port
        self.timeout = timeout
        self.compress = compress

        self.cManager = QueuedConnectionManager()
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager, 0)

        # By default, we are not connected
        self.connected = False

        self.connect(self.host, self.port, self.timeout)
        self.startPolling()

    def connect(self, host, port, timeout=3000):
        # Connect to our host's socket
        self.myConnection = self.cManager.openTCPClientConnection(host, port, timeout)
        if self.myConnection:
            self.cReader.addConnection(self.myConnection)  # receive messages from server
            self.connected = True  # Let us know that we're connected

    def startPolling(self):
        taskMgr.add(self.tskDisconnectPolling, "clientDisconnectTask", -39)

    def tskDisconnectPolling(self, task):
        while self.cManager.resetConnectionAvailable() == True:
            connPointer = PointerToConnection()
            self.cManager.getResetConnection(connPointer)
            connection = connPointer.p()

            # Remove the connection we just found to be "reset" or "disconnected"
            self.cReader.removeConnection(connection)

            # Let us know that we are not connected
            self.connected = False

        return Task.cont

    def processData(self, netDatagram):
        myIterator = PyDatagramIterator(netDatagram)
        return self.decode(myIterator.getString())

    def getConnected(self):
        # Check whether we are connected or not
        return self.connected

    def encode(self, data, compress=False):
        # encode(and possibly compress) the data with rencode
        return rencode.dumps(data, compress)

    def decode(self, data):
        # decode(and possibly decompress) the data with rencode
        return rencode.loads(data)

    def sendData(self, data):
        myPyDatagram = PyDatagram()
        myPyDatagram.addString(self.encode(data, self.compress))
        self.cWriter.send(myPyDatagram, self.myConnection)

    def getData(self):
        data = []
        while self.cReader.dataAvailable():
            datagram = NetDatagram()  # catch the incoming data in this instance
            # Check the return value; if we were threaded, someone else could have
            # snagged this data before we did
            if self.cReader.getData(datagram):
                data.append(self.processData(datagram))
        return data
class SocketServer():

    def __init__(self, port, virtual_world, camera_mgr, sync_session):
        self.port = port
        self.virtual_world = virtual_world
        self.cam_mgr = camera_mgr
        
        self.task_mgr = virtual_world.taskMgr
        self.cManager = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cReader.setRawMode(True)
        self.cWriter = ConnectionWriter(self.cManager, 1)
        self.cWriter.setRawMode(True)
        self.tcpSocket = self.cManager.openTCPServerRendezvous(port, BACKLOG)
        self.cListener.addConnection(self.tcpSocket)
        
        self.activeSessions = {}
        self.connection_map = {}
        self.set_handlers()
        
        hostname = socket.gethostname()
        a, b, address_list = socket.gethostbyname_ex(hostname)
        self.ip = address_list[0]
        logging.info("Addresses %s" % address_list)
        logging.info("Server is running on ip: %s, port: %s" 
                     %(self.ip, self.port))
        
        self.client_counter = 0
        self.read_buffer = ''
        self.read_state = 0
        self.read_body_length = 0
        self.packet = SocketPacket()
        
        controller = virtual_world.getController()
        self.sync = Sync(self.task_mgr, controller, camera_mgr, sync_session)
        self.vv_id = None
        if sync_session:
            logging.info("Waiting for Sync Client!")
        
        self.showing_info = False
        virtual_world.accept("i", self.toggleInfo)
        self.sync_session = sync_session
        self.createInfoLabel()

        atexit.register(self.exit)


    def createInfoLabel(self):

        string = self.generateInfoString()
        self.info_label = OST(string, 
                              pos=(-1.3, -0.5), 
                              fg=(1,1,1,1), 
                              bg=(0,0,0,0.7),
                              scale=0.05, 
                              align=TextNode.ALeft)
        self.info_label.hide()
    
    def generateInfoString(self,):
        string = " IP:\t%s  \n" % self.ip
        string += " PORT:\t%s \n" % self.port
        if self.sync_session:
            string += " MODE:\tSync Client\n"
            string += " VV ID:\t%s\n" % self.vv_id
        else:
            string += " MODE:\tAutomatic\n"
          
        cameras = self.cam_mgr.getCameras()
        num_cameras = len(cameras)

        for camera in cameras:
            id = camera.getId()
            type = camera.getTypeString()
            string += " Cam%s:\t%s\n" %(id, type)
        string += "\n"
        return string
    
    
    def set_handlers(self):
        self.task_mgr.add(self.connection_polling, "Poll new connections", -39)
        self.task_mgr.add(self.reader_polling, "Poll reader", -40)
        self.task_mgr.add(self.disconnection_polling, "PollDisconnections", -41)


    def connection_polling(self, taskdata):
        if self.cListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            newConn = PointerToConnection()
            if self.cListener.getNewConnection(rendezvous,netAddress, newConn):
                conn = newConn.p()
                self.cReader.addConnection(conn)     # Begin reading connection
                conn_id = self.client_counter
                logging.info("New Connection from ip:%s, conn:%s"
                             % (conn.getAddress(), conn_id))
                self.connection_map[conn_id] = conn
                self.client_counter += 1
                message = eVV_ACK_OK(self.ip, self.port, conn_id)
                self.sendMessage(message, conn)

        return Task.cont


    def reader_polling(self, taskdata):

        if self.cReader.dataAvailable():
            datagram = NetDatagram()  # catch the incoming data in this instance
            # Check the return value; if we were threaded, someone else could have
            # snagged this data before we did
            if self.cReader.getData(datagram):
                self.read_buffer = self.read_buffer + datagram.getMessage()
        while (True):
            if self.read_state == 0:
                if len(self.read_buffer) >= self.packet.header_length:
                    bytes_consumed = self.packet.header_length
                    self.packet.header = self.read_buffer[:bytes_consumed]
                    self.read_body_length = self.packet.decode_header()
                    self.read_buffer = self.read_buffer[bytes_consumed:]
                    self.read_state = 1
                else:
                    break
            if self.read_state == 1:
                if len(self.read_buffer) >= self.read_body_length:
                    bytes_consumed = self.read_body_length
                    self.packet.data = self.read_buffer[:bytes_consumed]
                    self.packet.offset = 0        
                    self.read_body_length = 0
                    self.read_buffer = self.read_buffer[bytes_consumed:]
                    self.read_state = 0
                    self.new_data_callback(self.packet)

                else:
                    break
        return Task.cont


    def new_data_callback(self, packet):
        packet = copy.deepcopy(packet)
        message_type = packet.get_int()
        conn_id = packet.get_int()
        if message_type == VP_SESSION:
            conn = self.connection_map[conn_id]
            type = packet.get_char()
            pipeline = packet.get_char()
            req_cam_id = packet.get_int()
            logging.debug("Received VP_SESSION message from conn:%s, " \
                          "type=%s, pipeline=%s requested camera id=%d" 
                          %(conn_id, VP_TYPE[type], PIPELINE[pipeline], req_cam_id))
            self.newVPSession(conn, type, pipeline, conn_id, req_cam_id)

        elif message_type == SYNC_SESSION:
            vv_id = packet.get_int()
            self.vv_id = vv_id
            string = self.generateInfoString()
            self.info_label.setText(string)
            conn = self.connection_map[conn_id]
            logging.debug("Received SYNC_SESSION message from conn:%s" %conn_id)
            self.newSyncSession(conn, conn_id, vv_id)
            logging.info("Sync client connected")
            
        elif message_type == VP_REQ_CAM_LIST:
            logging.debug("Received VP_REQ_CAM_LIST message from conn:%s" 
                          % conn_id) 
            cameras = self.cam_mgr.getCameras()
            pipeline = self.activeSessions[conn_id].getPipeline()
            camera_type = None
            if pipeline == STATIC_PIPELINE:
                camera_type = VP_STATIC_CAMERA
            elif pipeline == PTZ_PIPELINE:
                camera_type = VP_ACTIVE_CAMERA
            cam_list = []
            for camera in cameras:
                if camera_type == camera.getType() and not camera.hasSession():
                    cam_list.append(camera.getId())
            message = eVV_CAM_LIST(self.ip, self.port, cam_list)
            conn = self.connection_map[conn_id]
            logging.debug("Sent VV_CAM_LIST message to conn:%s" % conn_id)
            self.sendMessage(message, conn)

        elif message_type == VP_REQ_IMG:
            cam_id = packet.get_int()
            frequency = packet.get_char()
            width = packet.get_int()
            height = packet.get_int()
            jpeg = packet.get_bool()
            data = (frequency, width, height, jpeg)
            camera = self.cam_mgr.getCameraById(cam_id)
            logging.debug("Received VV_REQ_IMG message from conn:%s" % conn_id)
            if camera and not camera.hasSession():
                session = self.activeSessions[conn_id]
                session.addCamera(cam_id)
                camera.setSession(session, VP_BASIC, self.ip, self.port, data)
            
        else:
            if conn_id in self.activeSessions:
                self.activeSessions[conn_id].newMessage(message_type, packet)


    def newVPSession(self, conn, type, pipeline, conn_id, req_cam_id):

        if type == VP_ADVANCED:
            camera_type = -1
            if pipeline == STATIC_PIPELINE:
                camera_type = STATIC_CAMERA ## Change this to use a different static camera class
            elif pipeline == PTZ_PIPELINE:
                camera_type = ACTIVE_CAMERA
            if camera_type != -1:
                #cam = self.cam_mgr.getAvailableCamera(camera_type)
                cam = self.cam_mgr.getRequestedCamera(camera_type, req_cam_id)
                if cam:
                    session = VPSession(conn_id, conn, self, VP, pipeline)
                    session.addCamera(cam.getId())
                    self.activeSessions[conn_id] = session
                    message = eVV_VP_ACK_OK(self.ip, self.port, cam.getId())
                    logging.debug("Sent VV_VP_ACK_OK message to conn:%s" 
                                  % conn_id)
                    self.sendMessage(message, conn)
                    cam.setSession(session, type, self.ip, self.port)
                    
                else:
                    message = eVV_VP_ACK_FAILED(self.ip, self.port)
                    logging.debug("Sent VV_VP_ACK_FAILED message to conn:%s" 
                                  % conn_id)
                    self.sendMessage(message, conn)
        else:
            message = eVV_VP_ACK_FAILED(self.ip, self.port)
            logging.debug("Sent VV_VP_ACK_FAILED message to conn:%s" 
                          % conn_id)
            self.sendMessage(message, conn)


    def newSyncSession(self, conn, conn_id, vv_id):
        session = SyncSession(conn_id, conn, self, SYNC)
        self.sync.setSession(session, vv_id, self.ip, self.port)
        self.activeSessions[conn_id] = session
        message = eVV_SYNC_ACK(self.ip, self.port, vv_id)
        logging.debug("Sent VV_SYNC_ACK message to conn:%s" % conn_id)
        self.sendMessage(message, conn)


    def sendMessage(self, message, conn):
        self.cWriter.send(message, conn)


    def disconnection_polling(self, taskdata):
        if(self.cManager.resetConnectionAvailable()):
            connectionPointer = PointerToConnection()
            self.cManager.getResetConnection(connectionPointer)
            lostConnection = connectionPointer.p()
            for session in self.activeSessions.values():
                if session.conn == lostConnection:
                    logging.info("Lost Connection from ip:%s, conn:%s" 
                                 %(session.client_address, session.conn_id))
                    conn_id = session.conn_id
                    if session.getSessionType() == VP:
                        cameras = session.getCameras()
                        for cam_id in cameras:
                            camera = self.cam_mgr.getCameraById(cam_id)
                            camera.clearSession()
                      
                    del self.activeSessions[conn_id]
                    del self.connection_map[conn_id]
                    break
            self.cManager.closeConnection(lostConnection)
        return Task.cont
    

    def toggleInfo(self):
        if self.showing_info:
            self.info_label.hide()
            self.showing_info = False
        else:
            self.info_label.show()
            self.showing_info = True


    def exit(self):
        for connection in self.connection_map.values():
            self.cReader.removeConnection(connection)
        self.cManager.closeConnection(self.tcpSocket)
        self.tcpSocket.getSocket().Close()
示例#9
0
class Server(DirectObject): 
    def __init__( self ): 
        self.port = 9099 
        self.portStatus = "Closed" 
        self.host = "localhost" 
        self.backlog = 1000 
        self.Connections = {} 
        # basic configuration variables that are used by most of the 
        # other functions in this class 

        self.StartConnectionManager() 
        # manages the connection manager 
        
        self.DisplayServerStatus() 
        # output a status box to the console which tells you the port 
        # and any connections currently connected to your server 
        
    def DisplayServerStatusTASK(self, task): 
        # all this does is periodically load the status function below 
        # add a task to display it every 30 seconds while you are doing 
        # any new coding 
        self.DisplayServerStatus() 
        return Task.again 
    
    def DisplayServerStatus(self): 
        print "\n----------------------------------------------------------------------------\n" 
        print "SERVER STATUS:\n\n" 
        print "Connection Manager Port: " + str(self.port)  + " [" + str(self.portStatus) + "]" 
        for k, v in self.Connections.iteritems(): 
            print "Connection " + k 

    ################################################################## 
    #              TCP Networking Functions and Tasks 
    ################################################################## 
        
    def StartConnectionManager(self): 
        # this function creates a connection manager, and then 
        # creates a bunch of tasks to handle connections 
        # that connect to the server 
        self.cManager = QueuedConnectionManager() 
        self.cListener = QueuedConnectionListener(self.cManager, 0) 
        self.cReader = QueuedConnectionReader(self.cManager, 0) 
        self.cWriter = ConnectionWriter(self.cManager,0) 
        self.tcpSocket = self.cManager.openTCPServerRendezvous(self.port,self.backlog)
        self.cListener.addConnection(self.tcpSocket) 
        self.portStatus = "Open" 
        taskMgr.add(self.ConnectionManagerTASK_Listen_For_Connections,"Listening for Connections",-39) 
        # This task listens for new connections 
        taskMgr.add(self.ConnectionManagerTASK_Listen_For_Datagrams,"Listening for Datagrams",-40) 
        # This task listens for new datagrams 
        taskMgr.add(self.ConnectionManagerTASK_Check_For_Dropped_Connections,"Listening for Disconnections",-41) 
        # This task listens for disconnections 
        
    def ConnectionManagerTASK_Listen_For_Connections(self, task): 
        if(self.portStatus == "Open"): 
        # This exists in case you want to add a feature to disable your 
        # login server for some reason.  You can just put code in somewhere 
        # to set portStatus = 'closed' and your server will not 
        # accept any new connections 
            if self.cListener.newConnectionAvailable(): 
                print "CONNECTION" 
                rendezvous = PointerToConnection() 
                netAddress = NetAddress() 
                newConnection = PointerToConnection() 
                if self.cListener.getNewConnection(rendezvous,netAddress,newConnection): 
                    newConnection = newConnection.p() 
                    self.Connections[str(newConnection.this)] = rendezvous 
                    # all connections are stored in the self.Connections 
                    # dictionary, which you can use as a way to assign 
                    # unique identifiers to each connection, making 
                    # it easy to send messages out 
                    self.cReader.addConnection(newConnection)    
                    print "\nSOMEBODY CONNECTED" 
                    print "IP Address: " + str(newConnection.getAddress()) 
                    print "Connection ID: " + str(newConnection.this) 
                    print "\n" 
                    # you can delete this, I've left it in for debugging 
                    # purposes 
                    self.DisplayServerStatus()                
                    # this fucntion just outputs the port and 
                    # current connections, useful for debugging purposes 
        return Task.cont  

    def ConnectionManagerTASK_Listen_For_Datagrams(self, task): 
        if self.cReader.dataAvailable(): 
            datagram=NetDatagram()  
            if self.cReader.getData(datagram): 
                print "\nDatagram received, sending response" 
                myResponse = PyDatagram() 
                myResponse.addString("GOT YER MESSAGE") 
                self.cWriter.send(myResponse, datagram.getConnection()) 
                # this was just testing some code, but the server will 
                # automatically return a 'GOT YER MESSAGE' datagram 
                # to any connection that sends a datagram to it 
                # this is where you add a processing function here 
                #myProcessDataFunction(datagram) 
        return Task.cont 

    def ConnectionManagerTASK_Check_For_Dropped_Connections(self, task): 
        # if a connection has disappeared, this just does some house 
        # keeping to officially close the connection on the server, 
        # if you don't have this task the server will lose track 
        # of how many people are actually connected to you 
        if(self.cManager.resetConnectionAvailable()): 
            connectionPointer = PointerToConnection() 
            self.cManager.getResetConnection(connectionPointer) 
            lostConnection = connectionPointer.p() 
            # the above pulls information on the connection that was lost 
            print "\nSOMEBODY DISCONNECTED" 
            print "IP Address: " + str(lostConnection.getAddress()) 
            print "ConnectionID: " + str(lostConnection.this) 
            print "\n" 
            del self.Connections[str(lostConnection.this)] 
            # remove the connection from the dictionary 
            self.cManager.closeConnection(lostConnection) 
            # kills the connection on the server 
            self.DisplayServerStatus() 
        return Task.cont 
示例#10
0
class UDPconnection():
    """
    base class for UDP server and client, handles basic communication (decoding/encoding), buffering and resending
    """
    def __init__(self, port='9099', timeout=3.0, commTicks=50, resendTime=0.33, reliable=0, concurrent=10, maxlength=480):
        self.logger = logging.getLogger('UDPcon')
        self.port = port
        # Start the UDP Connection
        self.cManager = QueuedConnectionManager()
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager, 0)
        self.conn = self.cManager.openUDPConnection(self.port)
        self.cReader.addConnection(self.conn)
        self.handlers = {}
        self.nextID = 1
        self.commBuffer = []
        self.conAddresses = []
        self.conIDs = []
        self.timeout = timeout
        self.commTicks = commTicks
        self.commTime = 1.0 / self.commTicks
        self.time = ClockObject()
        self.resendTime = resendTime
        self.reliable = reliable
        self.concurrent = concurrent
        self.maxlength = maxlength
        self.multMsgID = 0
        # receive data
#        taskMgr.add(self.listendata, "Incoming Data Listener", -40)
        self.running = True
        self.threadLock = threading.Lock()
        self.listenThread = threading.Thread(target=self.listendata)
        self.batchThread = threading.Thread(target=self.batch)
        for thread in [self.listenThread, self.batchThread]:
            thread.daemon = True
            thread.start()
        self.handlers[KEEP_ALIVE] = self.reply
        self.handlers[CONFIRM] = self.sync
#        logging.debug('UDPconnection created')
        self.logger.debug('UDPconnection created')

    def batch(self):
        # recurring tasks
        while self.running:
            self.threadLock.acquire()
            self.timenow = self.time.getFrameTime()
            self.sendDataBuffer()
            self.chkCommBuffers()
            self.threadLock.release()
            time.sleep(self.commTime)

    def listendata(self):
        # function that listens for incoming data, updating communication clock and calling handler-functions, should be added to taskMgr
        time.sleep(0.02)
        while self.running:
            time.sleep(0.005)
#            time.sleep(0.1)
            self.time.tick()
            data = self.getData()
            if data:
                self.threadLock.acquire()
                self.timenow = self.time.getFrameTime()
                # we only accept authentication requests from not-connected remote machines, all other incomming data is discarded
                for d in data:
#                    print "incoming: ", d[MSG_TYPE], d[SEQN]
                    if d[MSG_TYPE] == CMSG_AUTH or d[MSG_TYPE] == SMSG_AUTH_RESPONSE:
    #                if d[MSG_TYPE] == CMSG_AUTH:
                        if d[MSG_TYPE] in self.handlers:
                            self.handlers[d[MSG_TYPE]](d[DATA], d[ADDR])
                        continue
                    ind = self.getCommBufferByAddr(d[ADDR])
                    if ind < 0:
                        continue

                    self.commBuffer[ind].lastRecv = self.timenow
                    # remove confirmed messages
                    self.commBuffer[ind].confirm(d[AKN], time=self.timenow)

                    if d[MSG_TYPE] == MULT:
                        if d[SEQN] > 0 and d[SEQN] <= self.commBuffer[ind].rseqNumber:
                            continue    
                        d = self.commBuffer[ind].addPartialMsg(d, time=self.timenow)                    
                    else:
                        if d[OAKN]:
                            self.commBuffer[ind].remove(d[OAKN])

                    # discard message if already received
                    if d[SEQN] > 0 and d[SEQN] <= self.commBuffer[ind].rseqNumber:
                        continue

                    execute = []
                    # unreliable messages are always executed when they are received without sending a confirmation
                    if d[SEQN] < 0:
                        execute = [d]
                    else:
                        # if received message is the next in line or can be executed out of line -> execute=1, otherwise store in recvBuffer
                        if d[SEQN] == self.commBuffer[ind].rseqNumber + 1:
                            self.commBuffer[ind].rseqNumber += 1
                            execute = [d]
                        else:
                            if d[OOL]:
                                execute = [d]
                            self.commBuffer[ind].addRecvMessage(d, recvtime=self.timenow)

                    # look for messages that are now in line to be processed
                    for msg in self.commBuffer[ind].getRecvBuffer():
                        if not msg[OOL]:
                            execute.append(msg)

                    # call handler and pass data to it
                    for msg in execute:
                        if msg[MSG_TYPE] in self.handlers and not msg[MSG_TYPE] == MULT:
                            try:
                                self.handlers[msg[MSG_TYPE]](msg[DATA], id=self.commBuffer[ind].id)
                            except:
                                self.handlers[msg[MSG_TYPE]](msg[DATA])
                self.threadLock.release()
                                            


    def chkCommBuffers(self):
        for cb in self.commBuffer:
            for msg in cb.incompleteRecvBuffer[:]:
                if msg['lastupdate'] and (self.timenow - msg['lastupdate']) > self.timeout:
                    cb.incompleteRecvBuffer.remove(msg)

        # timeout not yet fully implemented
        return

        remove = []
        for cb in self.commBuffer:
            if (self.time.getFrameTime() - cb.lastRecv) > self.timeout:
                remove.append(cb.id)
        for id in remove:
            ind = self.getCommBufferByID(id)
            del self.commBuffer[ind]

    def getCommBufferByAddr(self, addr):
        # self.conAddresses = [(cb.addr.getIp(), cb.addr.getPort()) for cb in self.commBuffer]
        try:
            ind = self.conAddresses.index((addr.getIp(), addr.getPort()))
        except ValueError:
            ind = -1
        return ind

    def getCommBufferByID(self, id):
        # print type(self.commBuffer)
        # self.conIDs = [cb.id for cb in self.commBuffer]
        try:
            ind = self.conIDs.index(id)
        except ValueError:
            ind = -1
        return ind

    def encode(self, data):
        # encode the data with rencode
        # return rencode.dumps(data)
        return rencode.dumps(data)
        

    def decode(self, data):
        # decode the data with rencode
        # return rencode.loads(data)
        return rencode.loads(data)

    def sync(self, data, id=None):
        if id is not None:
            ind = self.getCommBufferByID(id)
            if abs(data[0] - self.commBuffer[ind].lastKeepAlive) > 1.e-3:
                ping = self.time.getFrameTime() - data[0]
                self.commBuffer[ind].addping(ping, time=self.timenow)

    def reply(self, data, id=None):
        if id is not None:
            data = [data, self.time.getFrameTime()]
            self.sendDataToID(data, id, msgtype=CONFIRM, reliable=False)

    def sendDataBuffer(self):
        # all messages that haven't been confirmed in ping + sigma(ping) will be resend
        for buff in self.commBuffer:
            addr = buff.addr
            # timenow = self.time.getFrameTime()
            timenow = self.timenow
            sent = 0
            for msg in buff.sendBuffer:
                oakn = [m[SEQN] for m in buff.recvBuffer]
                if len(oakn) > 5:
                    oakn = oakn[0:4]
                oakn_encoded = self.encode(oakn)
                if self.time.getFrameTime() - msg[TIME] > buff.ping:
                    # self.sendData(msg['data'], addr, msgtype=msg['msgtype'], seqNum=msg['sqn'], encode=False)
                    msg[AKN] = buff.rseqNumber
                    if not msg[MSG_TYPE] == MULT:
                        if msg[ENCODED]:
                            msg[OAKN] = oakn_encoded
                        else:
                            msg[OAKN] = oakn
                    buff.lastAKN = msg[AKN]
                    self.sendMessage(msg, addr)
                    msg[TIME] = self.time.getFrameTime()
                    sent += 1
                    if sent >= self.concurrent:
                        break
            if timenow - buff.lastRecv > self.resendTime or buff.lastAKN < buff.rseqNumber or timenow - buff.lastPingAdded > 1.0:
                # self.sendDataToID("", buff.id, msgtype=KEEP_ALIVE, out_of_line=True)
                buff.lastKeepAlive = timenow
                self.sendDataToID(timenow, buff.id, msgtype=KEEP_ALIVE, reliable=False)

    def sendMessage(self, msg, addr):
        # print "sending!: ", msg, addr.getIpString(), addr.getPort()
        myPyDatagram = self._crDatagram(msg)
        # print "size: ", sys.getsizeof(myPyDatagram), "type: ", msg[MSG_TYPE], "data: ", msg[DATA]
        self.cWriter.send(myPyDatagram, self.conn, addr)

    def sendDataToID(self, data, cID, reliable=None, **kwargs):
        msg = self._crMessage(data, **kwargs)
        ind = self.getCommBufferByID(cID)
        if ind < 0:
            raise IndexError
        self._sendMessageToIndex(msg, ind, reliable=reliable)

    def broadcast(self, data, reliable=None, **kwargs):
        msg = self._crMessage(data, **kwargs)
        for ind in xrange(len(self.commBuffer)):
            self._sendMessageToIndex(msg, ind, reliable=reliable)

    def _sendDataToIndex(self, data, index, reliable=None, **kwargs):
        msg = self._crMessage(data, **kwargs)
        # print "sending msg: ", msg
        self._sendMessageToIndex(msg, index, reliable=reliable)

    def _sendMessageToIndex(self, message, index, reliable=None):
        if not isinstance(index, collections.Iterable):
            index = [index]
        if type(message)==dict:
            message = [message]
        for msg in message:    
            for ind in index:
                if reliable is None:
                    reliable = self.reliable
                if not reliable:
                    msg[SEQN] = -1
                else:
                    msg[SEQN] = self.commBuffer[ind].addSendMessage(msg, sendtime=self.time.getFrameTime())
                msg[AKN] = self.commBuffer[ind].rseqNumber
                if not msg[MSG_TYPE] == MULT:
                    if msg[ENCODED]:
                        msg[OAKN] = self.encode([m[SEQN] for m in self.commBuffer[ind].recvBuffer])
                    else:
                        msg[OAKN] = [m[SEQN] for m in self.commBuffer[ind].recvBuffer]
                # print "sending to: ", self.commBuffer[ind].id, self.commBuffer[ind].addr.getIpString(), self.commBuffer[ind].addr.getPort()
                self.commBuffer[ind].lastSend = self.time.getFrameTime()
                self.commBuffer[ind].lastAKN = msg[AKN]
                self.sendMessage(msg, self.commBuffer[ind].addr)

    def sendData(self, data, addr, **kwargs):
        msg = self._crMessage(data, **kwargs)
        if not isinstance(addr, collections.Iterable):
            addr = [addr]
        if type(msg)==dict:
            msg = [msg]    
        for address in addr:
            for m in msg:
                self.sendMessage(m, address)

    def _crMessage(self, data, msgtype=0, seqNum=-1, akn=0, oakn={}, out_of_line=False):
        enc_data = self.encode(data)
        if len(enc_data) > self.maxlength:
            chunks = self.chunks(enc_data, self.maxlength)
            nchunks = math.ceil(len(enc_data) / (1.0 * self.maxlength))
            identifier = self.multMsgID
            self.multMsgID += 1
            oakn = [msgtype, identifier, nchunks]
            msgtype = MULT
        else:
            chunks = [enc_data]
            nchunks = 1            

        messages = []
        n = 0
        for dat in chunks:
            msg = {}
            msg[SEQN] = seqNum
            msg[AKN] = akn
            msg[MSG_TYPE] = msgtype
            msg[OOL] = out_of_line
            if nchunks > 1:
                oakn.append(n)
                msg[OAKN] = self.encode(oakn)
                oakn.pop()
                n += 1
            else:
                msg[OAKN] = self.encode(oakn)
            msg[DATA] = dat
            msg[ENCODED] = True
            msg[ADDR] = None
            msg[TIME] = 0
            messages.append(msg)

        return messages

    def _crDatagram(self, msg):
        # create Datagram from message
        myPyDatagram = PyDatagram()
        myPyDatagram.addInt32(msg[SEQN])
        myPyDatagram.addInt32(msg[AKN])
        myPyDatagram.addInt16(msg[MSG_TYPE])
        myPyDatagram.addInt8(msg[OOL])
        if not msg[ENCODED]:
            myPyDatagram.addString(self.encode(msg[OAKN]))
            myPyDatagram.addString(self.encode(msg[DATA]))
        else:
            myPyDatagram.addString(msg[OAKN])
            myPyDatagram.addString(msg[DATA])
        return myPyDatagram

    def _processData(self, netDatagram):
        # convert incoming Datagram to dict
        myIterator = PyDatagramIterator(netDatagram)
        msg = {}
        msg[SEQN] = myIterator.getInt32()
        msg[AKN] = myIterator.getInt32()
        msg[MSG_TYPE] = myIterator.getInt16()
        msg[OOL] = myIterator.getInt8()
        msg[OAKN] = self.decode(myIterator.getString())
        if not msg[MSG_TYPE] == MULT:
            msg[DATA] = self.decode(myIterator.getString())
        else:
            msg[DATA] = (myIterator.getString())
        # msg.append(self.decode(myIterator.getString()))
        return msg

    def getData(self):
        data = []
        while self.cReader.dataAvailable():
            datagram = NetDatagram()  # catch the incoming data in this instance
            # Check the return value; if we were threaded, someone else could have
            # snagged this data before we did
            if self.cReader.getData(datagram):
                # pkg = []
                pkg = self._processData(datagram)
                tmpaddr = datagram.getAddress()
                addr = NetAddress()
                addr.setHost(tmpaddr.getIpString(), tmpaddr.getPort())
                pkg[ADDR] = addr
                data.append(pkg)
        return data

    def addCommBuffer(self, addr):
        cb_id = self.nextID
        self.commBuffer.append(commBuffer(id=cb_id, addr=addr, lastRecv=self.time.getFrameTime()))
        self.nextID += 1
        self.conAddresses = [(cb.addr.getIp(), cb.addr.getPort()) for cb in self.commBuffer]
        self.conIDs = [cb.id for cb in self.commBuffer]
        return cb_id

    def removeCommBuffer(self, cID):
        ind  = self.getCommBufferByID(cID)
        if ind < 0:
            raise IndexError
        del self.commBuffer[ind]
        self.conAddresses = [(cb.addr.getIp(), cb.addr.getPort()) for cb in self.commBuffer]
        self.conIDs = [cb.id for cb in self.commBuffer]

    def chunks(self, string, n):
        return [string[i:i+n] for i in range(0, len(string), n)]
示例#11
0
文件: GameServer.py 项目: crempp/psg
class PSGServer(object):
	''' The main server that listens for connections and manages active games.
		This also runs the console which can interact with the server.'''
		
	# registeredUsers is a list of User objects of registered users
	registeredUsers = []
	# connectedUsers is a list of User objects of currently connected users
	connectedUsers  = []
	# connections is a list of Connection objects
	connections =[]
	# Connections that have not responded to their keepalive request.
	# A dictionary of the form (Connection, pingtime)
	pingNonResponders = {}
	# games is a list of active GameStateServer objects
	games = []

	def __init__(self):
		''' Initialize the server.'''
		
		import __builtin__
		__builtin__.LOG = LogConsole()
		
		print('Starting PSG Server ...')
		self._cManager  = QueuedConnectionManager()
		self._cListener = QueuedConnectionListener(self._cManager, 0)
		self._cReader   = QueuedConnectionReader(self._cManager, 0)
		self._cWriter   = ConnectionWriter(self._cManager,0)
		
		#TODO - Load user file (DB)
		self.registeredUsers =[ServerPlayer('chad','password1'),
							   ServerPlayer('josh','password2'),
							   ServerPlayer('james','password3')]
		
		# Map store
		self._mapStore = MapStore()
		
		# Open socket
		self._tcpSocket = self._cManager.openTCPServerRendezvous(PORT,BACKLOG)
		self._cListener.addConnection(self._tcpSocket)
		
		# Setup interfaces
		self._console = InterfaceConsole(self)
		
		# Setup system tasks
		taskMgr.add(self.__listenTask, 'serverListenTask', -40)
		taskMgr.add(self.__readTask, 'serverReadTask', -39)
		taskMgr.doMethodLater(PING_DELAY, self.__pingTask, 'serverPingTask', sort=-41)
		taskMgr.doMethodLater(1, self.__checkPingRespTask, 'serverCheckPingRespTask', sort=-10)
		
		print('Server initialized')
	
	
	def __listenTask(self, Task):
		''' This task listens for connections. When a connection is made it
			adds the connection to the clients list and begins listening to
			that connection.'''
		if self._cListener.newConnectionAvailable():
			rendezvous = PointerToConnection()
			netAddress = NetAddress()
			newConnection = PointerToConnection()
			
			if self._cListener.getNewConnection(rendezvous,netAddress,newConnection):
				newConnection = newConnection.p()
				if newConnection not in self.connections:
					self.connections.append(newConnection)
					self._cReader.addConnection(newConnection)     # Begin reading connection
					self._console.printNotice('Connection from %s'%netAddress.getIpString())
				else:
					self._console.printNotice('%s: already connected'%(newConnection.getAddress().getIpString()))
		return Task.cont
	
	def __readTask(self, Task):
		''' This task listens for any messages coming in over any connections.
			If we get a connection passes it to the datagram handler.'''
		if self._cReader.dataAvailable():
			datagram=NetDatagram()
			if self._cReader.getData(datagram):
				data = PyDatagramIterator(datagram)
				msgID = data.getUint16()
			else:
				data = None
				msgID = MSG_NONE
		else:
			datagram = None
			data = None
			msgID = MSG_NONE
		if msgID is not MSG_NONE:
			self.__handleDatagram(data, msgID, datagram.getConnection())
		return Task.cont
	
	def __pingTask(self, Task):
		''' Ping all clients every PING_DELAY seconds to check for those who
			have dropped their connection.'''
		
		notice = 'Pinging: '
		
		for c in self.connections:
			# Don't ping connections we're still waiting on
			if c not in self.pingNonResponders.keys():
				notice = '%s%s '%(notice, c.getAddress().getIpString())
				self.pingNonResponders[c] = int(time.time())
				pkg = NetDatagram()
				pkg.addUint16(MSG_PING_REQ)
				self._cWriter.send(pkg, c)
		
		LOG.notice(notice)
		# Add task back into the taskmanager
		taskMgr.doMethodLater(PING_DELAY, self.__pingTask, 'serverPingTask', sort=-41)
		
	def __checkPingRespTask(self, Task):
		''' Run through the list of connections that haven't responded to their
			ping yet and disconnect them if has been more than PING_TIMEOUT
			seconds.'''
		
		notice = 'Cleaning non-responders '
		
		for c in self.pingNonResponders.keys():
			notice = '%s%s '%(notice, c.getAddress().getIpString())
			now = int(time.time())
			pingTime = self.pingNonResponders[c]
			if ((now - pingTime) > PING_TIMEOUT):
				#print('disconnecting '),
				self.__handleDisconnect(None, None, c)
		
		LOG.notice(notice)
		# Add task back into the taskmanager
		taskMgr.doMethodLater(1, self.__checkPingRespTask, 'serverCheckPingRespTask', sort=-10)
	
	def __handleDatagram(self, data, msgID, client):
		''' This handles incoming messages. It can run the appropriate handler
			from the server or pass it to the relevant game to deal with.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that this datagram came from'''
		self._console.printNotice('%s: Recieved msg: %d'%(client.getAddress().getIpString(),msgID))
		# System messages
		if (msgID == MSG_PING_REQ):
			self._console.printNotice('Notice: MSG_PING_REQ')
			self.__handlePingReq(data, msgID, client)
		elif (msgID == MSG_PING_RES):
			self._console.printNotice('Notice: MSG_PING_RES')
			self.__handlePingRes(data, msgID, client)
		elif (msgID == MSG_DISCONNECT_REQ):
			self._console.printNotice('Notice: MSG_DISCONNECT_REQ')
			self.__handleDisconnect(data, msgID, client)
		# Pre-game server messages
		elif (msgID == MSG_AUTH_REQ):
			self._console.printNotice('Notice: MSG_AUTH_REQ')
			self.__handleAuth(data, msgID, client)
		elif (msgID == MSG_MAPLIST_REQ):
			self._console.printNotice('Notice: MSG_MAPLIST_REQ')
			#self.__handleMapList(data, msgID, client)
		elif (msgID == MSG_GAMELIST_REQ):
			self._console.printNotice('Notice: MSG_GAMELIST_REQ')
			self.__handleGameList(data, msgID, client)
		elif (msgID == MSG_NEWGAME_REQ):
			self._console.printNotice('Notice: MSG_NEWGAME_REQ')
			self.__handleNewGame(data, msgID, client)
		elif (msgID == MSG_JOINGAME_REQ):
			self._console.printNotice('Notice: MSG_JOINGAME_REQ')
			self.__handleJoinGame(data, msgID, client)
		elif (msgID == MSG_DOWNLOADMAP_REQ):
			self._console.printNotice('Notice: MSG_DOWNLOADMAP_REQ')
			self.__handleDownloadMap(data, msgID, client)
		elif (msgID == MSG_DOWNLOADUPD_REQ):
			self._console.printNotice('Notice: MSG_DOWNLOADUPD_REQ')
			self.__handleDownloadUpdate(data, msgID, client)
		# In-game server messages
		elif (msgID >= MSG_INGAME):
			self.__route(data, msgID, client)
		else:
			self._console.printNotice('%s: Unkown MSG_ID: %d'%(client.getAddress().getIpString(),msgID))
			print(data)
	
	def __handlePingReq(self, data, msgID, client):
		''' Respond to a ping request.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that this datagram came from'''
		
		# Send response
		pkg = NetDatagram()
		pkg.addUint16(MSG_PING_RES)
		self._cWriter.send(pkg, client)
		
		self._console.printNotice('%s: Ping request'%(client.getAddress().getIpString()))
		
	def __handlePingRes(self, data, msgID, client):
		''' Handle an incoming ping response.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that this datagram came from'''
		
		self._console.printNotice('%s: Ping response'%(client.getAddress().getIpString()))
		
		# Client responded so remove from non-responder list
		try:
			del(self.pingNonResponders[client])
		except KeyError:
			self._console.printNotice("%s responded to ping but was not in pingNonResponders"%client.getAddress())
		
	
	def __handleDisconnect(self, data, msgID, client):
		''' Disconnect and send confirmation to the client.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that tendNehis datagram came from'''
		
		# Create a response
		pkg = NetDatagram()
		pkg.addUint16(MSG_DISCONNECT_RES)
		self._cWriter.send(pkg, client)
		
		# If user has joined a game, remove the player from that game
		for g in self.games:
			if g.isPlayerInGame(client):
				g.removePlayer(client)
		
		# If user is logged in disconnect
		username = ''
		for u in self.connectedUsers:
			if (u.connectedClient == client):
				username = u.username
				u.disconnect()
				self.connectedUsers.remove(u)
		
		# Delete client from list
		if client in self.connections:
			self.connections.remove(client)
			
		# Don't worry about pings any more
		if client in self.pingNonResponders:
			del(self.pingNonResponders[client])
		
		self._console.printNotice('%s: Disconnected user %s'%(client.getAddress().getIpString(),username))
	
	def __handleAuth(self, data, msgID, client):
		''' Try to authorize the connecting user, send the result.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that this datagram came from'''
		
		# Unpack message data
		username = data.getString()
		password = data.getString()
		auth = 0
		
		# Look for the username in the list of registered users
		for u in self.registeredUsers:
			if u.username == username:
				if u.connected:
					auth = 1
					self._console.printNotice('%s: User %s already connected'%(client.getAddress().getIpString(),username))
					break
				elif u.password != password:
					auth = 2
					self._console.printNotice('%s: User %s gave invalid password'%(client.getAddress().getIpString(),username))
					break
				else:
					auth = 3
					u.connect(client)
					self.connectedUsers.append(u)
					self._console.printNotice('%s: User %s connected with pass %s' %(client.getAddress().getIpString(),username,password))
		
		# Send response
		pkg = NetDatagram()
		pkg.addUint16(MSG_AUTH_RES)
		pkg.addUint32(auth)
		self._cWriter.send(pkg, client)
	
	def __handleMapList(self, data, msgID, client):
		''' Assemble a list of available maps and send it to the requesting client.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that this datagram came from'''
		
		# Assemble a list with entries in the form (filename,mapname,md5sum)
		mapFileList = Map.getMapFiles()
		responseList = []
		for f in mapFileList:
			fh = open(Map.MAP_PATH + f,' rb')
			mapObj = cPickle.load(fh)
			responseList.append((mapObj.name, f, Map.getMapMD5(f)))
		
		# Send response
		pkg = NetDatagram()
		pkg.addUint16(MSG_MAPLIST_RES)
		pkg.addString('SOT') # Start Of Transmission
		for i, (n,f,c) in enumerate(responseList):
			pkg.addString(n)
			pkg.addString(f)
			pkg.addString(c)
			if i < len(responseList)-1:
				pkg.addString('T') # Still tranmitting
		pkg.addString('EOT') # End Of Transmission
		self._cWriter.send(pkg, client)
		
		self._console.printNotice('%s: Request for map list.' %(client.getAddress().getIpString()))
	
	def __handleGameList(self, data, msgID, client):
		''' Assemble a list of active games and send it to the requesting client.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that this datagram came from'''
		
		# Send response
		pkg = NetDatagram()
		pkg.addUint16(MSG_GAMELIST_RES)
		if (len(self.games) == 0):
			pkg.addString('EOT') # Nothing to transmit
		else:
			pkg.addString('SOT') # Start Of Transmission
			for i,g in enumerate(self.games):
				pkg.addInt32(g.id)
				pkg.addString(g.name)
				pkg.addUint32(g.numPlayers)
				pkg.addString(g.map.name)
				pkg.addString(g.mapFile)
				pkg.addUint32(g.startTime)
				pkg.addUint32(g.turnNumber)
				if i < len(self.games)-1:
					pkg.addString('T') # Still tranmitting
			pkg.addString('EOT') # End Of Transmission
		self._cWriter.send(pkg, client)
		
		self._console.printNotice('%s: Request for game list.' %(client.getAddress().getIpString()))
		
	def __handleNewGame(self, data, msgID, client):
		''' Create a new game and respond with success or failure.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that tendNehis datagram came from'''
		
		# Unpack message data
		gameName    = data.getString()
		mapID       = data.getString()
		numPlayers  = data.getUint32()
		
		# If we do not have the map for the requested game tell client
		print("id=%s"%mapID)
		if(not self._mapStore.isAvailable(id=mapID)):
			response = 0
		else:
			# Create the game
			newGame = GameStateServer(gameName, numPlayers, mapID)
			if newGame is not None:
				self.games.append(newGame)
				response = newGame.id
			else:
				response = -1
		
		# Send response
		pkg = NetDatagram()
		pkg.addUint16(MSG_NEWGAME_RES)
		pkg.addInt32(response)
		self._cWriter.send(pkg, client)
		
		self._console.printNotice('%s: Request for new game: %s, %s, %d.' %(client.getAddress().getIpString(),gameName,mapID,numPlayers))
		
	def __handleJoinGame(self, data, msgID, client):
		''' Add client to the requested game.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that tendNehis datagram came from'''
		
		# Unpack message data
		id = data.getUint32()
		resp = 0
		
		# Find the game
		game = None
		mapMD5 = "00000000000000000000000000000000"
		print self.games
		for g in self.games:
			if g.id == id:
				game = g
				mapMD5 = g.mapID
		
		if game == None:
			LOG.debug('No such game')
			resp = 0
		elif len(game.connections) >= game.numPlayers:
			LOG.debug('Game full')
			resp = 1
		else:
			game.addPlayer(client)
			LOG.debug('Ok, joining game')
			resp = 2
		
		# Send response
		pkg = NetDatagram()
		pkg.addUint16(MSG_JOINGAME_RES)
		pkg.addUint32(resp)
		pkg.addString(mapMD5)
		self._cWriter.send(pkg, client)
		self._console.printNotice('%s: Request to join game id %d, gave %d.'%(client.getAddress().getIpString(),id,resp))
	
	def __handleDownloadMap(data, msgID, client):
		''' Prepare and send requested map to client
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that tendNehis datagram came from'''
		
		# Unpack message data
		id = data.getUint32()
		resp = 0
		
		filename = self._mapStore.getMap(id=id)['filename']
		mapString = self._mapStore.loadMapAsString(filename)
		
		if (mapString == None):
			LOG.debug('No such map')
			resp = 0
			mapString = ''
		else:
			LOG.debug('Sending map')
			resp = 1
			
		# Send response
		pkg = NetDatagram()
		pkg.addUint16(MSG_JOINGAME_RES)	
		pkg.addUint32(resp)
		pkg.addString(mapString)
		self._cWriter.send(pkg, client)
			
	def __handleDownloadUpdate(data, msgID, client):
		pass
	
	def __route(self, data, msgID, client):
		LOG.notice('Routing msg to GameStateServer')
		
	def shutdown(self):
		print('Shutting down server ...')
		
		# Send disconnect to all clients
		pkg = NetDatagram()
		pkg.addUint16(MSG_DISCONNECT_REQ)
		for c in self.connections:
			self._cWriter.send(pkg, c)
		self._cManager.closeConnection(self._tcpSocket)
		print('Server done')
		sys.exit()
		
	def disconnect(self, client):
		''' Disconnect client'''
		self.__handleDisconnect(None, None, client)
示例#12
0
class LoginServer(ShowBase):
    def __init__(self, port, backlog=1000, compress=False):
        ShowBase.__init__(self)

        self.compress = compress

        self.cManager = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager, 0)

        self.clientdb = ClientDataBase()
        if not self.clientdb.connected:
            self.clientdb = None
            print 'Login Server failed to start...'
        else:
            # This is for pre-login
            self.tempConnections = []

            # This is for authed clients
            self.activeClients = []
            # This is for authed servers
            self.activeServers = []
            # This is for authed chat servers
            self.activeChats = []

            self.connect(port, backlog)
            self.startPolling()

            self.taskMgr.doMethodLater(0.5, self.lobbyLoop, 'Lobby Loop')

            print 'Login Server operating...'

    def connect(self, port, backlog=1000):
        # Bind to our socket
        tcpSocket = self.cManager.openTCPServerRendezvous(port, backlog)
        self.cListener.addConnection(tcpSocket)

    def startPolling(self):
        self.taskMgr.add(self.tskListenerPolling, "serverListenTask", -40)
        self.taskMgr.add(self.tskDisconnectPolling, "serverDisconnectTask",
                         -39)

    def tskListenerPolling(self, task):
        if self.cListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            newConnection = PointerToConnection()
            if self.cListener.getNewConnection(rendezvous, netAddress,
                                               newConnection):
                newConnection = newConnection.p()
                self.tempConnections.append(newConnection)
                self.cReader.addConnection(newConnection)
        return Task.cont

    def tskDisconnectPolling(self, task):
        while self.cManager.resetConnectionAvailable() == True:
            connPointer = PointerToConnection()
            self.cManager.getResetConnection(connPointer)
            connection = connPointer.p()

            # Remove the connection
            self.cReader.removeConnection(connection)
            # Check for if it was a client
            for client in self.activeClients:
                if client.connection == connection:
                    print 'removing client'
                    self.activeClients.remove(client)
                    break
            # then check servers
            for server in self.activeServers:
                if server.connection == connection:
                    self.activeServers.remove(server)
                    break
            # then check servers
            for chat in self.activeChats:
                if chat.connection == connection:
                    self.activeChats.remove(chat)
                    break

        return Task.cont

    def processData(self, netDatagram):
        myIterator = PyDatagramIterator(netDatagram)
        return self.decode(myIterator.getString())

    def encode(self, data, compress=False):
        # encode(and possibly compress) the data with rencode
        return rencode.dumps(data, compress)

    def decode(self, data):
        # decode(and possibly decompress) the data with rencode
        return rencode.loads(data)

    def sendData(self, data, con):
        myPyDatagram = PyDatagram()
        myPyDatagram.addString(self.encode(data, self.compress))
        self.cWriter.send(myPyDatagram, con)

    # This will check and do the logins.
    def auth(self, datagram):
        # If in login state.
        con = datagram.getConnection()
        package = self.processData(datagram)
        if len(package) == 2:
            if package[0] == 'create':
                success, result = self.clientdb.addClient(
                    package[1][0], package[1][1])
                if success:
                    self.sendData(('createSuccess', result), con)
                else:
                    self.sendData(('createFailed', result), con)
                return False
            if package[0] == 'client':
                userFound = False
                for client in self.activeClients:
                    if client.name == package[1][0]:
                        userFound = True
                        self.sendData(('loginFailed', 'logged'), con)
                        break
                if not userFound:
                    valid, result = self.clientdb.validateClient(
                        package[1][0], package[1][1])
                    if valid:
                        self.activeClients.append(Client(package[1][0], con))
                        self.sendData(('loginValid', result), con)
                        return True
                    else:
                        self.sendData(('loginFailed', result), con)
                        return False
            # if server add it to the list of current active servers
            if package[0] == 'server':
                self.activeServers.append(Server(package[1], con))
                return True
            # if server add it to the list of current active servers
            if package[0] == 'chat':
                self.activeChats.append(Chat(package[1], con))
                return True

    def getData(self):
        data = []
        while self.cReader.dataAvailable():
            datagram = NetDatagram()
            if self.cReader.getData(datagram):
                if datagram.getConnection() in self.tempConnections:
                    if self.auth(datagram):
                        self.tempConnections.remove(datagram.getConnection())
                    continue
                # Check if the data recieved is from a valid client.
                for client in self.activeClients:
                    if datagram.getConnection() == client.connection:
                        data.append(
                            ('client', self.processData(datagram), client))
                        break
                # Check if the data recieved is from a valid server.
                for server in self.activeServers:
                    if datagram.getConnection() == server.connection:
                        data.append(
                            ('server', self.processData(datagram), server))
                        break
                # Check if the data recieved is from a valid chat.
                for chat in self.activeChats:
                    if datagram.getConnection() == chat.connection:
                        data.append(('chat', self.processData(datagram), chat))
                        break
        return data

    # handles new joining clients and updates all clients of chats and readystatus of players
    def lobbyLoop(self, task):
        # if in lobby state
        temp = self.getData()
        if temp != []:
            for package in temp:
                # handle client incoming packages here
                if package[0] == 'client':
                    # This is where packages will come after clients connect to the server
                    # will be things like requesting available servers and chat servers
                    if package[1] == 'server_query':
                        for server in self.activeServers:
                            if server.state == 'lobby':
                                self.sendData(
                                    ('server',
                                     (server.name,
                                      str(server.connection.getAddress()))),
                                    package[2].connection)
                        self.sendData(('final', 'No more servers'),
                                      package[2].connection)
                # handle server incoming packages here
                elif package[0] == 'server':
                    # auth
                    # game state change
                    if len(package[1]) == 2:
                        if package[1][0] == 'auth':
                            clientAuth = False
                            print 'Attempting Authentication on: ', package[1][
                                1]
                            for client in self.activeClients:
                                if client.name == package[1][1]:
                                    clientAuth = True
                                    break
                            if clientAuth:
                                self.sendData(('auth', client.name),
                                              package[2].connection)
                            else:
                                self.sendData(('fail', package[1][1]),
                                              package[2].connection)
                        elif package[1][0] == 'state':
                            package[2].state = package[1][1]
                # handle chat server incoming packages here
                elif package[0] == 'chat':
                    print 'Authorized chat server sent package'
                    # handle packages from the chat servers
                    # like making public/private
                    # authing clients
        return task.again
示例#13
0
class MiniServer:

    def __init__(self, host, port, channel, serverType):
        self.port = port
        self.host = host
        self.channel = channel
        self.serverType = serverType
        self.Connections = {}
        self.startConnectionMgr()
        self.locked = 0
        #base.taskMgr.add(self.displayServerStatusTask, "displayServerStatus")
        return

    def connectToServer(self, port):
        # Connect our MiniServer to the main server.
        self.serverConnection = self.cMgr.openTCPClientConnection(self.host,
                            port, 5000)
        if self.serverConnection:
            self.cReader.addConnection(self.serverConnection)
            self.handleConnected()

    def handleConnected(self):
        self.registerChannel()

    def registerChannel(self):
        dg = PyDatagram()
        dg.addServerControlHeader(CONTROL_ADD_CHANNEL)
        dg.addChannel(self.channel)
        self.cWriter.send(dg, self.serverConnection)
        print "Registered channel: " + str(self.channel)

    def setLocked(self, value):
        if value:
            self.locked = 1
        elif not value:
            self.locked = 0

    def displayServerStatusTask(self, task):
        self.displayServerStatus()
        task.delayTime = 30
        return Task.again

    def displayServerStatus(self):
        print "-----------------------------------"
        print "Server Status..."
        print "Host: %s" % self.host
        print "Port: %s" % self.port
        print "Number of active connections: %s" % len(self.Connections)

    def startConnectionMgr(self):
        self.cMgr = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cMgr, 0)
        self.cReader = QueuedConnectionReader(self.cMgr, 0)
        self.cWriter = ConnectionWriter(self.cMgr, 0)
        self.tcpSocket = self.cMgr.openTCPServerRendezvous('', self.port, 10)
        self.cListener.addConnection(self.tcpSocket)
        taskMgr.add(self.listenerPoll, "listenForConnections", -39)
        taskMgr.add(self.datagramPoll, "listenForDatagrams", -40)
        taskMgr.add(self.disconnectionPoll, "listenForDisconnections", -41)
        print "%s server started." % self.serverType.capitalize()

    def listenerPoll(self, task):
        """ Listen for connections. """
        if not self.locked:
            if self.cListener.newConnectionAvailable():
                print "-----------------------------------"
                print "New connection available..."
                rendezvous = PointerToConnection()
                netAddress = NetAddress()
                newConnection = PointerToConnection()
                if self.cListener.getNewConnection(rendezvous, netAddress, newConnection):
                    newConnection = newConnection.p()
                    self.Connections[str(newConnection.this)] = rendezvous
                    self.cReader.addConnection(newConnection)
                    print "IP Address: %s" % newConnection.getAddress()
                    print "ConnectionID: %s" % newConnection.this
                    self.displayServerStatus()
                    #if self.__class__.__name__ == 'LoginServer':
                     #   self.sendServerMessage('ciac',
                      #                         newConnection)
        return Task.cont

    def datagramPoll(self, task):
        if self.cReader.dataAvailable():
            datagram = NetDatagram()
            if self.cReader.getData(datagram):
                self.handleDatagram(datagram)
        return Task.cont

    def disconnectionPoll(self, task):
        if self.cMgr.resetConnectionAvailable():
            connectionPointer = PointerToConnection()
            self.cMgr.getResetConnection(connectionPointer)
            lostConnection = connectionPointer.p()
            print "-----------------------------------"
            print "Farewell connection..."
            print "IP Address: %s" % lostConnection.getAddress()
            print "ConnectionID: %s" % lostConnection.this
            del self.Connections[str(lostConnection.this)]
            self.cMgr.closeConnection(lostConnection)
            self.displayServerStatus()
        return Task.cont
示例#14
0
class Server(ShowBase):
	def __init__(self):
		ShowBase.__init__(self)

		# Server Networking handling stuff
		self.compress = False

		self.cManager = QueuedConnectionManager()
		self.cListener = QueuedConnectionListener(self.cManager, 0)
		self.cReader = QueuedConnectionReader(self.cManager, 0)
		self.cWriter = ConnectionWriter(self.cManager, 0)

		self.tempConnections = []
		self.unauthenticatedUsers = []
		self.users = []

		self.passedData = []

		self.connect(9099, 1000)
		self.startPolling()

		self.attemptAuthentication()
		
		self.taskMgr.doMethodLater(0.5, self.lobbyLoop, 'Lobby Loop')

	def connect(self, port, backlog = 1000):
		# Bind to our socket
		tcpSocket = self.cManager.openTCPServerRendezvous(port, backlog)
		self.cListener.addConnection(tcpSocket)

	def startPolling(self):
		self.taskMgr.add(self.tskListenerPolling, "serverListenTask", -40)
		self.taskMgr.add(self.tskDisconnectPolling, "serverDisconnectTask", -39)

	def tskListenerPolling(self, task):
		if self.cListener.newConnectionAvailable():
			rendezvous = PointerToConnection()
			netAddress = NetAddress()
			newConnection = PointerToConnection()

			if self.cListener.getNewConnection(rendezvous, netAddress, newConnection):
				newConnection = newConnection.p()
				newConnection.setNoDelay(True)
				self.tempConnections.append(newConnection)	# Remember connection
				self.cReader.addConnection(newConnection)	# Begin reading connection
		return Task.cont

	def tskDisconnectPolling(self, task):
		while self.cManager.resetConnectionAvailable() == True:
			connPointer = PointerToConnection()
			self.cManager.getResetConnection(connPointer)
			connection = connPointer.p()
			
			# Remove the connection we just found to be "reset" or "disconnected"
			self.cReader.removeConnection(connection)
			
			# remove from our activeConnections list
			if connection in self.tempConnections:
				self.tempConnections.remove(connection)
			for user in self.unauthenticatedUsers:
				if connection == user.connection:
					self.unauthenticatedUsers.remove(user)
			for user in self.users:
				if connection == user.connection:
					user.connection = None
					self.passData(('disconnect', user.name), None)
		
		return Task.cont

	def broadcastData(self, data):
		# Broadcast data out to all users
		for user in self.users:
			if user.connection:
				self.sendData(data, user.connection)

	def processData(self, netDatagram):
		myIterator = PyDatagramIterator(netDatagram)
		return self.decode(myIterator.getString())

	def getUsers(self):
		# return a list of all users
		return self.users

	def encode(self, data, compress = False):
		# encode(and possibly compress) the data with rencode
		return rencode.dumps(data, compress)

	def decode(self, data):
		# decode(and possibly decompress) the data with rencode
		return rencode.loads(data)

	def sendData(self, data, con):
		myPyDatagram = PyDatagram()
		myPyDatagram.addString(self.encode(data, self.compress))
		self.cWriter.send(myPyDatagram, con)

	def passData(self, data, connection):
		self.passedData.append((data, connection))

	def getData(self):
		data = []
		for passed in self.passedData:
			data.append(passed)
			self.passedData.remove(passed)
		while self.cReader.dataAvailable():
			datagram = NetDatagram()
			if self.cReader.getData(datagram):
				if datagram.getConnection() in self.tempConnections:
					self.processTempConnection(datagram)
					continue
				for authed in self.users:
					if datagram.getConnection() == authed.connection:
						data.append((self.processData(datagram), datagram.getConnection()))
		return data

	def processTempConnection(self, datagram):
		connection = datagram.getConnection()
		package = self.processData(datagram)
		if len(package) == 2:
			if package[0] == 'username':
				print 'attempting to authenticate', package[1]
				self.tempConnections.remove(connection)
				if not self.online:
					user = User(package[1], connection)
					# confirm authorization
					self.sendData(('auth', user.name), user.connection)
					self.updateClient(user)
					self.users.append(user)
				else:
					self.client.sendData(('auth', package[1]))
					self.unauthenticatedUsers.append(User(package[1], connection))

	def attemptAuthentication(self):
		config = ConfigParser.RawConfigParser()
		config.read('server.cfg')
		self.SERVER_NAME = config.get('SERVER DETAILS', 'serverName')

		config = ConfigParser.RawConfigParser()
		config.read('master.cfg')
		self.LOGIN_IP = config.get('MASTER SERVER CONNECTION', 'masterIp')
		self.LOGIN_PORT = config.getint('MASTER SERVER CONNECTION', 'masterPort')

		# Client for connecting to main server for showing exists and receiving clients
		self.client = Client(self, self.LOGIN_IP, self.LOGIN_PORT, compress = True)
		if self.client.getConnected():
			self.client.sendData(('server', self.SERVER_NAME))
			self.taskMgr.add(self.clientValidator, 'Client Validator')
			self.client.sendData(('state', 'lobby'))
			self.online = True
		else:
			# client not connected to login/auth server
			print 'Could not connect to Authentication Server.'
			print 'Server is not in online mode. No Authentication will happen for clients.'
			print 'Restart Server to attempt to connect to Authentication Server.'
			self.client = None
			self.online = False

	def clientValidator(self, task):
		temp = self.client.getData()
		for package in temp:
			if len(package) == 2:
				if package[0] == 'auth':
					print 'User authenticated: ', package[1]
					for user in self.unauthenticatedUsers:
						if user.name == package[1]:
							# confirm authorization
							self.sendData(('auth', user.name), user.connection)
							# send all required data to user
							self.updateClient(user)
							# all authenticated users
							self.users.append(user)
							self.unauthenticatedUsers.remove(user)
							print 'confirmation sent to ', package[1]
							break
				elif package[0] == 'fail':
					print 'User failed authentication: ', package[1]
					for user in self.unauthenticatedUsers:
						if user.name == package[1]:
							self.sendData(('fail', user.name), user.connection)
							self.unauthenticatedUsers.remove(user)
							break
		return task.again

	def updateClient(self, user):
		for existing in self.users:
			if existing.name != user.name:
				self.sendData(('client', existing.name), user.connection)
				self.sendData(('ready', (existing.name, existing.ready)), user.connection)
				if existing.connection:
					self.sendData(('client', user.name), existing.connection)
		self.sendData(('client', user.name), user.connection)

	def lobbyLoop(self, task):
		temp = self.getData()
		for package in temp:
			if len(package) == 2:
				print "Received: ", str(package)
				packet = package[0]
				connection = package[1]
				if len(packet) == 2:
					# check to make sure connection has username
					for user in self.users:
						if user.connection == connection:
							# if chat packet
							if packet[0] == 'chat':
								print 'Chat: ', packet[1]
								# Broadcast data to all clients ("username: message")
								self.broadcastData(('chat', (user.name, packet[1])))
							# else if ready packet
							elif packet[0] == 'ready':
								print user.name, ' changed readyness!'
								user.ready = packet[1]
								self.broadcastData(('ready', (user.name, user.ready)))
							# else if disconnect packet
							elif packet[0] == 'disconnect':
								print user.name, ' is disconnecting!'
								self.users.remove(user)
								self.broadcastData(('disconnect', user.name))
							# break out of for loop
							break
		# if all players are ready and there is X of them
		gameReady = True
		# if there is any clients connected
		if self.getUsers() == []:
			gameReady = False
		for user in self.users:
			if not user.ready:
				gameReady = False
		if gameReady:
			self.prepareGame()
			return task.done
		return task.again
		
	def prepareGame(self):
		if self.camera:
			# Disable Mouse Control for camera
			self.disableMouse()
			
			self.camera.setPos(0, 0, 500)
			self.camera.lookAt(0, 0, 0)

		self.gameData = GameData(True)
		
		# game data
		self.broadcastData(('gamedata', self.gameData.packageData()))
		self.broadcastData(('state', 'preround'))
		if self.online:
			self.client.sendData(('state', 'preround'))
		print "Preparing Game"
		self.gameTime = 0
		self.tick = 0

		usersData = []
		for user in self.users:
			usersData.append(user.gameData)
		self.game = Game(self, usersData, self.gameData)
		self.taskMgr.doMethodLater(0.5, self.roundReadyLoop, 'Game Loop')
		print "Round ready State"
		
	def roundReadyLoop(self, task):
		temp = self.getData()
		for package in temp:
			if len(package) == 2:
				print "Received: ", str(package)
				if len(package[0]) == 2:
					for user in self.users:
						if user.connection == package[1]:
							if package[0][0] == 'round':
								if package[0][1] == 'sync':
									user.sync = True
		# if all players are ready and there is X of them
		roundReady = True
		# if there is any clients connected
		for user in self.users:
			if user.sync == False:
				roundReady = False
		if roundReady:
			self.taskMgr.doMethodLater(2.5, self.gameLoop, 'Game Loop')
			print "Game State"
			return task.done
		return task.again
	
	def gameLoop(self, task):
		# process incoming packages
		temp = self.getData()
		for package in temp:
			if len(package) == 2:
				# check to make sure connection has username
				for user in self.users:
					if user.connection == package[1]:
						user.gameData.processUpdatePacket(package[0])
		# get frame delta time
		dt = self.taskMgr.globalClock.getDt()
		self.gameTime += dt
		# if time is less than 3 secs (countdown for determining pings of clients?)
		# tick out for clients
		while self.gameTime > gameTick:
			# update all clients with new info before saying tick
			for user in self.users:
				updates = user.gameData.makeUpdatePackets()
				for packet in updates:
					self.broadcastData((user.name, packet))
			self.broadcastData(('tick', self.tick))
			self.gameTime -= gameTick
			self.tick += 1
			# run simulation
			if not self.game.runTick(gameTick):
				print 'Game Over'
				# send to all players that game is over (they know already but whatever)
				# and send final game data/scores/etc
				for user in self.users:
					user.ready = False
				self.taskMgr.doMethodLater(0.5, self.lobbyLoop, 'Lobby Loop')
				return task.done
		return task.cont
示例#15
0
文件: Client.py 项目: czorn/Modifire
class Client(DirectObject):
    
    #-----------------
    # Initialization
    #-----------------

    def __init__(self):
        self.log = Log()
        self.log.Open('client.txt')

        self.clientSnapshotHandler = ClientSnapshotHandler()
        
        self.accept(EngineLoadedEvent.EventName, self.OnEngineLoadedEvent)

        self.fsm = ClientFSM(self)
        self.fsm.request('CreateNetworkObjects')
        
        self.lastServerPacketTimestamp = 0
        

    def CreateNetworkObjects(self):
        if(self.CreateUDPConnection() and self.CreateTCPConnection()):
            self.dataHandler = ClientDataHandler(self)
            self.reliablePacketController = ReliablePacketController(self.cWriter, self.conn, self.dataHandler)
            self.unreliablePacketController = UnreliablePacketController(self.cWriter, self.conn, self.dataHandler)
            self.tcpPacketController = TCPPacketController(self.tcpWriter, self.tcpReader, self.cManager, self.dataHandler)
            self.dataHandler.SetPacketControllers(self.reliablePacketController, self.unreliablePacketController, self.tcpPacketController)
                
            self.ListenForIncomingTraffic()
            return True

        return False
    
    def CreateUDPConnection(self):
        self.cManager = QueuedConnectionManager()
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager,0)
        self.conn = self.cManager.openUDPConnection(Globals.PORT_CLIENT_LISTENER)

        if(self.conn):
            self.log.WriteLine('Connection on %s okay.' % (Globals.PORT_CLIENT_LISTENER))
        else:
            self.log.WriteError('Connection on %s failed.' % (Globals.PORT_CLIENT_LISTENER))
            Globals.PORT_CLIENT_LISTENER += 1
            self.log.WriteError('Retrying on %s .' % (Globals.PORT_CLIENT_LISTENER))
            self.conn = self.cManager.openUDPConnection(Globals.PORT_CLIENT_LISTENER)
            if(self.conn):
                self.log.WriteLine('Connection on %s okay.' % (Globals.PORT_CLIENT_LISTENER))
            else:
                self.log.WriteError('Connection on %s failed.' % (Globals.PORT_CLIENT_LISTENER))
                self.log.WriteError('Connection unsuccessful, exiting Client')
                return False

        self.cReader.addConnection(self.conn)

        return True
    
    def CreateTCPConnection(self):
        self.tcpWriter = ConnectionWriter(self.cManager,0)
        self.tcpReader = QueuedConnectionReader(self.cManager, 0)
        return True
    
    #---------------------
    # Listening for data
    #---------------------

    def ListenForIncomingTraffic(self):
        taskMgr.add(self.UDPPacketListenTask, "UDPPacketListenTask")
        taskMgr.add(self.TCPPacketListenTask, "TCPPacketListenTask", -40)

    def UDPPacketListenTask(self, task):
        while self.cReader.dataAvailable():
            datagram = NetDatagram()
            if self.cReader.getData(datagram):
                #print 'PACKET', datagram
                data = PyDatagramIterator(datagram)
                ip = datagram.getAddress().getIpString()
                port = datagram.getAddress().getPort()
                peerAddr = NetAddress()
                peerAddr.setHost(ip, port)
                
                packetType = data.getUint8()
                if(packetType == Packet.PC_RELIABLE_PACKET):
                    self.reliablePacketController.OnPacketReceived(data, peerAddr)
                elif(packetType == Packet.PC_UNRELIABLE_PACKET):
                    self.unreliablePacketController.OnPacketReceived(data, peerAddr)
                elif(packetType == Packet.PC_ENVIRONMENT_PACKET):
                    self.dataHandler.OnDataReceived(data, peerAddr, Packet.PC_ENVIRONMENT_PACKET)

        return Task.cont
    
    def TCPPacketListenTask(self, task):
        if self.tcpReader.dataAvailable():
            datagram = NetDatagram()
            if self.tcpReader.getData(datagram):
                data = PyDatagramIterator(datagram)
                ip = datagram.getAddress().getIpString()
                port = datagram.getAddress().getPort()
                peerAddr = NetAddress()
                peerAddr.setHost(ip, port)
                
                packetType = data.getUint8()
                if(packetType == Packet.PC_TCP_PACKET):
                    self.tcpPacketController.OnPacketReceived(data, peerAddr)
        
        return task.cont
    
    #---------------
    # Sending Data
    #---------------
    
    def ConnectToServer(self, serverAddress):
        self.fsm.request('WaitingForJoinResponse')
        self.log.WriteLine('Requesting to join server (%s)' % serverAddress)
        serverAddr = NetAddress()
        serverAddr.setHost(serverAddress, Globals.PORT_SERVER_LISTENER)
        self.dataHandler.SetServerAddress(serverAddr)
        self.dataHandler.SendRequestToJoinServer()
        self.acceptOnce(ServerJoinResponseEvent.EventName, self.OnServerJoinResponseEvent)
        taskMgr.doMethodLater(1.8, self.OnRequestJoinTimeout, 'serverJoinTimeout', extraArgs = [False])

#    def SendChatMessage(self, messageType, message):
#        self.dataHandler.SendChatMessage(messageType, message)
        
#    def OnServerChatMessage(self, messageType, pid, message):
#        self.engine.OnServerChatMessage(messageType, pid, message)
    
    def SendInput(self, currentTime, myInput, myState):
        self.dataHandler.SendInputCommands(currentTime, myInput, myState)
        #self.game.ClearMyClicking()
        
#    def SendSelectedTeam(self, team):
#        self.dataHandler.SendSelectedTeam(team)

    def StoreSnapshot(self, t, myInput, myState):
        #myInput.SetTimestamp(t)
        
        snapshot = Snapshot(myInput,
                            myState.GetValue(PlayerState.POSITION),
                            t)
        
        self.clientSnapshotHandler.AddSnapshot(snapshot)
    
    def HandleEnvironmentChange(self, destroyed, added):
        self.engine.HandleEnvironmentChange(destroyed, added)

    def HandleServerPlayerStates(self, playerStates):
        if(self.engine is not None):
            self.engine.GetPlayerController().HandleServerPlayerStates(playerStates)

#    def UpdatePlayerState(self, playerId, key, value):
#        self.engine.UpdatePlayerState(playerId, key, value)
        
#    def OnPlayerDisconnect(self, pid):
#        self.engine.RemovePlayer(pid)
        
#    def OnConnectedPlayers(self, players):
#        for player in players:
#            self.engine.AddNewPlayer(player[0], player[1])

    def CompareSnapshots(self, playerStates):
            if(self.engine is not None):
                if(Globals.MY_PID in playerStates.keys()):
                    myState = playerStates[Globals.MY_PID]
                    oldStates = self.clientSnapshotHandler.GetOldStates(myState.GetValue(PlayerState.TIMESTAMP))
                    self.engine.GetPlayerController().VerifyPrediction(copy.deepcopy(myState), oldStates)

    def OnRequestJoinTimeout(self, task):
        taskMgr.remove('serverJoinTimeout')
        self.reliablePacketController.RemovePeerData(self.dataHandler.serverAddr)
        self.unreliablePacketController.RemovePeerData(self.dataHandler.serverAddr)
        ServerJoinResponseEvent(False, 'Server could not be reached.').Fire()
        
    def OnServerJoinResponseEvent(self, event):
        #self.fsm.request('WaitingForEnvironment')
        print 'removed timeout message'
        taskMgr.remove('serverJoinTimeout')
        
    def LoadEngine(self):
        LoadEngineEvent().Fire()
    
    def OnEngineLoadedEvent(self, event):
        self.dataHandler.SendEngineLoaded()
        
    def GetPlayer(self, pid):
        return self.engine.GetPlayerController().GetPlayer(pid)

    def Disconnect(self):
        self.fsm.request('Idle', 'Left Server')
        
    def CleanUp(self):
        self.reliablePacketController.CleanUp()
        self.unreliablePacketController.CleanUp()

    def Exit(self):
        self.log.Close()
示例#16
0
class ClientConnection(object):
	''' This class creates the communication links to a game server and
		presents an interface for communication.'''
	
	__metaclass__ = Singleton
	
	address        = 'chadrempp.com'
	port           = '9091'
	timeout        = '3000'
	_callback       = None
	_connected      = False
	_authorized   	= False
	_connectedGame 	= None
	_respCallback   = {MSG_AUTH_RES:       None,
					   MSG_MAPLIST_RES:    None,
					   MSG_GAMELIST_RES:   None,
					   MSG_NEWGAME_RES:    None,
					   MSG_JOINGAME_RES:   None}
	def __init__(self):
		''' ClientConnection constructor.'''
		self._cManager   = QueuedConnectionManager()
		self._cListener  = QueuedConnectionListener(self._cManager, 0)
		self._cReader    = QueuedConnectionReader(self._cManager, 0)
		self._cWriter    = ConnectionWriter(self._cManager,0)
	
	def isConnected(self):
		''' Return True if a connection is established, otherwise False.'''
		return self._connected
	
	def isAuthorized(self):
		''' Return True if the connection is authorized, otherwise False.'''
		return self._authorized
	
	def authenticate(self, username, password, callback):
		''' Send authentication request.
			
			username (string): Username for authentication
			password (string): Password for authentication
			callback (function): Funtion that will be called when a response is
				received. Callback will be passed one parameter (status)
					status = 0 if authorization failed
					status = 1 if the user is already authenticated
					status = 2 if an invalid password is supplied
					status = 3 if authentication succeeded
		'''
		self.__sendAuthReq(username, password)
		self._respCallback[MSG_AUTH_RES] = callback
	
	def connect(self, address, port, timeout, callback=None):
		''' Try to connect to the server.
			
			address (String): address for the server
			port (Int): port to connect to
			timeout (Int): how long to wait before giving up (milliseconds)
			callback (function): Funtion that will be called when a response is
				received. Callback will be passed one parameter (status)
					status = True if connection succeeded
					status = False if connection failed
		'''
		if self._connected:
			LOG.notice("Already Connected!")
		else:
			self._connected = False
			try:
				LOG.notice('connecting to %s'%address)
				self._tcpSocket = self._cManager.openTCPClientConnection(address, port, timeout)
				if self._tcpSocket:
					LOG.notice("Opened socket.")
					self._cReader.addConnection(self._tcpSocket)  # receive messages from server
					if self._cReader:
						taskMgr.add(self.__readTask,"Poll the connection reader",-40)
						taskMgr.doMethodLater(PING_DELAY, self.__pingTask, 'serverPingTask', sort=-41)
						self._connected = True
						LOG.notice("Created listener")
					else:
						LOG.error("Couldn't connect to server")
				else:
					LOG.error("Couldn't connect to server")
			except Exception:
				LOG.error("Couldn't connect to server")
		if callback:
			callback(self._connected)
		
	def disconnect(self, callback):
		''' Disconnect from the server.
			
			callback (function): Funtion that will be called when a response is
				received. Callback will be passed one parameter (status)
					status = 1 if connection succeeded
					status = 0 if connection failed
		'''
		if self._connected:
			LOG.notice('Disconnecting...')
			pkg = NetDatagram()
			pkg.addUint16(MSG_DISCONNECT_REQ)
			self._cWriter.send(pkg, self._tcpSocket)
			self._cManager.closeConnection(self._tcpSocket)
			self._connected = False
			if callback != None: callback(1)
		else:
			LOG.error('Can not disconnect, we are not connected.')
			if callback != None: callback(0)
	
	def getMapList(self, callback):
		''' Send a request for a list of maps available on the server.
			
			callback (function): Funtion that will be called when a response is
				received. Callback will be passed one parameter (mapDictList).
				mapDictList is a list of dictionaries, each dictionary
				represents a map. The following keys will be available in each
				dictionary.
					'filename' - The map filename
					'mapname'  - The name of the map
					'md5sum'   - The unique MD5 ID of the map
		'''
		self.__sendMapListReq()
		self._respCallback[MSG_MAPLIST_RES] = callback
	
	def getGameList(self, callback):
		''' Sends a request for a list of active games to the server.
			
			callback (function): Funtion that will be called when a response is
				received. Callback will be passed one parameter (gameDictList).
				gameDictList is a list of dictionaries, each dictionary
				represents a game. The following keys will be available in each
				dictionary.
					'id'          - The game ID
					'name'        - The game's name
					'numplayer'   - The number of players for this game
					'mapname'     - The name of the map for this game
					'mapfilename' - The filename of the map for this game
					'starttime'   - The game's start time
					'turnnumber   - The game's turn number
		'''
		self.__sendGameListReq()
		self._respCallback[MSG_GAMELIST_RES] = callback
		
	def newGame(self, gamename, mapID, numplayers, callback):
		''' Send info to start a new game on the server.
			
			gamename (string): The name of the game
			mapID (string): The unique MD5 ID of the map to use for this game
			numplayers (int): The number of players allowed for this game
			callback (function): Funtion that will be called when a response is
				received. Callback will be passed one parameter (status).
					status = -1 if the server failed to create the game
					status = 0 if the server needs the map in order to create
					status = x if the server succeeded in creating the game
								(x is the game ID)
		'''
		self.__sendNewGameReq(gamename, mapID, numplayers)
		self._respCallback[MSG_NEWGAME_RES] = callback
		
	def joinGame(self, gameid, callback):
		''' Attempt to join the game with ID=gameid.
		
			gameid (int): The ID of the game to join
			callback (function): Funtion that will be called when a response is
				received. Callback will be passed two parameters (status and
				mapMD5).
					status = 0 if no such game exists
					status = 1 if game is full
					status = 2 if joining game was successful
		'''
		self.__sendJoinGameReq(gameid)
		self._respCallback[MSG_JOINGAME_RES] = callback
	
	def downloadMap(self, mapid, callback):
		''' Download the map with the given id (MD5).
			
			mapid (string): The MD5 id of the map to download.
			callback (function): Funtion that will be called when a response is
				received. Callback will be passed two parameters (status and
				mapMD5).
					status = 0 if no such map exists
					status = 1 if download was successful
		'''
		self._respCallback[MSG_DOWNLOADMAP_RES] = callback
		self._download("MAP", mapid)
	
	def registerGame(self, game, callback):
		''' Tell server we are loaded and ready. The game ID is returned.
			
			game (Game): The game to be registered.
			callback (function): Funtion that will be called when a response is
				received. Callback will be passed one parameter (status).
					status = 0 if registration fails
					status > 0 the id of the game on success
		'''
		id = 1
		callback(id)
		
	def sendUnitMove(self, movedentity, callback):
		''' Send updated entity to server.'''
		self.__sendUnitMove(movedentity)
		self._respCallback[MSG_UNITMOVE_RES] = callback
		
	def sendUnitAttack(self, fromentity, toentity, callback):
		''' Send a message that fromentity attacked toentity. The entities
			have been updated from the attack.'''
		self.__sendUnitAttack(fromentity, toentity)
		self._respCallback[MSG_UNITATTACK_RES] = callback
		
	def sendUnitInfo(self, entity):
		''' Send a requst for information about the given entity.'''
		self.__sendUnitInfo(entity)
		self._respCallback[MSG_UNITINFO_RES] = callback
		
	#--ClientConnection Private Methods----------------------------------------
	def __readTask(self, taskdata):
		''' This task listens for any messages coming in over any connections.
			If we get a connection passes it to the datagram handler.'''
		if self._cReader.dataAvailable():
			datagram=NetDatagram()  # catch the incoming data in this instance
			# Check the return value; if we were threaded, someone else could have
			# snagged this data before we did
			if self._cReader.getData(datagram):
				data = PyDatagramIterator(datagram)
				msgID = data.getUint16()
			else:
				data = None
				msgID = MSG_NONE
		else:
			datagram = None
			data = None
			msgID = MSG_NONE
		if msgID is not MSG_NONE:
			self.__handleDatagram(data, msgID, datagram.getConnection())
		return Task.cont
	
	def __pingTask(self, Task):
		''' Ping the server every PING_DELAY seconds to check if it's still
			there.'''
		LOG.debug('Pinging')
		# Add task back into the taskmanager
		taskMgr.doMethodLater(PING_DELAY, self.__pingTask, 'serverPingTask', sort=-41)
	
	def __downloadTask(self, Task):
			if self.channel.run():
				# Still waiting for file to finish downloading.
				return task.cont
			if not self.channel.isDownloadComplete():
				print "Error downloading file."
				return task.done
			data = self.rf.getData()
			print "got data:"
			print data
			return task.done
	
	def __handleDatagram(self, data, msgID, client):
		''' This handles incoming messages by calling the appropriate handler.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that this datagram came from'''
		if (msgID == MSG_PING_REQ):
			self.__recievePingReq(data, msgID, client)
		elif (msgID == MSG_DISCONNECT_REQ):
			self.__recieveDisconnectReq(data, msgID, client)
		elif (msgID == MSG_AUTH_RES):
			self.__recieveAuthRes(data, msgID, client)
		elif (msgID == MSG_MAPLIST_RES):
			self.__recieveMapListRes(data, msgID, client)
		elif (msgID == MSG_GAMELIST_RES):
			self.__recieveGameListRes(data, msgID, client)
		elif (msgID == MSG_NEWGAME_RES):
			self.__recieveNewGameRes(data, msgID, client)
		elif (msgID == MSG_JOINGAME_RES):
			self.__recieveJoinGameRes(data, msgID, client)
		elif (msgID == MSG_CHAT_RECV):
			self.__recieveChatRes(data, msgID, client)
		elif (msgID == MSG_UNITMOVE_RECV):
			self.__recieveUnitMove(data, msgID, client)
		elif (msgID == MSG_UNITATTACK_RECV):
			self.__recieveUnitAttack(data, msgID, client)
		elif (msgID == MSG_UNITINFO_RECV):
			self.__recieveUnitInfo(data, msgID, client)
		elif (msgID == MSG_ENDTURN_RECV):
			self.__recieveEndTurn(data, msgID, client)
		else:
			LOG.error("Unkown MSG_ID: %d " %msgID),
			print(data)
	
	def __recievePingReq(self, data, msgID, client):
		''' Handle pings from the server.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that this datagram came from'''
		
		LOG.debug("Recieved a ping request")
		
		# Send response
		pkg = NetDatagram()
		pkg.addUint16(MSG_PING_RES)
		self._cWriter.send(pkg, self._tcpSocket)
	
	def __recieveDisconnectReq(self, data, msgID, client):
		''' Handle a disconnect request from the server.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that this datagram came from'''
			
		LOG.notice("Server told us it was leaving! Disconecting")
		
		self._cManager.closeConnection(self._tcpSocket)
		self._connected = False
	
	def __sendAuthReq(self, username, password):
		''' Send user name and password. The password is encypted first using
			SHA256.
			username (String): the username
			password (String): the password'''
			
		if self._connected:
			LOG.notice("Sending authorization")
			h = hashlib.sha256()
			h.update(password)
			pkg = NetDatagram()
			pkg.addUint16(MSG_AUTH_REQ)
			pkg.addString(username)
			pkg.addString(h.hexdigest())
			self._cWriter.send(pkg, self._tcpSocket)
		else:
			LOG.error("Cant authorize, we are not connected")
	
	def __recieveAuthRes(self, data, msgID, client):
		''' Recieve the authentication response from the server and deal
			with it by continuing or diconnecting.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that this datagram came from'''
		
		# Unpack message data
		response = data.getUint32()
		
		if (response == 0):
			LOG.error("Authorization for server failed for an unknown reason.")
			self.disconnect(None)
		elif (response == 1):
			LOG.error("You are already connected to this server. This could be due to an unclean disconnect.")
		elif (response == 2):
			LOG.error("Incorrect password")
		elif (response == 3):
			LOG.notice("Authorization granted.")
			self._authorized = True
		
		# If there is a callback function pass the game list to it
		if self._respCallback[MSG_AUTH_RES]:
			self._respCallback[MSG_AUTH_RES](response)
			self._respCallback[MSG_AUTH_RES] = None
	
	def __sendGameListReq(self):
		''' Request a list of games on the connected server.'''
		
		# Send request
		if (self._connected and self._authorized):
			pkg = NetDatagram()
			pkg.addUint16(MSG_GAMELIST_REQ)
			self._cWriter.send(pkg, self._tcpSocket)
		
	def __recieveGameListRes(self, data, msgID, client):
		''' Recieve the list of games requested.
			data (PyDatagramIterator): the list of data sent with this datagram
			msgID (Int): the message ID
			client (Connection): the connection that this datagram came from'''
		
		games = []
		
		# Unpack message data
		indicator = data.getString()

		while (indicator != 'EOT'):
			id          = data.getInt32()
			name        = data.getString()
			maxPlayers  = data.getUint32()
			mapName     = data.getString()
			mapFileName = data.getString()
			startTime   = data.getUint32()
			turnNumber  = data.getUint32()
			indicator   = data.getString()
			games.append({'id':id,
						  'name':name,
						  'numplayers':maxPlayers,
						  'mapname':mapName,
						  'mapfilename':mapFileName,
						  'starttime':startTime,
						  'turnnumber':turnNumber})
			
		# If there is a callback function pass the game list to it
		if self._respCallback[MSG_GAMELIST_RES]:
			self._respCallback[MSG_GAMELIST_RES](games)
		#self._availableGames = games
	
	def __sendNewGameReq(self, gamename, mapID, numplayers):
		''' Create a new game on the server.
			name (String): the name of the game
			mapID (String): the MD5 ID of the map
			maxplayers (Int): the max players allowed'''
			
		LOG.debug('Sending new game request %s'%map)
		
		# Send Request
		if (self._connected and self._authorized):
			pkg = NetDatagram()
			pkg.addUint16(MSG_NEWGAME_REQ)
			pkg.addString(gamename)
			pkg.addString(mapID)
			pkg.addUint32(numplayers)
			self._cWriter.send(pkg, self._tcpSocket)
		
	def __recieveNewGameRes(self, data, msgID, client):
		''' Recieve the response of our attempt to create a new game.'''
		
		LOG.debug('Recieving new game response')
		
		# Unpack message data
		game_created = data.getInt32()
		
		# If there is a callback function pass the response to it
		if self._respCallback[MSG_NEWGAME_RES]:
			self._respCallback[MSG_NEWGAME_RES](game_created)
			self._respCallback[MSG_NEWGAME_RES] = None
			
	def __sendJoinGameReq(self, id):
		''' Join a game on the server.
			id (int): the id of the game to join'''
			
		LOG.debug('Sending join game request')
		
		# Send Request
		if (self._connected and self._authorized):
			pkg = NetDatagram()
			pkg.addUint16(MSG_JOINGAME_REQ)
			pkg.addUint32(id)
			self._cWriter.send(pkg, self._tcpSocket)
	
	def __recieveJoinGameRes(self, data, msgID, client):
		''' Handle the response to a join game request.'''
		
		LOG.debug("Recieving joing game response")
		
		# Unpack message data
		join_response = data.getUint32()
		map_md5 = data.getString()
		
		# If there is a callback function pass the response to it
		if self._respCallback[msgID]:
			self._respCallback[msgID](join_response, map_md5)
			self._respCallback[msgID] = None
	
	def _sendDownloadReq(type, id):
		''' Download a file from the server.'''
		
		LOG.debug("Downloading type=%s, id=%s"%(type, id))
		
		if (self._connected and self._authorized):
			pkg = NetDatagram()
			if (type == "MAP"):
				pkg.addUint16(MSG_DOWNLOADMAP_REQ)
				pkg.addUint32(id)
			elif (type == "UPDATE"):
				pkg.addUint16(MSG_DOWNLOADUPD_REQ)
				pkg.addUint32(id)
			self._cWriter.send(pkg, self._tcpSocket)
	
	def __sendChat(self, message):
		''' Send chat message to the server.'''
		
		LOG.debug('Sending chat')
		
	def __recieveChat(self, data, msgID, client):
		''' Recieve chat message from server.'''
		
		LOG.debug('Recieved chat')
	
	def __sendUnitMove(self, entity):
		''' Send the updated entity to the server.'''
		
		LOG.debug('Sending move')
	
	def __recieveUnitMove(self, data, msgID, client):
		''' Recieve an updated entity.'''
		
		LOG.debug('Recieved move')
	
	def __sendUnitAttack(self, fromentity, toentity):
		''' Send a an attacking entity (fromentity) and an attacked
			entity (toentity).'''
			
		LOG.debug('Sending attack')
	
	def __recieveUnitAttack(self, data, msgID, client):
		''' Recieve an attack from the server.'''
		
		LOG.debug('Recieved attack')
		
	def __sendUnitInfo(self, entity):
		''' Send a request for info on an entity.'''
		
		LOG.debug('Sending info request')
		
	def __recieveUnitInfo(self, data, msgID, client):
		''' Recieve unit info.'''
		
		LOG.debug('Recieving unit info')
		
	def __sendEndTurn(self):
		''' Send end turn request.'''
		
		LOG.debug('Sending end turn')
	
	def __recieveEndTurn(self, data, msgID, client):
		''' Recieve end turn.'''
		
		LOG.debug('Recieving end turn.')
		
	def __del__(self):
		''' This destructor tells the server we are leaving so things do not
			get too messy.'''
		self.disconnect()
示例#17
0
class Server:
    def __init__(self, port, backlog=1000, compress=False):
        self.port = port
        self.backlog = backlog
        self.compress = compress

        self.cManager = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager, 0)

        self.activeConnections = []  # We'll want to keep track of these later

        self.connect(self.port, self.backlog)
        self.startPolling()

    def connect(self, port, backlog=1000):
        # Bind to our socket
        self.tcpSocket = self.cManager.openTCPServerRendezvous(port, backlog)
        self.cListener.addConnection(self.tcpSocket)

    def disconnect(self, port, backlog=1000):
        self.tcpSocket = self.cManager.openTCPServerRendezvous(port, backlog)
        self.cManager.closeConnection(self.tcpSocket)
        taskMgr.remove("serverListenTask")
        taskMgr.remove("serverDisconnectTask")

    def startPolling(self):
        taskMgr.add(self.tskListenerPolling, "serverListenTask", -40)
        taskMgr.add(self.tskDisconnectPolling, "serverDisconnectTask", -39)

    def tskListenerPolling(self, task):
        if self.cListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            newConnection = PointerToConnection()

            if self.cListener.getNewConnection(rendezvous, netAddress,
                                               newConnection):
                newConnection = newConnection.p()
                self.activeConnections.append(
                    newConnection)  # Remember connection
                self.cReader.addConnection(
                    newConnection)  # Begin reading connection
        return Task.cont

    def tskDisconnectPolling(self, task):
        while self.cManager.resetConnectionAvailable() == True:
            connPointer = PointerToConnection()
            self.cManager.getResetConnection(connPointer)
            connection = connPointer.p()

            # Remove the connection we just found to be "reset" or "disconnected"
            self.cReader.removeConnection(connection)

            # Loop through the activeConnections till we find the connection we just deleted
            # and remove it from our activeConnections list
            for c in range(0, len(self.activeConnections)):
                if self.activeConnections[c] == connection:
                    del self.activeConnections[c]
                    break

        return Task.cont

    def broadcastData(self, data):
        # Broadcast data out to all activeConnections
        for con in self.activeConnections:
            self.sendData(data, con)

    def processData(self, netDatagram):
        myIterator = PyDatagramIterator(netDatagram)
        return self.decode(myIterator.getString())

    def getClients(self):
        # return a list of all activeConnections
        return self.activeConnections

    def encode(self, data, compress=False):
        # encode(and possibly compress) the data with rencode
        return rencode.dumps(data, compress)

    def decode(self, data):
        # decode(and possibly decompress) the data with rencode
        return rencode.loads(data)

    def sendData(self, data, con):
        myPyDatagram = PyDatagram()
        myPyDatagram.addString(self.encode(data, self.compress))
        self.cWriter.send(myPyDatagram, con)

    def getData(self):
        data = []
        while self.cReader.dataAvailable():
            datagram = NetDatagram(
            )  # catch the incoming data in this instance
            # Check the return value; if we were threaded, someone else could have
            # snagged this data before we did
            if self.cReader.getData(datagram):
                data.append(self.processData(datagram))
        return data
class Server(DirectObject):
    def __init__(self):
        self.cManager = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager,0)
 
        self.activeConnections = [] # Keeps tracks of active connections
        
        #Set up the connection
        port_address=9099 #No-other TCP/IP services are using this port
        backlog=1000 #If we ignore 1,000 connection attempts, something is wrong!
        self.tcpSocket = self.cManager.openTCPServerRendezvous(port_address,backlog)
 
        self.cListener.addConnection(self.tcpSocket)
        self.setTaskManagers() #Set the Managers
        
    def tskListenerPolling(self,taskdata):
        if self.cListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            newConnection = PointerToConnection()
            
            if self.cListener.getNewConnection(rendezvous,netAddress,newConnection):
                newConnection = newConnection.p()
                self.activeConnections.append(newConnection) # Remember connection
                self.cReader.addConnection(newConnection)     # Begin reading connection
                self.broadCast(newConnection) #Broadcasts the Server Message
        return Task.cont
    
    def tskReaderPolling(self,taskdata):
        if self.cReader.dataAvailable():
            datagram = NetDatagram()  # catch the incoming data in this instance
            # Check the return value; if we were threaded, someone else could have
            # snagged this data before we did
            if self.cReader.getData(datagram):
                myProcessDataFunction(datagram)
        return Task.cont
    
    def setTaskManagers(self):
        taskMgr.add(self.tskListenerPolling,"Poll the connection listener",-39)
        taskMgr.add(self.tskReaderPolling,"Poll the connection reader",-40)
        
    '''
    Terminate all connections.
    '''
    def terminateAllConnection(self):
        for aClient in self.activeConnections:
            self.cReader.removeConnections(aClient)
        self.activeConnections = []
        #Close our listener
        self.cManager.closeConnection(self.tcpSocket)
        
    '''
    Terminate a connection.
    '''
    def terminateConnection(self, aClient):
        self.cReader.removeConnections(aClient)
        
    '''
    PyDatagram for messages
    Arguments: message must be a string
    '''
    def messageData(self, message):
        messDat = PyDatagram()
        messDat.addUint8(PRINT_MESSAGE)
        messDat.addString(message)
        return messDat
    
    '''
    Broadcast Server Message
    '''
    def broadCast(self, aClient):
        message = self.messageData("Welcome to BaziBaz's Server\nConnection has been estabilished\n")
        self.cWriter.send(message, aClient)
示例#19
0
class LoginServer:
    def __init__(self, port, backlog=1000, compress=False):
        self.port = port
        self.backlog = backlog
        self.compress = compress

        self.cManager = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager, 0)

        self.db = DataBase()
        # This is for pre-login
        self.tempConnections = []
        # This is for authed clients
        self.activeConnections = []

        # Temp user dict
        self.clients = {}

        self.connect(self.port, self.backlog)
        self.startPolling()

    def connect(self, port, backlog=1000):
        # Bind to our socket
        tcpSocket = self.cManager.openTCPServerRendezvous(port, backlog)
        self.cListener.addConnection(tcpSocket)

    def startPolling(self):
        taskMgr.add(self.tskListenerPolling, "serverListenTask", -40)
        taskMgr.add(self.tskDisconnectPolling, "serverDisconnectTask", -39)

    def tskListenerPolling(self, task):
        if self.cListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            newConnection = PointerToConnection()

            if self.cListener.getNewConnection(rendezvous, netAddress, newConnection):
                newConnection = newConnection.p()
                self.tempConnections.append(newConnection)  # Lets add it to a temp list first.
                self.cReader.addConnection(newConnection)  # Begin reading connection

                # Make the temp place holder then add to temp, under dataget check the temp list, if something ther do
                # auth and then add to the active
        return Task.cont

    def tskDisconnectPolling(self, task):
        while self.cManager.resetConnectionAvailable() == True:
            print "disconnect"
            connPointer = PointerToConnection()
            self.cManager.getResetConnection(connPointer)
            connection = connPointer.p()

            # Remove the connection we just found to be "reset" or "disconnected"
            self.cReader.removeConnection(connection)
            # Remove the connection we just found to be "reset" or "disconnected"
            self.cReader.removeConnection(connection)
            for u in range(len(self.clients)):
                if self.clients[u]["connection"] == connection:
                    del self.clients[u]
                    break

                    # Loop through the activeConnections till we find the connection we just deleted
                    # and remove it from our activeConnections list
            for c in range(0, len(self.activeConnections)):
                if self.activeConnections[c] == connection:
                    del self.activeConnections[c]
                    break

        return Task.cont

    def broadcastData(self, data):
        # Broadcast data out to all activeConnections
        for con in self.activeConnections:
            self.sendData(data, con)

    def processData(self, netDatagram):
        myIterator = PyDatagramIterator(netDatagram)
        return self.decode(myIterator.getString())

    def getClients(self):
        # return a list of all activeConnections
        return self.activeConnections

    def encode(self, data, compress=False):
        # encode(and possibly compress) the data with rencode
        return rencode.dumps(data, compress)

    def decode(self, data):
        # decode(and possibly decompress) the data with rencode
        return rencode.loads(data)

    def sendData(self, data, con):
        myPyDatagram = PyDatagram()
        myPyDatagram.addString(self.encode(data, self.compress))
        self.cWriter.send(myPyDatagram, con)

        # This will check and do the logins.

    def auth(self, datagram):
        # If in login state.
        clientIp = datagram.getAddress()  # This is the ip :P
        clientCon = datagram.getConnection()  # This is the connection data. used to send the shit.
        package = self.processData(datagram)
        print "SERVER: ", package
        valid_packet = False
        if len(package) == 2:
            # if login request is send reply
            # Should add a checker like in the db something like isLogged(0 or 1)
            # If found then say no for client
            user_found = False
            if package[0] == "login_request":
                valid_packet = True
                print "Try login"
                for u in range(len(self.clients)):
                    if self.clients[u]["name"] == package[1][0]:
                        print "User already exists"
                        user_found = True
                        data = {}
                        data[0] = "error"
                        data[1] = "User already logged in"
                        self.sendData(data, clientCon)
                        break
                        # send something back to the client saying to change username
                if not user_found:
                    username = package[1][0]
                    password = package[1][1]
                    self.db.Client_getLogin(username, password)
                    if self.db.login_valid:
                        # Add the user
                        new_user = {}
                        new_user["name"] = package[1][0]
                        new_user["connection"] = clientCon
                        new_user["ready"] = False
                        new_user["new_dest"] = False
                        new_user["new_spell"] = False
                        self.clients[len(self.clients)] = new_user
                        # Send back the valid check.
                        data = {}
                        data[0] = "login_valid"  # If client gets this the client should switch to main_menu.
                        data[1] = {}
                        data[1][0] = self.db.status
                        data[1][1] = len(self.clients) - 1  # This is part of the old 'which' packet
                        self.sendData(data, clientCon)

                        # Move client to the self.activeConnections list.
                        self.activeConnections.append(clientCon)
                        print "HERE IS ACTIVE: ", self.activeConnections
                        self.tempConnections.remove(clientCon)
                        print "HERE IS TEMP", self.tempConnections

                else:
                    status = self.db.status
                    data = {}
                    data[0] = "db_reply"
                    data[1] = status
                    self.sendData(data, clientCon)
            if not valid_packet:
                data = {}
                data[0] = "error"
                data[1] = "Wrong Packet"
                self.sendData(data, clientCon)
                print "Login Packet not correct"

        else:
            print "Data in packet wrong size"

    def getData(self):
        data = []
        while self.cReader.dataAvailable():
            datagram = NetDatagram()  # catch the incoming data in this instance
            # Check the return value; if we were threaded, someone else could have
            # snagged this data before we did
            if self.cReader.getData(datagram):

                if datagram.getConnection() in self.tempConnections:
                    print "Check Auth!"
                    self.auth(datagram)
                    print "Auth Done!"
                    # in auth def or after the connection will be moved to self.activeConnections
                    # and then removed from the temp list
                    break
                    # Check if the data rechieved is from a valid client.
                elif datagram.getConnection() in self.activeConnections:
                    appendage = {}
                    appendage[0] = self.processData(datagram)
                    appendage[1] = datagram.getConnection()
                    data.append(appendage)

        return data
示例#20
0
class Server:
    def __init__(self, port, backlog=1000, compress=False):
        self.port = port
        self.backlog = backlog
        self.compress = compress
        
        self.cManager = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager,0)
        
        self.activeConnections = [] # We'll want to keep track of these later
        
        self.connect(self.port, self.backlog)
        self.startPolling()

    def connect(self, port, backlog=1000):
        # Bind to our socket
        tcpSocket = self.cManager.openTCPServerRendezvous(port, backlog)
        self.cListener.addConnection(tcpSocket)

    def startPolling(self):
        taskMgr.add(self.tskListenerPolling, "serverListenTask", -40)
        taskMgr.add(self.tskDisconnectPolling, "serverDisconnectTask", -39)
        
    def tskListenerPolling(self, task):
        if self.cListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            newConnection = PointerToConnection()
        
            if self.cListener.getNewConnection(rendezvous, netAddress, newConnection):
                newConnection = newConnection.p()
                self.activeConnections.append(newConnection) # Remember connection
                self.cReader.addConnection(newConnection)     # Begin reading connection
        return Task.cont
    
    def tskDisconnectPolling(self, task):
        while self.cManager.resetConnectionAvailable() == True:
            connPointer = PointerToConnection()
            self.cManager.getResetConnection(connPointer)
            connection = connPointer.p()
            
            # Remove the connection we just found to be "reset" or "disconnected"
            self.cReader.removeConnection(connection)
            
            # Loop through the activeConnections till we find the connection we just deleted
            # and remove it from our activeConnections list
            for c in range(0, len(self.activeConnections)):
                if self.activeConnections[c] == connection:
                    del self.activeConnections[c]
                    break
                    
        return Task.cont
    
    def broadcastData(self, data):
        # Broadcast data out to all activeConnections
        for con in self.activeConnections:
            self.sendData(data, con)
        
    def processData(self, netDatagram):
        myIterator = PyDatagramIterator(netDatagram)
        return self.decode(myIterator.getString())
        
    def getClients(self):
        # return a list of all activeConnections
        return self.activeConnections
        
    def encode(self, data, compress=False):
        # encode(and possibly compress) the data with rencode
        return rencode.dumps(data, compress)
        
    def decode(self, data):
        # decode(and possibly decompress) the data with rencode
        return rencode.loads(data)
        
    def sendData(self, data, con):
        myPyDatagram = PyDatagram()
        myPyDatagram.addString(self.encode(data, self.compress))
        self.cWriter.send(myPyDatagram, con)
    
    def getData(self):
        data = []
        while self.cReader.dataAvailable():
            datagram = NetDatagram()  # catch the incoming data in this instance
            # Check the return value; if we were threaded, someone else could have
            # snagged this data before we did
            if self.cReader.getData(datagram):
                data.append(self.processData(datagram))
        return data
class SocketServer():
    def __init__(self, port, virtual_world, camera_mgr, sync_session):
        self.port = port
        self.virtual_world = virtual_world
        self.cam_mgr = camera_mgr

        self.task_mgr = virtual_world.taskMgr
        self.cManager = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cReader.setRawMode(True)
        self.cWriter = ConnectionWriter(self.cManager, 1)
        self.cWriter.setRawMode(True)
        self.tcpSocket = self.cManager.openTCPServerRendezvous(port, BACKLOG)
        self.cListener.addConnection(self.tcpSocket)

        self.activeSessions = {}
        self.connection_map = {}
        self.set_handlers()

        hostname = socket.gethostname()
        a, b, address_list = socket.gethostbyname_ex(hostname)
        self.ip = address_list[0]
        logging.info("Addresses %s" % address_list)
        logging.info("Server is running on ip: %s, port: %s" %
                     (self.ip, self.port))

        self.client_counter = 0
        self.read_buffer = ''
        self.read_state = 0
        self.read_body_length = 0
        self.packet = SocketPacket()

        controller = virtual_world.getController()
        self.sync = Sync(self.task_mgr, controller, camera_mgr, sync_session)
        self.vv_id = None
        if sync_session:
            logging.info("Waiting for Sync Client!")

        self.showing_info = False
        virtual_world.accept("i", self.toggleInfo)
        self.sync_session = sync_session
        self.createInfoLabel()

        atexit.register(self.exit)

    def createInfoLabel(self):

        string = self.generateInfoString()
        self.info_label = OST(string,
                              pos=(-1.3, -0.5),
                              fg=(1, 1, 1, 1),
                              bg=(0, 0, 0, 0.7),
                              scale=0.05,
                              align=TextNode.ALeft)
        self.info_label.hide()

    def generateInfoString(self, ):
        string = " IP:\t%s  \n" % self.ip
        string += " PORT:\t%s \n" % self.port
        if self.sync_session:
            string += " MODE:\tSync Client\n"
            string += " VV ID:\t%s\n" % self.vv_id
        else:
            string += " MODE:\tAutomatic\n"

        cameras = self.cam_mgr.getCameras()
        num_cameras = len(cameras)

        for camera in cameras:
            id = camera.getId()
            type = camera.getTypeString()
            string += " Cam%s:\t%s\n" % (id, type)
        string += "\n"
        return string

    def set_handlers(self):
        self.task_mgr.add(self.connection_polling, "Poll new connections", -39)
        self.task_mgr.add(self.reader_polling, "Poll reader", -40)
        self.task_mgr.add(self.disconnection_polling, "PollDisconnections",
                          -41)

    def connection_polling(self, taskdata):
        if self.cListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            newConn = PointerToConnection()
            if self.cListener.getNewConnection(rendezvous, netAddress,
                                               newConn):
                conn = newConn.p()
                self.cReader.addConnection(conn)  # Begin reading connection
                conn_id = self.client_counter
                logging.info("New Connection from ip:%s, conn:%s" %
                             (conn.getAddress(), conn_id))
                self.connection_map[conn_id] = conn
                self.client_counter += 1
                message = eVV_ACK_OK(self.ip, self.port, conn_id)
                self.sendMessage(message, conn)

        return Task.cont

    def reader_polling(self, taskdata):

        if self.cReader.dataAvailable():
            datagram = NetDatagram(
            )  # catch the incoming data in this instance
            # Check the return value; if we were threaded, someone else could have
            # snagged this data before we did
            if self.cReader.getData(datagram):
                self.read_buffer = self.read_buffer + datagram.getMessage()
        while (True):
            if self.read_state == 0:
                if len(self.read_buffer) >= self.packet.header_length:
                    bytes_consumed = self.packet.header_length
                    self.packet.header = self.read_buffer[:bytes_consumed]
                    self.read_body_length = self.packet.decode_header()
                    self.read_buffer = self.read_buffer[bytes_consumed:]
                    self.read_state = 1
                else:
                    break
            if self.read_state == 1:
                if len(self.read_buffer) >= self.read_body_length:
                    bytes_consumed = self.read_body_length
                    self.packet.data = self.read_buffer[:bytes_consumed]
                    self.packet.offset = 0
                    self.read_body_length = 0
                    self.read_buffer = self.read_buffer[bytes_consumed:]
                    self.read_state = 0
                    self.new_data_callback(self.packet)

                else:
                    break
        return Task.cont

    def new_data_callback(self, packet):
        packet = copy.deepcopy(packet)
        message_type = packet.get_int()
        conn_id = packet.get_int()
        if message_type == VP_SESSION:
            conn = self.connection_map[conn_id]
            type = packet.get_char()
            pipeline = packet.get_char()
            logging.debug("Received VP_SESSION message from conn:%s, " \
                          "type=%s, pipeline=%s"
                          %(conn_id, VP_TYPE[type], PIPELINE[pipeline]))
            self.newVPSession(conn, type, pipeline, conn_id)

        elif message_type == SYNC_SESSION:
            vv_id = packet.get_int()
            self.vv_id = vv_id
            string = self.generateInfoString()
            self.info_label.setText(string)
            conn = self.connection_map[conn_id]
            logging.debug("Received SYNC_SESSION message from conn:%s" %
                          conn_id)
            self.newSyncSession(conn, conn_id, vv_id)
            logging.info("Sync client connected")

        elif message_type == VP_REQ_CAM_LIST:
            logging.debug("Received VP_REQ_CAM_LIST message from conn:%s" %
                          conn_id)
            cameras = self.cam_mgr.getCameras()
            pipeline = self.activeSessions[conn_id].getPipeline()
            camera_type = None
            if pipeline == STATIC_PIPELINE:
                camera_type = VP_STATIC_CAMERA
            elif pipeline == PTZ_PIPELINE:
                camera_type = VP_ACTIVE_CAMERA
            cam_list = []
            for camera in cameras:
                if camera_type == camera.getType() and not camera.hasSession():
                    cam_list.append(camera.getId())
            message = eVV_CAM_LIST(self.ip, self.port, cam_list)
            conn = self.connection_map[conn_id]
            logging.debug("Sent VV_CAM_LIST message to conn:%s" % conn_id)
            self.sendMessage(message, conn)

        elif message_type == VP_REQ_IMG:
            cam_id = packet.get_int()
            frequency = packet.get_char()
            width = packet.get_int()
            height = packet.get_int()
            jpeg = packet.get_bool()
            data = (frequency, width, height, jpeg)
            camera = self.cam_mgr.getCameraById(cam_id)
            logging.debug("Received VV_REQ_IMG message from conn:%s" % conn_id)
            if camera and not camera.hasSession():
                session = self.activeSessions[conn_id]
                session.addCamera(cam_id)
                camera.setSession(session, VP_BASIC, self.ip, self.port, data)

        else:
            if conn_id in self.activeSessions:
                self.activeSessions[conn_id].newMessage(message_type, packet)

    def newVPSession(self, conn, type, pipeline, conn_id):

        if type == VP_ADVANCED:
            camera_type = -1
            if pipeline == STATIC_PIPELINE:
                camera_type = STATIC_CAMERA  ## Change this to use a different static camera class
            elif pipeline == PTZ_PIPELINE:
                camera_type = ACTIVE_CAMERA
            if camera_type != -1:
                cam = self.cam_mgr.getAvailableCamera(camera_type)
                if cam:
                    session = VPSession(conn_id, conn, self, VP, pipeline)
                    session.addCamera(cam.getId())
                    self.activeSessions[conn_id] = session
                    message = eVV_VP_ACK_OK(self.ip, self.port, cam.getId())
                    logging.debug("Sent VV_VP_ACK_OK message to conn:%s" %
                                  conn_id)
                    self.sendMessage(message, conn)
                    cam.setSession(session, type, self.ip, self.port)

                else:
                    message = eVV_VP_ACK_FAILED(self.ip, self.port)
                    logging.debug("Sent VV_VP_ACK_FAILED message to conn:%s" %
                                  conn_id)
                    self.sendMessage(message, conn)
        else:
            message = eVV_VP_ACK_FAILED(self.ip, self.port)
            logging.debug("Sent VV_VP_ACK_FAILED message to conn:%s" % conn_id)
            self.sendMessage(message, conn)

    def newSyncSession(self, conn, conn_id, vv_id):
        session = SyncSession(conn_id, conn, self, SYNC)
        self.sync.setSession(session, vv_id, self.ip, self.port)
        self.activeSessions[conn_id] = session
        message = eVV_SYNC_ACK(self.ip, self.port, vv_id)
        logging.debug("Sent VV_SYNC_ACK message to conn:%s" % conn_id)
        self.sendMessage(message, conn)

    def sendMessage(self, message, conn):
        self.cWriter.send(message, conn)

    def disconnection_polling(self, taskdata):
        if (self.cManager.resetConnectionAvailable()):
            connectionPointer = PointerToConnection()
            self.cManager.getResetConnection(connectionPointer)
            lostConnection = connectionPointer.p()
            for session in self.activeSessions.values():
                if session.conn == lostConnection:
                    logging.info("Lost Connection from ip:%s, conn:%s" %
                                 (session.client_address, session.conn_id))
                    conn_id = session.conn_id
                    if session.getSessionType() == VP:
                        cameras = session.getCameras()
                        for cam_id in cameras:
                            camera = self.cam_mgr.getCameraById(cam_id)
                            camera.clearSession()

                    del self.activeSessions[conn_id]
                    del self.connection_map[conn_id]
                    break
            self.cManager.closeConnection(lostConnection)
        return Task.cont

    def toggleInfo(self):
        if self.showing_info:
            self.info_label.hide()
            self.showing_info = False
        else:
            self.info_label.show()
            self.showing_info = True

    def exit(self):
        for connection in self.connection_map.values():
            self.cReader.removeConnection(connection)
        self.cManager.closeConnection(self.tcpSocket)
        self.tcpSocket.getSocket().Close()
示例#22
0
文件: Server.py 项目: czorn/Modifire
class Server(DirectObject):
    
    #-----------------
    # Initialization
    #-----------------
    
    def __init__(self):
        self.log = Log()
        self.log.Open('server.txt')
        
        self.activeClients = {}
        self.nextAvailablePid = 0
        
        self.fsm = ServerFSM(self)
        self.fsm.request('LoadingEngine')
        
        self.heartbeat = Heartbeat()
        
        self.chat = ChatBox()
        
        taskMgr.doMethodLater(1, self.CheckForTimedOutClients, 'CheckForTimedOutClients')
        
    def CreateNetworkObjects(self):
        
        if(self.CreateUDPConnection() and self.CreateTCPConnection()):
            self.dataHandler = ServerDataHandler(self)
            self.reliablePacketController = ReliablePacketController(self.cWriter, self.conn, self.dataHandler, self.UDPPacketListenTask)
            self.unreliablePacketController = UnreliablePacketController(self.cWriter, self.conn, self.dataHandler)
            self.tcpPacketController = TCPPacketController(self.tcpWriter, self.tcpReader, self.cManager, self.dataHandler)
            self.dataHandler.SetPacketControllers(self.reliablePacketController, self.unreliablePacketController, self.tcpPacketController)
            
            self.ListenForIncomingTraffic()
            return True
        
        return False
    
    def CreateUDPConnection(self):   
        self.cManager = QueuedConnectionManager()
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager,0)
        self.conn = self.cManager.openUDPConnection(Globals.PORT_SERVER_LISTENER)
        
        if(self.conn):
            self.log.WriteLine('Connection on %s okay.' % (Globals.PORT_SERVER_LISTENER))
        else:
            self.log.WriteError('Connection on %s failed.' % (Globals.PORT_SERVER_LISTENER))
            sys.exit()
            return False
    
        self.cReader.addConnection(self.conn)
        
        return True
    
    def CreateTCPConnection(self):
        self.tcpSocket = self.cManager.openTCPServerRendezvous(Globals.PORT_SERVER_LISTENER, 1000)
        self.tcpWriter = ConnectionWriter(self.cManager,0)
        self.tcpListener = QueuedConnectionListener(self.cManager, 0)
        self.tcpListener.addConnection(self.tcpSocket)
        self.tcpReader = QueuedConnectionReader(self.cManager, 0)
        return True
    
    def ListenForIncomingTraffic(self):
        taskMgr.add(self.UDPPacketListenTask, "UDPPacketListenTask")
        taskMgr.add(self.TCPConnectionListenTask, "TCPConnectionListenTask", -39)
        taskMgr.add(self.TCPPacketListenTask, "TCPPacketListenTask", -40)
    
    def StartBroadcastGameState(self):
        print 'StartBroadcastGameState'
        taskMgr.doMethodLater(Globals.SERVER_SEND_DELAY, self.BroadcastGameState, "BroadcastGameState")
        taskMgr.doMethodLater(2.0, self.BroadcastScoreboard, 'BroadcastScoreboard')
        
    #----------------------
    # Listening for data
    #----------------------
        
    def UDPPacketListenTask(self, task = None):        
        while self.cReader.dataAvailable():
            datagram = NetDatagram()
            if self.cReader.getData(datagram):
                data = PyDatagramIterator(datagram)
                ip = datagram.getAddress().getIpString()
                port = datagram.getAddress().getPort()
                peerAddr = NetAddress()
                peerAddr.setHost(ip, port)
                #print 'GOT UDP PACKET FROM', peerAddr.getIpString(), peerAddr.getPort()
                
                isReliable = data.getUint8()
                if(isReliable == Packet.PC_RELIABLE_PACKET):
                    self.reliablePacketController.OnPacketReceived(data, peerAddr)
                elif(isReliable == Packet.PC_UNRELIABLE_PACKET):
                    self.unreliablePacketController.OnPacketReceived(data, peerAddr)
                    
                if(self.ClientIsConnected(peerAddr)):
                    self.GetActiveClient(peerAddr).timestamp = GameTime.time
                    
        return task.cont
    
    def TCPPacketListenTask(self, task):
        if self.tcpReader.dataAvailable():
            datagram = NetDatagram()
            if self.tcpReader.getData(datagram):
                data = PyDatagramIterator(datagram)
                ip = datagram.getAddress().getIpString()
                port = datagram.getAddress().getPort()
                peerAddr = NetAddress()
                peerAddr.setHost(ip, port)
                
                packetType = data.getUint8()
                if(packetType == Packet.PC_TCP_PACKET):
                    self.tcpPacketController.OnPacketReceived(data, peerAddr)
                    
        return task.cont
    
    def TCPConnectionListenTask(self, task):
        if self.tcpListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            newConnection = PointerToConnection()
        
            if self.tcpListener.getNewConnection(rendezvous, netAddress, newConnection):
                newConnection = newConnection.p()
                self.tcpReader.addConnection(newConnection)
                self.tcpPacketController.AddConnection(newConnection, netAddress)
        return task.cont
        
    def CheckForTimedOutClients(self, task):
        t = GameTime.GetTime()
        for ac in self.activeClients.values():
            if(t - ac.timestamp > 2):
                print 'player timed out', t, ac.timestamp
                self.OnClientDisconnect(ac.peerAddr)
                self.chat.AddMessage('[Server]: ', Vec4(0.9, 0.9, 0.9, 1), '%s timed out' % (ac.name))
                
        return task.again
        
    def IsFull(self):
        return len(self.activeClients) > Globals.MAX_PLAYERS    
    
    def BroadcastScoreboard(self, task = None):
        self.dataHandler.BroadcastScoreboard(self.GetAllPeerAddrs(), self.engine.GetPlayerController().GetAllPlayerStates()) 
        return Task.again
    
    def BroadcastGameState(self, task = None):
        peerAddrs = self.GetAllPeerAddrs()
        
        if(peerAddrs):
            self.dataHandler.BroadcastGameState(peerAddrs, self.engine.GetPlayerController().GetAllPlayerStates())
            #self.game.ClearAllDeltaStates()
        
        if(self.engine.environment.HasChanged()):
            self.dataHandler.BroadcastEnvironmentChange(self.GetAllPeerAddrs(), self.engine.environment.GetDestroyedBlocks(), self.engine.environment.GetAddedBlocks())
            self.engine.environment.ClearBlockNotifications()
        
        return Task.again
    
    def ClientIsConnected(self, peerAddr):
        return Packet.PeerAddrToIpPort(peerAddr) in self.activeClients.keys()
    
    def GetAllPeerAddrs(self):
        peerAddrs = []
        for ac in self.activeClients.values():
            if(ac.engineLoaded):
                peerAddrs.append(ac.peerAddr)
        return peerAddrs
    
    def SendPlayerDeath(self, playerState):
        peerAddrs = self.GetAllPeerAddrs()
        self.dataHandler.SendPlayerDeath(playerState, peerAddrs)
        
    def SendPlayerRespawn(self, playerState):
        peerAddrs = self.GetAllPeerAddrs()
        self.dataHandler.SendPlayerRespawn(playerState, peerAddrs)
    
    #-----------------------------
    # Handling data from clients 
    #----------------------------- 
    
    def OnEngineLoaded(self, peerAddr):
        if(self.ClientIsConnected(peerAddr)):
            ac = self.GetActiveClient(peerAddr)
            ac.timestamp = GameTime.GetTime()
            ac.engineLoaded = True
            
            self.dataHandler.SendListOfConnectedPlayers(peerAddr, self.engine.GetPlayerController().GetAllPlayerStates())
        
    def OnTeamSelect(self, peerAddr, team):
        if(self.ClientIsConnected(peerAddr)):
            ac = self.GetActiveClient(peerAddr)
            self.engine.game.AddPlayerToTeam(self.GetPlayer(ac.pid), team)
            PlayerRespawnEvent(self.engine.playerController.GetPlayer(ac.pid), Point3(random.randint(0, 8), random.randint(0, 8), 50)).Fire()
    
    def AddClient(self, peerAddr, name):
        a = ActiveClient()
        a.peerAddr = peerAddr
        a.pid = self.GetNextPid()
        a.name = name
        self.activeClients[Packet.PeerAddrToIpPort(peerAddr)] = a
        self.engine.GetPlayerController().AddNewPlayer(pid = a.pid, teamId = Game.SPECTATE, name = name)
        self.reliablePacketController.CreatePeerData(peerAddr)
        self.reliablePacketController.SetCurrentPeer(peerAddr)
#        self.reliablePacketController.AddRecvdSeqNum()
#        self.reliablePacketController.currentPeer.mostRecentSeqRecvd = 1
        Globals.CURRENT_PLAYERS = len(self.activeClients)
        
        return a.pid
    
    def OnClientChatMessage(self, messageType, message, peerAddr):
        peerAddrs = []
        for ac in self.activeClients.values():
            if(ac.engineLoaded):
                peerAddrs.append(ac.peerAddr)
        
        if(self.ClientIsConnected(peerAddr)):
            print 'message', message
            if(message.startswith('/')):
                if(message[1:] == 'save'):
                    self.engine.SaveEnvironment()
                    self.dataHandler.SendChatMessage(ChatBox.TYPE_CONSOLE, 255, 'Saving Environment...', peerAddrs)
                    return
                
            pid = self.activeClients[Packet.PeerAddrToIpPort(peerAddr)].pid
            self.dataHandler.SendChatMessage(messageType, pid, message, peerAddrs)
    
    def OnClientDisconnect(self, peerAddr):
        if(self.ClientIsConnected(peerAddr)):
            pid = self.activeClients[Packet.PeerAddrToIpPort(peerAddr)].pid
            self.engine.GetPlayerController().RemovePlayer(pid)
            self.RemovePeer(peerAddr)
            
            self.dataHandler.SendPlayerDisconnect(pid, self.GetAllPeerAddrs())
            self.engine.SaveEnvironment()
        Globals.CURRENT_PLAYERS = len(self.activeClients)
        
    def OnClientItemChange(self, peerAddr, itemId, extraData):
        pid = self.GetActiveClient(peerAddr).pid
        player = self.GetPlayer(pid)
        print 'server item change', player, itemId
        self.engine.GetPlayerController().OtherPlayerItemChange(player, itemId, extraData)
            
    def RemovePeer(self, peerAddr):
        self.reliablePacketController.RemovePeerData(peerAddr)
        self.unreliablePacketController.RemovePeerData(peerAddr)
        if(self.ClientIsConnected(peerAddr)):
            del self.activeClients[Packet.PeerAddrToIpPort(peerAddr)]
    
    def ProcessClientInput(self, peerAddr, keys, lookingDir, clicks, timestamp):
        if(self.ClientIsConnected(peerAddr)):
            pid = self.GetActiveClient(peerAddr).pid
            self.engine.GetPlayerController().QueueClientInput(self.GetPlayer(pid), keys, lookingDir, clicks, timestamp)
        
    def SetLastClientTimestamp(self, peerAddr, timestamp):
        if(self.ClientIsConnected(peerAddr)):
            self.GetActiveClient(peerAddr).timestamp = timestamp
        
    def GetEnvironment(self):
        return self.engine.environment
    
    def GetNextPid(self):
        self.nextAvailablePid += 1
        return self.nextAvailablePid
    
    def GetPlayer(self, pid):
        return self.engine.GetPlayerController().GetPlayer(pid)
    
    def GetName(self, peerAddr):
        if(self.ClientIsConnected(peerAddr)):
            return self.GetActiveClient(peerAddr).name
        else:
            return 'NOT A PLAYER'
    
    def GetActiveClient(self, peerAddr):
        return self.activeClients[Packet.PeerAddrToIpPort(peerAddr)]
    
    def Exit(self):
        self.log.Close()
示例#23
-1
class LoginServer(ShowBase):
	def __init__(self, port, backlog = 1000, compress = False):
		ShowBase.__init__(self)

		self.compress = compress

		self.cManager = QueuedConnectionManager()
		self.cListener = QueuedConnectionListener(self.cManager, 0)
		self.cReader = QueuedConnectionReader(self.cManager, 0)
		self.cWriter = ConnectionWriter(self.cManager,0)
		
		self.clientdb = ClientDataBase()
		if not self.clientdb.connected:
			self.clientdb = None
			print 'Login Server failed to start...'
		else:
			# This is for pre-login
			self.tempConnections = []
			
			# This is for authed clients
			self.activeClients = []
			# This is for authed servers
			self.activeServers = []
			# This is for authed chat servers
			self.activeChats = []
			
			self.connect(port, backlog)
			self.startPolling()
			
			self.taskMgr.doMethodLater(0.5, self.lobbyLoop, 'Lobby Loop')
			
			print 'Login Server operating...'

	def connect(self, port, backlog = 1000):
		# Bind to our socket
		tcpSocket = self.cManager.openTCPServerRendezvous(port, backlog)
		self.cListener.addConnection(tcpSocket)

	def startPolling(self):
		self.taskMgr.add(self.tskListenerPolling, "serverListenTask", -40)
		self.taskMgr.add(self.tskDisconnectPolling, "serverDisconnectTask", -39)

	def tskListenerPolling(self, task):
		if self.cListener.newConnectionAvailable():
			rendezvous = PointerToConnection()
			netAddress = NetAddress()
			newConnection = PointerToConnection()
			if self.cListener.getNewConnection(rendezvous, netAddress, newConnection):
				newConnection = newConnection.p()
				self.tempConnections.append(newConnection)
				self.cReader.addConnection(newConnection)
		return Task.cont

	def tskDisconnectPolling(self, task):
		while self.cManager.resetConnectionAvailable() == True:
			connPointer = PointerToConnection()
			self.cManager.getResetConnection(connPointer)
			connection = connPointer.p()
			
			# Remove the connection
			self.cReader.removeConnection(connection)
			# Check for if it was a client
			for client in self.activeClients:
				if client.connection == connection:
					print 'removing client'
					self.activeClients.remove(client)
					break
			# then check servers
			for server in self.activeServers:
				if server.connection == connection:
					self.activeServers.remove(server)
					break
			# then check servers
			for chat in self.activeChats:
				if chat.connection == connection:
					self.activeChats.remove(chat)
					break
		
		return Task.cont

	def processData(self, netDatagram):
		myIterator = PyDatagramIterator(netDatagram)
		return self.decode(myIterator.getString())

	def encode(self, data, compress = False):
		# encode(and possibly compress) the data with rencode
		return rencode.dumps(data, compress)

	def decode(self, data):
		# decode(and possibly decompress) the data with rencode
		return rencode.loads(data)

	def sendData(self, data, con):
		myPyDatagram = PyDatagram()
		myPyDatagram.addString(self.encode(data, self.compress))
		self.cWriter.send(myPyDatagram, con)
		
	# This will check and do the logins.
	def auth(self, datagram): 
		# If in login state.
		con = datagram.getConnection()
		package = self.processData(datagram)
		if len(package) == 2:
			if package[0] == 'create':
				success, result = self.clientdb.addClient(package[1][0], package[1][1])
				if success:
					self.sendData(('createSuccess', result), con)
				else:
					self.sendData(('createFailed', result), con)
				return False
			if package[0] == 'client':
				userFound = False
				for client in self.activeClients:
					if client.name == package[1][0]:
						userFound = True
						self.sendData(('loginFailed', 'logged'), con)
						break
				if not userFound:
					valid, result = self.clientdb.validateClient(package[1][0], package[1][1])
					if valid:
						self.activeClients.append(Client(package[1][0], con))
						self.sendData(('loginValid', result), con)
						return True
					else:
						self.sendData(('loginFailed', result), con)
						return False
			# if server add it to the list of current active servers
			if package[0] == 'server':
				self.activeServers.append(Server(package[1], con))
				return True
			# if server add it to the list of current active servers
			if package[0] == 'chat':
				self.activeChats.append(Chat(package[1], con))
				return True

	def getData(self):
		data = []
		while self.cReader.dataAvailable():
			datagram = NetDatagram()
			if self.cReader.getData(datagram):
				if datagram.getConnection() in self.tempConnections:
					if self.auth(datagram):
						self.tempConnections.remove(datagram.getConnection())
					continue
				# Check if the data recieved is from a valid client.
				for client in self.activeClients:
					if datagram.getConnection() == client.connection:
						data.append(('client', self.processData(datagram), client))
						break
				# Check if the data recieved is from a valid server.
				for server in self.activeServers:
					if datagram.getConnection() == server.connection:
						data.append(('server', self.processData(datagram), server))
						break
				# Check if the data recieved is from a valid chat.
				for chat in self.activeChats:
					if datagram.getConnection() == chat.connection:
						data.append(('chat', self.processData(datagram), chat))
						break
		return data

	# handles new joining clients and updates all clients of chats and readystatus of players
	def lobbyLoop(self, task):
		# if in lobby state
		temp = self.getData()
		if temp != []:
			for package in temp:
				# handle client incoming packages here
				if package[0] == 'client':
					# This is where packages will come after clients connect to the server
					# will be things like requesting available servers and chat servers
					if package[1] == 'server_query':
						for server in self.activeServers:
							if server.state == 'lobby':
								self.sendData(
									('server', (server.name, str(server.connection.getAddress()))),
									package[2].connection)
						self.sendData(
							('final', 'No more servers'),
							package[2].connection)
				# handle server incoming packages here
				elif package[0] == 'server':
					# auth
					# game state change
					if len(package[1]) == 2:
						if package[1][0] == 'auth':
							clientAuth = False
							print 'Attempting Authentication on: ', package[1][1]
							for client in self.activeClients:
								if client.name == package[1][1]:
									clientAuth = True
									break
							if clientAuth:
								self.sendData(('auth', client.name), package[2].connection)
							else:
								self.sendData(('fail', package[1][1]), package[2].connection)
						elif package[1][0] == 'state':
							package[2].state = package[1][1]
				# handle chat server incoming packages here
				elif package[0] == 'chat':
					print 'Authorized chat server sent package'
					# handle packages from the chat servers
					# like making public/private
					# authing clients
		return task.again