Exemplo n.º 1
0
class TCP():

    def __init__(self, _core):
        print ("TCP Protocol Startup...")
        self.core = _core
        self.config = self.core.server.config


    def start(self):
        self.setupTCP()
        self.startTCPTasks()


    def setupTCP(self):
        self.tcpManager = QueuedConnectionManager()
        self.tcpReader = QueuedConnectionReader(self.tcpManager, 0)
        self.tcpWriter = ConnectionWriter(self.tcpManager, 0)
        self.tcpListener = QueuedConnectionListener(self.tcpManager, 0)

        self.tcpSocket = self.tcpManager.openTCPServerRendezvous(self.config.TCPPORT, self.config.BACKLOG)
        self.tcpListener.addConnection(self.tcpSocket)
        print ("Started Server on: ", self.config.HOSTNAME, self.config.TCPPORT)


    def startTCPTasks(self):
        taskMgr.add(self.tcpListenerTask, "tcpListenerTask", 0)
        print ("TCP Listener Started")
        taskMgr.add(self.tcpReaderTask, "tcpReaderTask", -10)
        print ("TCP Reader Started")
        taskMgr.add(self.tcpDisconnectionHandler, "tcpDisconnectionHandler", 20)
        print ("TCP Disconnection Handler Started")

    # TCP Listener Task
    def tcpListenerTask(self, task):
        """
        Accept new incoming connection from clients, related to TCP
        """
        # Handle new connection
        if self.tcpListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            newConnection = PointerToConnection()
            
            if self.tcpListener.getNewConnection(rendezvous, netAddress, newConnection):
                newConnection = newConnection.p()
                
                # Tell the reader about the new TCP connection
                self.tcpReader.addConnection(newConnection)

                # Handle the connection depending on persistent or not
                if self.core.server.isPersistent:
                    self.core.handleConnection(generateUUID(), newConnection, netAddress)
                else:
                    self.core.createPlayerObject(generateUUID(),newConnection, netAddress)
                    
                print ("Server: New Connection from -", str(netAddress.getIpString()))
            else:
                print ("Server: Connection Failed from -", str(netAddress.getIpString()))    
                    
            
        return Task.cont


    def tcpReaderTask(self, task):
        """
        Handle any data from clients by sending it to the Handlers.
        """
        while 1:
            (datagram, data, opcode) = self.tcpNonBlockingRead(self.tcpReader)
            if opcode is MSG_NONE:
                # Do nothing or use it as some 'keep_alive' thing.
                break
            else:
                # Handle it
                self.core.packetManager.handlePacket(opcode, data, datagram.getAddress())
                
        return Task.cont


    # TCP NonBlockingRead??
    def tcpNonBlockingRead(self, qcr):
        """
        Return a datagram collection and type if data is available on
        the queued connection udpReader
        """
        if self.tcpReader.dataAvailable():
            datagram = NetDatagram()
            if self.tcpReader.getData(datagram):
                data = DatagramIterator(datagram)
                opcode = data.getUint8()

            else:
                data = None
                opcode = MSG_NONE

        else:
            datagram = None
            data = None
            opcode = MSG_NONE

        # Return the datagram to keep a handle on the data
        return (datagram, data, opcode)


    # TCP Disconnection Handler
    def tcpDisconnectionHandler(self, task):
        # Check for resets
        if self.tcpManager.resetConnectionAvailable():
            resetConnection = PointerToConnection()
            self.tcpManager.getResetConnection(resetConnection)
            
            for client in self.core.server.clients:
                if self.core.server.clients[client].connection == resetConnection.p():
                    del self.core.server.clients[client]
                    self.tcpReader.removeConnection(resetConnection.p())
                    print ("Removed Connection:", resetConnection.p())
                    print ('Current Clients:', self.core.server.clients)
                    break

        return Task.cont


    def sendPacket(self, _pkt, _connection):
        self.tcpWriter.send(_pkt, _connection)


    def sendBroadcast(self, _pkt, _skipif=None):
        for client in self.serverManager.clients:
            if _skipif == client:
                pass
            else:
                conn = self.serverManager.clients[client].connection
                self.tcpWriter.send(_pkt, conn)
