Exemple #1
0
class Client(object):
    def __init__(self, host="localhost", port=5001, name="client"):
        self.name = name

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

        self.readerCallbacks = []

        taskMgr = Task.TaskManager()

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

        self.myConnection = self.cManager.openTCPClientConnection(
            host, port, timeout_in_miliseconds)
        if not self.myConnection:
            print("{}: Failed to connect to server!".format(self.name))
            return

        self.cReader.addConnection(
            self.myConnection)  # receive messages from server
        taskMgr.add(self.tskReaderPolling, "Poll the connection reader", -40)
        print("{}: Successfully connected to server {} at {}!".format(
            self.name, port, host))

    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 ProcessReaderData(self, data):
        # TODO(vicdie): overwrite in derived classes
        pass

    def Close(self):
        # close connection if it exists
        if self.myConnection:
            self.cManager.closeConnection(self.myConnection)
class Network():
	def __init__(self):
		self.c_manager = QueuedConnectionManager()
		self.c_listener = QueuedConnectionListener(self.c_manager, 0)
		self.c_reader = QueuedConnectionReader(self.c_manager, 0)
		self.c_writer = ConnectionWriter(self.c_manager,0)

		self.active_conns=[]

		self.port_address=9099 #No-other TCP/IP services are using this port
		self.backlog=1000 #If we ignore 1,000 connection attempts, something is wrong!

		#tcp_socket = c_manager.openTCPServerRendezvous(port_address,backlog)
		#self.tcp_socket = self.c_manager.openTCPServerRendezvous("0.0.0.0", 9099, 1000)
		#self.c_listener.addConnection(self.tcp_socket)

	def tsk_listener_pol(self, taskdata):
		if self.c_listener.newConnectionAvailable():

			rendezvous = PointerToConnection()
			netAddress = NetAddress()
			newConnection = PointerToConnection()

			if self.c_listener.getNewConnection(rendezvous,netAddress,newConnection):
				print("Connected: "+str(netAddress))
				newConnection = newConnection.p()
				self.active_conns.append(newConnection) # Remember connection
				self.c_reader.addConnection(newConnection)     # Begin reading connection
		return Task.cont

	def tsk_reader_pol(self, taskdata):
		if self.c_reader.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.c_reader.getData(datagram):
				self.data_process(datagram)
		return Task.cont

	def data_process(self, datagram):
			it = PyDatagramIterator(datagram)
			message = it.getString()
			print("Processed: "+message+" from: "+str(datagram.getAddress()))

	def listen(self):
		print("Now listening on all addresses on port 9099")
		self.tcp_socket = self.c_manager.openTCPServerRendezvous("0.0.0.0", 9099, 1000)
		self.c_listener.addConnection(self.tcp_socket)
		taskMgr.add(self.tsk_listener_pol, "Poll connection listener", -39)
		taskMgr.add(self.tsk_reader_pol, "Pol the connection reader", -40)

	def unlisten(self):
		print("Stopping listen")
		self.c_manager.closeConnection(self.tcp_socket)
Exemple #3
0
class Client(ShowBase):
    def __init__(self):
        ShowBase.__init__(self, windowType='none')

        self.port = 5555
        self.addr = "127.0.0.1"
        self.timeout = 3000

        self.connect_to_server()

    def connect_to_server(self) -> None:
        self.manager = QueuedConnectionManager()
        self.reader = QueuedConnectionReader(self.manager, 0)
        self.writer = ConnectionWriter(self.manager, 0)
        try:
            self.connection = self.manager.openTCPClientConnection(
                self.addr, self.port, self.timeout)
            # Listen for data sent from server
            taskMgr.add(self.handle_server_connection,
                        "Poll the connection listener", -40)
            print("Connected to server...")
            self.reader.addConnection(self.connection)
            taskMgr.add(self.send_server_message, "Send msg", -41)
        except:
            print("Server not connected...")

    def handle_server_connection(self, task_data: Task) -> Task:
        if self.reader.dataAvailable():
            datagram = PyDatagram()
            if self.reader.getData(datagram):
                self.handle_server_message(datagram)
        return Task.cont

    def send_server_message(self, task_data: Task) -> None:
        new_datagram = PyDatagram()
        name = input("What's your name? ")
        new_datagram.addString(name)
        self.writer.send(new_datagram, self.connection)

    def handle_server_message(self, message: str) -> None:
        iterator = PyDatagramIterator(message)
        print(iterator.getString())
Exemple #4
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)]
class Connection(ShowBase):
    def __init__(self):

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

        try:
            host = "localhost"
            port = 9252
            self.connection = self.cManager.openTCPClientConnection(host, port, 10000)

            self.received = 1

            if self.connection:
                self.cReader.addConnection(self.connection)
                taskMgr.add(self.updateRoutine, "updateRoutine")
                # taskMgr.add(self.message, 'message')
        except:
            pass

            # def message(self, task):
            # 	self.option = 0
            # 	self.option = str(raw_input("1-Send integer\n2-Send string\n3-Send short\n4-Send float\n"))
            # 	if self.option == "1":
            # 		msg = int(100 * random.random()) - 50
            # 		request = self.intRequest(msg)
            # 		self.cWriter.send(request,self.connection)
            # 		print "sent ", msg
            # 		taskMgr.remove('message')
            # 	elif self.option == "2":
            # 		msg = ''.join(random.choice('abcdefghijklmnopqrstuvwxyz') for x in range(7))
            # 		request = self.stringRequest(msg)
            # 		self.cWriter.send(request,self.connection)
            # 		print "sent ", msg
            # 		taskMgr.remove('message')
            # 	elif self.option == "3":
            # 		msg = int(100 * random.random())
            # 		request = self.shortRequest(msg)
            # 		self.cWriter.send(request,self.connection)
            # 		print "sent ", msg
            # 		taskMgr.remove('message')
            # 	elif self.option == "4":
            # 		msg = 100 * random.random()
            # 		request = self.floatRequest(msg)
            # 		self.cWriter.send(request,self.connection)
            # 		print "sent ", msg
            # 		taskMgr.remove('message')

    def intRequest(self, msg):
        pkg = PyDatagram()
        pkg.addUint16(1)
        pkg.addInt32(msg)
        return pkg

    def stringRequest(self, msg):
        pkg = PyDatagram()
        pkg.addUint16(2)
        pkg.addString(msg)
        return pkg

    def shortRequest(self, msg):
        pkg = PyDatagram()
        pkg.addUint16(3)
        pkg.addUint16(msg)
        return pkg

    def floatRequest(self, msg):
        pkg = PyDatagram()
        pkg.addUint16(4)
        pkg.addFloat32(msg)
        return pkg

    def loginRequest(self, username, password):
        pkg = PyDatagram()
        pkg.addUint16(101)
        pkg.addString(username)
        pkg.addString(password)
        return pkg

    def registerRequest(self, username, password):
        pkg = PyDatagram()
        pkg.addUint16(103)
        pkg.addString(username)
        pkg.addString(password)
        return pkg

    def characterCreationRequest(self, username, classType):
        pkg = PyDatagram()
        pkg.addUint16(104)
        pkg.addString(username)
        pkg.addUint16(0)
        pkg.addUint16(classType)
        return pkg

    def chatRequest(self, message):
        pkg = PyDatagram()
        pkg.addUint16(105)
        pkg.addString(message)
        return pkg

    def moveRequest(self, x, y, z, h, isMoving):
        pkg = PyDatagram()
        pkg.addUint16(106)
        pkg.addFloat32(x)
        pkg.addFloat32(y)
        pkg.addFloat32(z)
        pkg.addFloat32(h)
        pkg.addUint16(isMoving)
        return pkg

    def check(self):
        while self.cReader.dataAvailable():
            print "data here"
            datagram = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram):
                data = PyDatagramIterator(datagram)
                responseCode = data.getUint16()
                print responseCode
                if responseCode == 1:
                    self.getInt(data)
                elif responseCode == 2:
                    self.getString(data)
                elif responseCode == 3:
                    self.getShort(data)
                elif responseCode == 4:
                    self.getFloat(data)
                elif responseCode == 201:
                    self.getLogin(data)
                elif responseCode == 203:
                    self.getRegistion(data)
                elif responseCode == 204:
                    self.getCharacterCreation(data)
                elif responseCode == 205:
                    self.getChat(data)
                elif responseCode == 206:
                    self.getMove(data)
                else:
                    print "nothing found"

    def getInt(self, data):
        msg = data.getInt32()
        print "recieved ", msg
        taskMgr.add(self.message, "message")

    def getString(self, data):
        msg = data.getString()
        print "recieved ", msg
        taskMgr.add(self.message, "message")

    def getShort(self, data):
        msg = data.getUint16()
        print "recieved ", msg
        taskMgr.add(self.message, "message")

    def getFloat(self, data):
        msg = data.getFloat32()
        print "recieved ", msg
        taskMgr.add(self.message, "message")

    def getLogin(self, data):
        flag = data.getUint16()

        if flag == 0:
            print "Invalid Login"
        else:
            listSize = data.getUint16()

            for i in xrange(listSize):
                characterName = data.getString()
                characterId = data.getUint16()
                characterType = data.getUint16()
                characterFaction = data.getUint16()

                # Need to add these to an active characters class

    def getRegistion(self, data):
        flag = data.getUint16()

        if flag == 0:
            print "Invalid Login"
        else:
            print "Account Created"

    def getCharacterCreation(self, data):
        flag = data.getUint16()

        if flag == 0:
            print "Invalid Character"
        else:
            listSize = data.getUint16()

            for i in xrange(listSize):
                characterName = data.getString()
                characterId = data.getUint16()
                characterType = data.getUint16()
                characterFaction = data.getUint16()

                # Need to add these to an active characters class

    def getChat(self, data):
        username = data.getString()
        factionId = data.getUint16()
        message = data.getString()

    def getMove(self, data):
        username = data.getString()
        x = data.getFloat32()
        y = data.getFloat32()
        z = data.getFloat32()
        h = data.getFloat32()
        isMoving = data.getUint16()

    def updateRoutine(self, task):
        self.check()
        return task.again
Exemple #6
0
class TCP():

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

        # Connection on TCP 
        self.tcpConnection = None


    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)

    def startTCPTasks(self):
        taskMgr.add(self.tcpReaderTask, "tcpReaderTask", -10)
        print ("TCP Reader Started")


    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)

        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)


    def connectToServer(self, _ip, _port):
        self.tcpConnection = self.tcpManager.openTCPClientConnection(_ip, _port, 1000)

        if self.tcpConnection != None:
            self.tcpReader.addConnection(self.tcpConnection)
            # Close the main menu and move the client into the game
            # for now we will make a shortcut
            #self.clientManager.guiManager.menu.hide()
