def sendActivate(self, doId, parentId, zoneId, dclass=None, fields=None):
        """
        Activate a DBSS object, given its doId, into the specified parentId/zoneId.

        If both dclass and fields are specified, an ACTIVATE_WITH_DEFAULTS_OTHER
        will be sent instead. In other words, the specified fields will be
        auto-applied during the activation.
        """

        fieldPacker = DCPacker()
        fieldCount = 0
        if dclass and fields:
            for k, v in fields.items():
                field = dclass.getFieldByName(k)
                if not field:
                    self.notify.error(
                        'Activation request for %s object contains '
                        'invalid field named %s' % (dclass.getName(), k))

                fieldPacker.rawPackUint16(field.getNumber())
                fieldPacker.beginPack(field)
                field.packArgs(fieldPacker, v)
                fieldPacker.endPack()
                fieldCount += 1

            dg = PyDatagram()
            dg.addServerHeader(doId, self.ourChannel,
                               DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS)
            dg.addUint32(doId)
            dg.addUint32(0)
            dg.addUint32(0)
            self.send(dg)
            # DEFAULTS_OTHER isn't implemented yet, so we chase it with a SET_FIELDS
            dg = PyDatagram()
            dg.addServerHeader(doId, self.ourChannel,
                               STATESERVER_OBJECT_SET_FIELDS)
            dg.addUint32(doId)
            dg.addUint16(fieldCount)
            dg.appendData(fieldPacker.getString())
            self.send(dg)
            # Now slide it into the zone we expect to see it in (so it
            # generates onto us with all of the fields in place)
            dg = PyDatagram()
            dg.addServerHeader(doId, self.ourChannel,
                               STATESERVER_OBJECT_SET_LOCATION)
            dg.addUint32(parentId)
            dg.addUint32(zoneId)
            self.send(dg)
        else:
            dg = PyDatagram()
            dg.addServerHeader(doId, self.ourChannel,
                               DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS)
            dg.addUint32(doId)
            dg.addUint32(parentId)
            dg.addUint32(zoneId)
            self.send(dg)
 def sendSetLocation(self, do, parentId, zoneId):
     dg = PyDatagram()
     dg.addServerHeader(do.doId, self.ourChannel,
                        STATESERVER_OBJECT_SET_LOCATION)
     dg.addUint32(parentId)
     dg.addUint32(zoneId)
     self.send(dg)
Ejemplo n.º 3
0
 def _sendRemoveInterest(self, handle, contextId):
     datagram = PyDatagram()
     datagram.addUint16(CLIENT_REMOVE_INTEREST)
     datagram.addUint16(handle)
     if contextId != 0:
         datagram.addUint32(contextId)
     self.send(datagram)
Ejemplo n.º 4
0
    def _sendAddInterest(self, contextId, scopeId, parentId, zoneIdList):
        """
        Part of the new otp-server code.

        contextId is a client-side created number that refers to
                a set of interests.  The same contextId number doesn't
                necessarily have any relationship to the same contextId
                on another client.
        """
        assert self.notify.debugCall()
        datagram = PyDatagram()
        # Add message type
        datagram.addUint16(CLIENT_ADD_INTEREST)
        datagram.addUint16(contextId)
        datagram.addUint32(scopeId)
        datagram.addUint32(parentId)
        if isinstance(zoneIdList, types.ListType):
            vzl = list(zoneIdList)
            vzl.sort()
            PythonUtil.uniqueElements(vzl)
            for zone in vzl:
                datagram.addUint32(zone)
        else:
            datagram.addUint32(zoneIdList)
        self.send(datagram)
Ejemplo n.º 5
0
 def sendSetLocation(self, doId, parentId, zoneId):
     datagram = PyDatagram()
     datagram.addUint16(CLIENT_OBJECT_LOCATION)
     datagram.addUint32(doId)
     datagram.addUint32(parentId)
     datagram.addUint32(zoneId)
     self.send(datagram)
    def writeServerEvent(self, logtype, *args, **kwargs):
        """
        Write an event to the central Event Logger, if one is configured.

        The purpose of the Event Logger is to keep a game-wide record of all
        interesting in-game events that take place. Therefore, this function
        should be used whenever such an interesting in-game event occurs.
        """

        if self.eventSocket is None:
            return  # No event logger configured!

        log = collections.OrderedDict()
        log['type'] = logtype
        log['sender'] = self.eventLogId

        for i, v in enumerate(args):
            # +1 because the logtype was _0, so we start at _1
            log['_%d' % (i + 1)] = v

        log.update(kwargs)

        dg = PyDatagram()
        msgpack_encode(dg, log)
        self.eventSocket.Send(dg.getMessage())