Exemplo n.º 2
0
class TCP():
    def __init__(self, _core):
        print("TCP Protocol Startup...")
        self.core = _core
        self.config = self.core.server.config

    def start(self):
        self.setupTCP()
        self.startTCPTasks()

    def setupTCP(self):
        self.tcpManager = QueuedConnectionManager()
        self.tcpReader = QueuedConnectionReader(self.tcpManager, 0)
        self.tcpWriter = ConnectionWriter(self.tcpManager, 0)
        self.tcpListener = QueuedConnectionListener(self.tcpManager, 0)

        self.tcpSocket = self.tcpManager.openTCPServerRendezvous(
            self.config.TCPPORT, self.config.BACKLOG)
        self.tcpListener.addConnection(self.tcpSocket)
        print("Started Server on: ", self.config.HOSTNAME, self.config.TCPPORT)

    def startTCPTasks(self):
        taskMgr.add(self.tcpListenerTask, "tcpListenerTask", 0)
        print("TCP Listener Started")
        taskMgr.add(self.tcpReaderTask, "tcpReaderTask", -10)
        print("TCP Reader Started")
        taskMgr.add(self.tcpDisconnectionHandler, "tcpDisconnectionHandler",
                    20)
        print("TCP Disconnection Handler Started")

    # TCP Listener Task
    def tcpListenerTask(self, task):
        """
        Accept new incoming connection from clients, related to TCP
        """
        # Handle new connection
        if self.tcpListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            newConnection = PointerToConnection()

            if self.tcpListener.getNewConnection(rendezvous, netAddress,
                                                 newConnection):
                newConnection = newConnection.p()

                # Tell the reader about the new TCP connection
                self.tcpReader.addConnection(newConnection)

                # Handle the connection depending on persistent or not
                if self.core.server.isPersistent:
                    self.core.handleConnection(generateUUID(), newConnection,
                                               netAddress)
                else:
                    self.core.createPlayerObject(generateUUID(), newConnection,
                                                 netAddress)

                print("Server: New Connection from -",
                      str(netAddress.getIpString()))
            else:
                print("Server: Connection Failed from -",
                      str(netAddress.getIpString()))

        return Task.cont

    def tcpReaderTask(self, task):
        """
        Handle any data from clients by sending it to the Handlers.
        """
        while 1:
            (datagram, data, opcode) = self.tcpNonBlockingRead(self.tcpReader)
            if opcode is MSG_NONE:
                # Do nothing or use it as some 'keep_alive' thing.
                break
            else:
                # Handle it
                self.core.packetManager.handlePacket(opcode, data,
                                                     datagram.getAddress())

        return Task.cont

    # TCP NonBlockingRead??
    def tcpNonBlockingRead(self, qcr):
        """
        Return a datagram collection and type if data is available on
        the queued connection udpReader
        """
        if self.tcpReader.dataAvailable():
            datagram = NetDatagram()
            if self.tcpReader.getData(datagram):
                data = DatagramIterator(datagram)
                opcode = data.getUint8()

            else:
                data = None
                opcode = MSG_NONE

        else:
            datagram = None
            data = None
            opcode = MSG_NONE

        # Return the datagram to keep a handle on the data
        return (datagram, data, opcode)

    # TCP Disconnection Handler
    def tcpDisconnectionHandler(self, task):
        # Check for resets
        if self.tcpManager.resetConnectionAvailable():
            resetConnection = PointerToConnection()
            self.tcpManager.getResetConnection(resetConnection)

            for client in self.core.server.clients:
                if self.core.server.clients[
                        client].connection == resetConnection.p():
                    del self.core.server.clients[client]
                    self.tcpReader.removeConnection(resetConnection.p())
                    print("Removed Connection:", resetConnection.p())
                    print('Current Clients:', self.core.server.clients)
                    break

        return Task.cont

    def sendPacket(self, _pkt, _connection):
        self.tcpWriter.send(_pkt, _connection)

    def sendBroadcast(self, _pkt, _skipif=None):
        for client in self.serverManager.clients:
            if _skipif == client:
                pass
            else:
                conn = self.serverManager.clients[client].connection
                self.tcpWriter.send(_pkt, conn)