Exemple #7
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
Exemple #8
0
class World(DirectObject):
 
    def __init__(self):
         
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}
        
        self.cManager = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager, 0)
        
        self.opponents = dict()
        self.logStat = -1
        self.id = 0
        self.username = ""
        
        host = "localhost"
        port = 9252
        self.connection = self.cManager.openTCPClientConnection(host, port, 10000)
        
        self.received = 1
        
        self.playersText = []
        
        if self.connection:
         self.cReader.addConnection(self.connection)
         taskMgr.add(self.updateRoutine, 'updateRoutine')
         taskMgr.add(self.login, 'login')
         taskMgr.doMethodLater(.1, self.heartbeat, 'heartbeat')
         
        # Replace with actual, dynamic list of players from the server
        self.players = dict()
         
        # Placeholder, replace with actual # of players later
        self.numberOfPlayers = 2
         
        # Stores the OnScreenText for each player in the players list
        # Populated and depopulated using listPlayers and delistPlayers
        self.playersText = []
         
        # Stores all the player objects currently logged in
        self.playerObjects = []
         
        base.win.setClearColor(Vec4(0,0,0,1))
 
        # Post the instructions
 
        #self.title = addTitle("Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        #self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        #self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left")
        #self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right")
        #self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward")
        #self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left")
        #self.inst7 = addInstructions(0.65, "[S]: Rotate Camera Right")
        #self.inst8 = addInstructions(0.60, "[Q]: Display List Of Connected Players")
         
        # Set up the environment
        #
        # This environment model contains collision meshes.  If you look
        # in the egg file, you will see the following:
        #
        #    <Collide> { Polyset keep descend }
        #
        # This tag causes the following mesh to be converted to a collision
        # mesh -- a mesh which is optimized for collision, not rendering.
        # It also keeps the original mesh, so there are now two copies ---
        # one optimized for rendering, one for collisions.  
 
        self.environ = loader.loadModel("models/world")      
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,0)
         
         
         
         
         
        # Create the main character, Ralph
 
        ralphStartPos = self.environ.find("**/start_point").getPos()
        self.ralph = Actor("models/ralph",
                                 {"run":"models/ralph-run",
                                  "walk":"models/ralph-walk"})
        self.ralph.reparentTo(render)
        self.ralph.setScale(.2)
        self.ralph.setPos(ralphStartPos)
        ralphStartPos.setY(ralphStartPos.getY()-10)
        self.ralph.setPos(ralphStartPos.getX(),ralphStartPos.getY(),ralphStartPos.getZ())
        self.initx = ralphStartPos.getX()
         
        # Add our Ralph to list to Ralphs
        self.playerObjects.append(self.ralph)
         
        # Load and transform the panda actor.
        self.pandaActor = Actor("models/panda-model",
                                {"walk": "models/panda-walk4"})
        self.pandaActor.setScale(0.003, 0.003, 0.003)
        self.pandaActor.reparentTo(render)
        # Loop its animation.
        #self.pandaActor.loop("walk")
        self.pandaActor.setPos(ralphStartPos.getX(),ralphStartPos.getY()-20,ralphStartPos.getZ())
         
        # Create a floater object.  We use the "floater" as a temporary
        # variable in a variety of calculations.
         
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)
 
        # Accept the control keys for movement and rotation
 
        self.accept("escape", self.disconnect)
        self.accept("arrow_left", self.setKey, ["left",1])
        self.accept("arrow_right", self.setKey, ["right",1])
        self.accept("arrow_up", self.setKey, ["forward",1])
        self.accept("a", self.setKey, ["cam-left",1])
        self.accept("s", self.setKey, ["cam-right",1])
        self.accept("arrow_left-up", self.setKey, ["left",0])
        self.accept("arrow_right-up", self.setKey, ["right",0])
        self.accept("arrow_up-up", self.setKey, ["forward",0])
        self.accept("a-up", self.setKey, ["cam-left",0])
        self.accept("s-up", self.setKey, ["cam-right",0])
        self.accept("q", self.listPlayers)
        self.accept("q-up", self.delistPlayers)
 
        taskMgr.add(self.move,"moveTask")
         
        # Call whenever a ralph has logged in, use arg "out" for logouts
        self.displayLoginText()
 
        # Game state variables
        self.isMoving = False
 
        # Set up the camera
         
        base.disableMouse()
        base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2)
         
        # We will detect the height of the terrain by creating a collision
        # ray and casting it downward toward the terrain.  One ray will
        # start above ralph's head, and the other will start above the camera.
        # A ray may hit the terrain, or it may hit a rock or a tree.  If it
        # hits the terrain, we can detect the height.  If it hits anything
        # else, we rule that the move is illegal.
 
        self.cTrav = CollisionTraverser()
 
        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0,0,1000)
        self.ralphGroundRay.setDirection(0,0,-1)
        self.ralphGroundCol = CollisionNode('ralphRay')
        self.ralphGroundCol.addSolid(self.ralphGroundRay)
        self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol)
        self.ralphGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)
         
        self.pandaActorGroundRay = CollisionRay()
        self.pandaActorGroundRay.setOrigin(0,0,1000)
        self.pandaActorGroundRay.setDirection(0,0,-1)
        self.pandaActorGroundCol = CollisionNode('pandaActorRay')
        self.pandaActorGroundCol.addSolid(self.pandaActorGroundRay)
        self.pandaActorGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.pandaActorGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.pandaActorGroundColNp = self.pandaActor.attachNewNode(self.pandaActorGroundCol)
        self.pandaActorGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.pandaActorGroundColNp, self.pandaActorGroundHandler)
         
 
        self.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0,0,1000)
        self.camGroundRay.setDirection(0,0,-1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)
 
        # Uncomment this line to see the collision rays
        #self.ralphGroundColNp.show()
        #self.camGroundColNp.show()
        
        self.miniMap = miniMap(self.ralph)
        self.miniMap.setNpc('tower_1', 'models/hexahedron.png', 0.05, 0.2, 0.3)
        self.miniMap.setNpc('tower_2', 'models/hexahedron.png', 0.05, -0.4, -0.5)
        
        # Uncomment this line to show a visual representation of the 
        # collisions occuring
        #self.cTrav.showCollisions(render)
         
        # Create some lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(.3, .3, .3, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(Vec3(-5, -5, -5))
        directionalLight.setColor(Vec4(1, 1, 1, 1))
        directionalLight.setSpecularColor(Vec4(1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))
 
        self.setAI()
     
    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value
     
 
    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):
        
        self.miniMap.updateHeroPos(self.ralph.getX(), self.ralph.getY())
        self.miniMap.updateHeroHpr(self.ralph.getH())
        
        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.
 
        base.camera.lookAt(self.ralph)
        if (self.keyMap["cam-left"]!=0):
            base.camera.setX(base.camera, -20 * globalClock.getDt())
        if (self.keyMap["cam-right"]!=0):
            base.camera.setX(base.camera, +20 * globalClock.getDt())
 
        # save ralph's initial position so that we can restore it,
        # in case he falls off the map or runs into something.
 
        startpos = self.ralph.getPos()
 
        # If a move-key is pressed, move ralph in the specified direction.
 
        if (self.keyMap["left"]!=0):
            self.ralph.setH(self.ralph.getH() + 300 * globalClock.getDt())
        if (self.keyMap["right"]!=0):
            self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.ralph.setY(self.ralph, -25 * globalClock.getDt())
 
        # Makes the panda look at ralph when not using AI
        #self.pandaActor.lookAt(self.ralph)
        #self.pandaActor.setH(self.pandaActor.getH() + 180)
         
        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.
 
        if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0):
            if self.isMoving is False:
                self.ralph.loop("run")
                self.isMoving = True
        else:
            if self.isMoving:
                self.ralph.stop()
                self.ralph.pose("walk",5)
                self.isMoving = False
                print "stop"
                self.requestStop()
         
        
 
 
        # If the camera is too far from ralph, move it closer.
        # If the camera is too close to ralph, move it farther.
 
        camvec = self.ralph.getPos() - base.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if (camdist > 10.0):
            base.camera.setPos(base.camera.getPos() + camvec*(camdist-10))
            camdist = 10.0
        if (camdist < 5.0):
            base.camera.setPos(base.camera.getPos() - camvec*(5-camdist))
            camdist = 5.0
 
        # Now check for collisions.
 
        self.cTrav.traverse(render)
 
        # Adjust ralph's Z coordinate.  If ralph's ray hit terrain,
        # update his Z. If it hit anything else, or didn't hit anything, put
        # him back where he was last frame.
 
        entries = []
        for i in range(self.ralphGroundHandler.getNumEntries()):
            entry = self.ralphGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
        else:
            self.ralph.setPos(startpos)
             
        entries2 = []
        for i in range(self.pandaActorGroundHandler.getNumEntries()):
            entry = self.pandaActorGroundHandler.getEntry(i)
            entries2.append(entry)
        entries2.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries2)>0) and (entries2[0].getIntoNode().getName() == "terrain"):
            self.pandaActor.setZ(entries2[0].getSurfacePoint(render).getZ())
        else:
            self.pandaActor.setPos(startpos)   
 
        # Keep the camera at one foot above the terrain,
        # or two feet above ralph, whichever is greater.
         
        entries = []
        for i in range(self.camGroundHandler.getNumEntries()):
            entry = self.camGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0)
        if (base.camera.getZ() < self.ralph.getZ() + 2.0):
            base.camera.setZ(self.ralph.getZ() + 2.0)
             
        # The camera should look in ralph's direction,
        # but it should also try to stay horizontal, so look at
        # a floater which hovers above ralph's head.
         
        self.floater.setPos(self.ralph.getPos())
        self.floater.setZ(self.ralph.getZ() + 2.0)
        base.camera.lookAt(self.floater)
        
        if self.isMoving:
         self.moveRalph()
        
        return task.cont
     
    def displayLoginText(self, s="in"):
        self.loginText = addInstructions(-0.95, "A Ralph has logged " + s)
        myTask = taskMgr.doMethodLater(3, self.removeLoginText, 'removeLoginTextTask')
    
    def moveRalph(self):
     pkg = PyDatagram()
     pkg.addUint16(114)
     pkg.addFloat32(self.ralph.getX())
     pkg.addFloat32(self.ralph.getY())
     pkg.addFloat32(self.ralph.getZ())
     pkg.addFloat32(self.ralph.getH())
     self.cWriter.send(pkg,self.connection)
     
    def disconnect(self):
		pkg = PyDatagram()
		pkg.addUint16(119)
		self.cWriter.send(pkg,self.connection)
		sys.exit()
                
    def requestStop(self):
     pkg = PyDatagram()
     pkg.addUint16(115)
     self.cWriter.send(pkg,self.connection)
    
    def stopPlayer(self, data):
     id = data.getInt32()
     if id != self.id:
      self.opponents[id].character.stop()
      self.opponents[id].character.pose("walk",5)
     
    def movePlayer(self, data):
		id = data.getInt32()
		x = data.getFloat32()
		y = data.getFloat32()
		z = data.getFloat32()
                rotation = data.getFloat32()
                if id == self.id:
                 self.ralph.setPos(x, y, z)
                 self.ralph.setH(rotation)
                else:
                 self.opponents[id].character.setPos(x,y,z)
                 self.opponents[id].character.setH(rotation)
                 self.opponents[id].character.loop("run", restart = 0)
                 self.miniMap.updateTeamMatePos(id, x, y)
     
    def check(self):
               while self.cReader.dataAvailable():
                       print "data here"
                       datagram = NetDatagram()
                       # Retrieve the contents of the datagram.
                       if self.cReader.getData(datagram):
                               data = PyDatagramIterator(datagram)
                               responseCode = data.getUint16()
                               print responseCode
                               if responseCode == 201:
                                       self.getPlayer(data)
                               elif responseCode == 202:
                                       self.register(data)
                               elif responseCode == 203:
                                       self.getOpponent(data)
                               elif responseCode == 214:
                                       self.movePlayer(data)
                               elif responseCode == 215:
                                       self.stopPlayer(data)
                               elif responseCode == 219:
                                       self.dropPlayer(data)
                               else:
                                       print "nothing found"
    
    def heartbeat(self, task):
		pkg = PyDatagram()
		pkg.addUint16(113)
		self.cWriter.send(pkg,self.connection)
		return task.again
    
    def updateRoutine(self,task):
		self.check()
		return task.again;
    def login(self, task):
		self.option = 0
		self.option = str(raw_input("1-Login\n2-Register\n"))
		if self.option == "1":
			un = str(raw_input("Username: "******"Password: "******"2":
			un = str(raw_input("Username: "******"Password: "******"Account Made"
			taskMgr.add(self.login, 'login')
		else:
			print "Username Taken"
			taskMgr.add(self.login, 'login')
         
    def registerRequest(self, username, password):
		pkg = PyDatagram()
		pkg.addUint16(102)
		pkg.addString(username)
		pkg.addString(password)
		return pkg
		
    def getPlayer(self, data):
		self.logStat = data.getUint16()
		if self.logStat == 0:
			self.id = data.getInt32()
			self.username = data.getString()
			x = data.getFloat32()
			y = data.getFloat32()
			z = data.getFloat32()
                        rotation = data.getFloat32()
                        if x == 0 and y == 0 and z == 0:
                         ralphStartPos = self.environ.find("**/start_point").getPos()
                         self.ralph.setPos(ralphStartPos.getX(),ralphStartPos.getY(),ralphStartPos.getZ())
			else:
                         self.ralph.setPos( x, y, z )
                         self.ralph.setH( rotation )
		else:
			print "login failed"
			taskMgr.add(self.login, 'login')
                        
    def getOpponent(self, data):
        opponent = Player()
        opponent.id = data.getInt32()
        opponent.username = data.getString()
        x = data.getFloat32()
        y = data.getFloat32()
        z = data.getFloat32()
        rotation = data.getFloat32()
        opponent.character.reparentTo(render)
        opponent.character.setScale(.2)
        opponent.character.setPos(x, y, z)
        opponent.character.setH(rotation)
        self.opponents[opponent.id] = opponent
        self.displayLoginText()
        self.miniMap.setTeamMate(opponent.id, 0.025, x, y)
                
    def dropPlayer(self, data):
        id = data.getInt32()
        self.opponents[id].character.removeNode()
        del self.opponents[id]
        self.displayLoginText(s="out")
        self.miniMap.delTeamMate(id)
                
    def removeLoginText(self, task):
        self.loginText.destroy()
        return task.done
     
    def listPlayers(self):
        i = 0.55
        for p in self.opponents:
            self.playersText.append( addInstructions(i, self.opponents[p].username) )
            i -= 0.05
     
    def delistPlayers(self):
        for x in self.playersText:
            x.destroy()
             
    def findClosestRalph(self):
        px = self.pandaActor.getX()
        py = self.pandaActor.getY()
        pz = self.pandaActor.getZ()
        
        closestPlayer = self.ralph
        rx = self.ralph.getX()
        ry = self.ralph.getY()
        rz = self.ralph.getZ()
        minDist = math.sqrt( (rx-px)*(rx-px) + (ry-py)*(ry-py) + (rz-pz)*(rz-pz) )
 
        for x in self.opponents:
            rx = self.opponents[x].character.getX()
            ry = self.opponents[x].character.getY()
            rz = self.opponents[x].character.getZ()
             
            dist = math.sqrt( (rx-px)*(rx-px) + (ry-py)*(ry-py) + (rz-pz)*(rz-pz) )
            if (dist < minDist):
                minDist = dist
                closestPlayer = self.opponents[x].character
         
        return closestPlayer, minDist
 
    # Panda chasing Ralph
    def setAI(self):        
        #Creating AI World
        self.AIworld = AIWorld(render)
  
        self.AIchar = AICharacter("panda",self.pandaActor, 100, 0.05, 5)
        self.AIworld.addAiChar(self.AIchar)
        self.AIbehaviors = self.AIchar.getAiBehaviors()
  
        closestRalph = self.findClosestRalph()
        self.AIbehaviors.pursue(closestRalph[0])
        self.pandaActor.loop("walk")
  
        #AI World update        
        taskMgr.add(self.AIUpdate,"AIUpdate")
  
    #to update the AIWorld    
    def AIUpdate(self,task):
        self.AIworld.update()
         
        closestRalph = self.findClosestRalph()
        if ( self.numberOfPlayers <= 1 or not restrain(closestRalph[1], -CHASE_DISTANCE, CHASE_DISTANCE) or closestRalph[1] < 3):
            self.AIbehaviors.pauseAi("pursue")
        else: self.AIbehaviors.pursue(closestRalph[0])
         
        return task.cont
Exemple #9
0
class ConnectionManager:
    notify = DirectNotifyGlobal.directNotify.newCategory("ConnectionManager")

    def __init__(self):
        self.socket = None
        self.hostName = None
        self.port = None

        self.ourChannel = 100001

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

    def start(self):
        self.hostName = base.configManager.getString('host-name', '127.0.0.1')
        self.port = base.configManager.getInt('port-number', 6667)

        self.socket = self.cManager.openTCPServerRendezvous(
            self.hostName, self.port, 1000)
        if self.socket:
            self.cListener.addConnection(self.socket)
            self._serverStarted(self.hostName, self.port)
            taskMgr.add(self._socketListener, 'Connection Listener')
            taskMgr.add(self._socketReader, 'Connection Reader')
        else:
            self.notify.warning(
                "Unable to start server on %s:%d - is the port in use?" %
                (self.hostName, self.port))
            base.logManager.writeServerEvent(
                'ServerBase',
                'Unable to start server on %s:%d - is the port in use?' %
                (self.hostName, self.port))
            sys.exit()

    def _serverStarted(self, host, port):
        self.notify.warning("Server started on %s:%d" % (host, port))
        base.logManager.writeServerEvent(
            'ServerBase', 'Server started on %s:%d' % (host, port))

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

            if self.cListener.getNewConnection(rendezvous, netAddress,
                                               newConnection):
                newConnection = newConnection.p()
                base.activeConnections[newConnection] = NetworkedClient()
                self.cReader.addConnection(newConnection)
                self.notify.warning("New Unauthed Client Connected: %s" %
                                    (netAddress))

        return Task.cont

    def _socketReader(self, task):
        if self.cReader.dataAvailable():
            datagram = NetDatagram()

            if self.cReader.getData(datagram):
                base.messageManager.handleMessage(datagram)

        return Task.cont
Exemple #10
0
class NetworkClient():
    """
        All remote clients will have one of these in their GameManager. This
         class communicates with a server (NetworkHost) to update game state.
    """
    def __init__(self, gameManager):
        self._connManager = QueuedConnectionManager()
        self._timeout = CLIENT_TIMEOUT
        self._loadConfig()
        self._gameManager = gameManager
        self._playerInfo = dict()  # Party Member Info
        self._creatures = dict()  # Creates by cID.
        self._connection = None

    def _loadConfig(self):
        """
            Loads network configuration defaults.
        """
        self._portAddress = ConfigVariableInt("default-port",
                                              DEFAULT_PORT).getValue()

    def startClient(self, ipAddress):
        """
            Finishes client init and attempts a connection.
        """
        # Initialize Reader and Writer:
        self._connReader = QueuedConnectionReader(self._connManager, 0)
        self._connWriter = ConnectionWriter(self._connManager, 0)
        # Initialize connection:
        self._connection = self._connManager.openTCPClientConnection(
            ipAddress, self._portAddress, self._timeout)
        if self._connection:
            print("[Client Connected]")
            self._connReader.addConnection(self._connection)
            # Begin handling messages (start listening):
            taskMgr.add(self._onReaderPoll, "Poll the connection reader", -40)
            self._gameManager.onLocalClientJoinedParty(self._connection\
                .this) # GameManager callback

    def _onReaderPoll(self, taskdata):
        """
            Called on an interval to interpret messages from the reader.
        """
        if self._connReader.dataAvailable():
            newDatagram = NetDatagram()
            # Double check to make sure (Multithreading safety):
            if self._connReader.getData(newDatagram):
                self._interpretDatagram(newDatagram)
        return Task.cont  # Repeat this call on an interval

    def sendMessage(self, msg, msgType):
        """
            Sends a given message to the server.
        """
        print("[Client Sending %s message type %s]" %
              (str(self._connection), str(msgType)))
        self._connWriter.send(msg, self._connection)

    def _interpretDatagram(self, datagram):
        """
            Interprets a received datagram and performs actions based on
             its values.
        """
        msg = PyDatagramIterator(datagram)
        msgType = msg.getUint8()
        if msgType == DEBUG_MESSAGE:
            print(msg.getString())
        elif msgType == MAP_MESSAGE:
            print("[Client Received Map Data]")
            if self._gameManager.getTileMap() == None:
                data = msg.getString32()
                self._gameManager.onClientFirstReceivedMap(data)
        elif msgType == UPDATE_PLAYER_INFO:
            data = msg.getString()
            self._updatePlayerInfoHandler(data)
        elif msgType == SPAWN_CHARACTER:
            data = msg.getString()
            dataDict = json.loads(data)
            self._onSpawnHandler(dataDict)
        elif msgType == SYNC_ACTION:
            data = msg.getString()
            dataDict = json.loads(data)
            self._onActionSyncHandler(dataDict)
        elif msgType == SYNC_HEALTH:
            data = msg.getString()
            dataDict = json.loads(data)
            self._onHealthSyncHandler(dataDict)
        elif msgType == SYNC_DEATH:
            data = msg.getString()
            dataDict = json.loads(data)
            self._onDeathSyncHandler(dataDict)
        elif msgType == SYNC_RESPAWN:
            data = msg.getString()
            dataDict = json.loads(data)
            self._onRespawnPermissionGranted(dataDict)
        elif msgType == SPAWN_ITEM:
            data = msg.getString()
            dataDict = json.loads(data)
            self._onItemSpawned(dataDict)
        elif msgType == WIN_STATE:
            data = msg.getString()
            self._onGameWon(data)

    def _onGameWon(self, data):
        """
            Show the win state achieved screen with the specified playerinfo as
             the winner details.
        """
        newPlayerData = PlayerInfo(fromJson=data)
        self._gameManager.onWinStateAchieved(newPlayerData)

    def _onItemSpawned(self, dataDict):
        """ The server spawned an item, handle spawning on this client """
        itemType = ITEM_ID_DICT[dataDict['itemType']]
        itemID = dataDict['objID']
        newPos = Point2D(dataDict['pos'][0], dataDict['pos'][1])
        # Create item locally:
        newItem = itemType(self._gameManager, itemID, coords=newPos)
        self._gameManager.getTileMap().spawnItem(newItem, newPos)
        # Track new item:
        self._creatures[itemID] = newItem

    def _onDeathSyncHandler(self, dataDict):
        """ Handles syncing of death for the given creature """
        deadCreature = self._creatures[dataDict['objID']]
        # Play death sequence on this character:
        deadCreature.deathSequence(amClient=True)

    def _onHealthSyncHandler(self, dataDict):
        """ Handles syncing of health values for creatures """
        print("_onHealthSyncHandler")
        newHealth = dataDict['newHealth']
        affectedCreature = self._creatures[dataDict['objID']]

        affectedCreature.onHPModified(newHealth)

    def _onSpawnHandler(self, dataDict):
        """ Handles networking spawning characters """
        # Spawn object locally if the object at cID doesn't already exist.
        if not dataDict['objID'] in self._creatures.keys():
            # Spawn object of charType at pos
            objectType = getCharacterTypeAsClass(dataDict['charType'])
            newPos = Point2D(dataDict['pos'][0], dataDict['pos'][1])
            newChar = objectType(parentCtrlr=None,
                                 cID=dataDict['objID'],
                                 gameManager=self._gameManager,
                                 coords=newPos)
            self._creatures[dataDict['objID']] = newChar
            self._gameManager.getTileMap().spawnObject(newChar, newPos)
            print("[Client Spawned %s]" % dataDict['objID'])
            # If we have a player info for this player, use their name for the
            #  displayName:
            print(dataDict['objID'], self._playerInfo)
            if dataDict['objID'] in self._playerInfo:
                newName = self._playerInfo[dataDict['objID']].cName
                newChar.setNameDisplay(newName)
        else:
            # Ignore Overwrite
            pass

    def _updatePlayerInfoHandler(self, data):
        """
            Update our player list with a player info given by data.
        """
        newPlayerData = PlayerInfo(fromJson=data)
        self._playerInfo[newPlayerData.cID] = newPlayerData
        self._gameManager.updatePartyInfo(self._playerInfo,
                                          self._connection.this)
        # Update the creature's floating display name (unless it is ours):
        ignoreThisUpdate = False
        if self._gameManager._localPlayer:
            if newPlayerData.cID == self._gameManager._localPlayer\
                            .getCharacter().getCID():
                ignoreThisUpdate = True
        if not ignoreThisUpdate and newPlayerData.cID in self._creatures:
            self._creatures[newPlayerData.cID]\
                .setNameDisplay(newPlayerData.cName)

    def _onRespawnPermissionGranted(self, dataDict):
        """
            Respawn the given character at the given location.
        """
        targetObj = self._creatures[dataDict['objID']]
        newPos = Point2D(dataDict['pos'][0], dataDict['pos'][1])
        targetObj.respawn(newPos)

    def _onActionSyncHandler(self, dataDict):
        """
            Attempts to queue an action for execution on a target denoted by
             dataDict['objID']
        """
        syncedAction = ACTION_NETWORKING_DICT[dataDict['actionID']]
        # Add a few local variables to dataDict:
        targetObj = self._creatures[
            dataDict['objID']]  # TODO Maybe make this part of dataDict!
        dataDict['tileMap'] = self._gameManager.getTileMap()
        if 'targetCID' in dataDict:  # If there is another target:
            # Assign the target:
            dataDict['target'] = self._creatures[dataDict['targetCID']]
        dataDict['isServer'] = False  # Let sync function know we are remote

        # Create the newAction
        newAction = syncedAction(targetObj, **dataDict)
        targetObj.startAction(newAction)  # queue or start the new action

    def updateLocalPlayerInfo(self, info=None):
        """
            Updates info for this local player and sends it to the server.
        """
        if not info:
            initData = PlayerInfo(cID=self._connection.this)
            self._playerInfo[self._connection.this] = initData
            infoMsg = createPlayerInfoMessage(initData)
            self.sendMessage(infoMsg, UPDATE_PLAYER_INFO)
        else:
            infoMsg = createPlayerInfoMessage(info)
            self.sendMessage(infoMsg, UPDATE_PLAYER_INFO)

    def syncAction(self, actionID, **kwargs):
        """
            The local player has performed an action that must be synced across
             the network. Send a message to all clients telling them to perform
             a related action on that character.
        """
        msg = createSyncActionMessage(self._connection.this, actionID,
                                      **kwargs)
        self.sendMessage(msg, SYNC_ACTION)

    def sendPlayerRespawnRequest(self):
        msg = createRespawnRequest(self._connection.this)
        self.sendMessage(msg, SYNC_RESPAWN)

    def localPlayerWins(self):
        """
            Tell host we won. Then wait for a response.
        """
        msg = createWinMessage(self._playerInfo[self._connection.this])
        self.sendMessage(msg, WIN_STATE)

    def spawnGameObject(self, gameObject):
        """
            Tracks the given gameObject and sends it to the server
        """
        # First, track it locally:
        self._creatures[self.getCID()] = gameObject
        # Tell server to spawn it for them and everyone else:
        msg = createSpawnCharacterMessage(gameObject, self.getCID())
        self.sendMessage(msg, SPAWN_CHARACTER)

    def getCID(self):
        return self._connection.this
Exemple #11
0
class Connection(GlobalClockMixin, TaskMixin):

    def __init__(self, base, host, port):
        self.base = base
        self.host = host
        self.port = port

        self._conn = None

        self._retry_elapsed = 0
        self._retry_next = 0
        self._data_last_received = 0

        self.manager = QueuedConnectionManager()

        self.reader = QueuedConnectionReader(
            self.manager,
            0,  # number of threads
        )

        # we're using our own protocol so we don't want panda reading our headers and getting
        # all foobared by it (not setting raw mode causes `dataAvailable` to block
        # once there is actually data to process)
        self.reader.setRawMode(True)

        self.writer = ConnectionWriter(
            self.manager,
            0,  # number of threads
        )

    def connect(self, connected_callback, task):
        """
        Attempts to connect to the server and if unable to will retry adding
        a second to the wait time to each consecutive failure.
        """
        self._retry_elapsed += self.get_dt()
        if self._retry_elapsed < self._retry_next:
            return task.cont

        logging.debug(
            'attempting to connect to server at %s:%d',
            self.host,
            self.port
        )
        self._conn = self.manager.openTCPClientConnection(
            self.host,
            self.port,
            10000,  # timeout ms
        )

        if self._conn:
            logging.debug('connection established')
            self.reader.addConnection(self._conn)

            # reset the counters in case the connection drops and we have to restart the
            # connection process
            self._retry_elapsed = 0
            self._retry_next = 0

            # add a task to poll the connection for data
            self.add_task(
                self.task_read_polling,
                name='connection_reader_poll',
                sort=-39,
            )

            connected_callback()
            return

        # no connection so retry in a bit
        self._retry_elapsed = 0
        if self._retry_next == 0:
            self._retry_next = 1
        elif self._retry_next > 9:
            self._retry_next = 10
        else:
            self._retry_next += 1

        logging.error(
            'Unable to connect to server %s:%s, will retry in %d seconds',
            self.host,
            self.port,
            self._retry_next,
        )
        return task.cont

    def task_read_polling(self, task):
        if self.reader.dataAvailable():
            logging.debug('data available from server')
            datagram = Datagram()
            if self.reader.getData(datagram):
                logging.debug('received data from server: %s', datagram)
                logging.debug('received data from server: %s', datagram.getMessage())
                # TODO: provide a way to supply a data callback
            self._data_last_received = 0
        else:
            # no data received
            logging.debug('no data')
            self._data_last_received += self.get_dt()

        if self._data_last_received >= 10:
            logging.error('connection to server lost')
            return

        return task.cont

    def shutdown(self):
        logging.info('connection reader shutting down')
        self.reader.shutdown()
Exemple #12
0
class SocketTCP(ShowBase):

    def __init__(self, _parent=None):
        ShowBase.__init__(self, windowType = 'none')
        print ("TCP Protocol Startup...")
        #self.parent = _parent

        #self.config = self.parent.server.config
        # tmp config
        self.tcpport = 6000
        self.backlog = 10
        self.hostname = '127.0.0.1'

        self.sendPacketQueue = None


    def startAll(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.tcpport, self.backlog)
        self.tcpListener.addConnection(self.tcpSocket)
        print ("Started Server on: ", self.hostname, self.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")
        taskMgr.add(self.tcpQueuedSendHandlerTask, "tcpQueuedSendhandlerTask", -11)
        print ("TCP Queued Send 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)

                #self.core.createPlayerObject(generateUUID(),newConnection, netAddress)
                    
                print ("Server: " + str(generateUUID), 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())
                print("Set Packet Handler to handle packets!")
                
        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)
            print(str(resetConnection.p()))
            #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)

    def addPacketToSendQueue(self, _data):
        # _data should contain packet and connection
        pass

    def addPacketToBroadcastQueue(self, _pkt, _connectionList):
        # _data should contain the pkt data and _connectionList should be the valid connections for that broadcast
        # Could have a grouping system that put clients together and broadcasts go per group
        pass

    def tcpQueuedSendHandlerTask(self, task):
        
        if not self.sendPacketQueue.isEmpty():
            self.addPacketToSendQueue(self.sendPacketQueue.removeFromQue())
        
        return Task.cont
Exemple #13
0
class MyApp(ShowBase):
	def __init__(self):
		ShowBase.__init__(self)
		
		self.cManager = QueuedConnectionManager()
		self.cListener = QueuedConnectionListener(self.cManager, 0)
		self.cReader = QueuedConnectionReader(self.cManager, 0)
		self.cWriter = ConnectionWriter(self.cManager, 0)
		
		host = "localhost"
		port = 9252
		self.connection = self.cManager.openTCPClientConnection(host, port, 10000)
		
		self.received = 1
		
		if self.connection:
			self.cReader.addConnection(self.connection)                	
			taskMgr.add(self.updateRoutine, 'updateRoutine')
			taskMgr.add(self.message, 'message')
		
	def message(self, task):
		self.option = 0
		self.option = str(raw_input("1-Send integer\n2-Send string\n3-Send short\n4-Send float\n"))
		if self.option == "1":
			msg = int(100 * random.random()) - 50
			request = self.intRequest(msg)
			self.cWriter.send(request,self.connection)
			print "sent ", msg
			taskMgr.remove('message')
		elif self.option == "2":
			msg = ''.join(random.choice('abcdefghijklmnopqrstuvwxyz') for x in range(7))
			request = self.stringRequest(msg)
			self.cWriter.send(request,self.connection)
			print "sent ", msg
			taskMgr.remove('message')
		elif self.option == "3":
			msg = int(100 * random.random())
			request = self.shortRequest(msg)
			self.cWriter.send(request,self.connection)
			print "sent ", msg
			taskMgr.remove('message')
		elif self.option == "4":
			msg = 100 * random.random()
			request = self.floatRequest(msg)
			self.cWriter.send(request,self.connection)
			print "sent ", msg
			taskMgr.remove('message')
	
	def intRequest(self, msg):
		pkg = PyDatagram()
		pkg.addUint16(1)
		pkg.addInt32(msg)
		return pkg
	
	def stringRequest(self, msg):
		pkg = PyDatagram()
		pkg.addUint16(2)
		pkg.addString(msg)
		return pkg
	
	def shortRequest(self, msg):
		pkg = PyDatagram()
		pkg.addUint16(3)
		pkg.addUint16(msg)
		return pkg
	
	def floatRequest(self, msg):
		pkg = PyDatagram()
		pkg.addUint16(4)
		pkg.addFloat32(msg)
		return pkg
		
	def registerRequest(self, username, password):
		pkg = PyDatagram()
		pkg.addUint16(102)
		pkg.addString(username)
		pkg.addString(password)
		return pkg
		
	def check(self):
		while self.cReader.dataAvailable():
			print "data here"
			datagram = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram):
				data = PyDatagramIterator(datagram)
				responseCode = data.getUint16()
				print responseCode
				if responseCode == 1:
					self.getInt(data)
				elif responseCode == 2:
					self.getString(data)
				elif responseCode == 3:
					self.getShort(data)
				elif responseCode == 4:
					self.getFloat(data)
				else:
					print "nothing found"
	
	def getInt(self, data):
		msg = data.getInt32()
		print "recieved ", msg
		taskMgr.add(self.message, 'message')
		
	def getString(self, data):
		msg = data.getString()
		print "recieved ", msg
		taskMgr.add(self.message, 'message')
	
	def getShort(self, data):
		msg = data.getUint16()
		print "recieved ", msg
		taskMgr.add(self.message, 'message')
	
	def getFloat(self, data):
		msg = data.getFloat32()
		print "recieved ", msg
		taskMgr.add(self.message, 'message')
	
	
	def updateRoutine(self,task):
		self.check()
		return task.again;
class Connection(ShowBase):
    def __init__(self):

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

        try:
            host = "localhost"
            port = 9252
            self.connection = self.cManager.openTCPClientConnection(
                host, port, 10000)

            self.received = 1

            if self.connection:
                self.cReader.addConnection(self.connection)
                taskMgr.add(self.updateRoutine, 'updateRoutine')
                # taskMgr.add(self.message, 'message')
        except:
            pass

    # def message(self, task):
    # 	self.option = 0
    # 	self.option = str(raw_input("1-Send integer\n2-Send string\n3-Send short\n4-Send float\n"))
    # 	if self.option == "1":
    # 		msg = int(100 * random.random()) - 50
    # 		request = self.intRequest(msg)
    # 		self.cWriter.send(request,self.connection)
    # 		print "sent ", msg
    # 		taskMgr.remove('message')
    # 	elif self.option == "2":
    # 		msg = ''.join(random.choice('abcdefghijklmnopqrstuvwxyz') for x in range(7))
    # 		request = self.stringRequest(msg)
    # 		self.cWriter.send(request,self.connection)
    # 		print "sent ", msg
    # 		taskMgr.remove('message')
    # 	elif self.option == "3":
    # 		msg = int(100 * random.random())
    # 		request = self.shortRequest(msg)
    # 		self.cWriter.send(request,self.connection)
    # 		print "sent ", msg
    # 		taskMgr.remove('message')
    # 	elif self.option == "4":
    # 		msg = 100 * random.random()
    # 		request = self.floatRequest(msg)
    # 		self.cWriter.send(request,self.connection)
    # 		print "sent ", msg
    # 		taskMgr.remove('message')

    def intRequest(self, msg):
        pkg = PyDatagram()
        pkg.addUint16(1)
        pkg.addInt32(msg)
        return pkg

    def stringRequest(self, msg):
        pkg = PyDatagram()
        pkg.addUint16(2)
        pkg.addString(msg)
        return pkg

    def shortRequest(self, msg):
        pkg = PyDatagram()
        pkg.addUint16(3)
        pkg.addUint16(msg)
        return pkg

    def floatRequest(self, msg):
        pkg = PyDatagram()
        pkg.addUint16(4)
        pkg.addFloat32(msg)
        return pkg

    def loginRequest(self, username, password):
        pkg = PyDatagram()
        pkg.addUint16(101)
        pkg.addString(username)
        pkg.addString(password)
        return pkg

    def registerRequest(self, username, password):
        pkg = PyDatagram()
        pkg.addUint16(103)
        pkg.addString(username)
        pkg.addString(password)
        return pkg

    def characterCreationRequest(self, username, classType):
        pkg = PyDatagram()
        pkg.addUint16(104)
        pkg.addString(username)
        pkg.addUint16(0)
        pkg.addUint16(classType)
        return pkg

    def chatRequest(self, message):
        pkg = PyDatagram()
        pkg.addUint16(105)
        pkg.addString(message)
        return pkg

    def moveRequest(self, x, y, z, h, isMoving):
        pkg = PyDatagram()
        pkg.addUint16(106)
        pkg.addFloat32(x)
        pkg.addFloat32(y)
        pkg.addFloat32(z)
        pkg.addFloat32(h)
        pkg.addUint16(isMoving)
        return pkg

    def check(self):
        while self.cReader.dataAvailable():
            print "data here"
            datagram = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram):
                data = PyDatagramIterator(datagram)
                responseCode = data.getUint16()
                print responseCode
                if responseCode == 1:
                    self.getInt(data)
                elif responseCode == 2:
                    self.getString(data)
                elif responseCode == 3:
                    self.getShort(data)
                elif responseCode == 4:
                    self.getFloat(data)
                elif responseCode == 201:
                    self.getLogin(data)
                elif responseCode == 203:
                    self.getRegistion(data)
                elif responseCode == 204:
                    self.getCharacterCreation(data)
                elif responseCode == 205:
                    self.getChat(data)
                elif responseCode == 206:
                    self.getMove(data)
                else:
                    print "nothing found"

    def getInt(self, data):
        msg = data.getInt32()
        print "recieved ", msg
        taskMgr.add(self.message, 'message')

    def getString(self, data):
        msg = data.getString()
        print "recieved ", msg
        taskMgr.add(self.message, 'message')

    def getShort(self, data):
        msg = data.getUint16()
        print "recieved ", msg
        taskMgr.add(self.message, 'message')

    def getFloat(self, data):
        msg = data.getFloat32()
        print "recieved ", msg
        taskMgr.add(self.message, 'message')

    def getLogin(self, data):
        flag = data.getUint16()

        if (flag == 0):
            print "Invalid Login"
        else:
            listSize = data.getUint16()

            for i in xrange(listSize):
                characterName = data.getString()
                characterId = data.getUint16()
                characterType = data.getUint16()
                characterFaction = data.getUint16()

                # Need to add these to an active characters class

    def getRegistion(self, data):
        flag = data.getUint16()

        if (flag == 0):
            print "Invalid Login"
        else:
            print "Account Created"

    def getCharacterCreation(self, data):
        flag = data.getUint16()

        if (flag == 0):
            print "Invalid Character"
        else:
            listSize = data.getUint16()

            for i in xrange(listSize):
                characterName = data.getString()
                characterId = data.getUint16()
                characterType = data.getUint16()
                characterFaction = data.getUint16()

                # Need to add these to an active characters class

    def getChat(self, data):
        username = data.getString()
        factionId = data.getUint16()
        message = data.getString()

    def getMove(self, data):
        username = data.getString()
        x = data.getFloat32()
        y = data.getFloat32()
        z = data.getFloat32()
        h = data.getFloat32()
        isMoving = data.getUint16()

    def updateRoutine(self, task):
        self.check()
        return task.again
Exemple #15
0
class MyApp(ShowBase):
	uname = None
	def __init__(self):
		ShowBase.__init__(self)
		
		self.cManager = QueuedConnectionManager()
		self.cListener = QueuedConnectionListener(self.cManager, 0)
		self.cReader = QueuedConnectionReader(self.cManager, 0)
		self.cWriter = ConnectionWriter(self.cManager, 0)
               
		
		host = "localhost";
    	        port = 6002;
		self.connection = self.cManager.openTCPClientConnection(host, port, 10000)
		
		self.received = 1
		
		if self.connection:
                	self.cReader.addConnection(self.connection)                	
			#taskMgr.add(self.updateRoutine, 'updateRoutine')
                       
                        # LOGIN Request Starts        
                        self.uname = raw_input('Enter username :'******'Enter password :'******'Login')
			if(self.received):
				print "->Client request:"
			# Send a request to the server
		
			myPyDatagram101 = PyDatagram()
			prot = 101
			myPyDatagram101.addUint16(prot)
			myPyDatagram101.addString(self.uname)
			myPyDatagram101.addString(self.password)
			self.cWriter.send(myPyDatagram101,self.connection)	
			self.received = 0
                        taskMgr.add(self.receiveResponse101,'Login')
                       
        def sendRequest101(self):
		if(self.received):
			print "->Client request:"
			# Send a request to the server
		
		myPyDatagram101 = PyDatagram()
		prot = 101
		myPyDatagram101.addUint16(prot)
		myPyDatagram101.addString(self.uname)
		myPyDatagram101.addString(self.password)
		self.cWriter.send(myPyDatagram101,self.connection)	
		self.received = 0
        
	def receiveResponse101(self,task):
		
		while self.cReader.dataAvailable():
			datagram = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram):
				self.myIterator = PyDatagramIterator(datagram)
                                print "<-Server response:"
				print self.myIterator.getUint16()
				self.msg = self.myIterator.getUint32()
				self.l = self.myIterator.getUint32()
                                if self.msg is not None:
				    if self.l is not 0:
					for x in range(0,self.l):
						print self.myIterator.getString()
						print self.myIterator.getUint32()
						print self.myIterator.getUint32()
							
				    print self.msg, " received"
                                    #raw_input("Press Enter to continue...")
				    
                                    self.received = 0
				    taskMgr.remove('Login')
				   
				    #1-Character creatopm
				    #taskMgr.add(self.sendRequest104, 'CharacterCreation')
				    
				    #2-heartbeat of playgame after login
				    MyApp.sendRequest113(self)
		return task.again               	
		   	            
                # LOGIN Request End        
                              
			      
		# CHARACTER CREATION Starts
	
        def sendRequest104(self,task):
		if(self.received):
			print "->Client request:"
			# Send a request to the server
		
		myPyDatagram = PyDatagram()
		prot = 104
		cname = raw_input('Character Name :')
		faction_id_104 = raw_input('press 0 for Red Or 1 for Blue ? :')
   		classType_104 = raw_input('press 0 for Axe Or 1 for Sword ? :')
		myPyDatagram.addUint16(prot)
		myPyDatagram.addString(cname)
		myPyDatagram.addUint32(faction_id_104)
		myPyDatagram.addUint32(classType_104)		
		self.cWriter.send(myPyDatagram,self.connection)	
					
		print "104 sent"
		self.received = 0
                taskMgr.add(self.receiveResponse104,"characterresponse")
        
	def receiveResponse104(self,task):
		
		while self.cReader.dataAvailable():
			datagram = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram):
				self.myIterator1 = PyDatagramIterator(datagram)
				print '------'
                                print self.myIterator1.getUint16()
                                self.msg = self.myIterator1.getUint32()
                                if self.msg is not None:
				    print "<-Server response:"
				    print self.msg, " received"
                                    raw_input("Press Enter to continue...")
                                    self.received = 0
				    taskMgr.remove('CharacterCreation')
				    taskMgr.add(self.sendRequest106, 'move')
				
	        return task.again
				
				
					
		#CHARACTER CREATION Ends
        
	
	# Move Starts    	
        def sendRequest106(self,task):
		if(self.received):
			print "->Client request:"
			# Send a request to the server
		
		myPyDatagram106 = PyDatagram()
		prot = 106
		xpos = raw_input('X Position :')
		ypos = raw_input('Y Position :')
    		zpos = raw_input('Z Position :')
    		hpos = raw_input('Heading (0 to 360):')
		ismoving = raw_input('Moving ? -- 0 for NO , 1 for YES :')
		myPyDatagram106.addUint16(prot)
		myPyDatagram106.addUint32(xpos)
		myPyDatagram106.addUint32(ypos)
		myPyDatagram106.addUint32(zpos)
		myPyDatagram106.addUint32(hpos)
		myPyDatagram106.addUint32(ismoving)
		self.cWriter.send(myPyDatagram106,self.connection)	
					
		self.received = 0
                taskMgr.add(self.receiveResponse106,"characterresponse")
        
	def receiveResponse106(self,task):	
		while self.cReader.dataAvailable():
			datagram6 = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram6):
				
				myIterator = PyDatagramIterator(datagram6)
                                print myIterator.getUint16()
				
                                msg = myIterator.getString()
                                
                                if msg is not None:
				    print "<-Server response:"
				    print msg
				    print myIterator.getUint32()
				    print myIterator.getUint32()
				    print myIterator.getUint32()
				    print myIterator.getUint32()
				    print myIterator.getUint32()
                                    raw_input("Press Enter to continue...")
                                    self.received = 1
				    # Attack
				    #raw_input("Press Enter to continue...") 
				    taskMgr.add(self.sendRequest108, 'health')
		return task.again				    
		#Move Ends
        
	#Change Health Starts
        def sendRequest108(self,task):
		if(self.received):
			print "->Client request:"
			# Send a request to the server
		
		myPyDatagram108 = PyDatagram()
		prot = 108
		change_Health = raw_input('Change in health (-100 to 100):')
		myPyDatagram108.addUint16(prot)
		myPyDatagram108.addUint32(change_Health)
		self.cWriter.send(myPyDatagram108,self.connection)	
					
		self.received = 0
                taskMgr.add(self.receiveResponse108,"healthresponse")
        
	def receiveResponse108(self,task):
		
		while self.cReader.dataAvailable():
			datagram8 = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram8):
				myIterator = PyDatagramIterator(datagram8)
                                print myIterator.getUint16()
                                msg = myIterator.getString()
                               
                                if msg is not None:
				    print "<-Server response:"
				    print msg
				    print myIterator.getUint32()
                                    self.received = 1
				    # CP State
				    raw_input("Press Enter to continue...") 
				    taskMgr.add(self.sendRequest107, 'attack')
		#Change Health Ends
	        return task.again
	
	# Attack Starts
        def sendRequest107(self,task):
		if(self.received):
			print "->Client request:"
			# Send a request to the server
		
		myPyDatagram107 = PyDatagram()
		prot = 107
		attackId = raw_input('Attack Id (0 or 1):')
		myPyDatagram107.addUint16(prot)
		myPyDatagram107.addUint32(attackId)
		self.cWriter.send(myPyDatagram107,self.connection)	
					
		#print " sent"
		self.received = 0
                taskMgr.add(self.receiveResponse108,"attackresponse")
        
	def receiveResponse107(self,task):
		
		
		while self.cReader.dataAvailable():
			datagram7 = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram7):
				myIterator = PyDatagramIterator(datagram7)
                                print myIterator.getUint16()
                                msg = myIterator.getString()
                                
                                if msg is not None:
				    print "<-Server response:"	
                                    print msg
				    print myIterator.getUint32()
				    raw_input("Press Enter to continue...")
                                    self.received = 1
                                     # Change Health
				    taskMgr.add(self.sendRequest112, 'CP Capture')
		return task.again				    
		#Attack Ends
	
				
	
	
	
	#CP Capture Starts
        def sendRequest112(self,task):
		if(self.received):
			print "->Client request:"
			# Send a request to the server
		
		myPyDatagram112 = PyDatagram()
		prot = 112
		CP_id = raw_input('Control Point ID (1 to 5): ')
		faction_id = raw_input('press 0 for Red Or 1 for Blue ? :')
		myPyDatagram112.addUint16(prot)
		myPyDatagram112.addUint32(CP_id)
		myPyDatagram112.addUint32(faction_id)
		self.cWriter.send(myPyDatagram112,self.connection)	
					
		#print " sent"
		self.received = 0
                taskMgr.add(self.receiveResponse112,"CPCaptureRes")
        
	def receiveResponse112(self,task):
		
		while self.cReader.dataAvailable():
			datagram12 = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram12):
				myIterator = PyDatagramIterator(datagram12)
                                print myIterator.getUint16()
                                msg = myIterator.getUint32()
                                
                                if msg is not None:
				    print "<-Server response:"
                                    print msg
				    print myIterator.getUint32()
				    raw_input("Press Enter to continue...")
                                    self.received = 1
                                     #HeartBeat
				    #raw_input("Press Enter to continue...") 
				    #taskMgr.add(self.communicate105, 'chat')
						    
		#CP Capture Ends
		
		
	# CHAT Starts
	def communicate105(self,task):
		#print "communicate"
		self.sendRequest105()
		self.receiveResponse105(task)		
                return task.again;
        		
        def sendRequest105(self):
		if(self.received):
			print "->Client request:"
			# Send a request to the server
		
		myPyDatagram105 = PyDatagram()
		prot = 105
		chat = raw_input('Insert Chat Message :')
		myPyDatagram105.addUint16(prot)
		myPyDatagram105.addString(chat)
		self.cWriter.send(myPyDatagram105,self.connection)	
					
		print " sent"
		self.received = 0
                
        
	def receiveResponse105(self,task):
		print "<-Server response:"
		while self.cReader.dataAvailable():
			datagram5 = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram5):
				myIterator = PyDatagramIterator(datagram5)
                                print myIterator.getUint16()
                                msg = myIterator.getUint16()
                                print msg, " received"
                                if msg is not None:
                                    raw_input("Press Enter to continue...")
                                    self.received = 1
                                     # Move
				    raw_input("Press Enter to continue...") 
				    taskMgr.add(self.communicate111, 'CP state')
						    
		#CHAT Ends
	
	
	#CP State Starts
	def communicate111(self,task):
		#print "communicate"
		self.sendRequest111()
		self.receiveResponse111(task)		
                return task.again;
        		
	def sendRequest111(self):
		if(self.received):
			print "->Client request:"
			# Send a request to the server
		
		myPyDatagram111 = PyDatagram()
		prot = 111
		CP_id = raw_input('Control Point ID (1 to 5): ')
		CP_state = raw_input('Control Point state (1 red, 2 blue, 3 purple): ')
		myPyDatagram111.addUint16(prot)
		myPyDatagram111.addUint16(CP_id)
		myPyDatagram111.addUint16(CP_state)
		self.cWriter.send(myPyDatagram111,self.connection)	
					
		print " sent"
		self.received = 0
                
        
	def receiveResponse111(self,task):
		print "<-Server response:"
		while self.cReader.dataAvailable():
			datagram11 = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram11):
				myIterator = PyDatagramIterator(datagram11)
                                print myIterator.getUint16()
                                msg = myIterator.getUint16()
                                print msg, " received"
                                if msg is not None:
                                    raw_input("Press Enter to continue...")
                                    self.received = 1
                                     # CP Capture
				    raw_input("Press Enter to continue...") 
				    taskMgr.add(self.communicate102, 'Logout')
		#CP State Ends
	
	
	# LOGOUT Starts
	def communicate102(self,task):
		#print "communicate"
		self.sendRequest102()
		self.receiveResponse102(task)		
                return task.again;
        		
        def sendRequest102(self):
		if(self.received):
			print "->Client request:"
			# Send a request to the server
		
		myPyDatagram102 = PyDatagram()
		prot = 102
		myPyDatagram102.addUint16(prot)
		self.cWriter.send(myPyDatagram102,self.connection)	
					
		print " sent"
		self.received = 0
          
	def receiveResponse102(self,task):
		print "<-Server response:"
		while self.cReader.dataAvailable():
			datagram2 = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram2):
				myIterator = PyDatagramIterator(datagram2)
                                print myIterator.getUint16()
                                msg = myIterator.getUint16()
                                print msg, " received"
                                if msg is not None:
                                    raw_input("Press Enter to continue...")
                                    self.received = 1
                                     # Register
				    raw_input("Press Enter to continue...")
				    taskMgr.add(self.communicate301, 'Heartbeat')
						    
		#LOGOUT Ends
		
		
		#HeartBeat Starts
	def communicate301(self):
		#print "communicate"
		self.sendRequest301()
		self.receiveResponse301()		
                #return task.again;
        		
        def sendRequest301(self,task):
		if(self.received):
			print "->Client request:"
			# Send a request to the server
		
		myPyDatagram301 = PyDatagram()
		prot = 301
		myPyDatagram301.addUint16(prot)
		self.cWriter.send(myPyDatagram301,self.connection)	
		self.received = 0
                return task.again
        
	def receiveResponse301(self):
		
		while self.cReader.dataAvailable():
			datagram301 = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram301):
				myIterator = PyDatagramIterator(datagram301)
                                p =  myIterator.getUint16()
                                if p == 213:
					un = myIterator.getString()
					cname = myIterator.getString()
					ctype = myIterator.getUint32()
					cteam = myIterator.getUint32()	
					if un ==  MyApp.uname:
						abc = 'abc'
					else:	
						print cname+' just joined a game......!! hurray'
				
					#print msg, " received"
					
					self.received = 1
                                		    
		#HeartBeat Ends
		
	#heartbeat
	def sendRequest113(self):
		if(self.received):
			print "->Client request:"
			# Send a request to the server
		
		myPyDatagram113 = PyDatagram()
		prot = 113
		myPyDatagram113.addUint16(prot)
		print MyApp.uname+'-------'
		if MyApp.uname == 'chintan':
			myPyDatagram113.addUint32(18)
		elif MyApp.uname == 'paras':
			myPyDatagram113.addUint32(35)
		else:
			myPyDatagram113.addUint32(3)
		self.cWriter.send(myPyDatagram113,self.connection)	
		self.received = 0
		#taskMgr.add(self.updateRoutine,'update113')
		#taskMgr.doMethodLater(1,self.sendRequest301,'HeatBeat')
		MyApp.retrieve113(self)
		
	def retrieve113(self):
		taskMgr.add(self.updateRoutine,'update113')
		taskMgr.doMethodLater(1,self.sendRequest301,'HeatBeat')
	
		
	def updateRoutine(self,task):
		self.receiveResponse301()
		return task.again;