Ejemplo n.º 7
0
    def _sendAddInterest(self,
                         handle,
                         contextId,
                         parentId,
                         zoneIdList,
                         description,
                         action=None):
        if parentId == 0:
            DoInterestManager.notify.error(
                'trying to set interest to invalid parent: %s' % parentId)
        datagram = PyDatagram()
        datagram.addUint16(CLIENT_ADD_INTEREST)
        datagram.addUint16(handle)
        datagram.addUint32(contextId)
        datagram.addUint32(parentId)
        if isinstance(zoneIdList, types.ListType):
            vzl = list(zoneIdList)
            vzl.sort()
            uniqueElements(vzl)
            for zone in vzl:
                datagram.addUint32(zone)

        else:
            datagram.addUint32(zoneIdList)
        self.send(datagram)
Ejemplo n.º 8
0
    def setInterestZones(self, interestZoneIds):
        datagram = PyDatagram()
        datagram.addUint16(CLIENT_SET_INTEREST_CMU)
        for zoneId in interestZoneIds:
            datagram.addUint32(zoneId)

        self.send(datagram)
        self.interestZones = interestZoneIds[:]
Ejemplo n.º 9
0
 def sendDisconnect(self):
     if self.isConnected():
         datagram = PyDatagram()
         datagram.addUint16(CLIENT_DISCONNECT_CMU)
         self.send(datagram)
         self.notify.info('Sent disconnect message to server')
         self.disconnect()
     self.stopHeartbeat()
Ejemplo n.º 10
0
    def sendDeleteMsg(self, doId):
        # This method is only used in conjunction with the CMU LAN
        # server.

        datagram = PyDatagram()
        datagram.addUint16(CLIENT_OBJECT_DELETE)
        datagram.addUint32(doId)
        self.send(datagram)
Ejemplo n.º 11
0
 def sendSetShardMsg(self, shardId):
     datagram = PyDatagram()
     # Add message type
     datagram.addUint16(CLIENT_SET_SHARD)
     # Add shard id
     datagram.addUint32(shardId)
     # send the message
     self.send(datagram)
    def getActivated(self, doId, callback):
        ctx = self.getContext()
        self.__callbacks[ctx] = callback

        dg = PyDatagram()
        dg.addServerHeader(doId, self.ourChannel, DBSS_OBJECT_GET_ACTIVATED)
        dg.addUint32(ctx)
        dg.addUint32(doId)
        self.send(dg)
Ejemplo n.º 13
0
 def sendUpdateToChannel(self, distObj, channelId, fieldName, args):
     datagram = distObj.dclass.clientFormatUpdate(fieldName, distObj.doId, args)
     dgi = PyDatagramIterator(datagram)
     dgi.getUint16()
     dg = PyDatagram()
     dg.addUint16(CLIENT_OBJECT_UPDATE_FIELD_TARGETED_CMU)
     dg.addUint32(channelId & 4294967295L)
     dg.appendData(dgi.getRemainingBytes())
     self.send(dg)
Ejemplo n.º 14
0
 def sendHeartbeat(self):
     datagram = PyDatagram()
     # Add message type
     datagram.addUint16(CLIENT_HEARTBEAT)
     # Send it!
     self.send(datagram)
     self.lastHeartbeat = globalClock.getRealTime()
     # This is important enough to consider flushing immediately
     # (particularly if we haven't run readerPollTask recently).
     self.considerFlush()
    def setAI(self, doId, aiChannel):
        """
        Sets the AI of the specified DistributedObjectAI to be the specified channel.
        Generally, you should not call this method, and instead call DistributedObjectAI.setAI.
        """

        dg = PyDatagram()
        dg.addServerHeader(doId, aiChannel, STATESERVER_OBJECT_SET_AI)
        dg.add_uint64(aiChannel)
        self.send(dg)
Ejemplo n.º 16
0
 def _sendRemoveAIInterest(self, handle):
     """
     handle is a bare int, NOT an InterestHandle.  Use this to
     close an AI opened interest.
     """
     datagram = PyDatagram()
     # Add message type
     datagram.addUint16(CLIENT_REMOVE_INTEREST)
     datagram.addUint16((1<<15) + handle)
     self.send(datagram)
    def eject(self, clientChannel, reasonCode, reason):
        """
        Kicks the client residing at the specified clientChannel, using the specifed reasoning.
        """

        dg = PyDatagram()
        dg.addServerHeader(clientChannel, self.ourChannel, CLIENTAGENT_EJECT)
        dg.add_uint16(reasonCode)
        dg.addString(reason)
        self.send(dg)
    def setOwner(self, doId, newOwner):
        """
        Sets the owner of a DistributedObject. This will enable the new owner to send "ownsend" fields,
        and will generate an OwnerView.
        """

        dg = PyDatagram()
        dg.addServerHeader(doId, self.ourChannel, STATESERVER_OBJECT_SET_OWNER)
        dg.add_uint64(newOwner)
        self.send(dg)