Exemplo n.º 3
0
class Server:
    def __init__(self):

        self.port = 5555
        self.addr = "127.0.0.1"
        self.backlog = 7
        self.active_connections = dict()
        self.start = False

        self.connect()

    def connect(self) -> None:
        # Handle connections and terminations
        self.manager = QueuedConnectionManager()
        # Wait for clients connection requests
        self.listener = QueuedConnectionListener(self.manager, 0)
        # Buffers incoming data from active connection
        self.reader = QueuedConnectionReader(self.manager, 0)
        # Transmit PyDatagrams to active connection
        self.writer = ConnectionWriter(self.manager, 0)
        # Open TCP Rendezvous to accept client connections with a limit
        self.socket = self.manager.openTCPServerRendezvous(
            self.port, self.backlog)
        self.listener.addConnection(self.socket)
        print("Server listening on port %s...." % str(self.port))
        # Listen for mew incoming connections
        taskMgr.add(self.handle_incoming_connections,
                    "Poll the connection listener", -39)
        # Listen for new datagrams
        taskMgr.add(self.handle_connection_data,
                    "Poll the connection reader", -40)
        # Listen for dropped connections
        taskMgr.add(self.handle_dropped_connections,
                    "Poll the dropped connection listener", -41)
        # See if game can be started
        taskMgr.add(self.start_game, "Start Game", -42)

    def start_game(self, task_data: Task) -> Task:
        if len(self.active_connections) == self.backlog:
            self.start = True
        return Task.cont

    def handle_incoming_connections(self, task_data: Task) -> Task:
        if self.listener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            net_addr = NetAddress()
            new_connection = PointerToConnection()
            if self.listener.getNewConnection(rendezvous, net_addr, new_connection):
                new_connection = new_connection.p()
                # Keep track of our active connections
                self.active_connections[str(
                    new_connection.this)] = new_connection
                # Start reading the new connection
                self.reader.addConnection(new_connection)
                print("%s just connected" % str(new_connection))
        return Task.cont

    def handle_connection_data(self, task_data: Task) -> Task:
        if self.reader.dataAvailable():
            # Catch the incoming data
            datagram = NetDatagram()
            if self.reader.getData(datagram):
                name = self.handle_client_message(datagram)
                broadcast = f"Everyone, welcome {name} to the game!"
                self.broadcast_message(broadcast)

        return Task.cont

    def handle_dropped_connections(self, task_data: Task) -> Task:
        if self.manager.resetConnectionAvailable():
            connection_pointer = PointerToConnection()
            self.manager.getResetConnection(connection_pointer)
            lost_connection = connection_pointer.p()
            print("% s disconnected from server" % str(lost_connection))
            del self.active_connections[str(lost_connection.this)]
            self.manager.closeConnection(lost_connection)
        return Task.cont

    def handle_client_message(self, message: str) -> str:
        iterator = PyDatagramIterator(message)
        return iterator.getString()

    def get_connections_count(self) -> int:
        return len(self.active_connections)

    def send_personal_message(self, message: str, client: PointerToConnection) -> None:
        datagram = self.create_new_datagram(message)
        self.writer.send(datagram, client)

    def broadcast_message(self, message: str) -> None:
        datagram = self.create_new_datagram(message)
        for client in self.active_connections:
            self.writer.send(datagram, self.active_connections[client])

    def create_new_datagram(self, message: str) -> PyDatagram:
        new_datagram = PyDatagram()
        new_datagram.addString(message)
        return new_datagram

    def terminate_all_clients(self) -> None:
        for client in self.active_connections:
            self.reader.removeConnection(client)
        self.active_connections = list()

    def terminate_specific_client(self, client: PointerToConnection) -> None:
        self.reader.removeConnection(client)
        del self.active_connections[str(client)]
