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)
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()
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 
Exemple #4
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
Exemple #5
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()
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)
Exemple #7
0
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)
Exemple #8
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
Exemple #9
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 disconnect(self):
        # Connect to our host's socket
        self.cManager.closeConnection(self.myConnection)
        self.connected = False  # 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
Exemple #10
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 disconnect(self):
        # Connect to our host's socket
        self.cManager.closeConnection(self.myConnection)
        self.connected = False  # 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
Exemple #11
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 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()