Exemple #16
0
class OldNetworkSystem(sandbox.EntitySystem):
    def init(self, port=1999, backlog=1000, compress=False):
        log.debug("Initing Network System")
        self.accept("broadcastData", self.broadcastData)
        self.port = port
        self.backlog = backlog
        self.compress = compress

        self.cManager = QueuedConnectionManager()
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        #self.cReader.setRawMode(True)
        self.cWriter = ConnectionWriter(self.cManager, 0)
        self.udpSocket = self.cManager.openUDPConnection(self.port)
        self.cReader.addConnection(self.udpSocket)

        self.activePlayers = []  # PlayerComponent
        self.activeConnections = {}  # {NetAddress : PlayerComponent}
        self.lastAck = {}  # {NetAddress: time}

        self.startPolling()
        self.accept("shipGenerated", self.shipGenerated)

    def startPolling(self):
        #taskMgr.add(self.tskReaderPolling, "serverListenTask", -40)
        taskMgr.doMethodLater(10, self.activeCheck, "activeCheck")

    #def tskReaderPolling(self, taskdata):
    def begin(self):
        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):
                myIterator = PyDatagramIterator(datagram)
                msgID = myIterator.getUint8()

                #If not in our protocol range then we just reject
                if msgID < 0 or msgID > 200:
                    return

                self.lastAck[datagram.getAddress()] = datetime.datetime.now()
                #TODO Switch to ip address and port

                #Order of these will need to be optimized later
                #We now pull out the rest of our headers
                remotePacketCount = myIterator.getUint8()
                ack = myIterator.getUint8()
                acks = myIterator.getUint16()
                hashID = myIterator.getUint16()

                if msgID == protocol.LOGIN:
                    username = myIterator.getString()
                    password = myIterator.getString()
                    if username not in accountEntities:
                        entity = sandbox.createEntity()
                        component = AccountComponent()
                        component.name = username
                        component.passwordHash = password
                        if not accountEntities:
                            component.owner = True
                        component.address = datagram.getAddress()
                        entity.addComponent(component)
                        accountEntities[username] = entity.id
                        log.info("New player " + username + " logged in.")
                        #
                        self.activePlayers.append(component)
                        self.activeConnections[component.address] = component
                        ackDatagram = protocol.loginAccepted(entity.id)
                        self.sendData(ackDatagram, datagram.getAddress())
                        #TODO: Send initial states?
                        messenger.send("newPlayerShip", [component, entity])
                    else:
                        component = sandbox.entities[accountEntities[username]].get_component(AccountComponent)
                        if component.passwordHash != password:
                            log.info("Player " + username + " has the wrong password.")
                        else:
                            component.connection = datagram.getConnection()
                            log.info("Player " + username + " logged in.")

    def activeCheck(self, task):
        """Checks for last ack from all known active conenctions."""
        for address, lastTime in self.lastAck.items():
            if (datetime.datetime.now() - lastTime).seconds > 30:
                component = self.activeConnections[address]
                #TODO: Disconnect
        return task.again

    def sendData(self, datagram, address):
        self.cWriter.send(datagram, self.udpSocket, address)

    def broadcastData(self, datagram):
        # Broadcast data out to all activeConnections
        #for accountID in accountEntities.items():
            #sandbox.entities[accountID].get_component()
        for addr in self.activeConnections.keys():
            self.sendData(datagram, addr)

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

    def shipGenerated(self, ship):
        datagram = protocol.newShip(ship)
        log.info("Checking if new ship is valid for udp:", self.cWriter.isValidForUdp(datagram))
        self.broadcastData(datagram)
        datagram = protocol.movedShip(ship)
        address = self.getAddress(ship.get_component(ships.PilotComponent).accountEntityID)
        self.sendData(datagram, address)

    def getAddress(self, entityID):
        return sandbox.components[entityID][AccountComponent].address