Exemplo n.º 4
0
class Client(DirectObject):
    def __init__(self,
                 host,
                 port,
                 timeout=3000,
                 compress=False,
                 connectionStateChangedHandler=None):
        DirectObject.__init__(self)

        self.connectionStateChangedHandler = connectionStateChangedHandler

        self.myConnection = None

        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)

    def cleanup(self):
        self.removeAllTasks()

    def startPolling(self):
        self.doMethodLater(0.1, self.tskDisconnectPolling,
                           "clientDisconnectTask")

    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.myConnection.setNoDelay(True)
            self.myConnection.setKeepAlive(True)
            print "Connected"
            self.cReader.addConnection(
                self.myConnection)  # receive messages from server
            self.connected = True  # Let us know that we're connected
            self.startPolling()
            if self.connectionStateChangedHandler:
                self.connectionStateChangedHandler.handleConnection()
        else:
            print "Unable to connect"
            if self.connectionStateChangedHandler:
                self.connectionStateChangedHandler.handleFailure()

    def tskDisconnectPolling(self, task):
        if not self.connected:
            return Task.done

        # TODO: Hacky sending nothing to force disconnect triggers
        #self.sendData()
        # Also checking for dataAvailable on reader will trigger the connection disconnected
        self.cReader.dataAvailable()
        # TODO: Confirm this works for client side (to both game server and master server)
        while self.cManager.resetConnectionAvailable():
            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
            print "disconnected"

            if self.connectionStateChangedHandler:
                self.connectionStateChangedHandler.handleDisconnection()

        return Task.again

    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=None):
        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 = self.passedData
        self.passedData = []
        while self.cReader.dataAvailable():
            datagram = NetDatagram()
            if self.cReader.getData(datagram):
                data.append(self.processData(datagram))
        return data
