class NetworkClient(): def __init__(self): self.timeout = 3000 self.c_manager = QueuedConnectionManager() self.c_reader = QueuedConnectionReader(self.c_manager, 0) self.c_writer = ConnectionWriter(self.c_manager, 0) def connect(self, ip, port): self.connection = self.c_manager.openTCPClientConnection( ip, port, self.timeout) if self.connection: self.c_reader.addConnection(self.connection) return (True) return (False) def disconnect(self): if self.connection: self.c_manager.closeConnection(self.connection) else: print("Trying to disconnect while not connected!") def send_data(self): data = PyDatagram() data.addString("Hello, world!") self.c_writer.send(data, self.connection)
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 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())
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)
cReader.addConnection(newConnection) # Begin reading connection return Task.cont def tskReaderPolling(taskdata): if 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 cReader.getData(datagram): myProcessDataFunction(datagram) return Task.cont taskMgr.add(tskListenerPolling, "Poll the connection listener", -39) taskMgr.add(tskReaderPolling, "Poll the connection reader", -40) 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 = "localhost" # how long until we give up trying to reach the server? timeout_in_miliseconds = 3000 # 3 seconds myConnection = cManager.openTCPClientConnection(ip_address, port_address, timeout_in_miliseconds) if myConnection: cReader.addConnection(myConnection) # receive messages from server
class Login_Page(DirectObject): def __init__(self): base.setBackgroundColor( 254, 254, 254 ) # sets the background color to black because the # default grey color bugs me for some reason self.loginScreen() # draws the login screen self.usernameBox['focus'] = 1 # sets the cursor to the username field by default self.accept('tab', self.cycleLoginBox) # enables the user to cycle through the text fields with the tab key # this is a standard feature on most login forms self.accept('enter', self.attemptLogin) # submits the login form, or you can just click the Login button def loginScreen(self): # creates a basic login screen that asks for a username/password boxloc = Vec3(0.0, 0.0, 0.0) # all items in the login form will have a position relative to this # this makes it easier to shift the entire form around once we have # some graphics to display with it without having to change the # positioning of every form element # p is the position of the form element relative to the boxloc # coordinates set above it is changed for every form element p = boxloc + Vec3(-0.5, 0, 0.0) self.textObject = OnscreenText(text = "Username:"******"Username: "******"" , pos = p, scale=.05, initialText="", numLines = 1) # Username textbox where you type in your username p = boxloc + Vec3(-0.5, -0.1, 0.0) self.textObject = OnscreenText(text = "Password:"******"Password: "******"" , pos = p, scale=.05, initialText="", numLines = 1, obscured = 1) # Password textbox where you type in your password # Note - obscured = 1 denotes that all text entered will be replaced # with a * like a standard password box p = boxloc + Vec3(0, 0, -0.2) self.loginButton = DirectButton(text = ("Login", "Login", "Login", "Login"), pos = p, scale = 0.075, command=self.attemptLogin) # The 'Login' button that will trigger the attemptLogin function # when clicked p = boxloc + Vec3(-0.5, -0.4, 0) self.statusText = OnscreenText(text = "", pos = p, scale = 0.05, fg = (1, 0, 0, 1), align=TextNode.ALeft) # A simple text object that you can display an error/status messages # to the user def updateStatus(self, statustext): self.statusText.setText(statustext) # all this does is change the status text. def composeStringMessage(self, msg): myPyDatagram = PyDatagram() myPyDatagram.addString(msg) return myPyDatagram def retrieveStringMessage(self,datagram): myIterator = PyDatagramIterator(datagram) msg = myIterator.getString() print msg, " received" def sendRequest(self): if(self.received): print "->Client request:" # Send a request to the server msg = self.usernameBox.get()+" "+self.passwordBox.get() 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): self.retrieveStringMessage(datagram) self.received = 1 def communicate(self): #print "communicate" self.sendRequest() self.receiveResponse() def updateRoutine(self,task): self.communicate() return task.again; def attemptLogin(self): # checks to make sure the user inputed a username and password: # if they didn't it will spit out an error message # if they did, it will try to connect to the login server # (under construction) if(self.usernameBox.get() == ""): if(self.passwordBox.get() == ""): self.updateStatus("ERROR: You must enter a username and password before logging in.") else: self.updateStatus("ERROR: You must specify a username") self.passwordBox['focus'] = 0 self.usernameBox['focus'] = 1 elif(self.passwordBox.get() == ""): self.updateStatus("ERROR: You must enter a password") self.usernameBox['focus'] = 0 self.passwordBox['focus'] = 1 else: self.updateStatus("Attempting to login...") print "Attempting to connect to Server with credentials: (" + self.usernameBox.get() + ", " + self.passwordBox.get() + ")" # this is where the networking code will get put in self.cManager = QueuedConnectionManager() self.cListener = QueuedConnectionListener(self.cManager, 0) self.cReader = QueuedConnectionReader(self.cManager, 0) self.cWriter = ConnectionWriter(self.cManager, 0) HOST = "localhost"; PORT = 1234; 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.doMethodLater(3, self.updateRoutine, 'updateRoutine') def cycleLoginBox(self): # function is triggered by the tab key so you can cycle between # the two input fields like on most login screens # IMPORTANT: When you change the focus to one of the text boxes, # you have to unset the focus on the other textbox. If you do not # do this Panda seems to get confused. if(self.passwordBox['focus'] == 1): self.passwordBox['focus'] = 0 self.usernameBox['focus'] = 1 elif(self.usernameBox['focus'] == 1): self.usernameBox['focus'] = 0 self.passwordBox['focus'] = 1
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
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 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
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
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;
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
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 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
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
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
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()
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
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
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
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()
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
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()
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
class Register_Page(DirectObject): def __init__(self): base.setBackgroundColor( 254, 254, 254 ) # sets the background color to black because the # default grey color bugs me for some reason self.loginScreen() # draws the login screen self.usernameBox['focus'] = 1 # sets the cursor to the username field by default self.accept('tab', self.cycleLoginBox) # enables the user to cycle through the text fields with the tab key # this is a standard feature on most login forms self.accept('enter', self.attemptLogin) # submits the login form, or you can just click the Login button def loginScreen(self): # creates a basic login screen that asks for a username/password boxloc = Vec3(0.0, 0.0, 0.0) # all items in the login form will have a position relative to this # this makes it easier to shift the entire form around once we have # some graphics to display with it without having to change the # positioning of every form element # p is the position of the form element relative to the boxloc # coordinates set above it is changed for every form element p = boxloc + Vec3(-0.5, 0, 0.0) self.username = OnscreenText(text = "Username:"******"Username: "******"" , pos = p, scale=.05, initialText="", numLines = 1) # Username textbox where you type in your username p = boxloc + Vec3(-0.49, -0.1, 0.0) self.password = OnscreenText(text = "Password:"******"Password: "******"Confirm password:"******"Password: "******"" , pos = p, scale=.05, initialText="", numLines = 1, obscured = 1) # Password textbox where you type in your password # Note - obscured = 1 denotes that all text entered will be replaced # with a * like a standard password box p = boxloc + Vec3(-0.1, 0, -0.2) self.password2Box = DirectEntry(text = "" , pos = p, scale=.05, initialText="", numLines = 1, obscured = 1) # Password textbox where you type in your password # Note - obscured = 1 denotes that all text entered will be replaced # with a * like a standard password box p = boxloc + Vec3(0, 0, -0.3) self.registerButton = DirectButton(text = ("Register", "Register", "Register", "Register"), pos = p, scale = 0.075, command=self.attemptLogin) # The 'Login' button that will trigger the attemptLogin function # when clicked p = boxloc + Vec3(-0.5, -0.5, 0) self.statusText = OnscreenText(text = "", pos = p, scale = 0.05, fg = (1, 0, 0, 1), align=TextNode.ALeft) # A simple text object that you can display an error/status messages # to the user def updateStatus(self, statustext): self.statusText.setText(statustext) # all this does is change the status text. def attemptLogin(self): # checks to make sure the user inputed a username and password: # if they didn't it will spit out an error message # if they did, it will try to connect to the login server # (under construction) if(self.usernameBox.get() == ""): if(self.passwordBox.get() == ""): self.updateStatus("ERROR: You must enter a username and password before logging in.") else: self.updateStatus("ERROR: You must specify a username") self.passwordBox['focus'] = 0 self.usernameBox['focus'] = 1 elif(self.passwordBox.get() == ""): self.updateStatus("ERROR: You must enter a password") self.usernameBox['focus'] = 0 self.passwordBox['focus'] = 1 elif(self.password2Box.get() == ""): self.updateStatus("ERROR: You must confirm the password") self.passwordBox['focus'] = 0 self.password2Box['focus'] = 1 elif(self.passwordBox.get() != self.password2Box.get()): self.updateStatus("ERROR: Wrong confirmed password, please enter password again") self.passwordBox.set("") self.password2Box.set("") self.passwordBox['focus'] = 1 self.password2Box['focus'] = 0 self.usernameBox['focus'] = 0 else: self.updateStatus("Attempting to login...") print "Attempting to connect to Server with credentials: (" + self.usernameBox.get() + ", " + self.passwordBox.get() + ")" # this is where the networking code will get put in self.cManager = QueuedConnectionManager() self.cListener = QueuedConnectionListener(self.cManager, 0) self.cReader = QueuedConnectionReader(self.cManager, 0) self.cWriter = ConnectionWriter(self.cManager, 0) HOST = "localhost"; PORT = 1234; 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.doMethodLater(3, self.updateRoutine, 'updateRoutine') def cycleLoginBox(self): # function is triggered by the tab key so you can cycle between # the two input fields like on most login screens # IMPORTANT: When you change the focus to one of the text boxes, # you have to unset the focus on the other textbox. If you do not # do this Panda seems to get confused. if(self.passwordBox['focus'] == 1): self.passwordBox['focus'] = 0 self.password2Box['focus'] = 1 self.usernameBox['focus'] = 0 elif(self.usernameBox['focus'] == 1): self.usernameBox['focus'] = 0 self.passwordBox['focus'] = 1 self.password2Box['focus'] = 0 elif(self.password2Box['focus'] == 1): self.passwordBox['focus'] = 0 self.password2Box['focus'] = 0 self.usernameBox['focus'] = 1
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
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