Exemple #17
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)
class ClientServerBase(object):
    '''
    Baseclass for client and server, 
    these two have almost all functionality similar, except for who is responsible for opening / closing connections
    and the fact that server can have multiple connections
    '''
    def __init__(self, host="localhost", port=5001, name="client or server"):
        self.name = name
        self.port = port
        self.host = host

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

        self.connections = [
        ]  # list of connections, contains 1 item for client, multiple for server

        self.readerCallback = None  # will be called when a new message arrives
        self.writerCallback = None  # will be called when a message needs to be constructed

        self.taskMgr = Task.TaskManager()
        self.taskMgr.add(self.tskReaderPolling, "Poll the connection reader",
                         -40)
        self.taskMgr.add(self.tskWriterPolling, "Send data package", -39)

    def setReaderCallback(self, callbackFunction):
        self.readerCallback = callbackFunction

    def setWriterCallback(self, callbackFunction):
        self.writerCallback = callbackFunction

    def tskReaderPolling(self, taskdata):

        # reader callback
        if not self.cReader.dataAvailable():
            # print( "tskReaderPolling(): no data available!" )
            return Task.cont

        datagram = NetDatagram()
        if not self.cReader.getData(datagram):
            print("tskReaderPolling(): cannot claim data!")
            return Task.cont

        if self.readerCallback:
            print("tskReaderPolling():readerCallback()")
            self.readerCallback(datagram)

        return Task.cont

    def tskWriterPolling(self, data):

        if not self.writerCallback:
            return Task.cont

        data = self.writerCallback()
        if data == None:
            return Task.cont

        assert (isinstance(data, Datagram))

        print("tskWriterPolling() sending to : {}".format(len(
            self.connections)))

        for con in self.connections:
            if con:
                print("tskWriterPolling() sending")
                self.cWriter.send(data, con)

        return Task.cont

    def Close(self):
        # close each of the connections
        for c in self.connections:
            self.cManager.closeConnection(c)

    def ProcessReaderData(self, data):
        raise NotImplementedError(
            "overwrite ProcessReaderData() in client/server implementation")
class SocketHandler:
    logger = Logger("socket_handler")

    def __init__(self,
                 port=None,
                 host=None,
                 ip_addr="127.0.0.1",
                 backlog=10000,
                 timeout=5000):
        self.port = port  # our port
        self.host = host  # host port
        self.ip_addr = ip_addr
        self.backlog = backlog
        self.timeout = timeout

        self.socket = None
        self.connection = None
        self.active_connections = []

        self.handler = None

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

    def setup_socket(self):
        self.socket = self.cManager.openTCPServerRendezvous(
            self.ip_addr, self.port, self.backlog)
        if self.socket is None:
            raise Exception("unable to open new socket at %s:%d" %
                            (self.ip_addr, self.port))
        self.cListener.addConnection(self.socket)

        taskMgr.add(self.listen_suggestions, "poll the suggestion listener")
        taskMgr.add(self.read_data, "poll the connection reader")

    def connect_socket(self):
        if self.connection is None:
            self.connection = self.cManager.openTCPClientConnection(
                self.ip_addr, self.host, self.timeout)
            if self.connection is None:
                raise Exception("unable to connect to socket at %s:%d" %
                                (self.ip_addr, self.host))
            self.cReader.addConnection(self.connection)

            taskMgr.add(self.read_data, "poll the socket reader")

    def listen_suggestions(self, task):
        # to be overridden by inheritors
        pass

    def read_data(self, task):
        if self.cReader.dataAvailable():
            dg = NetDatagram()

            if self.cReader.getData(dg):
                self.handle_data(dg)
        return task.cont

    def handle_data(self, dg):
        # to be overridden by inheritors
        pass
Exemple #20
0
class OldNetworkSystem(sandbox.EntitySystem):
    def init(self, port=2000, server="127.0.0.1", serverPort=1999, backlog=1000, compress=False):
        self.packetCount = 0
        self.port = port
        self.serverPort = serverPort
        self.serverIP = server
        self.serverAddress = NetAddress()
        self.serverAddress.setHost(server, serverPort)
        self.cManager = QueuedConnectionManager()
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager, 0)

        self.udpSocket = self.cManager.openUDPConnection(self.port)
        self.cReader.addConnection(self.udpSocket)

    def begin(self):
        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):
                myIterator = PyDatagramIterator(datagram)
                msgID = myIterator.getUint8()

                #If not in our protocol range then we just reject
                if msgID < 0 or msgID > 200:
                    return

                #Order of these will need to be optimized later
                #We now pull out the rest of our headers
                remotePacketCount = myIterator.getUint8()
                ack = myIterator.getUint8()
                acks = myIterator.getUint16()
                hashID = myIterator.getUint16()
                sourceOfMessage = datagram.getConnection()

                if msgID == protocol.NEW_SHIP:
                    log.info("New ship")
                    playerPilotID = myIterator.getUint16()
                    shipID = myIterator.getUint16()
                    shipName = myIterator.getString()
                    health = myIterator.getUint8()
                    position = Point3(myIterator.getFloat32(), myIterator.getFloat32(), myIterator.getFloat32())
                    linearVelocity = Vec3(myIterator.getFloat32(), myIterator.getFloat32(), myIterator.getFloat32())
                    rotiation = VBase3(myIterator.getFloat32(), myIterator.getFloat32(), myIterator.getFloat32())
                    angularVelocity = Vec3(myIterator.getFloat32(), myIterator.getFloat32(), myIterator.getFloat32())
                    ship = sandbox.addEntity(shipID)
                    component = ships.PilotComponent()
                    component.accountEntityID = playerPilotID
                    ship.addComponent(component)
                    component = ships.BulletPhysicsComponent()
                    messenger.send("addSpaceShip", [component, shipName, position, linearVelocity])
                    ship.addComponent(component)
                    component = ships.ThrustComponent()
                    ship.addComponent(component)
                    component = ships.InfoComponent()
                    component.health = health
                    component.name = shipName
                    ship.addComponent(component)
                elif msgID == protocol.PLAYER_MOVED_SHIP:
                    log.debug("Player moved ship")
                    accountID = myIterator.getUint16()
                    shipID = myIterator.getUint16()
                    print sandbox.components[shipID]
                    universals.shipNode = sandbox.components[shipID][ships.BulletPhysicsComponent].nodePath
                elif msgID == protocol.LOGIN_ACCEPTED:
                    log.info("Login accepted")
                    entityID = myIterator.getUint8()
                    universals.day = myIterator.getFloat32()
                elif msgID == protocol.LOGIN_DENIED:
                    log.info("Login failed")

    def genBasicData(self, proto):
        myPyDatagram = PyDatagram()
        myPyDatagram.addUint8(proto)
        myPyDatagram.addUint8(self.packetCount)
        myPyDatagram.addUint8(0)
        myPyDatagram.addUint16(0)
        myPyDatagram.addUint16(0)
        self.packetCount += 1
        return myPyDatagram

    def sendLogin(self, username, hashpassword):
        datagram = self.genBasicData(protocol.LOGIN)
        datagram.addString(username)
        datagram.addString(hashpassword)
        universals.log.debug("sending login")
        self.sendData(datagram)

    def sendData(self, datagram):
        sent = self.cWriter.send(datagram, self.udpSocket, self.serverAddress)
        while not sent:
            print "resending"
            sent = self.cWriter.send(datagram, self.udpSocket, self.serverAddress)
Exemple #21
0
class Connection(GlobalClockMixin, TaskMixin):
    def __init__(self, base, host, port):
        self.base = base
        self.host = host
        self.port = port

        self._conn = None

        self._retry_elapsed = 0
        self._retry_next = 0
        self._data_last_received = 0

        self.manager = QueuedConnectionManager()

        self.reader = QueuedConnectionReader(
            self.manager,
            0,  # number of threads
        )

        # we're using our own protocol so we don't want panda reading our headers and getting
        # all foobared by it (not setting raw mode causes `dataAvailable` to block
        # once there is actually data to process)
        self.reader.setRawMode(True)

        self.writer = ConnectionWriter(
            self.manager,
            0,  # number of threads
        )

    def connect(self, connected_callback, task):
        """
        Attempts to connect to the server and if unable to will retry adding
        a second to the wait time to each consecutive failure.
        """
        self._retry_elapsed += self.get_dt()
        if self._retry_elapsed < self._retry_next:
            return task.cont

        logging.debug('attempting to connect to server at %s:%d', self.host,
                      self.port)
        self._conn = self.manager.openTCPClientConnection(
            self.host,
            self.port,
            10000,  # timeout ms
        )

        if self._conn:
            logging.debug('connection established')
            self.reader.addConnection(self._conn)

            # reset the counters in case the connection drops and we have to restart the
            # connection process
            self._retry_elapsed = 0
            self._retry_next = 0

            # add a task to poll the connection for data
            self.add_task(
                self.task_read_polling,
                name='connection_reader_poll',
                sort=-39,
            )

            connected_callback()
            return

        # no connection so retry in a bit
        self._retry_elapsed = 0
        if self._retry_next == 0:
            self._retry_next = 1
        elif self._retry_next > 9:
            self._retry_next = 10
        else:
            self._retry_next += 1

        logging.error(
            'Unable to connect to server %s:%s, will retry in %d seconds',
            self.host,
            self.port,
            self._retry_next,
        )
        return task.cont

    def task_read_polling(self, task):
        if self.reader.dataAvailable():
            logging.debug('data available from server')
            datagram = Datagram()
            if self.reader.getData(datagram):
                logging.debug('received data from server: %s', datagram)
                logging.debug('received data from server: %s',
                              datagram.getMessage())
                # TODO: provide a way to supply a data callback
            self._data_last_received = 0
        else:
            # no data received
            logging.debug('no data')
            self._data_last_received += self.get_dt()

        if self._data_last_received >= 10:
            logging.error('connection to server lost')
            return

        return task.cont

    def shutdown(self):
        logging.info('connection reader shutting down')
        self.reader.shutdown()
Exemple #22
0
class TCP():
    def __init__(self, _core):
        print("TCP Protocol Startup...")
        self.core = _core
        self.config = self.core.client.config

        # Connection on TCP
        self.tcpConnection = None

    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)

    def startTCPTasks(self):
        taskMgr.add(self.tcpReaderTask, "tcpReaderTask", -10)
        print("TCP Reader Started")

    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)

        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)

    def connectToServer(self, _ip, _port):
        self.tcpConnection = self.tcpManager.openTCPClientConnection(
            _ip, _port, 1000)

        if self.tcpConnection != None:
            self.tcpReader.addConnection(self.tcpConnection)
Exemple #23
0
class World(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)
        
        host = "localhost"
        port = 9898
        self.connection = self.cManager.openTCPClientConnection(host, port, 10000)
        #self.received = 1
        
        #store a dictionary of active players with username player as key value pair
        #the dictionary also contain a special player named panda
        self.players = {}
        
        #for display the list on the screen
        self.temp = []
        
        #store a dictionary of playerObject
        self.playerObjects = {}
        self.render = render
        self.loginSuccessful = False
        self.isMoving = False
        self.justStoping = False
        self.targetPlayer = None        
        
        if self.connection:
            self.cReader.addConnection(self.connection)
            taskMgr.add(self.updateRoutine, 'updateRoutine')
            #taskMgr.doMethodLater(0.5, self.updateRoutine, 'updateRoutine')
            #taskMgr.add(self.updatePandaAttack, 'updatePandaAttack')
            #taskMgr.doMethodLater(3, self.updatePandaAttack, 'updatePandaAttack')
            self.loginRegister()
            

    #################Communication Method################
    
    def loginRegister(self):
        print "1. Login"
        print "2. Register"
        userInput = str(raw_input("Enter 1 or 2: "))
        if userInput == "1":
            self.login()
        elif userInput == "2":
            self.register();
        else:
            print "Invalid input"
            self.loginRegister()
    
    def register(self):
        print "Please enter your username: "******"Please enter your password: "******"{} {} {}".format(REGISTER, username, password)
        self.sendRequest(msg)
    
    #define self.username to specify the username for this object   
    def login(self):
        print "Please enter your username: "******"Please enter your password: "******"{} {} {}".format(LOGIN, self.username, password)            
        self.sendRequest(msg)
  
    #user need to press esc key to logout       
    def logout(self, x, y, z, h):
        print "logout called"
        player = self.players[self.username]
        
        msg = "{} {},{},{},{},{}".format(LOGOUT, self.username, 
                        player.getX(), player.getY(), player.getZ(), player.getH())         
        print msg          
        self.sendRequest(msg)
        sys.exit()  
    
    def updateMovement(self, isMove, x, y, z, h):
        #send code username,ismove,x,y,z,h to the server according to the protocol
        msg = "{} {},{},{},{},{},{}".format(UPDATE_PLAYER_MOVE, self.username, isMove, x, y, z, h)
        self.sendRequest(msg)
    
    def possibleAttackRequest(self, distance):
        msg = "{} {},{}".format(PANDA_ATTACK_REQUEST, self.username, distance)
        self.sendRequest(msg)
        
    def composeStringMessage(self, msg):
        myPyDatagram = PyDatagram()
        myPyDatagram.addString(msg)
        return myPyDatagram
                
    def retrieveStringMessage(self,datagram):
        myIterator = PyDatagramIterator(datagram)
        msg = myIterator.getString()
        #print msg, " received"
        return msg
            
#     def sendRequest(self):
#         if(self.received):
#             print "->Client request:"
#             # Send a request to the server
#         mylist = ["apple", "ball", "cat", "dog"] 
#         
#         msg = random.choice(mylist)
#         request = self.composeStringMessage(msg)
#         ack = self.cWriter.send(request,self.connection)                
#         print msg, " sent"
#         self.received = 0

    def sendRequest(self, msg):
        request = self.composeStringMessage(msg)
        ack = self.cWriter.send(request,self.connection)                
        #print msg, " sent"
        #self.received = 0
        
    def receiveResponse(self):
        #print "<-Server response:"
        while self.cReader.dataAvailable():
            datagram = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram):
                msg = self.retrieveStringMessage(datagram)
                msgs = msg.split(' ')
                #print msgs[0]
                
                if msgs[0] == REGISTER_SUCCESSFUL:
                    self.registerSuccessfulResponse()
                elif msgs[0] == USERNAME_EXIST:
                    self.usernameExistResponse()
                elif msgs[0] == LOGIN_SUCCESSFUL:
                    self.loginSuccessfulResponse(msgs[1])
                elif msgs[0] == ADD_NEW_PLAYER:
                    self.addNewPlayerResponse(msgs[1])
                elif msgs[0] == LOGIN_FAIL:
                    self.loginFailResponse()
                elif msgs[0] == LOGOUT:
                    self.logoutResponse(msgs[1])
                elif msgs[0] == UPDATE_PLAYER_MOVE_RESPONSE:
                    self.updateMoveResponse(msgs[1])
                elif msgs[0] == PANDA_ATTACK:
                    self.pandaAttackResponse(msgs[1])
                #self.received = 1
                