Exemplo n.º 5
0
class NetworkManager:
    def __init__(self):
        print "Network Manager Started"

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

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

        self.cListener = QueuedConnectionListener(self.cManager, 0)
        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)
        print "Network Connection Opened"
        taskMgr.add(self.tskListenerPolling,"Poll the connection listener",-39)
        taskMgr.add(self.tskReaderPolling,"Poll the connection reader",-40)

    def connection_close(self):
        for aClient in self.activeConnections:
            self.cReader.removeConnection(aClient)
        self.activeConnections=[]

         # close down our listener
        self.cManager.closeConnection(self.tcpSocket)
        print "Network Connection Closed"

    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
        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):
                if base.client == True:
                    self.client_processing(datagram)
                else:
                    self.server_processing(datagram)
        return Task.cont

    def server_messager(self,msg,args=[]):
        if msg == "map_set":
            order = PyDatagram()
            order.addUint16(MAP_SET)
            order.addInt32(args[0])
            self.send_package(order)
        elif msg == "client_update":
            order = PyDatagram()
            order.addUint16(CLIENT_INIT_UPDATE)
            order.addString(args[0])
            order.addString(args[1])
            order.addInt32(args[2])
            order.addInt32(args[3])
            self.send_package(order)
        elif msg == "chat_send":
            r = args[0][0]
            g = args[0][1]
            b = args[0][2]
            order = PyDatagram()
            order.addUint16(SERVER_CHAT)
            order.addInt32(r)
            order.addInt32(g)
            order.addInt32(b)
            order.addString(args[1])
            self.send_package(order)
            base.menu_manager.menus["mp-game"].chat_add((r,g,b,1),args[1])
        elif msg == "ready_button":
            order = PyDatagram()
            order.addUint16(SERVER_READY)
            order.addInt32(args[0])
            order.addInt32(args[1])
            self.send_package(order)
            base.menu_manager.menus["mp-game"].obj_list[args[0]]["indicatorValue"]=args[1]
            base.menu_manager.menus["mp-game"].start_game_check()
        elif msg == "server_loaded":
            order = PyDatagram()
            order.addUint16(SERVER_LOADED)
            self.send_package(order)
        elif msg == "all_loaded":
            order = PyDatagram()
            order.addUint16(ALL_LOADED)
            self.send_package(order)
        elif msg == "game_start":
            order = PyDatagram()
            order.addUint16(GAME_START)
            self.send_package(order)
        elif msg == "army_kill":
            order = PyDatagram()
            order.addUint16(ARMY_KILL)
            order.addInt32(args[0])
            self.send_package(order)
        elif msg == "build_start":
            order = PyDatagram()
            order.addUint16(BUILD_START)
            order.addInt32(args[0])
            order.addInt8(args[1])
            order.addString(args[2])
            self.send_package(order)
        elif msg == "tower_capture":
            order = PyDatagram()
            order.addUint16(TOWER_CAPTURE)
            order.addInt32(args[0])
            order.addInt8(args[1])
            self.send_package(order)
        elif msg == "build_complete":
            order = PyDatagram()
            order.addUint16(BUILD_COMPLETE)
            order.addInt32(args[0])
            order.addInt8(args[1])
            order.addString(args[2])
            self.send_package(order)
        elif msg == "build_cancel":
            order = PyDatagram()
            order.addUint16(BUILD_CANCEL)
            order.addInt32(args[0])
            self.send_package(order)
        elif msg == "battle_start":
            order = PyDatagram()
            order.addUint16(BATTLE_START)
            order.addInt32(args[0])
            order.addFloat32(args[1])
            order.addFloat32(args[2])
            order.addInt32(args[3])
            order.addFloat32(args[4])
            order.addFloat32(args[5])
            order.addInt32(args[6])
            self.send_package(order)
        elif msg == "battle_clash":
            order = PyDatagram()
            order.addUint16(BATTLE_CLASH)
            order.addInt32(args[0])
            order.addInt32(args[1])
            order.addInt32(args[2])
            order.addString(args[3])
            order.addInt8(args[4])
            self.send_package(order)
        elif msg == "battle_turn":
            order = PyDatagram()
            order.addUint16(BATTLE_TURN)
            order.addInt32(args[0])
            order.addInt32(args[1])
            self.send_package(order)
        elif msg == "battle_end":
            order = PyDatagram()
            order.addUint16(BATTLE_END)
            order.addInt32(args[0])
            self.send_package(order)
        elif msg == "battle_armyadd":
            order = PyDatagram()
            order.addUint16(BATTLE_ARMYADD)
            order.addInt32(args[0])
            order.addInt32(args[1])
            order.addFloat32(args[2])
            order.addFloat32(args[3])
            self.send_package(order)


    def client_messager(self,msg,args=[]):
        if msg == "chat_send":
            order = PyDatagram()
            order.addUint16(CLIENT_CHAT)
            order.addInt32(args[0][0])
            order.addInt32(args[0][1])
            order.addInt32(args[0][2])
            order.addString(args[1])
            self.send_package(order)
        elif msg == "ready_button":
            order = PyDatagram()
            order.addUint16(CLIENT_READY)
            order.addInt32(args[0])
            order.addInt32(args[1])
            self.send_package(order)
        elif msg == "client_loaded":
            order = PyDatagram()
            order.addUint16(CLIENT_LOADED)
            self.send_package(order)
        elif msg == "game_init_request":
            order = PyDatagram()
            order.addUint16(CLIENT_INIT_REQUEST)
            order.addString(args[0])
            order.addString(args[1])
            self.send_package(order)
        elif msg == "build_start_request":
            order = PyDatagram()
            order.addUint16(BUILD_START_REQUEST)
            order.addInt32(args[0])
            order.addInt32(args[1])
            order.addString(args[2])
            self.send_package(order)
        elif msg == "build_cancel_request":
            order = PyDatagram()
            order.addUint16(BUILD_CANCEL_REQUEST)
            order.addInt32(args[0])
            self.send_package(order)

    def client_processing(self,datagram):
        data_iter = PyDatagramIterator(datagram)
        msgID = data_iter.getUint16()
        if msgID == PRINT_MESSAGE:
            messageToPrint = data_iter.getString()
            print messageToPrint
        if msgID == ARMY_MOVE:
            army_id = data_iter.getInt16()
            ax = data_iter.getFloat64()
            ay = data_iter.getFloat64()
            tx = data_iter.getFloat64()
            ty = data_iter.getFloat64()
            base.armies[army_id].node_path.setX(ax)
            base.armies[army_id].node_path.setY(ay)
            base.armies[army_id].move_to_point(tx,ty)
        if msgID == CLIENT_INIT_UPDATE:
            p1_name = data_iter.getString()
            p1_kingdom = data_iter.getString()
            p1_ready = data_iter.getInt32()
            game_map = data_iter.getInt32()
            base.menu_manager.menus["mp-game"].client_update(p1_name,p1_kingdom,p1_ready,game_map)
        if msgID == SERVER_CHAT:
            r = data_iter.getInt32()
            g = data_iter.getInt32()
            b = data_iter.getInt32()
            text = data_iter.getString()
            base.menu_manager.menus["mp-game"].chat_add((r,g,b),text)
        if msgID == SERVER_READY:
            but_id = data_iter.getInt32()
            state = data_iter.getInt32()
            base.menu_manager.menus["mp-game"].obj_list[but_id]["indicatorValue"]=state
            base.menu_manager.menus["mp-game"].start_game_check()
        if msgID == SERVER_LOADED:
            base.menu_manager.menus["mp-load"].load()
        if msgID == ALL_LOADED:
            base.menu_manager.menus["mp-load"].load_complete()
        if msgID == GAME_START:
            base.menu_manager.menu_goto("mp-load")
        if msgID == MAP_SET:
            map = data_iter.getInt32()
            base.menu_manager.menus["mp-game"].map_selected = map
            mapname = base.menu_manager.menus["mp-game"].maplist[map]["fullname"]
            mapimage = base.menu_manager.menus["mp-game"].maplist[map]["preview"]
            base.menu_manager.menus["mp-game"].obj_list[11]["text"]=mapname
            base.menu_manager.menus["mp-game"].obj_list[10].setImage(mapimage)
        if msgID == BATTLE_TURN:
            bat = data_iter.getInt32()
            turn = data_iter.getInt32()
            base.battles[bat].turn_change(turn)
        if msgID == BATTLE_START:
            a1 = data_iter.getInt32()
            a1_x = data_iter.getFloat32()
            a1_y = data_iter.getFloat32()
            a2 = data_iter.getInt32()
            a2_x = data_iter.getFloat32()
            a2_y = data_iter.getFloat32()
            army_start = data_iter.getInt32()
            base.armies[a1].stop()
            base.armies[a2].stop()
            base.armies[a1].node_path.setPos(a1_x,a1_y,0)
            base.armies[a2].node_path.setPos(a2_x,a2_y,0)
            base.battles.append(TimObjects.Battle([base.armies[a1],base.armies[a2]],army_start))
        if msgID == BATTLE_CLASH:
            battle = data_iter.getInt32()
            a1 = data_iter.getInt32()
            a2 = data_iter.getInt32()
            result = data_iter.getString()
            buff = data_iter.getInt8()
            base.battles[battle].clash(base.armies[a1],base.armies[a2],result,buff)
        if msgID == BATTLE_ARMYADD:
            bat = data_iter.getInt32()
            army = data_iter.getInt32()
            a_x = data_iter.getFloat32()
            a_y = data_iter.getFloat32()
            base.battles[bat].add_army(base.armies[army])
            base.armies[army].node_path.setPos(a_x,a_y,0)
        if msgID == BATTLE_END:
            bat = data_iter.getInt32()
            base.battles[bat].end()
        if msgID == BUILD_START:
            t_id = data_iter.getInt32()
            player = data_iter.getInt8()
            type = data_iter.getString()
            base.towers[t_id].build_start()
        if msgID == TOWER_CAPTURE:
            t_id = data_iter.getInt32()
            player = data_iter.getInt8()
            base.towers[t_id].change_owner(player)
        if msgID == BUILD_CANCEL:
            t_id = data_iter.getInt32()
            base.towers[t_id].build_cancel()
        if msgID == BUILD_COMPLETE:
            t_id = data_iter.getInt32()
            player = data_iter.getInt8()
            type = data_iter.getString()
            base.towers[t_id].create_counter()

    def server_processing(self,datagram):
        data_iter = PyDatagramIterator(datagram)
        msgID = data_iter.getUint16()
        if msgID == PRINT_MESSAGE:
            messageToPrint = data_iter.getString()
            print messageToPrint
        if msgID == ARMY_MOVE_REQUEST:
            army_id = data_iter.getInt16()
            ax = data_iter.getFloat64()
            ay = data_iter.getFloat64()
            tx = data_iter.getFloat64()
            ty = data_iter.getFloat64()
            base.armies[army_id].set_target(False,tx,ty)
        if msgID == CLIENT_CHAT:
            r = data_iter.getInt32()
            g = data_iter.getInt32()
            b = data_iter.getInt32()
            text = data_iter.getString()
            self.server_messager("chat_send",[(r,g,b),text])
            #base.main_menu.chat_add((r,g,b,1),text)
        if msgID == CLIENT_READY:
            but_id = data_iter.getInt32()
            state = data_iter.getInt32()
            self.server_messager("ready_button",[but_id,state])
            #base.main_menu.chat_add((r,g,b,1),text)
        if msgID == CLIENT_LOADED:
            self.server_messager("all_loaded",[])
            base.menu_manager.menus["mp-load"].load_complete()
        if msgID == CLIENT_INIT_REQUEST:
            pn = data_iter.getString()
            pk = data_iter.getString()
            base.menu_manager.menus["mp-game"].obj_list[6]["text"] = pn
            base.menu_manager.menus["mp-game"].obj_list[7]["text"] = pk
            self.server_messager("client_update",[base.menu_manager.menus["mp-game"].obj_list[4]["text"],
                                                 base.menu_manager.menus["mp-game"].obj_list[5]["text"],
                                                 base.menu_manager.menus["mp-game"].obj_list[8]["indicatorValue"],
                                                 base.menu_manager.menus["mp-game"].map_selected])
        if msgID == BUILD_START_REQUEST:
            t_id = data_iter.getInt32()
            player = data_iter.getInt32()
            type = data_iter.getString()
            base.towers[t_id].build_start()
        if msgID == BUILD_CANCEL_REQUEST:
            t_id = data_iter.getInt32()
            player = data_iter.getInt32()
            type = data_iter.getString()
            base.towers[t_id].build_cancel()

    def msgAllClients(self):
        myPyDatagram=self.myNewPyDatagram()  # build a datagram to send
        for aClient in self.activeConnections:
            self.cWriter.send(myPyDatagram,aClient)

    def send_package(self,package):
