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 __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)
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)
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) -> None: # Handle connections and terminations self.manager = QueuedConnectionManager() # Wait for clients connection requests self.listener = QueuedConnectionListener(self.manager, 0) # Buffers incoming data from active connection self.reader = QueuedConnectionReader(self.manager, 0) # Transmit PyDatagrams to active connection self.writer = ConnectionWriter(self.manager, 0) # Open TCP Rendezvous to accept client connections with a limit self.socket = self.manager.openTCPServerRendezvous( self.port, self.backlog) self.listener.addConnection(self.socket) print("Server listening on port %s...." % str(self.port)) # Listen for mew incoming connections taskMgr.add(self.handle_incoming_connections, "Poll the connection listener", -39) # Listen for new datagrams taskMgr.add(self.handle_connection_data, "Poll the connection reader", -40) # Listen for dropped connections taskMgr.add(self.handle_dropped_connections, "Poll the dropped connection listener", -41) # See if game can be started taskMgr.add(self.start_game, "Start Game", -42)
def __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 __init__(self, worldMgr, connectionObj): self.connectionObj = connectionObj if connectionObj.cManager != None: self.cManager = connectionObj.cManager else: self.cManager = QueuedConnectionManager() if connectionObj.cListener != None: self.cListener = connectionObj.cListener else: self.cListener = QueuedConnectionManager() if connectionObj.cReader != None: self.cReader = connectionObj.cReader else: self.cReader = QueuedConnectionManager() if connectionObj.cWriter != None: self.cWriter = connectionObj.cWriter else: self.cWriter = QueuedConnectionManager() if connectionObj.connection != None: self.connection = connectionObj.connection else: self.connection = self.cManager.openTCPClientConnection(Constants.SERVER_IP, Constants.SERVER_PORT, 1000) if self.connection: self.cReader.addConnection(self.connection) self.rqTable = ServerRequestTable() self.rsTable = ServerResponseTable() self.worldMgr = worldMgr self.world = worldMgr.gameWorld
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 setupTCP(self): self.tcpManager = QueuedConnectionManager() self.tcpReader = QueuedConnectionReader(self.tcpManager, 0) self.tcpWriter = ConnectionWriter(self.tcpManager, 0) self.tcpListener = QueuedConnectionListener(self.tcpManager, 0) self.tcpSocket = self.tcpManager.openTCPServerRendezvous(self.tcpport, self.backlog) self.tcpListener.addConnection(self.tcpSocket) print ("Started Server on: ", self.hostname, self.tcpport)
def setupTCP(self): self.tcpManager = QueuedConnectionManager() self.tcpReader = QueuedConnectionReader(self.tcpManager, 0) self.tcpWriter = ConnectionWriter(self.tcpManager, 0) self.tcpListener = QueuedConnectionListener(self.tcpManager, 0) self.tcpSocket = self.tcpManager.openTCPServerRendezvous( self.config.TCPPORT, self.config.BACKLOG) self.tcpListener.addConnection(self.tcpSocket) print("Started Server on: ", self.config.HOSTNAME, self.config.TCPPORT)
def __init__(self): self.c_manager = QueuedConnectionManager() self.c_listener = QueuedConnectionListener(self.c_manager, 0) self.c_reader = QueuedConnectionReader(self.c_manager, 0) self.c_writer = ConnectionWriter(self.c_manager,0) self.active_conns=[] self.port_address=9099 #No-other TCP/IP services are using this port self.backlog=1000 #If we ignore 1,000 connection attempts, something is wrong!
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)
def __init__(self): self.socket = None self.hostName = None self.port = None self.ourChannel = 100001 self.cManager = QueuedConnectionManager() self.cListener = QueuedConnectionListener(self.cManager, 0) self.cReader = QueuedConnectionReader(self.cManager, 0) self.cWriter = ConnectionWriter(self.cManager, 0)
def __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 __init__ (self, gameManager): self._connManager = QueuedConnectionManager() self._loadConfig() self._activeConns = [] # Active connections list. self._isActive = False self._backlog = HOST_MAX_BACKLOG self._gameManager = gameManager self._playerInfo = dict() # connections by connectionID (cID) self._creatures = dict() # Creatures by cID. self._localPlayerCID = None self._creatureIDCount = 0
class Network(): def __init__(self): self.c_manager = QueuedConnectionManager() self.c_listener = QueuedConnectionListener(self.c_manager, 0) self.c_reader = QueuedConnectionReader(self.c_manager, 0) self.c_writer = ConnectionWriter(self.c_manager,0) self.active_conns=[] self.port_address=9099 #No-other TCP/IP services are using this port self.backlog=1000 #If we ignore 1,000 connection attempts, something is wrong! #tcp_socket = c_manager.openTCPServerRendezvous(port_address,backlog) #self.tcp_socket = self.c_manager.openTCPServerRendezvous("0.0.0.0", 9099, 1000) #self.c_listener.addConnection(self.tcp_socket) def tsk_listener_pol(self, taskdata): if self.c_listener.newConnectionAvailable(): rendezvous = PointerToConnection() netAddress = NetAddress() newConnection = PointerToConnection() if self.c_listener.getNewConnection(rendezvous,netAddress,newConnection): print("Connected: "+str(netAddress)) newConnection = newConnection.p() self.active_conns.append(newConnection) # Remember connection self.c_reader.addConnection(newConnection) # Begin reading connection return Task.cont def tsk_reader_pol(self, taskdata): if self.c_reader.dataAvailable(): datagram=NetDatagram() # catch the incoming data in this instance # Check the return value; if we were threaded, someone else could have # snagged this data before we did if self.c_reader.getData(datagram): self.data_process(datagram) return Task.cont def data_process(self, datagram): it = PyDatagramIterator(datagram) message = it.getString() print("Processed: "+message+" from: "+str(datagram.getAddress())) def listen(self): print("Now listening on all addresses on port 9099") self.tcp_socket = self.c_manager.openTCPServerRendezvous("0.0.0.0", 9099, 1000) self.c_listener.addConnection(self.tcp_socket) taskMgr.add(self.tsk_listener_pol, "Poll connection listener", -39) taskMgr.add(self.tsk_reader_pol, "Pol the connection reader", -40) def unlisten(self): print("Stopping listen") self.c_manager.closeConnection(self.tcp_socket)
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 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 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 __init__(self, port, backlog=1000, compress=False): DirectObject.__init__(self) self.port = port self.compress = compress self.cManager = QueuedConnectionManager() self.cListener = QueuedConnectionListener(self.cManager, 0) self.cReader = QueuedConnectionReader(self.cManager, 0) self.cWriter = ConnectionWriter(self.cManager, 0) self.passedData = [] self.connect(port, backlog) self.startPolling()
def __init__(self, server_address): # server information self.server_address = server_address self.server_port = 15000 self.timeout = 4000 self.server_connection = None # networking modules from panda3d self.manager = QueuedConnectionManager() self.reader = QueuedConnectionReader(self.manager, 0) self.writer = ConnectionWriter(self.manager, 0) # modules that deal with messages self.sender_manager = MessageSendersManager(self) self.handler = Handler(self) self.section_state_fetcher = SectionStateFetcher(self)
def __init__(self): self.activeConnections = [] # lists all connections self.players = {} # keys are the players logins, values are the players datagram connections self.parties = {} # keys are the parties names, values are dicts representing parties data self.sessions = {} # keys are the datagram connections, values are dicts storing the characters of the player and its party self.playersinlobby = [] # lists players in the party screen self.charid = 0 # used for random team generation self.chars = [] # lists of dicts representing characters data self.cManager = QueuedConnectionManager() self.cListener = QueuedConnectionListener(self.cManager, 0) self.cReader = QueuedConnectionReader(self.cManager, 0) self.cReader.setTcpHeaderSize(4) self.send = Send(self.cManager) port = 3001 if len(sys.argv) > 1: port = sys.argv[1] self.tcpSocket = self.cManager.openTCPServerRendezvous(port, 10) self.cListener.addConnection(self.tcpSocket) print("Server listening on port", port) taskMgr.add(self.tskListenerPolling, "Poll the connection listener", -39) taskMgr.add(self.tskReaderPolling, "Poll the connection reader", -40)
def __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 __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()
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 __init__(self, dc_loader, address, port, channel, timeout=5000): NetworkManager.__init__(self) self._dc_loader = dc_loader self.__address = address self.__port = port self._channel = channel self.__timeout = timeout self.__manager = QueuedConnectionManager() self.__reader = QueuedConnectionReader(self.__manager, 0) self.__writer = ConnectionWriter(self.__manager, 0) self.__socket = None self.__read_task = None self.__disconnect_task = None
def __init__(self, host="localhost", port=5001): taskMgr = Task.TaskManager() self.cManager = QueuedConnectionManager() self.cListener = QueuedConnectionListener(self.cManager, 0) self.cReader = QueuedConnectionReader(self.cManager, 0) self.cWriter = ConnectionWriter(self.cManager, 0) self.activeConnections = [] # We'll want to keep track of these later self.readerCallbacks = [] backlog = 1000 #If we ignore 1,000 connection attempts, something is wrong! self.tcpSocket = self.cManager.openTCPServerRendezvous(port, backlog) self.cListener.addConnection(self.tcpSocket) taskMgr.add(self.tskListenerPolling, "Poll the connection listener", -39) taskMgr.add(self.tskReaderPolling, "Poll the connection reader", -40) print("started server! ({} at {})".format(port, host))
def __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 setupTCP(self): self.tcpManager = QueuedConnectionManager() self.tcpReader = QueuedConnectionReader(self.tcpManager, 0) self.tcpWriter = ConnectionWriter(self.tcpManager, 0) self.tcpListener = QueuedConnectionListener(self.tcpManager, 0) self.tcpSocket = self.tcpManager.openTCPServerRendezvous(self.config.TCPPORT, self.config.BACKLOG) self.tcpListener.addConnection(self.tcpSocket) print ("Started Server on: ", self.config.HOSTNAME, self.config.TCPPORT)
class NetClient: """ Main networking class. """ def __init__(self, server_address): # server information self.server_address = server_address self.server_port = 15000 self.timeout = 4000 self.server_connection = None # networking modules from panda3d self.manager = QueuedConnectionManager() self.reader = QueuedConnectionReader(self.manager, 0) self.writer = ConnectionWriter(self.manager, 0) # modules that deal with messages self.sender_manager = MessageSendersManager(self) self.handler = Handler(self) self.section_state_fetcher = SectionStateFetcher(self) def connect(self): """ Establish connection with the server. """ self.server_connection = self.manager.open_TCP_client_connection( self.server_address, self.server_port, self.timeout) if self.server_connection: self.reader.add_connection(self.server_connection) return True return False def send_ready_for_updates(self): """ Send message to the server saying that client is ready for updates about game state. """ datagram = PyDatagram() ReadyForSyncRequest.build().dump(datagram) self.writer.send(datagram, self.server_connection) def begin_sync_with_server(self): """ Start synchronizing client's state with server's state. """ core.instance.task_mgr.add(self.listen_for_updates, "listen-for-updates") def listen_for_updates(self, task): """ Listen for any incoming packets from the server. """ if self.reader.data_available(): datagram = NetDatagram() if self.reader.get_data(datagram): self.handler.handle_data(datagram) return Task.cont
def __init__(self, host="localhost", port=5001, name="client or server"): self.name = name self.port = port self.host = host self.cManager = QueuedConnectionManager() self.cReader = QueuedConnectionReader(self.cManager, 0) self.cWriter = ConnectionWriter(self.cManager, 0) self.connections = [ ] # list of connections, contains 1 item for client, multiple for server self.readerCallback = None # will be called when a new message arrives self.writerCallback = None # will be called when a message needs to be constructed self.taskMgr = Task.TaskManager() self.taskMgr.add(self.tskReaderPolling, "Poll the connection reader", -40) self.taskMgr.add(self.tskWriterPolling, "Send data package", -39)
def __init__(self, address, port, handler, backlog=10000): NetworkManager.__init__(self) self.__address = address self.__port = port self.__handler = handler self.__backlog = backlog self.__manager = QueuedConnectionManager() self.__listener = QueuedConnectionListener(self.__manager, 0) self.__reader = QueuedConnectionReader(self.__manager, 0) self.__writer = ConnectionWriter(self.__manager, 0) self.__socket = None self.__handlers = {} self.__listen_task = None self.__read_task = None self.__disconnect_task = None
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 __init__(self): super().__init__() # Support objects self.manager = QueuedConnectionManager() self.listener = QueuedConnectionListener(self.manager, 0) self.reader = QueuedConnectionReader(self.manager, 0) self.writer = ConnectionWriter(self.manager, 0) self.handler = Handler(self) # Server model self.session_manager = SessionManager() self.notifier_manager = NotifierManager(self) self.task_manager = TaskManager(self) self.connections = [] # Socket self.tcp_socket = self.manager.open_TCP_server_rendezvous(15000, 1000) self.listener.add_connection(self.tcp_socket) self.accept_event(Event.CLIENT_DISCONNECTION_PUBLISHED, self.close_connection)
class Client(ShowBase): # notify notify = directNotify.newCategory("lp") # network cManager = QueuedConnectionManager() cListener = QueuedConnectionListener(cManager, 0) cReader = QueuedConnectionReader(cManager, 0) cWriter = ConnectionWriter(cManager, 0) def __init__(self): ShowBase.__init__(self) ShowBase.set_background_color(self, 0.08, 0.08, 0.08, 1) render.setAntialias(AntialiasAttrib.MAuto) self.disableMouse() # create father self.father = Father(self.cWriter, self.cManager, self.cReader) # create messager self.messager = Messager(self.father) # inputs self.accept('escape', self.debug) # try to connect self.connect() def debug(self): # testing_alert = Alert(-1) self.father.set_active_level(NIGHT) def connect(self): port_address = SERVER_PORT ip_address = SERVER_IP timeout = 3000 my_connection = self.cManager.openTCPClientConnection( ip_address, port_address, timeout) if my_connection: self.notify.info("Connected") self.father.set_connection(my_connection) self.cReader.addConnection(my_connection) # tasks taskMgr.add(self.messager.check_for_message, "Poll the connection reader", -39) taskMgr.doMethodLater(HEARTBEAT_PLAYER, self.messager.heartbeat, "Send heartbeat") else: Alert(-2) self.father.failed_to_connect() self.notify.warning("Could not connect!")
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 init(self, port=2000, server="127.0.0.1", serverPort=1999, backlog=1000, compress=False): self.packetCount = 0 self.port = port self.serverPort = serverPort self.serverIP = server self.serverAddress = NetAddress() self.serverAddress.setHost(server, serverPort) self.cManager = QueuedConnectionManager() self.cReader = QueuedConnectionReader(self.cManager, 0) self.cWriter = ConnectionWriter(self.cManager, 0) self.udpSocket = self.cManager.openUDPConnection(self.port) self.cReader.addConnection(self.udpSocket)
def SetupCommunication(self): cManager = QueuedConnectionManager() cListener = QueuedConnectionListener(cManager, 0) cReader = QueuedConnectionReader(cManager, 0) self.activeConnections = [] # We'll want to keep track of these later port_address = 9098 # No-other TCP/IP services are using this port backlog = 1000 # If we ignore 1,000 connection attempts, something is wrong! tcpSocket = cManager.openTCPServerRendezvous(port_address, backlog) cListener.addConnection(tcpSocket) def tskListenerPolling(taskdata): if cListener.newConnectionAvailable(): rendezvous = PointerToConnection() netAddress = NetAddress() newConnection = PointerToConnection() if cListener.getNewConnection(rendezvous, netAddress, newConnection): newConnection = newConnection.p() self.activeConnections.append( newConnection) # Remember connection 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): self.myProcessDataFunction(datagram) return Task.cont self.taskMgr.add(tskReaderPolling, "Poll the connection reader", -40) self.taskMgr.add(tskListenerPolling, "Poll the connection listener", -39)
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 init(self, port=1999, backlog=1000, compress=False): log.debug("Initing Network System") self.accept("broadcastData", self.broadcastData) self.port = port self.backlog = backlog self.compress = compress self.cManager = QueuedConnectionManager() self.cReader = QueuedConnectionReader(self.cManager, 0) #self.cReader.setRawMode(True) self.cWriter = ConnectionWriter(self.cManager, 0) self.udpSocket = self.cManager.openUDPConnection(self.port) self.cReader.addConnection(self.udpSocket) self.activePlayers = [] # PlayerComponent self.activeConnections = {} # {NetAddress : PlayerComponent} self.lastAck = {} # {NetAddress: time} self.startPolling() self.accept("shipGenerated", self.shipGenerated)
def __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()
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')
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 TCP(): def __init__(self, _core): print ("TCP Protocol Startup...") self.core = _core self.config = self.core.server.config def start(self): self.setupTCP() self.startTCPTasks() def setupTCP(self): self.tcpManager = QueuedConnectionManager() self.tcpReader = QueuedConnectionReader(self.tcpManager, 0) self.tcpWriter = ConnectionWriter(self.tcpManager, 0) self.tcpListener = QueuedConnectionListener(self.tcpManager, 0) self.tcpSocket = self.tcpManager.openTCPServerRendezvous(self.config.TCPPORT, self.config.BACKLOG) self.tcpListener.addConnection(self.tcpSocket) print ("Started Server on: ", self.config.HOSTNAME, self.config.TCPPORT) def startTCPTasks(self): taskMgr.add(self.tcpListenerTask, "tcpListenerTask", 0) print ("TCP Listener Started") taskMgr.add(self.tcpReaderTask, "tcpReaderTask", -10) print ("TCP Reader Started") taskMgr.add(self.tcpDisconnectionHandler, "tcpDisconnectionHandler", 20) print ("TCP Disconnection Handler Started") # TCP Listener Task def tcpListenerTask(self, task): """ Accept new incoming connection from clients, related to TCP """ # Handle new connection if self.tcpListener.newConnectionAvailable(): rendezvous = PointerToConnection() netAddress = NetAddress() newConnection = PointerToConnection() if self.tcpListener.getNewConnection(rendezvous, netAddress, newConnection): newConnection = newConnection.p() # Tell the reader about the new TCP connection self.tcpReader.addConnection(newConnection) # Handle the connection depending on persistent or not if self.core.server.isPersistent: self.core.handleConnection(generateUUID(), newConnection, netAddress) else: self.core.createPlayerObject(generateUUID(),newConnection, netAddress) print ("Server: New Connection from -", str(netAddress.getIpString())) else: print ("Server: Connection Failed from -", str(netAddress.getIpString())) return Task.cont def tcpReaderTask(self, task): """ Handle any data from clients by sending it to the Handlers. """ while 1: (datagram, data, opcode) = self.tcpNonBlockingRead(self.tcpReader) if opcode is MSG_NONE: # Do nothing or use it as some 'keep_alive' thing. break else: # Handle it self.core.packetManager.handlePacket(opcode, data, datagram.getAddress()) return Task.cont # TCP NonBlockingRead?? def tcpNonBlockingRead(self, qcr): """ Return a datagram collection and type if data is available on the queued connection udpReader """ if self.tcpReader.dataAvailable(): datagram = NetDatagram() if self.tcpReader.getData(datagram): data = DatagramIterator(datagram) opcode = data.getUint8() else: data = None opcode = MSG_NONE else: datagram = None data = None opcode = MSG_NONE # Return the datagram to keep a handle on the data return (datagram, data, opcode) # TCP Disconnection Handler def tcpDisconnectionHandler(self, task): # Check for resets if self.tcpManager.resetConnectionAvailable(): resetConnection = PointerToConnection() self.tcpManager.getResetConnection(resetConnection) for client in self.core.server.clients: if self.core.server.clients[client].connection == resetConnection.p(): del self.core.server.clients[client] self.tcpReader.removeConnection(resetConnection.p()) print ("Removed Connection:", resetConnection.p()) print ('Current Clients:', self.core.server.clients) break return Task.cont def sendPacket(self, _pkt, _connection): self.tcpWriter.send(_pkt, _connection) def sendBroadcast(self, _pkt, _skipif=None): for client in self.serverManager.clients: if _skipif == client: pass else: conn = self.serverManager.clients[client].connection self.tcpWriter.send(_pkt, conn)
class ConnectionManager: def __init__(self, main): #self.world = world self.cManager = QueuedConnectionManager() self.cListener = QueuedConnectionListener(self.cManager, 0) self.cReader = QueuedConnectionReader(self.cManager, 0) self.cWriter = ConnectionWriter(self.cManager, 0) self.main = main self.rqTable = ServerRequestTable() self.rsTable = ServerResponseTable() self.connection = None def startConnection(self): """Create a connection with the remote host. If a connection can be created, create a task with a sort value of -39 to read packets from the socket. """ try: if self.connection == None: self.connection = self.cManager.openTCPClientConnection(Constants.SERVER_IP, Constants.SERVER_PORT, 1000) if self.connection: self.cReader.addConnection(self.connection) taskMgr.add(self.updateRoutine, 'updateRoutine-Connection', -39) taskMgr.doMethodLater(5, self.checkConnection, 'checkConnection') return True except: pass return False def closeConnection(self): """Close the current connection with the remote host. If an existing connection is found, remove both the Main task, which is responsible for the heartbeat, and the Connection task, which is responsible for reading packets from the socket, then properly close the existing connection. """ if self.connection != None: taskMgr.remove('updateRoutine-Main') taskMgr.remove('updateRoutine-Connection') taskMgr.remove('checkConnection') self.cManager.closeConnection(self.connection) self.connection = None def sendRequest(self, requestCode, args = {}): """Prepare a request packet to be sent. If the following request code exists, create an instance of this specific request using any extra arguments, then properly send it to the remote host. """ if self.connection != None: request = self.rqTable.get(requestCode) if request != None: request.set(self.cWriter, self.connection) #print('requestCode:'+str(requestCode)) #print('args:'+str(args)) request.send(args) def handleResponse(self, responseCode, data): """Prepare a response packet to be processed. If the following response code exists, create an instance of this specific response using its data to be executed. """ response = self.rsTable.get(responseCode) if response != None: response.set(self.main) response.execute(data) def checkConnection(self, task): if not self.cReader.isConnectionOk(self.connection): self.closeConnection() #self.showDisconnected(0) return task.done return task.again def updateRoutine(self, task): """A once-per-frame task used to read packets from the socket.""" while self.cReader.dataAvailable(): # Create a datagram to store all necessary data. datagram = NetDatagram() # Retrieve the contents of the datagram. if self.cReader.getData(datagram): # Prepare the datagram to be iterated. data = PyDatagramIterator(datagram) # Retrieve a "short" that contains the response code. responseCode = data.getUint16() # Pass into another method to execute the response. if responseCode != Constants.MSG_NONE: self.handleResponse(responseCode, data) return task.cont
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 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 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()
def setupTCP(self): self.tcpManager = QueuedConnectionManager() self.tcpReader = QueuedConnectionReader(self.tcpManager, 0) self.tcpWriter = ConnectionWriter(self.tcpManager, 0)
from panda3d.core import QueuedConnectionManager, QueuedConnectionListener, QueuedConnectionReader, ConnectionWriter, PointerToConnection, NetAddress, NetDatagram from direct.distributed.PyDatagram import PyDatagram import protocol port_address=9099 # same for client and server ip_address="127.0.0.1" packetCount = 0 cManager = QueuedConnectionManager() cReader = QueuedConnectionReader(cManager, 0) cWriter = ConnectionWriter(cManager,0) myConnection=cManager.openUDPConnection() myPyDatagram = PyDatagram() myPyDatagram.addUint8(protocol.LOGIN) myPyDatagram.addUint8(packetCount) myPyDatagram.addUint8(0) myPyDatagram.addUint16(0) myPyDatagram.addUint16(0) myPyDatagram.addString("HUser name") myPyDatagram.addString("Hashed password") serverAddress = NetAddress() serverAddress.setHost(ip_address, port_address) cWriter.send(myPyDatagram, myConnection, serverAddress) print "Sending packet"
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 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
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()
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 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