from direct.distributed.ClientRepository import ClientRepository from panda3d.core import URLSpec, ConfigVariableInt, ConfigVariableString from message import Message class GameClientRepository(ClientRepository): def __init__(self): dcFileNames = ['../direct.dc', 'sample.dc'] ClientRepository.__init__( self, dcFileNames = dcFileNames, threadedNet = True) # Set the same port as configured on the server to be able to connect # to it tcpPort = ConfigVariableInt('server-port', 4400).getValue() # Set the IP or hostname of the server we want to connect to hostname = ConfigVariableString('server-host', '127.0.0.1').getValue() # Build the URL from the server hostname and port. If your server # uses another protocol then http you should change it accordingly. # Make sure to pass the connectMethod to the ClientRepository.__init__ # call too. Available connection methods are: # self.CM_HTTP, self.CM_NET and self.CM_NATIVE self.url = URLSpec('http://{}:{}'.format(hostname, tcpPort)) # Attempt a connection to the server self.connect([self.url], successCallback = self.connectSuccess, failureCallback = self.connectFailure) def lostConnection(self): ''' This should be overridden by a derived class to handle an unexpectedly lost connection to the gameserver. ''' # Handle the disconnection from the server. This can be a reconnect, # simply exiting the application or anything else. exit() def connectFailure(self, statusCode, statusString): ''' Something went wrong ''' # we could create a reconnect task to try and connect again. exit() def connectSuccess(self): ''' Successfully connected. But we still can't really do anything until we've got the doID range. ''' # Make sure we have interest in the by the AIRepository defined # TimeManager zone, so we always see it even if we switch to # another zone. self.setInterestZones([1]) # We must wait for the TimeManager to be fully created and # synced before we can enter another zone and wait for the # game object. The uniqueName is important that we get the # correct, our sync message from the TimeManager and not # accidentaly a message from another client self.acceptOnce(self.uniqueName('gotTimeSync'), self.syncReady) def syncReady(self): ''' Now we've got the TimeManager manifested, and we're in sync with the server time. Now we can enter the world. Check to see if we've received our doIdBase yet. ''' # This method checks whether we actually have a valid doID range # to create distributed objects yet if self.haveCreateAuthority(): # we already have one self.gotCreateReady() else: # Not yet, keep waiting a bit longer. self.accept(self.uniqueName('createReady'), self.gotCreateReady) def gotCreateReady(self): ''' Ready to enter the world. Expand our interest to include any other zones ''' # This method checks whether we actually have a valid doID range # to create distributed objects yet if not self.haveCreateAuthority(): # Not ready yet. return # we are ready now, so ignore further createReady events self.ignore(self.uniqueName('createReady')) # create a instance of the message class msg = Message(self) # and create the distributed Object with it self.createDistributedObject( distObj = msg, zoneId = 1) # save the created Distributed Object # in self.msg for later usage self.msg = msg def sendMessage(self, msgText): '''Function to call the send function of the message class, which sends the Message over the Network to the other users''' sentText = "{}: {}".format(self.doIdBase, msgText) self.msg.b_sendText(sentText)