#        print "packaged"
        for aClient in self.activeConnections:
            print "Package",package,"sent"
            self.cWriter.send(package,aClient)

    def army_move(self,army_id,tx,ty):
        order = PyDatagram()
        if base.client == True:
            order.addUint16(ARMY_MOVE_REQUEST)
        else:
            order.addUint16(ARMY_MOVE)
        ax = base.armies[army_id].node_path.getX()
        ay = base.armies[army_id].node_path.getY()
        order.addInt16(army_id)
        order.addFloat64(ax)
        order.addFloat64(ay)
        order.addFloat64(tx)
        order.addFloat64(ty)
        if base.client == True:
            self.cWriter.send(order,base.server_connection)
        else:
            self.send_package(order)
            base.armies[army_id].move_to_point(tx,ty)

    def tower_train(self,tower_id,build_object):
        order = PyDatagram()
        if base.client == True:
            order.addUint16(REQUEST_TOWER_TRAIN)
        else:
            order.addUint16(TOWER_TRAIN)
        order.addInt16(army_id)
        order.addFloat64(tx)
        order.addFloat64(ty)
        if base.client == True:
            self.cWriter.send(order,base.server_connection)
        else:
            self.send_package(order)
            base.towers[tower_id].train_counter()

#    def request_army_move(self,army_id,tx,ty):
#        order = PyDatagram()
#        order.addUint16(REQUEST_MOVE_COUNTER)
#        order.addInt16(army_id)
#        order.addFloat64(tx)
#        order.addFloat64(ty)
#        self.cWriter.send(order,base.server_connection)

    def myNewPyDatagram(self):
        # Send a test message
        myPyDatagram = PyDatagram()
        myPyDatagram.addUint16(PRINT_MESSAGE)
        myPyDatagram.addString("You got ze message!")
        return myPyDatagram

    def client_connect(self,ip):
        port_address=9099  # same for client and server

         # a valid server URL. You can also use a DNS name
         # if the server has one, such as "localhost" or "panda3d.org"
        ip_address=ip

         # how long until we give up trying to reach the server?
        timeout_in_miliseconds=3000  # 3 seconds

        base.server_connection=self.cManager.openTCPClientConnection(ip_address,port_address,timeout_in_miliseconds)

        if base.server_connection:
            self.cReader.addConnection(base.server_connection)  # receive messages from server
            self.activeConnections.append(base.server_connection)
            print "Connected to server",ip
            return True
        print "Connection failed"
        return False
