class Server(DirectObject): def __init__(self): DirectObject.__init__(self) self.accept("escape", self.quit) self.lastConnection = None self.cManager = QueuedConnectionManager() self.cListener = QueuedConnectionListener(self.cManager, 0) self.cReader = QueuedConnectionReader(self.cManager, 0) self.cWriter = ConnectionWriter(self.cManager,0) self.tcpSocket = self.cManager.openTCPServerRendezvous(SERVER_PORT, 1) self.cListener.addConnection(self.tcpSocket) taskMgr.add(self.listenTask, "serverListenTask", -40) taskMgr.add(self.readTask, "serverReadTask", -39) self.gameLogic = GameLogic() self.gameLogic.delegate = self; blackmaker = CardMaker("blackmaker") blackmaker.setColor(0,0,0,1) blackmaker.setFrame(-1.0, 1.0, -1.0, 1.0) instcard = NodePath(blackmaker.generate()) instcard.reparentTo(render2d) self.screenText = OnscreenText(text="Server started ...\n", style=1, fg=(1,1,1,1), pos=(-1.31, 0.925), scale = .06) self.screenText.setAlign(0) ###################################################################################### def listenTask(self, task): if self.cListener.newConnectionAvailable(): rendezvous = PointerToConnection() netAddress = NetAddress() newConnection = PointerToConnection() if self.cListener.getNewConnection(rendezvous, netAddress, newConnection): newConnection = newConnection.p() self.cReader.addConnection(newConnection) CLIENTS[newConnection] = netAddress.getIpString() self.lastConnection = newConnection self.screenText.appendText("New connection established.\n") else: self.screenText.appendText("getNewConnection returned false\n") return Task.cont ###################################################################################### def readTask(self, task): while 1: (datagram, data, msgID) = self.nonBlockingRead(self.cReader) if msgID is MSG_NONE: break else: self.handleDatagram(data, msgID, datagram.getConnection()) return Task.cont ###################################################################################### def nonBlockingRead(self, qcr): if self.cReader.dataAvailable(): datagram = NetDatagram() if self.cReader.getData(datagram): data = PyDatagramIterator(datagram) msgID = data.getUint16() else: data = None msgID = MSG_NONE else: datagram = None data = None msgID = MSG_NONE return (datagram, data, msgID) ###################################################################################### def handleDatagram(self, data, msgID, client): if msgID in Handlers.keys(): Handlers[msgID](msgID, data, client) else: self.screenText.appendText("Unknown msgID: ") self.screenText.appendText(msgID) self.screenText.appendText("\n") self.screenText.appendText(data) self.screenText.appendText("\n") return ###################################################################################### def msgAuth(self, msgID, data, client): name = data.getString() CLIENTS[client] = name self.gameLogic.addPlayer(name) pkg = PyDatagram() pkg.addUint16(SV_MSG_AUTH_RESPONSE) self.cWriter.send(pkg, client) self.screenText.appendText("Registered new client: ") self.screenText.appendText(name) self.screenText.appendText(" (") self.screenText.appendText(client.getAddress().getIpString()) self.screenText.appendText(")\n") ###################################################################################### def msgChat(self, msgID, data, senderClient): message = data.getString() self.screenText.appendText("Message: ") self.screenText.appendText(message) self.screenText.appendText("\n") pkg = PyDatagram() pkg.addUint16(SV_MSG_CHAT) pkg.addString(message) for receiverClient in CLIENTS: self.cWriter.send(pkg, receiverClient) ###################################################################################### def msgDisconnectReq(self, msgID, data, client): pkg = PyDatagram() pkg.addUint16(SV_MSG_DISCONNECT_ACK) self.cWriter.send(pkg, client) del CLIENTS[client] self.cReader.removeConnection(client) ###################################################################################### def handleCompleteSetup(self, msgID, data, senderClient): self.screenText.appendText("A new game will start... ") self.screenText.appendText(str(len(CLIENTS))) self.screenText.appendText(" pushies will fight to death.") setups = self.gameLogic.start() numberOfPlayers = len(setups) pkg = PyDatagram() pkg.addUint16(SV_MSG_START_GAME) pkg.addUint16(numberOfPlayers) for setup in setups: pkg.addString(setup["player"]) pkg.addFloat32(setup["position"][0]) pkg.addFloat32(setup["position"][1]) pkg.addFloat32(setup["position"][2]) for receiverClient in CLIENTS: self.cWriter.send(pkg, receiverClient) ###################################################################################### def handleMovementCommand(self, msgID, data, client): player = CLIENTS[client] movement = data.getUint8() status = data.getUint8() self.gameLogic.setPlayerMovement(player, movement, status) def handleJumpCommand(self, msgID, data, client): player = CLIENTS[client] status = data.getUint8() self.gameLogic.setPlayerJump(player, status) def handleChargeCommand(self, msgID, data, client): player = CLIENTS[client] status = data.getUint8() self.gameLogic.setPlayerCharge(player, status) ###################################################################################### def sendPositionUpdates(self, updates): pkg = PyDatagram() pkg.addUint16(SV_MSG_UPDATE_POSITIONS) pkg.addUint16(len(updates)) for update in updates: pkg.addString(update[0]) pkg.addFloat32(update[1][0]) pkg.addFloat32(update[1][1]) pkg.addFloat32(update[1][2]) pkg.addFloat32(update[2][0]) pkg.addFloat32(update[2][1]) pkg.addFloat32(update[2][2]) for client in CLIENTS: self.cWriter.send(pkg, client) def sendStatusUpdates(self, updates): pkg = PyDatagram() pkg.addUint16(SV_MSG_UPDATE_STATES) pkg.addUint16(len(updates)) for update in updates: pkg.addString(update["player"]) pkg.addUint8(update["status"]) pkg.addFloat32(update["health"]) pkg.addUint8(update["charge"]) pkg.addUint8(update["jump"]) for client in CLIENTS: self.cWriter.send(pkg, client) def quit(self): self.cManager.closeConnection(self.tcpSocket) sys.exit()
class WorldBase(DirectObject): """ Basic 3D world with logging and 2D display """ def __init__(self, controller, mem_logger, display_categories): self.display_categories = display_categories self.labels = OnscreenText( "", style = 1, fg = ( 1, 1, 1, 1 ), pos = ( -1.0, 0.9 ), scale = .05 ) self.txt = OnscreenText( "", style = 1, fg = ( 1, 1, 1, 1 ), pos = ( -0.5, 0.9 ), scale = .05 ) taskMgr.add( self.loop, "loop" ) self.enable_screen_updates = True self.log = KeplerLogger(mem_logger) self.logging = False self.accept("p", self.key_p) self.accept( "escape", self.quit ) self.accept("arrow_up", self.key_up) self.accept("arrow_down", self.key_down) self.accept("arrow_left", self.key_left) self.accept("arrow_right", self.key_right) self.accept("l", self.key_l) self.accept("s", self.key_s) self.accept("a", self.key_a) self.accept("f", self.key_f) self.accept("g", self.key_g) self.accept("d", self.key_d) self.accept("o", self.log_start_stop) self.accept("q", self.key_q) self.accept("w", self.key_w) self.accept("z", self.key_z) self.accept("x", self.key_x) self.accept("c", self.key_c) self.accept("v", self.key_v) self.accept("b", self.key_b) self.accept("n", self.key_n) self.controller = controller base.setFrameRateMeter(True) #self.txt = OnscreenText( "Nothing", style = 1, fg = ( 1, 1, 1, 1 ), shadow = ( .9, .9, .9, .5 ), pos = ( -1.0, 0.9 ), scale = .07 ) # task to be called every frame self.step = 0 self.last_time = time.time() self.text_refresh_band = 10 self.text_refresh_count = self.text_refresh_band self._set_title("Keplermatic") self.init_gui() def init_gui(self): x = -0.9 y = 0.7 inc_y = -0.1 cb = CallBack("Logging", self.display_categories, self) self.add_gui_checkbox("Logging", False, x, y, cb.callback) y += inc_y cb = CallBack("Update", self.display_categories,self) self.add_gui_checkbox("Update", True, x, y, cb.callback) y += inc_y y += inc_y keys = self.display_categories.keys() keys.sort() for k in keys: if k in ["axis1","axis2"]: cb = CallBack(k, self.display_categories,self) category_name = k enabled = self.display_categories[category_name] self.add_gui_checkbox(category_name, enabled, x, y, cb.callback) y += inc_y y += inc_y y += inc_y for k in keys: if k not in ["axis1","axis2"]: cb = CallBack(k, self.display_categories,self) category_name = k enabled = self.display_categories[category_name] self.add_gui_checkbox(category_name, enabled, x, y, cb.callback) y += inc_y def _set_title(self, title): from pandac.PandaModules import ConfigVariableString mygameserver = ConfigVariableString("window-title","Panda") mygameserver.setValue(title) def loop(self, task): #self.last_time = time.time() delta_time = task.time - self.last_time # avoid division by 0 if delta_time < 0.0001: delta_time = 0.0001 self.last_time = task.time self.step += 1 txt = "" self._refresh_text(txt) self.controller.loop(self.step, task.time, delta_time) if self.logging: data = self.controller.get_display_data() self.log.snapshot(get_data_logger(), self.step, task.time, data, ('self')) return Task.cont def _refresh_text(self, txt): if not self.enable_screen_updates: return self.text_refresh_count -=1 if self.text_refresh_count <0: self.text_refresh_count = self.text_refresh_band data = self.controller.get_display_data() st = str(self.last_time) data['Time'] = (st, "sim", 0) data['step'] = (self.step, "sim", 0) self.txt.clearText() self.txt.setAlign(TextNode.ALeft) keys = data.keys() keys.sort() txt += "logging: %s\n" % self.logging #print keys show_axis1 = self.display_categories['axis1'] show_axis2 = self.display_categories['axis2'] for name in keys: if name == 'self': continue display_data = data[name] #print display_data value, category, axis = display_data if category not in self.display_categories.keys(): category = "other" show_category = self.display_categories[category] show_it = show_category if not show_it: #print " %s hidden (category %s hidden)" % (name, category) pass if axis == 1: if show_axis1 == False: #print " %s hidden (axis 1)" % name show_it = False if axis == 2: if show_axis2 == False: #print " %s hidden (axis 2)" % name show_it = False if show_it: #print "**** name %s, cat %s [%s], axis %s, value %s show1 %s, show2 %s" %(name, category, show_it, axis, value, show_axis1, show_axis2) value_str = "%s" % value if type(value) == type(0.): # float value_str = "%.10f" % value txt += "%s: %s\n" % (name, value_str) else: pass #print "XXXX name %s, cat %s [%s], axis %s, value %s show1 %s, show2 %s" %(name, category, show_it, axis, value, show_axis1, show_axis2) self.txt.appendText(txt) def add_gui_checkbox(self, text, value, x, y, callback): b = DirectCheckButton(text = text ,scale=.05, pos=(x,0,y), command=callback) b["indicatorValue"] = value return b def quit(self): self.controller.stop() if len(self.log.data) >0: self.log.dump(get_data_logger()) sys.exit() def log_start_stop(self): if self.logging: # stopping self.controller.stop() self.log.dump(get_data_logger()) self.log.data = [] self.logging = not self.logging print "Logging %s" % self.logging def key_p(self): self.enable_screen_updates = not self.enable_screen_updates print "enable_screen_updates=", self.enable_screen_updates def key_right(self): self.controller.key_right() def key_left(self): self.controller.key_left() def key_l(self): self.controller.key_l() def key_s(self): self.controller.key_s() def key_a(self): self.controller.key_a() def key_f(self): self.controller.key_f() def key_g(self): self.controller.key_g() def key_d(self): self.controller.key_d() def key_up(self): self.controller.key_up() def key_down(self): self.controller.key_down() def key_q(self): self.controller.key_q() def key_w(self): self.controller.key_w() def key_z(self): self.controller.key_z() def key_x(self): self.controller.key_x() def key_c(self): self.controller.key_c() def key_v(self): self.controller.key_v() def key_b(self): self.controller.key_b() def key_n(self): self.controller.key_n()