Ejemplo n.º 19
0
 def sendDisconnect(self):
     if self.isConnected():
         # Tell the game server that we're going:
         datagram = PyDatagram()
         # Add message type
         datagram.addUint16(CLIENT_DISCONNECT)
         # Send the message
         self.send(datagram)
         self.notify.info("Sent disconnect message to server")
         self.disconnect()
     self.stopHeartbeat()
    def setClientState(self, clientChannel, state):
        """
        Sets the state of the client on the CA.
        Useful for logging in and logging out, and for little else.
        """

        dg = PyDatagram()
        dg.addServerHeader(clientChannel, self.ourChannel,
                           CLIENTAGENT_SET_STATE)
        dg.add_uint16(state)
        self.send(dg)
Ejemplo n.º 21
0
    def clearPostRemove(self):
        """
        Clear all datagrams registered with addPostRemove.

        This is useful if the Panda3D process is performing a clean exit. It may
        clear the "emergency clean-up" post-remove messages and perform a normal
        exit-time clean-up instead, depending on the specific design of the game.
        """

        dg = PyDatagram()
        dg.addServerControlHeader(CONTROL_CLEAR_POST_REMOVE)
        self.send(dg)
Ejemplo n.º 22
0
    def requestDelete(self, do):
        """
        Request the deletion of an object that already exists on the State Server.

        You should probably use do.requestDelete() instead.
        """

        dg = PyDatagram()
        dg.addServerHeader(do.doId, self.ourChannel,
                           STATESERVER_OBJECT_DELETE_RAM)
        dg.addUint32(do.doId)
        self.send(dg)
    def clientAddSessionObject(self, clientChannel, doId):
        """
        Declares the specified DistributedObject to be a "session object",
        meaning that it is destroyed when the client disconnects.
        Generally used for avatars owned by the client.
        """

        dg = PyDatagram()
        dg.addServerHeader(clientChannel, self.ourChannel,
                           CLIENTAGENT_ADD_SESSION_OBJECT)
        dg.add_uint32(doId)
        self.send(dg)
Ejemplo n.º 24
0
 def _sendRemoveInterest(self, contextId):
     """
     contextId is a client-side created number that refers to
             a set of interests.  The same contextId number doesn't
             necessarily have any relationship to the same contextId
             on another client.
     """
     assert self.notify.debugCall()
     datagram = PyDatagram()
     # Add message type
     datagram.addUint16(CLIENT_REMOVE_INTEREST)
     datagram.addUint16(contextId)
     self.send(datagram)
Ejemplo n.º 25
0
 def __getBarrierData(self):
     # Returns the barrier data formatted as a blob for sending to
     # the clients.  This lists all of the current outstanding
     # barriers and the avIds waiting for them.
     dg = PyDatagram()
     for context, barrier in self.__barriers.items():
         toons = barrier.pendingToons
         if toons:
             dg.addUint16(context)
             dg.addUint16(len(toons))
             for avId in toons:
                 dg.addUint32(avId)
     return dg.getMessage()
    def requestDelete(self, do):
        """
        Request the deletion of an object that already exists on the State Server.

        You should use do.requestDelete() instead. This is not meant to be
        called directly unless you really know what you are doing.
        """

        dg = PyDatagram()
        dg.addServerHeader(do.doId, self.ourChannel,
                           STATESERVER_OBJECT_DELETE_RAM)
        dg.addUint32(do.doId)
        self.send(dg)
Ejemplo n.º 27
0
    def addPostRemove(self, dg):
        """
        Register a datagram with the Message Director that gets sent out if the
        connection is ever lost.

        This is useful for registering cleanup messages: If the Panda3D process
        ever crashes unexpectedly, the Message Director will detect the socket
        close and automatically process any post-remove datagrams.
        """

        dg2 = PyDatagram()
        dg2.addServerControlHeader(CONTROL_ADD_POST_REMOVE)
        dg2.addString(dg.getMessage())
        self.send(dg2)
Ejemplo n.º 28
0
    def setInterestZones(self, interestZoneIds):
        """ Changes the set of zones that this particular client is
        interested in hearing about. """

        datagram = PyDatagram()
        # Add message type
        datagram.addUint16(CLIENT_SET_INTEREST_CMU)

        for zoneId in interestZoneIds:
            datagram.addUint32(zoneId)

        # send the message
        self.send(datagram)
        self.interestZones = interestZoneIds[:]
    def clientAddInterest(self, clientChannel, interestId, parentId, zoneId):
        """
        Opens an interest on the behalf of the client. This, used in conjunction
        with add_interest: visible (or preferably, disabled altogether), will mitigate
        possible security risks.
        """

        dg = PyDatagram()
        dg.addServerHeader(clientChannel, self.ourChannel,
                           CLIENTAGENT_ADD_INTEREST)
        dg.add_uint16(interestId)
        dg.add_uint32(parentId)
        dg.add_uint32(zoneId)
        self.send(dg)
    def unregisterForChannel(self, channel):
        """
        Unregister a channel subscription on the Message Director. The Message
        Director will cease to relay messages to this AIR sent on the channel.
        """

        if channel not in self._registeredChannels:
            return
        self._registeredChannels.remove(channel)

        dg = PyDatagram()
        dg.addServerControlHeader(CONTROL_REMOVE_CHANNEL)
        dg.addChannel(channel)
        self.send(dg)