Exemplo n.º 6
0
class Server(DirectObject):
    # TODO: Perhaps a better way to do this?
    handleNewConnection = None
    handleLostConnection = None

    def __init__(self, port, backlog=1000, compress=False):
        DirectObject.__init__(self)

        self.port = port
        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.passedData = []

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

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

    def startPolling(self):
        self.addTask(self.tskListenerPolling, "serverListenTask", -40)
        self.addTask(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)
                newConnection.setKeepAlive(True)
                if self.handleNewConnection:
                    self.handleNewConnection(newConnection)
                self.cReader.addConnection(
                    newConnection)  # Begin reading connection
        return Task.cont

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

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

            if self.handleLostConnection:
                self.handleLostConnection(connection)

        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)

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

    def getData(self):
        data = self.passedData
        self.passedData = []
        while self.cReader.dataAvailable():
            datagram = NetDatagram()
            if self.cReader.getData(datagram):
                data.append(
                    (datagram.getConnection(), self.processData(datagram)))
        return data
Exemplo n.º 7
0
class Server(object):

    # https://www.panda3d.org/manual/index.php/Client-Server_Connection

    def __init__(self, host="localhost", port=5001):
        taskMgr = Task.TaskManager()

        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.readerCallbacks = []

        backlog = 1000  #If we ignore 1,000 connection attempts, something is wrong!
        self.tcpSocket = self.cManager.openTCPServerRendezvous(port, backlog)
        self.cListener.addConnection(self.tcpSocket)

        taskMgr.add(self.tskListenerPolling, "Poll the connection listener",
                    -39)
        taskMgr.add(self.tskReaderPolling, "Poll the connection reader", -40)
        print("started server! ({} at {})".format(port, host))

    def Start(self):
        # derived servers can overwrite this function if needed
        pass

    def tskListenerPolling(self, taskdata):
        # listen for new connections
        # TODO(victor): what happens if a client shuts down?
        # print("server.tskListenerPolling()")
        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
                print("server: received new connection!")
        return Task.cont

    def tskReaderPolling(self, taskdata):
        # reader callback
        if not self.cReader.dataAvailable():
            return Task.cont

        # 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
        datagram = NetDatagram()
        if not self.cReader.getData(datagram):
            return Task.cont

        for callback in self.readerCallbacks:
            callback(datagram)

        return Task.cont

    def addReaderCallback(self, callbackFunction):
        self.readerCallbacks.append(callbackFunction)

    def BroadcastMessage(self, datagram):
        # send the same message to all clients
        for client in self.activeConnections:
            self.cWriter.send(datagram, client)

    def Close(self):
        # remove all clients
        for client in self.activeConnections:
            self.cReader.removeConnection(client)
            self.activeConnections = []

        # close down our listener
        self.cManager.closeConnection(self.tcpSocket)