#     def communicate(self):
#         #print "communicate"
#         #self.sendRequest()
#         self.receiveResponse()
        
    def updateRoutine(self,task):
        #self.communicate()
        self.receiveResponse()
        return task.again;
    
    def registerSuccessfulResponse(self):
        print "You have successfully registered. Please login to start the game."
        self.login()
    
    def usernameExistResponse(self):
        print "Username already exist. Please choose another username."
        self.register()
    
    #initail a dictionary of players
    def loginSuccessfulResponse(self, playerListMsg):
        actorsMsg = playerListMsg.split(":")
        #the dictionary also adds a special player named panda
        for aMsg in actorsMsg:
            elements = aMsg.split(",")
            actor = Player(elements[0], float(elements[1]), float(elements[2]), float(elements[3]), 
                           float(elements[4]))
            self.players[elements[0]] = actor
            
        print "login successful"
        
        #display other players' Ralph
        for username, value in self.players.iteritems():
            if username == self.username:
                #display this player's Ralph
                self.showRalph(value)      
            elif username != self.username and username != "panda":
                self.createActor(self.render, value)
            elif username == "panda":
                self.createPanda(self.render, value)
            else:
                pass
        
        self.loginSuccessful = True       
    
    #add new player to the players dictionary
    def addNewPlayerResponse(self, msg):
        elements = msg.split(",")
        actor = Player(elements[0], float(elements[1]), float(elements[2]), float(elements[3]), 
                       float(elements[4]))
        self.players[elements[0]] = actor        
        print "add new player: ", self.players[elements[0]].getUsername(), self.players[elements[0]].getX()
        self.createActor(self.render, actor)
        
        ###Line's Added###
        textMsg = elements[0]+" has logged in"
        self.notifyPlayer(textMsg)
        
    def loginFailResponse(self):
        print "Username and password does not match, please re-login or register."
        self.loginRegister()
        
    def logoutResponse(self, username):
        if username in self.players:
            del self.players[username]
        
        if username in self.playerObjects:
            playerObject = self.playerObjects[username]
            playerObject.getActor().delete()
        
            del self.playerObjects[username]
        #self.playerObjects
        print "{} logout".format(username)
        
        ###Lines Added###
        msg = username+" has logged out"
        self.notifyPlayer(msg)
        
    def notifyPlayer(self,msg):
        #label = DirectLabel(text=msg)
        label = OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(1.3,-0.95), align=TextNode.ARight, scale = .07)
        taskMgr.doMethodLater(5, self.destroyLabel, 'destroyLabel', extraArgs=[label])
        
    def destroyLabel(self,label):
        label.destroy()
        
    def updateMoveResponse(self, msg):
        if self.loginSuccessful:
            #msg contain username,isMoving,x,y,z,h
            msgs = msg.split(",")
            username = msgs[0]
            if username == self.username:
                #self already move, no need to update
                pass
            else:
                if username in self.playerObjects.keys(): 
                    player = self.players[username]
                    player.setX(float(msgs[2]))
                    player.setY(float(msgs[3]))        
                    player.setZ(float(msgs[4]))    
                     
                    actor = self.playerObjects[username].getActor()
                    actor.setPos(float(msgs[2]), float(msgs[3]), float(msgs[4]))
                    actor.setH(float(msgs[5]))
                    self.playerObjects[username].move(msgs[1])
    
    def pandaAttackResponse(self, msg):
        #msg contain targetUsername
        #print "pan Att: ", msg
        #msgs = msg.split(",")
        
        targetUsername = msg
        targetPlayer = self.players[targetUsername]

        pandaActor = self.pandaObject.getActor()
        pandax = pandaActor.getX()
        panday = pandaActor.getY()
        pandaz = pandaActor.getZ()        
         
        x = targetPlayer.getX()
        y = targetPlayer.getY()
        z = targetPlayer.getZ()
         
        distance = self.getDistance(pandax, panday, pandaz, x, y, z)
      
        if distance < PANDA_ATTACK_RANGE:
            if pandax > x and panday > y:
                self.pandaObject.setH(135)
            elif pandax > x and panday < y:
                self.pandaObject.setH(180)
            elif pandax < x and panday > y:
                self.pandaObject.setH(135)
            else:
                self.pandaObject.setH(90)
            #self.pandaObject.turn(180)         
            self.pandaObject.move(x-0.5, y-0.5, z)
            
            panda = self.players["panda"]
            panda.setX(pandax);
            panda.setY(panday);
            panda.setZ(pandaz);
        
        #self.setTargetPlayer(msg)
        
    def setTargetPlayer(self, username):
        self.targetPlayer = self.players[username]
        
    def getTargetPlayer(self):
        return self.targetPlayer        
                    
    def createActor(self, render, actor):
        playerObject = PlayerObject(render, actor)
        self.playerObjects[actor.getUsername()] = playerObject
#         nameplate = TextNode('textNode username_' + str(actor.username))
#         nameplate.setText(actor.username)
#         npNodePath = actor.actor.attachNewNode(nameplate)
#         npNodePath.setScale(1.0)
#         npNodePath.setBillboardPointEye()
#         npNodePath.setZ(8.0)
        
    def createPanda(self, render, actor):
        self.pandaObject = PandaObject(render, actor)
        
    def checkPossibleAttack(self, x, y, z):
        panda = self.players["panda"]
        pandax = panda.getX();
        panday = panda.getY();
        pandaz = panda.getZ();
        
        distance = self.getDistance(pandax, panday, pandaz, x, y, z)
        
        if distance < PANDA_ATTACK_RANGE:
            self.possibleAttackRequest(distance)
            
    def getDistance(self, pandax, panday, pandaz, x, y, z):
        
        return math.sqrt( math.pow(pandax-x, 2) + math.pow(panday-y, 2) + math.pow(pandaz-z, 2) )
        
    #################################################################
    
    ################Ralph code ##################### 
       
    def showRalph(self, player):        
        
#         self.render = render
         
        self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}
        base.win.setClearColor(Vec4(0,0,0,1))
 
        # Post the instructions
 
        #self.title = addTitle("Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)")
        self.inst1 = addInstructions(0.95, "[ESC]: Quit")
        self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left")
        self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right")
        self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward")
        self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left")
        self.inst7 = addInstructions(0.65, "[S]: Rotate Camera Right")
        
        self.inst8 = addInstructions(0.60, "[l] Show Players on the right corner")
         
        # Set up the environment
        #
        # This environment model contains collision meshes.  If you look
        # in the egg file, you will see the following:
        #
        #    <Collide> { Polyset keep descend }
        #
        # This tag causes the following mesh to be converted to a collision
        # mesh -- a mesh which is optimized for collision, not rendering.
        # It also keeps the original mesh, so there are now two copies ---
        # one optimized for rendering, one for collisions.  
         
        self.environ = loader.loadModel("models/world")      
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,0)
        
        # Create the main character, Ralph

        ralphStartPos = self.environ.find("**/start_point").getPos()
        self.ralph = Actor("models/ralph",
                                 {"run":"models/ralph-run",
                                  "walk":"models/ralph-walk"})
        self.ralph.reparentTo(render)
        self.ralph.setScale(.2)
        #self.ralph.setPos(ralphStartPos)
        
        self.ralph.setPos(player.getX(), player.getY(), player.getZ())
        self.ralph.setH(player.getH())
        
        #####################################


        # Create a floater object.  We use the "floater" as a temporary
        # variable in a variety of calculations.
        
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)

        # Accept the control keys for movement and rotation

        #self.accept("escape", sys.exit)
        self.accept("escape", self.logout, [self.ralph.getX(), self.ralph.getY(), self.ralph.getZ(), self.ralph.getH()])
        self.accept("arrow_left", self.setKey, ["left",1])
        self.accept("arrow_right", self.setKey, ["right",1])
        self.accept("arrow_up", self.setKey, ["forward",1])
        self.accept("a", self.setKey, ["cam-left",1])
        self.accept("s", self.setKey, ["cam-right",1])
        self.accept("arrow_left-up", self.setKey, ["left",0])
        self.accept("arrow_right-up", self.setKey, ["right",0])
        self.accept("arrow_up-up", self.setKey, ["forward",0])
        self.accept("a-up", self.setKey, ["cam-left",0])
        self.accept("s-up", self.setKey, ["cam-right",0])

        taskMgr.add(self.move,"moveTask")

        # Game state variables
        self.isMoving = False

        # Set up the camera
        
        base.disableMouse()
        base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2)
        
        # We will detect the height of the terrain by creating a collision
        # ray and casting it downward toward the terrain.  One ray will
        # start above ralph's head, and the other will start above the camera.
        # A ray may hit the terrain, or it may hit a rock or a tree.  If it
        # hits the terrain, we can detect the height.  If it hits anything
        # else, we rule that the move is illegal.

        self.cTrav = CollisionTraverser()

        self.ralphGroundRay = CollisionRay()
        self.ralphGroundRay.setOrigin(0,0,1000)
        self.ralphGroundRay.setDirection(0,0,-1)
        self.ralphGroundCol = CollisionNode('ralphRay')
        self.ralphGroundCol.addSolid(self.ralphGroundRay)
        self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol)
        self.ralphGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)

        self.camGroundRay = CollisionRay()
        self.camGroundRay.setOrigin(0,0,1000)
        self.camGroundRay.setDirection(0,0,-1)
        self.camGroundCol = CollisionNode('camRay')
        self.camGroundCol.addSolid(self.camGroundRay)
        self.camGroundCol.setFromCollideMask(BitMask32.bit(0))
        self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
        self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)
        self.camGroundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)

        # Uncomment this line to see the collision rays
        #self.ralphGroundColNp.show()
        #self.camGroundColNp.show()
       
        # Uncomment this line to show a visual representation of the 
        # collisions occuring
        #self.cTrav.showCollisions(render)
        
        # Create some lighting
        ambientLight = AmbientLight("ambientLight")
        ambientLight.setColor(Vec4(.3, .3, .3, 1))
        directionalLight = DirectionalLight("directionalLight")
        directionalLight.setDirection(Vec3(-5, -5, -5))
        directionalLight.setColor(Vec4(1, 1, 1, 1))
        directionalLight.setSpecularColor(Vec4(1, 1, 1, 1))
        render.setLight(render.attachNewNode(ambientLight))
        render.setLight(render.attachNewNode(directionalLight))


    #Records the state of the arrow keys
    def setKey(self, key, value):
        self.keyMap[key] = value
        
    '''method to show player list'''
    def showPlayers(self, set):
        for i in self.temp:
            i.destroy()
        self.temp = []
        y=[]
        i = 0
        while(i!=set.__len__()):
            y.append(0.95-(i*0.05))
            i=i+1
        i = 0
        while(i!=y.__len__()):
            if set[i] == "panda":
                pass
            else:
                self.temp.append(OnscreenText(text=set[i], style=1, fg=(1,1,1,1),
                        pos=(1.3, y[i]), align=TextNode.ARight, scale = .07))
            i=i+1  

    # Accepts arrow keys to move either the player or the menu cursor,
    # Also deals with grid checking and collision detection
    def move(self, task):
        
        '''Call to Show player list'''
        x = self.players.keys()
        self.accept("l", self.showPlayers, [x])
        ''' call end '''

        # If the camera-left key is pressed, move camera left.
        # If the camera-right key is pressed, move camera right.

        base.camera.lookAt(self.ralph)
        if (self.keyMap["cam-left"]!=0):
            base.camera.setX(base.camera, -20 * globalClock.getDt())
        if (self.keyMap["cam-right"]!=0):
            base.camera.setX(base.camera, +20 * globalClock.getDt())

        # save ralph's initial position so that we can restore it,
        # in case he falls off the map or runs into something.

        startpos = self.ralph.getPos()

        # If a move-key is pressed, move ralph in the specified direction.

        if (self.keyMap["left"]!=0):
            self.ralph.setH(self.ralph.getH() + 300 * globalClock.getDt())
        if (self.keyMap["right"]!=0):
            self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt())
        if (self.keyMap["forward"]!=0):
            self.ralph.setY(self.ralph, -25 * globalClock.getDt())

        # If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.

        if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0):
            if self.isMoving is False:
                self.ralph.loop("run")
                self.isMoving = True
                self.justStoping = False
        else:
            if self.isMoving:
                self.ralph.stop()
                self.ralph.pose("walk",5)
                self.isMoving = False
                self.justStoping = True
                
        
        #print self.ralph.getX(), self.ralph.getY(), self.ralph.getZ(), self.ralph.getH()
        if(self.isMoving or self.justStoping):       
            self.updateMovement(self.isMoving, self.ralph.getX(), self.ralph.getY(), 
                                self.ralph.getZ(), self.ralph.getH())
            
            #check if in panda attach range
            self.checkPossibleAttack(self.ralph.getX(), self.ralph.getY(), self.ralph.getZ())
            
            player = self.players[self.username]
            player.setX(self.ralph.getX())
            player.setY(self.ralph.getY())
            player.setZ(self.ralph.getZ())
            player.setH(self.ralph.getH())
            self.justStoping = False
        
        # If the camera is too far from ralph, move it closer.
        # If the camera is too close to ralph, move it farther.

        camvec = self.ralph.getPos() - base.camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()
        if (camdist > 10.0):
            base.camera.setPos(base.camera.getPos() + camvec*(camdist-10))
            camdist = 10.0
        if (camdist < 5.0):
            base.camera.setPos(base.camera.getPos() - camvec*(5-camdist))
            camdist = 5.0

        # Now check for collisions.

        self.cTrav.traverse(render)

        # Adjust ralph's Z coordinate.  If ralph's ray hit terrain,
        # update his Z. If it hit anything else, or didn't hit anything, put
        # him back where he was last frame.

        entries = []
        for i in range(self.ralphGroundHandler.getNumEntries()):
            entry = self.ralphGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
        else:
            self.ralph.setPos(startpos)

        # Keep the camera at one foot above the terrain,
        # or two feet above ralph, whichever is greater.
        
        entries = []
        for i in range(self.camGroundHandler.getNumEntries()):
            entry = self.camGroundHandler.getEntry(i)
            entries.append(entry)
        entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
                                     x.getSurfacePoint(render).getZ()))
        if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
            base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0)
        if (base.camera.getZ() < self.ralph.getZ() + 2.0):
            base.camera.setZ(self.ralph.getZ() + 2.0)
            
        # The camera should look in ralph's direction,
        # but it should also try to stay horizontal, so look at
        # a floater which hovers above ralph's head.
        
        self.floater.setPos(self.ralph.getPos())
        self.floater.setZ(self.ralph.getZ() + 2.0)
        base.camera.lookAt(self.floater)

        return task.cont
Exemple #24
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
Exemple #25
0
class ConnectionManager:
    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.rqTable = ServerRequestTable()
        self.rsTable = ServerResponseTable()

        self.connection = None

    def startConnection(self):
        """Create a connection with the remote host.

        If a connection can be created, create a task with a sort value of -39
        to read packets from the socket.

        """
        try:
            if self.connection == None:
                self.connection = self.cManager.openTCPClientConnection(
                    Constants.SERVER_IP, Constants.SERVER_PORT, 1000)

                if self.connection:
                    self.cReader.addConnection(self.connection)

                    taskMgr.add(self.updateRoutine, 'updateRoutine-Connection',
                                -39)
                    taskMgr.doMethodLater(5, self.checkConnection,
                                          'checkConnection')

                    return True
        except:
            pass

        return False

    def closeConnection(self):
        """Close the current connection with the remote host.

        If an existing connection is found, remove both the Main2 task, which
        is responsible for the heartbeat, and the Connection task, which is
        responsible for reading packets from the socket, then properly close
        the existing connection.

        """
        if self.connection != None:
            taskMgr.remove('updateRoutine-Main2')
            taskMgr.remove('updateRoutine-Connection')
            taskMgr.remove('checkConnection')

            self.cManager.closeConnection(self.connection)
            self.connection = None

    def sendRequest(self, requestCode, args={}):
        """Prepare a request packet to be sent.

        If the following request code exists, create an instance of this
        specific request using any extra arguments, then properly send it to
        the remote host.

        """
        if self.connection != None:
            request = self.rqTable.get(requestCode)

            if request != None:
                request.set(self.cWriter, self.connection)
                request.send(args)

    def handleResponse(self, responseCode, data):
        """Prepare a response packet to be processed.

        If the following response code exists, create an instance of this
        specific response using its data to be executed.

        """
        response = self.rsTable.get(responseCode)

        if response != None:
            #response.set(main)
            response.execute(data)

    def checkConnection(self, task):

        if not self.cReader.isConnectionOk(self.connection):
            self.closeConnection()
            self.showDisconnected(0)

            return task.done

        return task.again

    def updateRoutine(self, task):
        """A once-per-frame task used to read packets from the socket."""
        while self.cReader.dataAvailable():
            # Create a datagram to store all necessary data.
            datagram = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram):
                # Prepare the datagram to be iterated.
                data = PyDatagramIterator(datagram)
                # Retrieve a "short" that contains the response code.
                responseCode = data.getUint16()
                # Pass into another method to execute the response.
                if responseCode != Constants.MSG_NONE:
                    self.handleResponse(responseCode, data)

        return task.cont
Exemple #26
0
class Server:

    def __init__(self):

        self.activeConnections = [] # lists all connections
        self.players = {} # keys are the players logins, values are the players datagram connections
        self.parties = {} # keys are the parties names, values are dicts representing parties data
        self.sessions = {} # keys are the datagram connections, values are dicts storing the characters of the player and its party
        self.playersinlobby = [] # lists players in the party screen
        self.charid = 0 # used for random team generation
        self.chars = [] # lists of dicts representing characters data

        self.cManager  = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader   = QueuedConnectionReader(self.cManager, 0)
        self.cReader.setTcpHeaderSize(4)
        self.send = Send(self.cManager)

        port = 3001
        if len(sys.argv) > 1:
            port = sys.argv[1]

        self.tcpSocket = self.cManager.openTCPServerRendezvous(port, 10)
        self.cListener.addConnection(self.tcpSocket)
        print("Server listening on port", port)

        taskMgr.add(self.tskListenerPolling, "Poll the connection listener", -39)
        taskMgr.add(self.tskReaderPolling, "Poll the connection reader", -40)

    def processData(self, datagram):
        iterator = PyDatagramIterator(datagram)
        source = datagram.getConnection()
        callback = iterator.getString()
        getattr(globals()[callback], 'execute')(self, iterator, source)

    def updateAllPartyLists(self):
        parties = deepcopy(self.parties)
        for party in list(parties.values()):
            del party['map']['tiles']

        for player in self.playersinlobby:
            self.send.UPDATE_PARTY_LIST(parties, player)

    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)
                self.cReader.addConnection(newConnection)
                print('A new client is connected', newConnection)
        return Task.cont

    def tskReaderPolling(self, taskdata):
        if self.cReader.dataAvailable():
            datagram=NetDatagram()
            if self.cReader.getData(datagram):
                self.processData(datagram)
        return Task.cont
Exemple #27
0
class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

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

        self.player = Player()
        self.opponents = dict()
        self.logStat = -1

        host = "localhost"
        port = 9252
        self.connection = self.cManager.openTCPClientConnection(
            host, port, 10000)

        self.received = 1

        self.playersText = []

        if self.connection:
            self.cReader.addConnection(self.connection)
            taskMgr.add(self.updateRoutine, 'updateRoutine')
            taskMgr.add(self.login, 'login')
            #taskMgr.doMethodLater(3, self.updateRoutine, 'updateRoutine')
            taskMgr.doMethodLater(.1, self.heartbeat, 'heartbeat')

        self.accept("q", self.listPlayers)
        self.accept("q-up", self.delistPlayers)
        self.accept("escape", self.disconnect)
        self.accept("arrow_up", self.move)

    def login(self, task):
        self.option = 0
        self.option = str(raw_input("1-Login\n2-Register\n"))
        if self.option == "1":
            un = str(raw_input("Username: "******"Password: "******"2":
            un = str(raw_input("Username: "******"Password: "******"data here"
            datagram = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram):
                data = PyDatagramIterator(datagram)
                responseCode = data.getUint16()
                print responseCode
                if responseCode == 201:
                    self.getPlayer(data)
                elif responseCode == 202:
                    self.register(data)
                elif responseCode == 203:
                    self.getOpponent(data)
                elif responseCode == 214:
                    self.movePlayer(data)
                elif responseCode == 219:
                    self.dropPlayer(data)
                else:
                    print "nothing found"

    def heartbeat(self, task):
        pkg = PyDatagram()
        pkg.addUint16(113)
        self.cWriter.send(pkg, self.connection)
        return task.again

    def updateRoutine(self, task):
        self.check()
        return task.again

    def getPlayer(self, data):
        self.logStat = data.getUint16()
        if self.logStat == 0:
            self.player.id = data.getInt32()
            self.player.username = data.getString()
            self.player.x = data.getFloat32()
            self.player.y = data.getFloat32()
            self.player.z = data.getFloat32()
            self.player.rotation = data.getFloat32()
        else:
            print "login failed"
            taskMgr.add(self.login, 'login')

    def register(self, data):
        self.logStat = data.getUint16()
        if self.logStat == 0:
            print "Account Made"
            taskMgr.add(self.login, 'login')
        else:
            print "Username Taken"
            taskMgr.add(self.login, 'login')

    def listPlayers(self):
        i = 0.55
        for p in self.opponents:
            self.playersText.append(
                addInstructions(
                    i, self.opponents[p].username + " " +
                    "{:.2f}".format(self.opponents[p].x) + " " +
                    "{:.2f}".format(self.opponents[p].y) + " " +
                    "{:.2f}".format(self.opponents[p].z) + " " +
                    "{:.2f}".format(self.opponents[p].rotation)))
            i -= 0.05

    def delistPlayers(self):
        for x in self.playersText:
            x.destroy()

    def getOpponent(self, data):
        opponent = Player()
        opponent.id = data.getInt32()
        opponent.username = data.getString()
        opponent.x = data.getFloat32()
        opponent.y = data.getFloat32()
        opponent.z = data.getFloat32()
        opponent.rotation = data.getFloat32()
        self.opponents[opponent.id] = opponent
Exemple #28
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
Exemple #29
0
class MyApp(ShowBase):
    uname = None

    def __init__(self):
        ShowBase.__init__(self)

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

        host = "localhost"
        port = 6002
        self.connection = self.cManager.openTCPClientConnection(
            host, port, 10000)

        self.received = 1

        if self.connection:
            self.cReader.addConnection(self.connection)
            #taskMgr.add(self.updateRoutine, 'updateRoutine')

            # LOGIN Request Starts
            self.uname = raw_input('Enter username :'******'Enter password :'******'Login')
            if (self.received):
                print "->Client request:"
        # Send a request to the server

            myPyDatagram101 = PyDatagram()
            prot = 101
            myPyDatagram101.addUint16(prot)
            myPyDatagram101.addString(self.uname)
            myPyDatagram101.addString(self.password)
            self.cWriter.send(myPyDatagram101, self.connection)
            self.received = 0
            taskMgr.add(self.receiveResponse101, 'Login')

    def sendRequest101(self):
        if (self.received):
            print "->Client request:"
            # Send a request to the server

        myPyDatagram101 = PyDatagram()
        prot = 101
        myPyDatagram101.addUint16(prot)
        myPyDatagram101.addString(self.uname)
        myPyDatagram101.addString(self.password)
        self.cWriter.send(myPyDatagram101, self.connection)
        self.received = 0

    def receiveResponse101(self, task):

        while self.cReader.dataAvailable():
            datagram = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram):
                self.myIterator = PyDatagramIterator(datagram)
                print "<-Server response:"
                print self.myIterator.getUint16()
                self.msg = self.myIterator.getUint32()
                self.l = self.myIterator.getUint32()
                if self.msg is not None:
                    if self.l is not 0:
                        for x in range(0, self.l):
                            print self.myIterator.getString()
                            print self.myIterator.getUint32()
                            print self.myIterator.getUint32()

                    print self.msg, " received"
                    #raw_input("Press Enter to continue...")

                    self.received = 0
                    taskMgr.remove('Login')

                    #1-Character creatopm
                    #taskMgr.add(self.sendRequest104, 'CharacterCreation')

                    #2-heartbeat of playgame after login
                    MyApp.sendRequest113(self)
        return task.again

# LOGIN Request End

        # CHARACTER CREATION Starts

    def sendRequest104(self, task):
        if (self.received):
            print "->Client request:"
            # Send a request to the server

        myPyDatagram = PyDatagram()
        prot = 104
        cname = raw_input('Character Name :')
        faction_id_104 = raw_input('press 0 for Red Or 1 for Blue ? :')
        classType_104 = raw_input('press 0 for Axe Or 1 for Sword ? :')
        myPyDatagram.addUint16(prot)
        myPyDatagram.addString(cname)
        myPyDatagram.addUint32(faction_id_104)
        myPyDatagram.addUint32(classType_104)
        self.cWriter.send(myPyDatagram, self.connection)

        print "104 sent"
        self.received = 0
        taskMgr.add(self.receiveResponse104, "characterresponse")

    def receiveResponse104(self, task):

        while self.cReader.dataAvailable():
            datagram = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram):
                self.myIterator1 = PyDatagramIterator(datagram)
                print '------'
                print self.myIterator1.getUint16()
                self.msg = self.myIterator1.getUint32()
                if self.msg is not None:
                    print "<-Server response:"
                    print self.msg, " received"
                    raw_input("Press Enter to continue...")
                    self.received = 0
                    taskMgr.remove('CharacterCreation')
                    taskMgr.add(self.sendRequest106, 'move')

        return task.again

        #CHARACTER CREATION Ends

    # Move Starts
    def sendRequest106(self, task):
        if (self.received):
            print "->Client request:"
            # Send a request to the server

        myPyDatagram106 = PyDatagram()
        prot = 106
        xpos = raw_input('X Position :')
        ypos = raw_input('Y Position :')
        zpos = raw_input('Z Position :')
        hpos = raw_input('Heading (0 to 360):')
        ismoving = raw_input('Moving ? -- 0 for NO , 1 for YES :')
        myPyDatagram106.addUint16(prot)
        myPyDatagram106.addUint32(xpos)
        myPyDatagram106.addUint32(ypos)
        myPyDatagram106.addUint32(zpos)
        myPyDatagram106.addUint32(hpos)
        myPyDatagram106.addUint32(ismoving)
        self.cWriter.send(myPyDatagram106, self.connection)

        self.received = 0
        taskMgr.add(self.receiveResponse106, "characterresponse")

    def receiveResponse106(self, task):
        while self.cReader.dataAvailable():
            datagram6 = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram6):

                myIterator = PyDatagramIterator(datagram6)
                print myIterator.getUint16()

                msg = myIterator.getString()

                if msg is not None:
                    print "<-Server response:"
                    print msg
                    print myIterator.getUint32()
                    print myIterator.getUint32()
                    print myIterator.getUint32()
                    print myIterator.getUint32()
                    print myIterator.getUint32()
                    raw_input("Press Enter to continue...")
                    self.received = 1
                    # Attack
                    #raw_input("Press Enter to continue...")
                    taskMgr.add(self.sendRequest108, 'health')
        return task.again
        #Move Ends

    #Change Health Starts
    def sendRequest108(self, task):
        if (self.received):
            print "->Client request:"
            # Send a request to the server

        myPyDatagram108 = PyDatagram()
        prot = 108
        change_Health = raw_input('Change in health (-100 to 100):')
        myPyDatagram108.addUint16(prot)
        myPyDatagram108.addUint32(change_Health)
        self.cWriter.send(myPyDatagram108, self.connection)

        self.received = 0
        taskMgr.add(self.receiveResponse108, "healthresponse")

    def receiveResponse108(self, task):

        while self.cReader.dataAvailable():
            datagram8 = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram8):
                myIterator = PyDatagramIterator(datagram8)
                print myIterator.getUint16()
                msg = myIterator.getString()

                if msg is not None:
                    print "<-Server response:"
                    print msg
                    print myIterator.getUint32()
                    self.received = 1
                    # CP State
                    raw_input("Press Enter to continue...")
                    taskMgr.add(self.sendRequest107, 'attack')
        #Change Health Ends
        return task.again

    # Attack Starts
    def sendRequest107(self, task):
        if (self.received):
            print "->Client request:"
            # Send a request to the server

        myPyDatagram107 = PyDatagram()
        prot = 107
        attackId = raw_input('Attack Id (0 or 1):')
        myPyDatagram107.addUint16(prot)
        myPyDatagram107.addUint32(attackId)
        self.cWriter.send(myPyDatagram107, self.connection)

        #print " sent"
        self.received = 0
        taskMgr.add(self.receiveResponse108, "attackresponse")

    def receiveResponse107(self, task):

        while self.cReader.dataAvailable():
            datagram7 = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram7):
                myIterator = PyDatagramIterator(datagram7)
                print myIterator.getUint16()
                msg = myIterator.getString()

                if msg is not None:
                    print "<-Server response:"
                    print msg
                    print myIterator.getUint32()
                    raw_input("Press Enter to continue...")
                    self.received = 1
                    # Change Health
                    taskMgr.add(self.sendRequest112, 'CP Capture')
        return task.again
        #Attack Ends

    #CP Capture Starts
    def sendRequest112(self, task):
        if (self.received):
            print "->Client request:"
            # Send a request to the server

        myPyDatagram112 = PyDatagram()
        prot = 112
        CP_id = raw_input('Control Point ID (1 to 5): ')
        faction_id = raw_input('press 0 for Red Or 1 for Blue ? :')
        myPyDatagram112.addUint16(prot)
        myPyDatagram112.addUint32(CP_id)
        myPyDatagram112.addUint32(faction_id)
        self.cWriter.send(myPyDatagram112, self.connection)

        #print " sent"
        self.received = 0
        taskMgr.add(self.receiveResponse112, "CPCaptureRes")

    def receiveResponse112(self, task):

        while self.cReader.dataAvailable():
            datagram12 = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram12):
                myIterator = PyDatagramIterator(datagram12)
                print myIterator.getUint16()
                msg = myIterator.getUint32()

                if msg is not None:
                    print "<-Server response:"
                    print msg
                    print myIterator.getUint32()
                    raw_input("Press Enter to continue...")
                    self.received = 1
#HeartBeat
                    #raw_input("Press Enter to continue...")
                    #taskMgr.add(self.communicate105, 'chat')

        #CP Capture Ends

    # CHAT Starts
    def communicate105(self, task):
        #print "communicate"
        self.sendRequest105()
        self.receiveResponse105(task)
        return task.again

    def sendRequest105(self):
        if (self.received):
            print "->Client request:"
            # Send a request to the server

        myPyDatagram105 = PyDatagram()
        prot = 105
        chat = raw_input('Insert Chat Message :')
        myPyDatagram105.addUint16(prot)
        myPyDatagram105.addString(chat)
        self.cWriter.send(myPyDatagram105, self.connection)

        print " sent"
        self.received = 0

    def receiveResponse105(self, task):
        print "<-Server response:"
        while self.cReader.dataAvailable():
            datagram5 = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram5):
                myIterator = PyDatagramIterator(datagram5)
                print myIterator.getUint16()
                msg = myIterator.getUint16()
                print msg, " received"
                if msg is not None:
                    raw_input("Press Enter to continue...")
                    self.received = 1
                    # Move
                    raw_input("Press Enter to continue...")
                    taskMgr.add(self.communicate111, 'CP state')

        #CHAT Ends

    #CP State Starts
    def communicate111(self, task):
        #print "communicate"
        self.sendRequest111()
        self.receiveResponse111(task)
        return task.again

    def sendRequest111(self):
        if (self.received):
            print "->Client request:"
            # Send a request to the server

        myPyDatagram111 = PyDatagram()
        prot = 111
        CP_id = raw_input('Control Point ID (1 to 5): ')
        CP_state = raw_input('Control Point state (1 red, 2 blue, 3 purple): ')
        myPyDatagram111.addUint16(prot)
        myPyDatagram111.addUint16(CP_id)
        myPyDatagram111.addUint16(CP_state)
        self.cWriter.send(myPyDatagram111, self.connection)

        print " sent"
        self.received = 0

    def receiveResponse111(self, task):
        print "<-Server response:"
        while self.cReader.dataAvailable():
            datagram11 = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram11):
                myIterator = PyDatagramIterator(datagram11)
                print myIterator.getUint16()
                msg = myIterator.getUint16()
                print msg, " received"
                if msg is not None:
                    raw_input("Press Enter to continue...")
                    self.received = 1
                    # CP Capture
                    raw_input("Press Enter to continue...")
                    taskMgr.add(self.communicate102, 'Logout')
        #CP State Ends

    # LOGOUT Starts
    def communicate102(self, task):
        #print "communicate"
        self.sendRequest102()
        self.receiveResponse102(task)
        return task.again

    def sendRequest102(self):
        if (self.received):
            print "->Client request:"
            # Send a request to the server

        myPyDatagram102 = PyDatagram()
        prot = 102
        myPyDatagram102.addUint16(prot)
        self.cWriter.send(myPyDatagram102, self.connection)

        print " sent"
        self.received = 0

    def receiveResponse102(self, task):
        print "<-Server response:"
        while self.cReader.dataAvailable():
            datagram2 = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram2):
                myIterator = PyDatagramIterator(datagram2)
                print myIterator.getUint16()
                msg = myIterator.getUint16()
                print msg, " received"
                if msg is not None:
                    raw_input("Press Enter to continue...")
                    self.received = 1
                    # Register
                    raw_input("Press Enter to continue...")
                    taskMgr.add(self.communicate301, 'Heartbeat')

        #LOGOUT Ends

        #HeartBeat Starts
    def communicate301(self):
        #print "communicate"
        self.sendRequest301()
        self.receiveResponse301()

#return task.again;

    def sendRequest301(self, task):
        if (self.received):
            print "->Client request:"
            # Send a request to the server

        myPyDatagram301 = PyDatagram()
        prot = 301
        myPyDatagram301.addUint16(prot)
        self.cWriter.send(myPyDatagram301, self.connection)
        self.received = 0
        return task.again

    def receiveResponse301(self):

        while self.cReader.dataAvailable():
            datagram301 = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram301):
                myIterator = PyDatagramIterator(datagram301)
                p = myIterator.getUint16()
                if p == 213:
                    un = myIterator.getString()
                    cname = myIterator.getString()
                    ctype = myIterator.getUint32()
                    cteam = myIterator.getUint32()
                    if un == MyApp.uname:
                        abc = 'abc'
                    else:
                        print cname + ' just joined a game......!! hurray'

                    #print msg, " received"

                    self.received = 1

        #HeartBeat Ends

    #heartbeat
    def sendRequest113(self):
        if (self.received):
            print "->Client request:"
            # Send a request to the server

        myPyDatagram113 = PyDatagram()
        prot = 113
        myPyDatagram113.addUint16(prot)
        print MyApp.uname + '-------'
        if MyApp.uname == 'chintan':
            myPyDatagram113.addUint32(18)
        elif MyApp.uname == 'paras':
            myPyDatagram113.addUint32(35)
        else:
            myPyDatagram113.addUint32(3)
        self.cWriter.send(myPyDatagram113, self.connection)
        self.received = 0
        #taskMgr.add(self.updateRoutine,'update113')
        #taskMgr.doMethodLater(1,self.sendRequest301,'HeatBeat')
        MyApp.retrieve113(self)

    def retrieve113(self):
        taskMgr.add(self.updateRoutine, 'update113')
        taskMgr.doMethodLater(1, self.sendRequest301, 'HeatBeat')

    def updateRoutine(self, task):
        self.receiveResponse301()
        return task.again
Exemple #30
0
class MyApp(ShowBase):
	def __init__(self):
		ShowBase.__init__(self)
		
		self.cManager = QueuedConnectionManager()
		self.cListener = QueuedConnectionListener(self.cManager, 0)
		self.cReader = QueuedConnectionReader(self.cManager, 0)
		self.cWriter = ConnectionWriter(self.cManager, 0)
		
		host = "localhost"
		port = 9252
		self.connection = self.cManager.openTCPClientConnection(host, port, 10000)
		
		self.received = 1
		
		if self.connection:
			self.cReader.addConnection(self.connection)                	
			taskMgr.add(self.updateRoutine, 'updateRoutine')
			
			
		
		print 'Hello You Are Now Connected To The Server'
		#self.heartbeat()
		self.options()

	#options for the clients when game starts	
        def options(self):
                self.option = 0
		self.option = str(raw_input("Please Selection An Option\n1-Enter Chat\n2-Messages\n3-Quit\n"))
                if self.option == "1":
                        self.chat()
                if self.option == "2":
                        self.messages()
                if self.option == "3":
                        sys.exit(0)
                        
       
        #function to chat
        def chat(self):
                self.username = ""
                self.message = ""
                self.username = str(raw_input("Please enter your username: "******"Please enter your message: "))
                
                chat_message = self.username + " " + self.message
                request = self.chatRequest(chat_message)
                self.cWriter.send(request,self.connection)
                

        #package chat request       
        def chatRequest(self, chat_info):
		pkg = PyDatagram()
		pkg.addUint16(112)
		pkg.addString(chat_info)
		return pkg

	#message options for the clients when game starts	
        def messages(self):
                self.option = 0
		self.option = str(raw_input("Please Selection An Option\n1-Send A Message\n2-Check Messages\n3-Return\n"))
                if self.option == "1":
                        self.message()
                if self.option == "2":
                        self.checkMessages()
                if self.option == "3":
                        self.options()

        #function to message
        def checkMessages(self):
                self.username = str(raw_input("Please enter your username: "******""
                self.to_Username = "******"
                self.message = ""
                
                self.from_Username = str(raw_input("Please enter your username: "******"Please enter which username you want to send the message: "))
                self.message = str(raw_input("Please enter your message: "))
                
                chat_message = self.from_Username + " " +self.to_Username+ " " + self.message
                request = self.messageRequest(chat_message)
                self.cWriter.send(request,self.connection)
                

        #package message request       
        def messageRequest(self, chat_info):
		pkg = PyDatagram()
		pkg.addUint16(115)
		pkg.addString(chat_info)
		return pkg

        
        #check for messages for server
	def check(self):
		while self.cReader.dataAvailable():
			
			datagram = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram):
				data = PyDatagramIterator(datagram)
				responseCode = data.getUint16()
				
				if responseCode == 212:
					print self.getString(data)
					self.options()
				elif responseCode == 201: #login code
					if (self.getString(data)=="Unsuccessful login"): #appears if login unsuccessful
                                                print " "
                                                print "Unsuccessful login"
                                                print " "
                                                self.options()
                                        else:
                                                print "Your are logged in" #appear if login successful
                                                self.login_options()#appears the login options
				elif responseCode == 203: #register code
					if (self.getString(data)=="Registration successful"): #appear if registration was successful
                                                print "You are now registered"
                                                print "Please login" #user must login
                                                print " "
                                                self.options() 
                                        else:
                                                print " "#appear if registration wasn't successful
                                                print "Registration was unsuccessful. Pick a different username and please try again "
                                                print " "
                                                self.options()#user must attempt to register again
				elif responseCode == 215:
					print self.getString(data)
					self.messages()
				elif responseCode == 216:
					print self.getString(data)
					self.messages()
				else:
					print "nothing found"
					
	#function that unpackage the message from server
        def getString(self, data):
		msg = data.getString()
		return msg

        #heart beat function
	def heartbeat(self):
                request = self.heartbeatRequest()
                self.cWriter.send(request,self.connection)
                

        #heart beat packaged
        def heartbeatRequest(self):
		pkg = PyDatagram()
		pkg.addUint16(123)
		return pkg
	
        #updateRoutine for the program
	def updateRoutine(self,task):
                self.heartbeat()
		self.check()
		return task.again;
class client:

    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.connection = None
        

    def startConnection(self):
        """Create a connection with the remote host.

        If a connection can be created, create a task with a sort value of -39
        to read packets from the socket.

        """
        
        try:

            if self.connection == None:
                self.connection = self.cManager.openTCPClientConnection('localhost',
                                                                        9090,
                                                                        1000)


                if self.connection:
                    self.cReader.addConnection(self.connection)

                    taskMgr.add(self.updateRoutine, 'updateRoutine-Connection', -39)
                    taskMgr.doMethodLater(5, self.checkConnection, 'checkConnection')

                    return True



        except:
            pass

    	self.loginHandler()
        
        #send packet
        

        myPyDatagram = PyDatagram()
        myPyDatagram.addUint8(1)
        myPyDatagram.addString(self.username)
        myPyDatagram.addString('_')
        myPyDatagram.addString(self.password)
        self.cWriter.send(myPyDatagram,self.connection)
        
        #receive packet
        datagram = NetDatagram()
        if self.cReader.getData(datagram):
        	myProcessDataFunction(datagram)
        return False

    def loginHandler(self):
    	self.username = raw_input("Enter username: "******"Enter password: "******"short" that contains the response code.
                responseCode = data.getUint16()
                # Pass into another method to execute the response.
                if responseCode != 0:
                    self.handleResponse(responseCode, data)

        return task.cont
Exemple #32
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)
class ConnectionManager:

    def __init__(self, main):
        #self.world = world
        self.cManager = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager, 0)
        self.main = main
        
        self.rqTable = ServerRequestTable()
        self.rsTable = ServerResponseTable()

        self.connection = None

    def startConnection(self):
        """Create a connection with the remote host.

        If a connection can be created, create a task with a sort value of -39
        to read packets from the socket.

        """
        try:
            if self.connection == None:
                self.connection = self.cManager.openTCPClientConnection(Constants.SERVER_IP,
                                                                        Constants.SERVER_PORT,
                                                                        1000)

                if self.connection:
                    self.cReader.addConnection(self.connection)

                    taskMgr.add(self.updateRoutine, 'updateRoutine-Connection', -39)
                    taskMgr.doMethodLater(5, self.checkConnection, 'checkConnection')

                    return True
        except:
            pass

        return False

    def closeConnection(self):
        """Close the current connection with the remote host.

        If an existing connection is found, remove both the Main task, which
        is responsible for the heartbeat, and the Connection task, which is
        responsible for reading packets from the socket, then properly close
        the existing connection.

        """
        if self.connection != None:
            taskMgr.remove('updateRoutine-Main')
            taskMgr.remove('updateRoutine-Connection')
            taskMgr.remove('checkConnection')

            self.cManager.closeConnection(self.connection)
            self.connection = None

    def sendRequest(self, requestCode, args = {}):
        """Prepare a request packet to be sent.

        If the following request code exists, create an instance of this
        specific request using any extra arguments, then properly send it to
        the remote host.

        """
        if self.connection != None:
            request = self.rqTable.get(requestCode)

            if request != None:
                request.set(self.cWriter, self.connection)
                #print('requestCode:'+str(requestCode))
                #print('args:'+str(args))
                request.send(args)

    def handleResponse(self, responseCode, data):
        """Prepare a response packet to be processed.

        If the following response code exists, create an instance of this
        specific response using its data to be executed.

        """
        response = self.rsTable.get(responseCode)

        if response != None:
            response.set(self.main)
            response.execute(data)

    def checkConnection(self, task):

        if not self.cReader.isConnectionOk(self.connection):
            self.closeConnection()
            #self.showDisconnected(0)

            return task.done

        return task.again

    def updateRoutine(self, task):
        """A once-per-frame task used to read packets from the socket."""
        while self.cReader.dataAvailable():
            # Create a datagram to store all necessary data.
            datagram = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram):
                # Prepare the datagram to be iterated.
                data = PyDatagramIterator(datagram)
                # Retrieve a "short" that contains the response code.
                responseCode = data.getUint16()
                # Pass into another method to execute the response.
                if responseCode != Constants.MSG_NONE:
                    self.handleResponse(responseCode, data)

        return task.cont
Exemple #34
0
class MyApp(ShowBase):
	def __init__(self):
		ShowBase.__init__(self)
		
		self.cManager = QueuedConnectionManager()
		self.cListener = QueuedConnectionListener(self.cManager, 0)
		self.cReader = QueuedConnectionReader(self.cManager, 0)
		self.cWriter = ConnectionWriter(self.cManager, 0)
		
		self.player = Player()
		self.opponents = dict()
		self.logStat = -1
		
		host = "localhost"
		port = 9252
		self.connection = self.cManager.openTCPClientConnection(host, port, 10000)
		
		self.received = 1
		
		self.playersText = []
		
		if self.connection:
			self.cReader.addConnection(self.connection)                	
			taskMgr.add(self.updateRoutine, 'updateRoutine')
			taskMgr.add(self.login, 'login')
			#taskMgr.doMethodLater(3, self.updateRoutine, 'updateRoutine')
			taskMgr.doMethodLater(.1, self.heartbeat, 'heartbeat')
		
		self.accept("q", self.listPlayers)
		self.accept("q-up", self.delistPlayers)
		self.accept("escape", self.disconnect)
		self.accept("arrow_up", self.move)
		
	def login(self, task):
		self.option = 0
		self.option = str(raw_input("1-Login\n2-Register\n"))
		if self.option == "1":
			un = str(raw_input("Username: "******"Password: "******"2":
			un = str(raw_input("Username: "******"Password: "******"data here"
			datagram = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram):
				data = PyDatagramIterator(datagram)
				responseCode = data.getUint16()
				print responseCode
				if responseCode == 201:
					self.getPlayer(data)
				elif responseCode == 202:
					self.register(data)
				elif responseCode == 203:
					self.getOpponent(data)
				elif responseCode == 214:
					self.movePlayer(data)
				elif responseCode == 219:
					self.dropPlayer(data)
				else:
					print "nothing found"
    
	def heartbeat(self, task):
		pkg = PyDatagram()
		pkg.addUint16(113)
		self.cWriter.send(pkg,self.connection)
		return task.again
	
	def updateRoutine(self,task):
		self.check()
		return task.again;
	
	def getPlayer(self, data):
		self.logStat = data.getUint16()
		if self.logStat == 0:
			self.player.id = data.getInt32()
			self.player.username = data.getString()
			self.player.x = data.getFloat32()
			self.player.y = data.getFloat32()
			self.player.z = data.getFloat32()
			self.player.rotation = data.getFloat32()
		else:
			print "login failed"
			taskMgr.add(self.login, 'login')
	
	def register(self, data):
		self.logStat = data.getUint16()
		if self.logStat == 0:
			print "Account Made"
			taskMgr.add(self.login, 'login')
		else:
			print "Username Taken"
			taskMgr.add(self.login, 'login')
	
	def listPlayers(self):
		i = 0.55
		for p in self.opponents:
			self.playersText.append( addInstructions(i, self.opponents[p].username + " " + "{:.2f}".format(self.opponents[p].x) + " " + "{:.2f}".format(self.opponents[p].y) + " " + "{:.2f}".format(self.opponents[p].z) + " " + "{:.2f}".format(self.opponents[p].rotation) ))
			i -= 0.05
	
	def delistPlayers(self):
		for x in self.playersText:
			x.destroy()
	
	def getOpponent(self, data):
		opponent = Player()
		opponent.id = data.getInt32()
		opponent.username = data.getString()
		opponent.x = data.getFloat32()
		opponent.y = data.getFloat32()
		opponent.z = data.getFloat32()
		opponent.rotation = data.getFloat32()
		self.opponents[opponent.id] = opponent
class NetworkHost ():
    """
        Handles networking with one or more clients. This class is essentially
         a server that handles the communication of GameManager's game logic.
        One player will have a NetworkHost and the rest of players will have
         NetworkClients.
    """
    def __init__ (self, gameManager):
        self._connManager = QueuedConnectionManager()
        self._loadConfig()
        self._activeConns = [] # Active connections list.
        self._isActive = False
        self._backlog = HOST_MAX_BACKLOG
        self._gameManager = gameManager
        self._playerInfo = dict() # connections by connectionID (cID)
        self._creatures = dict() # Creatures by cID.
        self._localPlayerCID = None
        self._creatureIDCount = 0

    def _initListener (self):
        """
            Initializes this NetworkHost's connection listener.
        """
        self._connListener = QueuedConnectionListener(self._connManager, 0)
        self._tcpSocket = connManager.openTCPServerRendezvous(self._portAddress,
                                                              self._backlog)
        self._connListener.addConnection(self._tcpSocket)

    def _loadConfig (self):
        """
            Loads network configuration defaults.
        """
        self._portAddress = ConfigVariableInt("default-port",
                                              DEFAULT_PORT).getValue()

    def startHost (self):
        """
            Finishes initialization and begins listening.
        """
        # Initialize Reader and Writer:
        self._connReader = QueuedConnectionReader(self._connManager, 0)
        self._connWriter = ConnectionWriter(self._connManager, 0)
        # Initialize Listener:
        self._connListener = QueuedConnectionListener(self._connManager, 0)
        self._tcpSocket = self._connManager.openTCPServerRendezvous(
                                            self._portAddress, self._backlog)
        self._connListener.addConnection(self._tcpSocket)
        # Begin handling messages (start listening):
        taskMgr.add(self._onListenerPoll,"Poll the connection listener",-39)
        taskMgr.add(self._onReaderPoll,"Poll the connection reader",-40)
        self._isActive = True
        print ("[Host Started at %s]" % socket.gethostbyname(
                                            socket.gethostname()))

        self._gameManager.onHostInitialized()

    def _onListenerPoll(self, taskdata):
        """
            Updates list of connections based on the listener's current
             findings.
            Does not read messages. See onReaderPoll().
            (Assumes self._connListener has been initialized)
        """
        # Check for new connections:
        if self._connListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            newConnection = PointerToConnection()
            # If we have a new connection, add it to our list:
            if self._connListener.getNewConnection(rendezvous,netAddress,
                                                   newConnection):
                newConnection = newConnection.p()
                print ("[Host Received New Connection: %s]" % netAddress)
                self._activeConns.append(newConnection)
                # Begin reading messages from this new connection:
                self._connReader.addConnection(newConnection)
                # activate the onClientConnected functionalities:
                self.onClientConnected(newConnection)
        return Task.cont # Repeat this call on an interval

    def _onReaderPoll (self, taskdata):
        """
            Called on an interval to interpret messages from the reader.
        """
        if self._connReader.dataAvailable():
            newDatagram = NetDatagram()
            # Double check to make sure (Multithreading safety):
            if self._connReader.getData(newDatagram):
                self._interpretDatagram(newDatagram)
        return Task.cont # Repeat this call on an interval

    def sendToClient (self, newMsg, conn, msgType):
        """
            Sends a new message to a client at the other end of conn.
        """
        print("[Server Sending %s message type %s]"%(str(conn), str(msgType)))
        self._connWriter.send(newMsg, conn)

    def sendToAll (self, newMsg, msgType):
        """
            Writes and sends a new message to all connected clients.
        """
        for conn in self._activeConns:
            self.sendToClient(newMsg, conn, msgType)

    def _interpretDatagram (self, datagram):
        """
            Interprets a received datagram and performs actions based on its
             values.
        """
        msg = PyDatagramIterator(datagram)
        msgType = msg.getUint8()
        if msgType == DEBUG_MESSAGE:
            print (msg.getString())
        elif msgType == UPDATE_PLAYER_INFO:
            data = msg.getString()
            self._updatePlayerInfoHandler(datagram.getConnection().this, data)
        elif msgType == SPAWN_CHARACTER:
            data = msg.getString()
            dataDict = json.loads(data)
            self._onSpawnHandler(dataDict)
        elif msgType == SYNC_ACTION:
            data = msg.getString()
            dataDict = json.loads(data)
            self._onActionSyncHandler(dataDict, datagram.getConnection())
        elif msgType == SYNC_RESPAWN:
            data = msg.getString()
            dataDict = json.loads(data)
            self._onRespawnRequestReceived(dataDict)
        elif msgType == WIN_STATE:
            data = msg.getString()
            self._onGameWon(data)

    def isHosting (self):
        """
            Returns whether this NetworkHost is actively hosting.
        """
        return self._isActive

    def getMyCID (self):
        return self._localPlayerCID

    def registerNewCID (self):
        newCID = "host" + str(self._creatureIDCount)
        self._creatureIDCount += 1
        return newCID

    def registerLocalCID (self):
        newCID = self.registerNewCID()
        self._localPlayerCID = newCID

    # === [Local Client to Network] ===
    def onCreatureDeath (self, creature):
        """
            Sends a creature death message to all connected clients.
        """
        msg = createSyncDeathMessage(creature.getCID())
        self.sendToAll(msg, SYNC_DEATH)

    def onLocalPlayerRespawn (self, creature, newLocation):
        """
            Respawns the local player and sends a sync message to all remotes.
        """
        # Fulfill local player request to respawn:
        creature.respawn(newLocation)
        # Refill the creature's HP (Automatically syncs!):
        creature.takeDamage(-1*creature.getMaxHealth())
        # Spawn on all connected clients:
        msg = createRespawnMessage(creature.getCID(), newLocation)
        self.sendToAll(msg, SYNC_RESPAWN)

    def localPlayerWins (self):
        """
            End the game display the
             win screen.
        """
        self._gameManager.onWinStateAchieved(self._playerInfo[self.getMyCID()])
        msg = createWinMessage(self._playerInfo[self.getMyCID()])
        self.sendToAll(msg, WIN_STATE)

    def updateLocalPlayerInfo (self, info=None):
        """
            Updates info for this local player and sends it to all
             connected clients.
        """
        if not info:
            self._playerInfo[self.getMyCID()] = PlayerInfo(cID=self.getMyCID())
        else: # If info == None, we are just initializing.
            self._playerInfo[self.getMyCID()] = info
            infoMsg = createPlayerInfoMessage(info)
            self.sendToAll(infoMsg, UPDATE_PLAYER_INFO)
    # === ===

    # === [Gameplay specific] ===
    def _onGameWon (self, data):
        """
            Boo. A remote client won.
            Oh well. Still have to sync that win across all other clients.
        """
        # Show winner locally:
        winnerData = PlayerInfo(fromJson=data)
        self._gameManager.onWinStateAchieved(winnerData)
        msg = createWinMessage(winnerData)
        self.sendToAll(msg, WIN_STATE)

    def syncAction (self, cID, actionID, **kwargs):
        """
            The local player has performed an action that must be synced across
             the network. Send a message to all clients telling them to perform
             a related action on that character.
        """
        msg = createSyncActionMessage(cID, actionID, **kwargs)
        self.sendToAll(msg, SYNC_ACTION)

    def spawnGameObject (self, gameObject):
        """
            Tracks the given gameObject and sends it to all clients.
        """
        # First, track it locally:
        self._creatures[gameObject.getCID()] = gameObject
        # Send to all clients:
        msg = createSpawnCharacterMessage(gameObject, gameObject.getCID())
        self.sendToAll(msg, SPAWN_CHARACTER)

    def dropItem (self, itemEnum, pos):
        """
            Spawn a new item locally and sync!
        """
        itemID = self.registerNewCID()
        # Create item locally:
        newItem = ITEM_ID_DICT[itemEnum](self._gameManager, itemID, coords=pos)
        self._gameManager.getTileMap().spawnItem(newItem, pos)
        # Track new item:
        self._creatures[itemID] = newItem
        msg = createSpawnItemMessage(newItem)
        self.sendToAll(msg, SPAWN_ITEM)

    def _onSpawnHandler (self, dataDict):
        """ Handles networking spawning characters """
        # Spawn object locally if the object at cID doesn't already exist.
        if not dataDict['objID'] in self._creatures.keys():
            # Spawn object of charType at pos
            objectType = getCharacterTypeAsClass(dataDict['charType'])
            newPos = Point2D(dataDict['pos'][0], dataDict['pos'][1])
            newChar = objectType(parentCtrlr=None, cID=dataDict['objID'],
                                 gameManager=self._gameManager, coords=newPos)
            self._creatures[dataDict['objID']] = newChar
            self._gameManager.getTileMap().spawnObject(newChar, newPos)
            print("[Server Spawned %s]" % dataDict['objID'])
            # If we have a player info for this player, use their name for the
            #  displayName:
            if dataDict['objID'] in self._playerInfo:
                newName = self._playerInfo[dataDict['objID']].cName
                newChar.setNameDisplay(newName)
        else:
            # Ignore Overwrite
            pass
        # Tell all other clients to spawn objects:
        newMsg = createSpawnCharacterMessage(self._creatures[dataDict['objID']],
                                             dataDict['objID'])
        self.sendToAll(newMsg, SPAWN_CHARACTER)

    def _onActionSyncHandler (self, dataDict, msgConn):
        """
            Attempts to queue an action for execution on a target denoted by
             dataDict['objID']
        """
        copyMsg = createSyncActionMessage(**dataDict)

        syncedAction = ACTION_NETWORKING_DICT[dataDict['actionID']]
        # Add a few local variables to dataDict:
        targetObj = self._creatures[dataDict['objID']] # TODO Maybe make this part of dataDict!
        dataDict['tileMap'] = self._gameManager.getTileMap()
        if 'targetCID' in dataDict: # If there is another target:
            # Assign the target:
            dataDict['target'] = self._creatures[dataDict['targetCID']]
        dataDict['isServer'] = True # Let sync function know we are server

        # Create the newAction
        newAction = syncedAction(targetObj, **dataDict)
        targetObj.startAction(newAction) # queue or start the new action
        # Send action to all clients except the client that sent the sync msg:
        for client in self.getAllClientsExcept(msgConn):
            self.sendToClient(copyMsg, client, SYNC_ACTION)

    def _onRespawnRequestReceived (self, dataDict):
        """
            Respawns the remote clients character in a new position and then
             syncs to all clients (including the one who requested).
        """
        newPos = self._gameManager.getTileMap().getRandomEmptyFloor()
        targetObj = self._creatures[dataDict['objID']]
        # Set the target's HP to full and sync that:
        targetObj.takeDamage(-1*targetObj.getMaxHealth())
        targetObj.respawn(newPos)
        # Sync the respawn to all clients:
        newMsg = createRespawnMessage(targetObj.getCID(), newPos)
        self.sendToAll(newMsg, SYNC_RESPAWN)

    def getAllClientsExcept (self, exceptConn):
        clientList = list()
        for conn in self._activeConns:
            if conn != exceptConn:
                clientList.append(conn)
        return clientList

    def onClientConnected (self, clientConn):
        """
            If we have a map and/or any positional data, give it to this client.
            Also signal to the GameManager and all remote clients that a new
             player connected!
        """
        connID = clientConn.this
        tileMap = self._gameManager.getTileMap()
        if tileMap != None:
            data = tileMap.getTileMapStr()
            msg = createMapMessage(data)
            self.sendToClient(msg, clientConn, MAP_MESSAGE)
        # Send player info to the new client:
        for player in self._playerInfo:
            # Don't send an info message about the player to the same player!
            if player != connID:
                newInfoMsg = createPlayerInfoMessage(self._playerInfo[player])
                self.sendToClient(newInfoMsg, clientConn,
                                  UPDATE_PLAYER_INFO)
        # Send all creatures to the new client:
        for creatureID in self._creatures:
            newMsg = createSpawnCharacterMessage(self._creatures[creatureID],
                                                 creatureID)
            self.sendToClient(newMsg, clientConn, SPAWN_CHARACTER)

    def _updatePlayerInfoHandler (self, connID, data=None):
        """
            Adds data to self._playerInfo.
            If info doesn't exist, creates a new one for clientConn.
        """
        if data != None:
            newPlayerData = PlayerInfo(fromJson=data)
        else:
            newPlayerData = PlayerInfo(cID=connID)
        # Update the playerInfo dict with the new data:
        self._playerInfo[newPlayerData.cID] = newPlayerData
        self._gameManager.updatePartyInfo(self._playerInfo, self.getMyCID())
        # Send player info to every client:
        for player in self._playerInfo:
            newInfoMsg = createPlayerInfoMessage(self._playerInfo[player])
            #Send every player to every client:
            self.sendToAll(newInfoMsg, UPDATE_PLAYER_INFO)
        # Update the creature's floating display name locally:
        if newPlayerData.cID in self._creatures:
            self._creatures[newPlayerData.cID]\
                .setNameDisplay(newPlayerData.cName)

    def syncHealthChange (self, creatureID, newHealth):
        """
            Called after the host runs a damage/healing action on a creature.
            Lets all clients know to update to a new value.
        """
        data = createSyncHealthMessage(creatureID, newHealth)
        self.sendToAll(data, SYNC_HEALTH)
Exemple #36
0
class login(DirectObject):
    TEXT_COLOR = (1,1,1,1)
    FONT_TYPE_01 = 0
    TEXT_SHADOW_COLOR = (0,0,0,0.5)
    usernameInput = ""
    passwordInput = ""
    frame = DirectFrame()
    username = OnscreenText()
    password = OnscreenText()
    cpassword = OnscreenText()
    failed = OnscreenText()
    userTextbox = DirectEntry()
    passTextbox = DirectEntry()
    submitBtn = DirectButton()
    registerBtn = DirectButton()
    cancelBtn = DirectButton()
    
    
    registerUsername = ""
    registerPassword = ""
    registerCPassword = ""
    
    regInputUser = DirectEntry()
    regInputPass = DirectEntry()
    regInputCPass = DirectEntry()
    
    regRegisterBtn = DirectButton()
    regCancelBtn = DirectButton()

    #character selection varaiables
    createCharacter = DirectButton()
    deleteCharacter = DirectButton()
    selectCharacter = OnscreenText()
    selectCharacterTextbox = DirectEntry()
    selectCharacterInput=''
    referenceForSelection = OnscreenText()
    myScrolledList = DirectScrolledList()
    submitBtn = DirectButton()
    cancelBtn = DirectButton()
    
    #character deletion varaiables
    selectCharactertodelete = OnscreenText()
    deleteBtn = DirectButton()
    delCancelBtn = DirectButton()
    CharacterToDeleteTextbox = DirectEntry()
    referenceForDeletion = OnscreenText()
    CharacterToDeleteInput = ' '
    
    #character creation varaiables
    v=[0]
    v1=[0]
    nameOfChar = OnscreenText()
    nameOfCharTextbox = DirectEntry()
    factionSelection = OnscreenText()
    nameOfCharInput =''
    
    def __init__(self):
        print 'Loading Login...'
      #  self.cManager = ConnectionManager()
      #  self.startConnection()
      
        self.cManager = QueuedConnectionManager()
	self.cListener = QueuedConnectionListener(self.cManager, 0)
	self.cReader = QueuedConnectionReader(self.cManager, 0)
	self.cWriter = ConnectionWriter(self.cManager, 0)


	
        frame = DirectFrame(frameColor=(0, 0, 0, 1), #(R,G,B,A)
                            frameSize=(-1, 1, -1, 1),#(Left,Right,Bottom,Top)
                            pos=(-0.5, 0, 0.5))

        
        
        self.connection = self.cManager.openTCPClientConnection(Constants.SERVER_IP,
                                                                        Constants.SERVER_PORT,
                                                                        1000)

        if self.connection:
                self.cReader.addConnection(self.connection)

                taskMgr.add(self.updateRoutine, 'updateRoutine-Connection', -39)
                taskMgr.doMethodLater(5, self.checkConnection, 'checkConnection')

			
        self.createLoginWindow()

    def startConnection(self):
        """Create a connection to the remote host.

        If a connection cannot be created, it will ask the user to perform
        additional retries.

        """
        if self.cManager.connection == None:
            if not self.cManager.startConnection():
                return False

        return True

    def func1(self):
        self.clickedSubmit()
        self.createSelectionWindow()

    def clearPassText(self):
        self.passTextbox.enterText('')
    def clearUserText(self):
        self.userTextbox.enterText('')
    def getUserText(self):
        self.usernameInput = self.userTextbox.get()
    def getPassText(self):
        self.passwordInput = self.passTextbox.get()
    def setUserText(self, textEntered):
        print "username: "******"password: "******"" and self.passwordInput is not ""):
            print "You pressed Submit", self.usernameInput, " ; ",self.passwordInput
           # self.cManager.sendRequest(Constants.CMSG_AUTH, self.usernameInput+" "+self.passwordInput);

            login_info = self.usernameInput + " " + self.passwordInput
            request = self.loginRequest(login_info)
            self.cWriter.send(request,self.connection)
            self.createSelectionWindow()

        else:
            print "Please enter in a username and password"
    def clickedCancel(self):
        print "You pressed Cancel"
        exit()
    def clickedRegister(self):
        print "You pressed Register"
        self.createRegisterWindow()
    def clickedRegRegister(self):
        self.registerUsername = self.regInputUser.get()
        self.registerPassword = self.regInputPass.get()
        self.registerCPassword = self.regInputCPass.get()
        if self.registerPassword == self.registerCPassword:
            print "Success (",self.registerUsername, ", ",self.registerPassword,", ",self.registerCPassword,")"
            
            #self.cManager.sendRequest(Constants.CMSG_REGISTER, self.registerUsername+" "+self.registerPassword)
            register_info = self.registerUsername + " " + self.registerPassword
            request = self.registerRequest(register_info)
            self.cWriter.send(request,self.connection)
            self.createLoginWindow()
        else:
            self.failed = OnscreenText(text="Your password does not match Confirm Password.", pos=(-0.5, 0, 1), scale=0.06,fg=(1,0.5,0.5,1), align=TextNode.ACenter,mayChange=0)
            self.failed.reparentTo(self.frame)
            print "Failed (",self.registerUsername, ", ",self.registerPassword,", ",self.registerCPassword,")"
    def clickedRegCancel(self):
        self.destroyRegisterWindow()
        self.createLoginWindow()
    def destroyLoginWindow(self):
        self.frame.destroy()
        self.username.destroy()
        self.password.destroy()
        self.userTextbox.destroy()
        self.passTextbox.destroy()
        self.submitBtn.destroy()
        self.registerBtn.destroy()
        self.cancelBtn.destroy()
    def destroyRegisterWindow(self):
        self.frame.destroy()
        self.username.destroy()
        self.password.destroy()
        self.cpassword.destroy()
        self.regInputUser.destroy()
        self.regInputPass.destroy()
        self.regInputCPass.destroy()
        self.cancelBtn.destroy()
        self.registerBtn.destroy()
        self.failed.destroy();
    def createLoginWindow(self):
        self.frame = DirectFrame(frameColor=(0, 0, 0, 1), #(R,G,B,A)
                                frameSize=(-1, 1, -1, 1),#(Left,Right,Bottom,Top)
                                pos=(-0.5, 0, 0.5))
                
        self.username = OnscreenText(text = "username:"******"password: "******"" ,scale=.05,pos=(.1,0,0), command=self.setUserText,initialText="username", numLines = 1,focus=1,focusInCommand=self.clearUserText, focusOutCommand=self.getUserText)
        self.passTextbox = DirectEntry(text = "" ,scale=.05,pos=(.1,0, -.2),command=self.setPassText,initialText="password", numLines = 1,focus=0,focusInCommand=self.clearPassText, focusOutCommand=self.getPassText)
        self.userTextbox.reparentTo(self.frame)
        self.passTextbox.reparentTo(self.frame)
        self.submitBtn = DirectButton(text = ("Submit", "Login", "Submit", "disabled"), scale=.08, command=self.func1, pos=(0.8, 0.0, -0.90))
        self.registerBtn =  DirectButton(text = ("Register", "Register", "Register", "disabled"), scale=.075, command=self.clickedRegister, pos=(0.5, 0.0, -0.90))
        self.cancelBtn =  DirectButton(text = ("Cancel", "Cancel", "Cancel", "disabled"), scale=.08, command=self.clickedCancel, pos=(0.2, 0.0, -0.90))
        self.submitBtn.reparentTo(self.frame)
        self.cancelBtn.reparentTo(self.frame)
        self.registerBtn.reparentTo(self.frame)
    def createRegisterWindow(self):
        self.frame = DirectFrame(frameColor=(0, 0, 0, 1), #(R,G,B,A)
                                frameSize=(-1, 1, -1, 1),#(Left,Right,Bottom,Top)
                                pos=(-0.5, 0, 0.5))
        self.username = OnscreenText(text = "Username:"******"Password: "******"Confirm Password: "******"" ,scale=.05,pos=(.1,0,0), command=self.setUserText,initialText="username", numLines = 1,focus=1,focusInCommand=self.clearUserText, focusOutCommand=self.getUserText)
        self.regInputPass = DirectEntry(text = "" ,scale=.05,pos=(.1,0, -.2),command=self.setPassText,initialText="password", numLines = 1,focus=0,focusInCommand=self.clearPassText, focusOutCommand=self.getPassText)
        self.regInputCPass = DirectEntry(text = "" ,scale=.05,pos=(.1,0, -.4),command=self.setPassText,initialText="confirm password", numLines = 1,focus=0,focusInCommand=self.clearPassText, focusOutCommand=self.getPassText)
        self.regInputUser.reparentTo(self.frame)
        self.regInputPass.reparentTo(self.frame)
        self.regInputCPass.reparentTo(self.frame)
        self.registerBtn =  DirectButton(text = ("Register", "Register", "Register", "disabled"), scale=.075, command=self.clickedRegRegister, pos=(0.8, 0.0, -0.90))
        self.cancelBtn =  DirectButton(text = ("Cancel", "Cancel", "Cancel", "disabled"), scale=.08, command=self.clickedRegCancel, pos=(0.2, 0.0, -0.90))
        self.cancelBtn.reparentTo(self.frame)
        self.registerBtn.reparentTo(self.frame)

    def check(self):
		while self.cReader.dataAvailable():
			
			datagram = NetDatagram()
			# Retrieve the contents of the datagram.
			if self.cReader.getData(datagram):
                            
				data = PyDatagramIterator(datagram)
				responseCode = data.getUint16()
				
				if responseCode == 1:
					self.getInt(data)
				elif responseCode == 201: #login code
					if (self.getString(data)=="Unsuccessful login"): #appears if login unsuccessful
                                                print " "
                                                print "Unsuccessful login"
                                                print " "
                                                self.createLoginWindow()
                                        else:
                                                print "Your are logged in" #appear if login successful
                                                self.createLoginWindow()#appears the login options
                                                self.showRalph()      
				elif responseCode == 203: #register code
					if (self.getString(data)=="Registration successful"): #appear if registration was successful
                                                print "You are now registered"
                                                print "Please login" #user must login
                                                print " "
                                                self.createLoginWindow() 
                                        else:
                                                print " "#appear if registration wasn't successful
                                                print "Registration was unsuccessful. Pick a different username and please try again "
                                                print " "
                                                self.createLoginWindow()#user must attempt to register again
				elif responseCode == 4:
					self.getFloat(data)
				else:
					print "nothing found"

    def updateRoutine(self,task):
		self.check()
		return task.again;

    def checkConnection(self, task):

        if not self.cReader.isConnectionOk(self.connection):
            self.closeConnection()
            self.showDisconnected(0)

            return task.done

        return task.again

    def closeConnection(self):
        """Close the current connection with the remote host.

        If an existing connection is found, remove both the Main task, which
        is responsible for the heartbeat, and the Connection task, which is
        responsible for reading packets from the socket, then properly close
        the existing connection.

        """
        if self.connection != None:
            taskMgr.remove('updateRoutine-Main')
            taskMgr.remove('updateRoutine-Connection')
            taskMgr.remove('checkConnection')

            self.cManager.closeConnection(self.connection)
            self.connection = None

    #function that unpackage the message from server
    def getString(self, data):
	msg = data.getString()
	return msg

    #package login request       
    def loginRequest(self, login_info):
		pkg = PyDatagram()
		pkg.addUint16(101)
		pkg.addString(login_info)
		return pkg
        #package register request
    def registerRequest(self, register_info):
		pkg = PyDatagram()
		pkg.addUint16(103)
		pkg.addString(register_info)
		return 

    def showRalph(self):
        self.environ = loader.loadModel("models/square")
        self.environ.reparentTo(render)
        self.environ.setPos(0,0,0)
        self.environ.setScale(100,100,1)
        self.moon_tex = loader.loadTexture("models/moon_1k_tex.jpg")
        self.environ.setTexture(self.moon_tex, 1)

        # Create the main character, Ralph

        self.ralph = Actor("models/ralph",
                                 {"run":"models/ralph-run",
                                  "walk":"models/ralph-walk"})
        self.ralph.reparentTo(render)
        self.ralph.setScale(.2)
        self.ralph.setPos(0,0,0)

    #character Creation        
    def createCreateCharWindow(self):
        self.frame = DirectFrame(frameColor=(0, 0, 0, 1), #(R,G,B,A)
                                frameSize=(-3, 3, -3, 3),#(Left,Right,Bottom,Top)
                                pos=(-0.5, 0, 0.9))
        self.buttons = [
        DirectRadioButton(text = ' Sword ', variable=self.v, value=[0], scale=0.07, pos=(-0.4,0,0.32), command=self.setText),
        DirectRadioButton(text = ' Axe ', variable=self.v, value=[1], scale=0.07, pos=(0.2,0,0.32), command=self.setText)
        ]
 
        for button in self.buttons:
            button.setOthers(self.buttons)
        
        self.nameOfChar = OnscreenText(text = "Name The Character :", pos = (-0.2, -0.75), scale = 0.08,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=0)
        self.nameOfChar.reparentTo(self.frame)    
        self.nameOfCharTextbox = DirectEntry(text = "" ,scale=.07,pos=(0.25,0, -.75),command=self.setnameOfChar,initialText="name of character", numLines = 1,focus=0,focusInCommand=self.clearnameOfChar, focusOutCommand=self.getnameOfChar)
        self.nameOfCharTextbox.reparentTo(self.frame)   
        
        self.factionSelection = OnscreenText(text = "Faction Selection :", pos = (-0.15, -0.95), scale = 0.08,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=0)
        self.factionSelection.reparentTo(self.frame)
        
        self.factionBtns = [
        DirectRadioButton(text = ' Blue ', variable=self.v1, value=[0], scale=0.07, pos=(-0.05,0,-0.05), command=self.setfaction),
        DirectRadioButton(text = ' Red ', variable=self.v1, value=[1], scale=0.07, pos=(0.3,0,-0.05), command=self.setfaction)
        ]
         
        for button1 in self.factionBtns:
            button1.setOthers(self.factionBtns)
        self.okForCreateBtn = DirectButton(text = ("Ok", "Ok", "Ok", "disabled"), scale=.08, command=self.clickedOkForCreateBtn, pos=(-0.05, 0.0, -1.25))
        self.cancelForCreateBtn =  DirectButton(text = ("Cancel", "Cancel", "Cancel", "disabled"), scale=.08, command=self.clickedCancelForCreateBtn, pos=(0.4, 0.0, -1.25))
        self.okForCreateBtn.reparentTo(self.frame)
        self.cancelForCreateBtn.reparentTo(self.frame)
        
    def destroyCreateCharWindow(self):
        self.frame.destroy()
        self.nameOfChar.destroy()
        self.nameOfCharTextbox.destroy()
        self.factionSelection.destroy()
        self.okForCreateBtn.destroy()
        self.cancelForCreateBtn.destroy()
                                
    def clearnameOfChar(self):
        self.nameOfCharTextbox.enterText('')
        
    def getnameOfChar(self):
        self.nameOfCharInput = self.nameOfCharTextbox.get()
    
    def setnameOfChar(self, textEntered):
        print "name Of Char: ",textEntered
        self.nameOfChar = textEntered
        
    def clickedOkForCreateBtn(self):
        print "you have pressed the ok button for creating a character"
     
    def clickedCancelForCreateBtn(self):
        print "you have press the cancel button from the create character frame"
        self.destroyCreateCharWindow()
        self.createSelectionWindow()    
    
    def setText(status=None):
        bk_text = "CurrentValue "
        
    def setfaction(status=None):
        bk_text = "CurrentValue "    
        
    #character deletion        
    def createDeleteCharWindow(self):
        self.frame = DirectFrame(frameColor=(0, 0, 0, 1), #(R,G,B,A)
                                frameSize=(-3, 3, -3, 3),#(Left,Right,Bottom,Top)
                                pos=(-0.5, 0, 0.9))
        
        self.selectCharactertodelete = OnscreenText(text = "Select Character :", pos = (-0.02, -0.35), scale = 0.08,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=0)
        self.selectCharactertodelete.reparentTo(self.frame)
        self.selectCharacterToDeleteTextbox = DirectEntry(text = "" ,scale=.07,pos=(0.45,0, -.35),command=self.setselectCharacterToDelete,initialText="name of character", numLines = 1,focus=0,focusInCommand=self.clearselectCharacterToDelete, focusOutCommand=self.getselectCharacterToDelete)
        self.selectCharacterToDeleteTextbox.reparentTo(self.frame)
        self.referenceForDeletion = OnscreenText(text = "Reference to Character List:", pos = (-0.15, -0.75), scale = 0.08,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=0)
        self.referenceForDeletion.reparentTo(self.frame)
        self.deleteScrolledList = DirectScrolledList(
        decButton_pos= (0.35, 0, 0.53),
        decButton_text = "Dec",
        decButton_text_scale = 0.04,
        decButton_borderWidth = (0.005, 0.005),
 
        incButton_pos= (0.35, 0, -0.02),
        incButton_text = "Inc",
        incButton_text_scale = 0.04,
        incButton_borderWidth = (0.005, 0.005),
        
        
        pos = (0.7, 0, -0.99),
        numItemsVisible = 4,
        forceHeight = .11,
        itemFrame_frameSize = (-0.6, 0.6, -0.37, 0.11),
        itemFrame_pos = (0.35, 0, 0.4))
        
        for playerchar in ['xxxbluesword', 'xxxblueaxe', 'xxxredsword', 'xxxredsword01','xxx_red_sword04']:
            l = DirectLabel(text = playerchar, text_scale=0.1)
            self.deleteScrolledList.addItem(l)
            
        self.deleteScrolledList.reparentTo(self.frame)
        self.deleteBtn = DirectButton(text = ("Delete", "Delete", "Delete", "disabled"), scale=.08, command=self.clickedDelete, pos=(-0.2, 0.0, -1.25))
        
        self.delCancelBtn =  DirectButton(text = ("Cancel", "Cancel", "Cancel", "disabled"), scale=.08, command=self.clickedDelCancel, pos=(0.3, 0.0, -1.25))
        self.deleteBtn.reparentTo(self.frame)
        self.delCancelBtn.reparentTo(self.frame)
        
    def destroyDeleteCharWindow(self):
        self.frame.destroy()
        self.selectCharactertodelete.destroy()
        self.deleteBtn.destroy()
        self.delCancelBtn.destroy()
        self.selectCharacterToDeleteTextbox.destroy()
        self.referenceForDeletion.destroy()
        
    def clearselectCharacterToDelete(self):
        self.selectCharacterToDeleteTextbox.enterText('')
        
    def getselectCharacterToDelete(self):
        self.selectCharacterToDeleteInput = self.nameOfCharTextbox.get()
    
    def setselectCharacterToDelete(self, textEntered):
        print "name Of Char: ",textEntered
        self.selectCharacterToDelete = textEntered
        
    def clickedDelete(self):
        print "You pressed delete a character"
        
    def clickedDelCancel(self):
        print "to go back to slection menu"
        self.destroyDeleteCharWindow()
        self.createSelectionWindow()
            
    
    #character Selection
    def createSelectionWindow(self):
        self.frame = DirectFrame(frameColor=(0, 0, 0, 1), #(R,G,B,A)
                                frameSize=(-3, 3, -3, 3),#(Left,Right,Bottom,Top)
                                pos=(-0.5, 0, 0.9))
                
        self.createCharacter = DirectButton(text = ("Create Character","Create Character","Create Character","disabled"), scale=.08, command = self.clickedCreateChar, pos=(-0.14,0.0,-0.25))
        self.deleteCharacter = DirectButton(text = ("Delete Character","Delete Character","Delete Character","disabled"), scale=.08, command = self.clickedDeleteChar, pos=(-0.14,0.0,-0.40))
        self.createCharacter.reparentTo(self.frame)
        self.deleteCharacter.reparentTo(self.frame)
        self.selectCharacter = OnscreenText(text = "Select Character :", pos = (-0.12, -0.55), scale = 0.08,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=0)
        self.selectCharacter.reparentTo(self.frame)
        
        self.myScrolledList = DirectScrolledList(
        decButton_pos= (0.35, 0, 0.53),
        decButton_text = "Dec",
        decButton_text_scale = 0.04,
        decButton_borderWidth = (0.005, 0.005),
 
        incButton_pos= (0.35, 0, -0.02),
        incButton_text = "Inc",
        incButton_text_scale = 0.04,
        incButton_borderWidth = (0.005, 0.005),
 
        
        pos = (0.05, 0, -0.3),
        numItemsVisible = 4,
        forceHeight = .11,
        itemFrame_frameSize = (-0.6, 0.6, -0.37, 0.11),
        itemFrame_pos = (0.35, 0, 0.4),
        )
        
        self.selectCharacterTextbox = DirectEntry(text = "" ,scale=.07,pos=(0.28,0, -.55),command=self.setselectCharacterTextbox,initialText="name of character", numLines = 1,focus=0,focusInCommand=self.clearselectCharacterTextbox, focusOutCommand=self.getselectCharacterTextbox)
        self.selectCharacterTextbox.reparentTo(self.frame)
        self.referenceForSeletion = OnscreenText(text = "Reference to Character List:\n that already exists", pos = (-0.30, -0.75), scale = 0.08,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=0)
        self.referenceForSeletion.reparentTo(self.frame)
      
        for playerchar in ['xxxbluesword', 'xxxblueaxe', 'xxxredsword', 'xxxredsword01','xxx_red_sword04']:
            l = DirectLabel(text = playerchar, text_scale=0.1)
            self.myScrolledList.addItem(l) 
        
        self.submitBtn = DirectButton(text = ("Start", "Start", "Start", "disabled"), scale=.08, command=self.clickedSubmit, pos=(-0.2, 0.0, -1.45))
        
        self.cancelBtn =  DirectButton(text = ("Cancel", "Cancel", "Cancel", "disabled"), scale=.08, command=self.clickedCancel, pos=(0.3, 0.0, -1.45))
        self.submitBtn.reparentTo(self.frame)
        self.cancelBtn.reparentTo(self.frame)
        
    def destroySelectionWindow(self):
        self.frame.destroy()
        self.selectCharacter.destroy()
        self.createCharacter.destroy()
        self.deleteCharacter.destroy()
        self.submitBtn.destroy()        
        self.cancelBtn.destroy()
    
    def clearselectCharacterTextbox(self):
        self.selectCharacterTextbox.enterText('')
        
    def getselectCharacterTextbox(self):
        self.selectCharacterTextbox = self.selectCharacterTextbox.get()
    
    def setselectCharacterTextbox(self, textEntered):
        print "name Of Char: ",textEntered
        self.selectCharacterTextbox = textEntered
        
    def clickedCreateChar(self):
        print "You pressed create a new character"
        self.destroySelectionWindow()
        self.createCreateCharWindow()  
    
    def clickedDeleteChar(self):
        print "You pressed delete a character"
        self.destroySelectionWindow()
        self.createDeleteCharWindow()  
        
    def clickedSubmit(self):
        print "you pressed start button"
  
    def clickedCancel(self):
        print "You pressed Cancel"
class ConnectionManager:
    def __init__(self, main):
        self.main = main

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

        self.rqTable = ServerRequestTable()
        self.rsTable = ServerResponseTable()

        self.connection = None

    def startConnection(self):
        """Create a connection with the remote host.

        If a connection can be created, create a task with a sort value of -39
        to read packets from the socket.

        """
        if self.connection == None:
            self.connection = self.cManager.openTCPClientConnection(Constants.SERVER_IP, Constants.SERVER_PORT, 1000)

            if self.connection:
                self.cReader.addConnection(self.connection)
                return True

        return False

    def initTasks(self):
        """Initialize tasks to check on connection and send heartbeat.

        This must be done here because in `Main` we do not initialize Panda3D
        until after a connection is started. Thus, `taskMgr` is not defined
        when `startConnection()` is called. We rely on the callee to also run
        `initTasks()` after a successful connection is created.

        """
        if self.connection != None:
            taskMgr.add(self.updateRoutine, "updateRoutine-Connection")
            taskMgr.doMethodLater(5, self.checkConnection, "checkConnection")
            taskMgr.doMethodLater(1.0 / Constants.TICKRATE, self.sendHeartbeat, "sendHeartbeat")

    def closeConnection(self):
        """Close the current connection with the remote host.

        If an existing connection is found, remove both the Main task, which
        is responsible for the heartbeat, and the Connection task, which is
        responsible for reading packets from the socket, then properly close
        the existing connection.

        """
        if self.connection != None:
            taskMgr.remove("updateRoutine-Connection")
            taskMgr.remove("checkConnection")

            self.cManager.closeConnection(self.connection)
            self.connection = None

    def sendRequest(self, requestCode, args={}):
        """Prepare a request packet to be sent.

        If the following request code exists, create an instance of this
        specific request using any extra arguments, then properly send it to
        the remote host.

        """
        if self.connection != None:
            request = self.rqTable.get(requestCode)

            if request != None:
                request.set(self.cWriter, self.connection)
                request.send(args)

    def handleResponse(self, responseCode, data):
        """Prepare a response packet to be processed.

        If the following response code exists, create an instance of this
        specific response using its data to be executed.

        """
        response = self.rsTable.get(responseCode)

        if response != None:
            response.set(self.main)
            response.execute(data)

    def checkConnection(self, task):

        if not self.cReader.isConnectionOk(self.connection):
            self.closeConnection()
            self.showDisconnected(0)

            return task.done

        return task.again

    def updateRoutine(self, task):
        """A once-per-frame task used to read packets from the socket."""
        while self.cReader.dataAvailable():
            # Create a datagram to store all necessary data.
            datagram = NetDatagram()
            # Retrieve the contents of the datagram.
            if self.cReader.getData(datagram):
                # Prepare the datagram to be iterated.
                data = PyDatagramIterator(datagram)
                # Retrieve a "short" that contains the response code.
                responseCode = data.getUint16()
                # Pass into another method to execute the response.
                if responseCode != Constants.MSG_NONE:
                    self.handleResponse(responseCode, data)

        return task.cont

    def sendHeartbeat(self, task):
        if self.connection != None:
            self.sendRequest(Constants.C_HEARTBEAT)
        return task.again
Exemple #38
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)