Esempio n. 1
0
 def delete(self):
     if __dev__:
         del self._sentExitServerEvent
     self._doPlayerExit()
     ClsendTracker.destroy(self)
     if __dev__:
         GarbageReport.checkForGarbageLeaks()
     DistributedAvatarAI.DistributedAvatarAI.delete(self)
 def delete(self):
     if __dev__:
         del self._sentExitServerEvent
     self._doPlayerExit()
     ClsendTracker.destroy(self)
     if __dev__:
         GarbageReport.checkForGarbageLeaks()
     DistributedAvatarAI.DistributedAvatarAI.delete(self)
Esempio n. 3
0
 def delete(self):
     if __dev__:
         # make sure _sendExitServerEvent() was called
         assert self._sentExitServerEvent
         del self._sentExitServerEvent
     self._doPlayerExit()
     if __dev__:
         GarbageReport.checkForGarbageLeaks()
     DistributedAvatarAI.DistributedAvatarAI.delete(self)
Esempio n. 4
0
 def handleDetectGarbageHotkey(self):
     self._numClientGarbage = GarbageReport.b_checkForGarbageLeaks(wantReply=True)
     if self._numClientGarbage:
         s = '%s client garbage cycles found, see log' % self._numClientGarbage
     else:
         s = '0 client garbage cycles found'
     localAvatar.setChatAbsolute(s, CFSpeech | CFTimeout)
Esempio n. 5
0
 def handleDetectGarbageHotkey(self):
     self._numClientGarbage = GarbageReport.b_checkForGarbageLeaks(wantReply = True)
     if self._numClientGarbage:
         s = '%s client garbage cycles found, see log' % self._numClientGarbage
     else:
         s = '0 client garbage cycles found'
     localAvatar.setChatAbsolute(s, CFSpeech | CFTimeout)
Esempio n. 6
0
 def __init__(self, name, log=True):
     gr = GarbageReport.GarbageReport("ObjectReport's GarbageReport: %s" % name, log=log)
     gr.destroy()
     del gr
     self._name = name
     self._pool = ObjectPool.ObjectPool(self._getObjectList())
     if log:
         self.notify.info("===== ObjectReport: '%s' =====\n%s" % (self._name, self.typeFreqStr()))
Esempio n. 7
0
 def __init__(self, name, log=True):
     gr = GarbageReport.GarbageReport('ObjectReport\'s GarbageReport: %s' % name, log=log)
     gr.destroy()
     del gr
     self._name = name
     self._pool = ObjectPool.ObjectPool(self._getObjectList())
     #ExclusiveObjectPool.addExclObjs(self, self._pool, self._name)
     if log:
         self.notify.info('===== ObjectReport: \'%s\' =====\n%s' % (self._name, self.typeFreqStr()))
Esempio n. 8
0
 def _adjustGcThreshold(self, task):
     numGarbage = GarbageReport.checkForGarbageLeaks()
     if numGarbage == 0:
         self.gcNotify.debug('no garbage found, doubling gc threshold')
         a, b, c = gc.get_threshold()
         gc.set_threshold(min(a * 2, 1 << 30), b, c)
         task.delayTime = task.delayTime * 2
         retVal = Task.again
     else:
         self.gcNotify.warning('garbage found, reverting gc threshold')
         gc.set_threshold(*self._gcDefaultThreshold)
         retVal = Task.done
     return retVal
Esempio n. 9
0
 def checkForGarbageLeaks(self, wantReply):
     senderId = self.air.getAvatarIdFromSender()
     self.notify.info("checking for garbage leaks requested by %s" %
                      senderId)
     # okay checking for garbage leaks should only be done by devs, it's rare enough i'll flag it
     # as suspicious
     self.air.writeServerEvent('suspicious', senderId,
                               'checkForGarbageLeaks')
     numLeaks = GarbageReport.checkForGarbageLeaks()
     if wantReply:
         requesterId = self.air.getAvatarIdFromSender()
         self.sendUpdateToAvatarId(requesterId, 'setNumAIGarbageLeaks',
                                   [numLeaks])
Esempio n. 10
0
 def _adjustGcThreshold(self, task):
     # do an unconditional collect to make sure gc.garbage has a chance to be
     # populated before we start increasing the auto-collect threshold
     # don't distribute the leak check from the client to the AI, they both
     # do these garbage checks independently over time
     numGarbage = GarbageReport.checkForGarbageLeaks()
     if numGarbage == 0:
         self.gcNotify.debug('no garbage found, doubling gc threshold')
         a, b, c = gc.get_threshold()
         gc.set_threshold(min(a * 2, 1 << 30), b, c)
         task.delayTime = task.delayTime * 2
         retVal = Task.again
     else:
         self.gcNotify.warning('garbage found, reverting gc threshold')
         # the process is producing garbage, stick to the default collection threshold
         gc.set_threshold(*self._gcDefaultThreshold)
         retVal = Task.done
     return retVal
Esempio n. 11
0
    def _adjustGcThreshold(self, task):
        # do an unconditional collect to make sure gc.garbage has a chance to be
        # populated before we start increasing the auto-collect threshold
        # don't distribute the leak check from the client to the AI, they both
        # do these garbage checks independently over time
        numGarbage = GarbageReport.checkForGarbageLeaks()
        if numGarbage == 0:
            self.gcNotify.debug('no garbage found, doubling gc threshold')
            a, b, c = gc.get_threshold()
            gc.set_threshold(min(a * 2, 1 << 30), b, c)

            task.delayTime = task.delayTime * 2
            retVal = Task.again

        else:
            self.gcNotify.warning('garbage found, reverting gc threshold')
            # the process is producing garbage, stick to the default collection threshold
            gc.set_threshold(*self._gcDefaultThreshold)
            retVal = Task.done

        return retVal
    def doMagicWord(self, word, av, zoneId, senderId):
        wordIs = self.getWordIs(word)

        if wordIs("~rename"):
            if (not self.supportRename):
                self.notify.warning(
                    "Rename is not supported for %s, requested by %d" %
                    (av.name, senderId))
            else:
                name = string.strip(word[8:])
                if name == "":
                    response = "No name."
                else:
                    av.d_setName(name)

        elif wordIs("~badname"):
            self.notify.warning(
                "Renaming inappropriately named toon %s (doId %d)." %
                (av.name, av.doId))
            name = "toon%d" % (av.doId % 1000000)
            av.d_setName(name)

        elif wordIs("~chat"):
            if (not self.supportSuperchat) and (senderId != av.doId):
                self.notify.warning(
                    "Super chat is not supported for %s, requested by %d" %
                    (av.name, senderId))
            else:
                av.d_setCommonChatFlags(OTPGlobals.CommonChat)
                self.notify.debug("Giving common chat permission to " +
                                  av.name)
        elif wordIs("~superchat"):
            if not self.supportSuperchat:
                self.notify.warning("Super chat is not supported for " +
                                    av.name)
            else:
                av.d_setCommonChatFlags(OTPGlobals.SuperChat)
                self.notify.debug("Giving super chat permission to " + av.name)
        elif wordIs("~nochat"):
            av.d_setCommonChatFlags(0)
            self.notify.debug("Removing special chat permissions for " +
                              av.name)

        elif wordIs("~listen"):
            if (not self.supportSuperchat) and (senderId != av.doId):
                self.notify.warning(
                    "Listen is not supported for %s, requested by %d" %
                    (av.name, senderId))
            else:
                # This is a client-side word.
                if (senderId != av.doId):
                    self.sendUpdateToAvatarId(av.doId, 'setMagicWord',
                                              [word, av.doId, zoneId])

        elif wordIs("~fix"):
            anyChanged = av.fixAvatar()
            if anyChanged:
                response = "avatar fixed."
            else:
                response = "avatar does not need fixing."
            self.down_setMagicWordResponse(senderId, response)

            self.down_setMagicWordResponse(senderId, response)

        elif wordIs("~who all"):
            str = ''
            for obj in list(self.air.doId2do.values()):
                if hasattr(obj, "accountName"):
                    str += '%s %s\n' % (obj.accountName, obj.name)
            if not str:
                str = "No avatars."
            self.down_setMagicWordResponse(senderId, str)

        elif wordIs("~ouch"):
            if av.hp < 1:
                av.b_setHp(0)
                av.toonUp(1)
            else:
                av.b_setHp(1)
            self.notify.debug("Only 1 hp for " + av.name)
        elif wordIs("~sad"):
            av.b_setHp(0)
            self.notify.debug("Only 0 hp for " + av.name)
        elif wordIs("~dead"):
            av.takeDamage(av.hp)
            self.notify.debug(av.name + " is dead")
        elif wordIs("~waydead"):
            av.takeDamage(av.hp)
            av.b_setHp(-100)
            self.notify.debug(av.name + " is way dead")
        elif wordIs("~toonup"):
            av.toonUp(av.maxHp)
            self.notify.debug("Full heal for " + av.name)
        elif wordIs('~hp'):
            args = word.split()
            hp = int(args[1])
            av.b_setHp(hp)
            self.notify.debug('Set hp to %s for %s' % (hp, av.name))

        elif wordIs("~ainotify"):
            args = word.split()
            n = Notify.ptr().getCategory(args[1])
            n.setSeverity({
                'error': NSError,
                'warning': NSWarning,
                'info': NSInfo,
                'debug': NSDebug,
                'spam': NSSpam,
            }[args[2]])

        elif wordIs("~ghost"):
            # Toggle ghost mode.  Ghost mode == 2 indicates a magic
            # word was the source.
            if av.ghostMode:
                av.b_setGhostMode(0)
            else:
                av.b_setGhostMode(2)

        elif wordIs('~immortal'):
            # ~immortal toggles immortal mode on and off
            # ~immortal 0/1 and ~immortal on/off sets the mode explicitly
            args = word.split()
            invalid = False
            if len(args) > 1 and args[1] in ('0', 'off'):
                immortal = False
            elif len(args) > 1 and args[1] in ('1', 'on'):
                immortal = True
            elif len(args) > 1:
                invalid = True
            else:
                immortal = not av.immortalMode

            if invalid:
                self.down_setMagicWordResponse(senderId,
                                               'unknown argument %s' % args[1])
            else:
                # immortality
                av.setImmortalMode(immortal)
                if av.immortalMode:
                    response = 'immortality ON'
                else:
                    response = 'immortality OFF'
                self.down_setMagicWordResponse(senderId, response)

        elif wordIs("~dna"):
            # Fiddle with your dna.
            self.doDna(word, av, zoneId, senderId)

        elif wordIs('~ai'):
            # Execute an arbitrary Python command on the AI.
            command = string.strip(word[3:])
            self.notify.warning("Executing command '%s' from %s" %
                                (command, senderId))
            text = self.__execMessage(
                command)[:simbase.config.GetInt("ai-debug-length", 300)]
            self.down_setMagicWordResponse(senderId, text)

        elif wordIs('~ud'):
            # Execute an arbitrary Python command on the ud.
            print(word)
            channel, command = re.match("~ud ([0-9]+) (.+)", word).groups()
            channel = int(channel)
            if (simbase.air.doId2do.get(channel)):
                self.notify.warning("Passing command '%s' to %s from %s" %
                                    (command, channel, senderId))

                try:
                    simbase.air.doId2do[channel].sendUpdate(
                        "execCommand", [command, self.doId, senderId, zoneId])
                except:
                    pass

        elif wordIs('~aiobjects'):
            args = word.split()
            from direct.showbase import ObjectReport
            report = ObjectReport.ObjectReport('AI ~objects')

            if 'all' in args:
                self.notify.info('printing full object set...')
                report.getObjectPool().printObjsByType(
                    printReferrers='ref' in args)

            if hasattr(self, 'baselineObjReport'):
                self.notify.info(
                    'calculating diff from baseline ObjectReport...')
                self.lastDiff = self.baselineObjReport.diff(report)
                self.lastDiff.printOut(full=('diff' in args or 'dif' in args))

            if 'baseline' in args or not hasattr(self, 'baselineObjReport'):
                self.notify.info('recording baseline ObjectReport...')
                if hasattr(self, 'baselineObjReport'):
                    self.baselineObjReport.destroy()
                self.baselineObjReport = report

            self.down_setMagicWordResponse(senderId, 'objects logged')

        elif wordIs('~aiobjecthg'):
            import gc
            objs = gc.get_objects()
            type2count = {}
            for obj in objs:
                tn = safeTypeName(obj)
                type2count.setdefault(tn, 0)
                type2count[tn] += 1
            count2type = invertDictLossless(type2count)
            counts = list(count2type.keys())
            counts.sort()
            counts.reverse()
            for count in counts:
                print('%s: %s' % (count, count2type[count]))
            self.down_setMagicWordResponse(senderId, '~aiobjecthg complete')

        elif wordIs('~aicrash'):
            # TODO: require a typed explanation in production
            # if we call notify.error directly, the magic word mgr will catch it
            # self.notify.error doesn't seem to work either
            DelayedCall(
                Functor(simbase.air.notify.error,
                        '~aicrash: simulating an AI crash'))

        elif wordIs('~aicontainers'):
            args = word.split()
            limit = 30
            if 'full' in args:
                limit = None
            ContainerReport.ContainerReport('~aicontainers',
                                            log=True,
                                            limit=limit,
                                            threaded=True)

        elif wordIs('~aigarbage'):
            args = word.split()
            # it can take a LOOONG time to print out the garbage referrers and referents
            # by reference (as opposed to by number)
            full = ('full' in args)
            safeMode = ('safe' in args)
            verbose = ('verbose' in args)
            delOnly = ('delonly' in args)

            def handleGarbageDone(senderId, garbageReport):
                self.down_setMagicWordResponse(
                    senderId, 'garbage logged, %s AI cycles' %
                    garbageReport.getNumCycles())

            # This does a garbage collection and dumps the list of leaked (uncollectable) objects to the AI log.
            GarbageReport.GarbageReport('~aigarbage',
                                        fullReport=full,
                                        verbose=verbose,
                                        log=True,
                                        threaded=True,
                                        doneCallback=Functor(
                                            handleGarbageDone, senderId),
                                        safeMode=safeMode,
                                        delOnly=delOnly)

        elif wordIs("~creategarbage"):
            args = word.split()
            num = 1
            if len(args) > 1:
                num = int(args[1])
            GarbageReport._createGarbage(num)
            self.down_setMagicWordResponse(senderId, 'leaked garbage created')

        elif wordIs('~leaktask'):

            def leakTask(task):
                return task.cont

            taskMgr.add(leakTask, uniqueName('leakedTask'))
            leakTask = None
            self.down_setMagicWordResponse(senderId, 'leaked task created')

        elif wordIs('~aileakmessage'):
            MessengerLeakDetector._leakMessengerObject()
            self.down_setMagicWordResponse(senderId,
                                           'messenger leak object created')

        elif wordIs('~leakContainer'):
            ContainerLeakDetector._createContainerLeak()
            self.down_setMagicWordResponse(senderId,
                                           'leak container task created')

        elif wordIs('~aipstats'):
            args = word.split()
            hostname = None
            port = None
            if len(args) > 1:
                hostname = args[1]
            if len(args) > 2:
                port = int(args[2])
            # make sure pstats is enabled
            simbase.wantStats = 1
            Task.TaskManager.pStatsTasks = 1
            result = simbase.createStats(hostname, port)
            connectionName = '%s' % hostname
            if port is not None:
                connectionName += ':%s' % port
            if result:
                response = 'connected AI pstats to %s' % connectionName
            else:
                response = 'could not connect AI pstats to %s' % connectionName
            self.down_setMagicWordResponse(senderId, response)

        elif wordIs('~aiprofile'):
            args = word.split()
            if len(args) > 1:
                num = int(args[1])
            else:
                num = 5
            session = taskMgr.getProfileSession('~aiprofile')
            session.setLogAfterProfile(True)
            taskMgr.profileFrames(num, session)
            self.down_setMagicWordResponse(senderId,
                                           'profiling %s AI frames...' % num)

        elif wordIs('~aiframeprofile'):
            args = word.split()
            wasOn = bool(taskMgr.getProfileFrames())
            if len(args) > 1:
                setting = bool(int(args[1]))
            else:
                setting = not wasOn
            taskMgr.setProfileFrames(setting)
            self.down_setMagicWordResponse(
                senderId, 'AI frame profiling %s%s' %
                (choice(setting, 'ON',
                        'OFF'), choice(wasOn == setting, ' already', '')))

        elif wordIs('~aitaskprofile'):
            args = word.split()
            wasOn = bool(taskMgr.getProfileTasks())
            if len(args) > 1:
                setting = bool(int(args[1]))
            else:
                setting = not wasOn
            taskMgr.setProfileTasks(setting)
            self.down_setMagicWordResponse(
                senderId, 'AI task profiling %s%s' %
                (choice(setting, 'ON',
                        'OFF'), choice(wasOn == setting, ' already', '')))

        elif wordIs('~aitaskspikethreshold'):
            from direct.task.TaskProfiler import TaskProfiler
            args = word.split()
            if len(args) > 1:
                threshold = float(args[1])
                response = 'AI task spike threshold set to %ss' % threshold
            else:
                threshold = TaskProfiler.GetDefaultSpikeThreshold()
                response = 'AI task spike threshold reset to %ss' % threshold
            TaskProfiler.SetSpikeThreshold(threshold)
            self.down_setMagicWordResponse(senderId, response)

        elif wordIs('~ailogtaskprofiles'):
            args = word.split()
            if len(args) > 1:
                name = args[1]
            else:
                name = None
            taskMgr.logTaskProfiles(name)
            response = 'logged AI task profiles%s' % choice(
                name, ' for %s' % name, '')
            self.down_setMagicWordResponse(senderId, response)

        elif wordIs('~aitaskprofileflush'):
            args = word.split()
            if len(args) > 1:
                name = args[1]
            else:
                name = None
            taskMgr.flushTaskProfiles(name)
            response = 'flushed AI task profiles%s' % choice(
                name, ' for %s' % name, '')
            self.down_setMagicWordResponse(senderId, response)

        elif wordIs('~aiobjectcount'):
            simbase.air.printObjectCount()
            self.down_setMagicWordResponse(
                senderId, 'logging AI distributed object count...')

        elif wordIs('~aitaskmgr'):
            print(taskMgr)
            self.down_setMagicWordResponse(senderId, 'logging AI taskMgr...')

        elif wordIs('~aijobmgr'):
            print(jobMgr)
            self.down_setMagicWordResponse(senderId, 'logging AI jobMgr...')

        elif wordIs('~aijobtime'):
            args = word.split()
            if len(args) > 1:
                time = float(args[1])
            else:
                time = None
            response = ''
            if time is None:
                time = jobMgr.getDefaultTimeslice()
                time = time * 1000.
                response = 'reset AI jobMgr timeslice to %s ms' % time
            else:
                response = 'set AI jobMgr timeslice to %s ms' % time
                time = time / 1000.
            jobMgr.setTimeslice(time)
            self.down_setMagicWordResponse(senderId, response)

        elif wordIs('~aidetectleaks'):
            started = self.air.startLeakDetector()
            self.down_setMagicWordResponse(
                senderId,
                choice(
                    started,
                    'AI leak detector started',
                    'AI leak detector already started',
                ))

        elif wordIs('~aitaskthreshold'):
            args = word.split()
            if len(args) > 1.:
                threshold = float(args[1])
            else:
                threshold = None
            response = ''
            if threshold is None:
                threshold = taskMgr.DefTaskDurationWarningThreshold
                response = 'reset AI task duration warning threshold to %s' % threshold
            else:
                response = 'set AI task duration warning threshold to %s' % threshold
            taskMgr.setTaskDurationWarningThreshold(threshold)
            self.down_setMagicWordResponse(senderId, response)

        elif wordIs('~aimessenger'):
            print(messenger)
            self.down_setMagicWordResponse(senderId, 'logging AI messenger...')

        elif wordIs('~requestdeleted'):
            requestDeletedDOs = self.air.getRequestDeletedDOs()
            response = '%s requestDeleted AI objects%s' % (
                len(requestDeletedDOs),
                choice(len(requestDeletedDOs), ', logging...', ''))
            s = '~requestDeleted: ['
            for do, age in requestDeletedDOs:
                s += '[%s, %s]' % (do.__class__.__name__, age)
            s += ']'
            self.notify.info(s)
            if len(requestDeletedDOs):
                response += '\noldest: %s, %s' % (
                    requestDeletedDOs[0][0].__class__.__name__,
                    formatTimeCompact(requestDeletedDOs[0][1]))
            self.down_setMagicWordResponse(senderId, response)

        elif wordIs('~aigptc'):
            args = word.split()
            if len(args) > 1. and hasattr(self.cr, 'leakDetector'):
                gptcJob = self.cr.leakDetector.getPathsToContainers(
                    '~aigptc', args[1],
                    Functor(self._handleGPTCfinished, senderId, args[1]))
            else:
                self.down_setMagicWordResponse(senderId, 'error')

        elif wordIs('~aigptcn'):
            args = word.split()
            if len(args) > 1. and hasattr(self.cr, 'leakDetector'):
                gptcnJob = self.cr.leakDetector.getPathsToContainersNamed(
                    '~aigptcn', args[1],
                    Functor(self._handleGPTCNfinished, senderId, args[1]))
            else:
                self.down_setMagicWordResponse(senderId, 'error')

        else:
            # The word is not an AI-side magic word.  If the sender is
            # different than the target avatar, then pass the magic
            # word down to the target client-side MagicWordManager to
            # execute a client-side magic word.
            # MPG this gets done in child class
            #if (senderId != av.doId):
            #    self.sendUpdateToAvatarId(av.doId, 'setMagicWord', [word, av.doId, zoneId])
            return 0
        return 1
    def doMagicWord(self, word, avId, zoneId):
        wordIs = self.getWordIs(word)
        print word
        if wordIs('~oobe'):
            base.oobe()
        elif wordIs('~oobeCull'):
            base.oobeCull()
        elif wordIs('~tex'):
            self.doTex(word)
        elif wordIs('~texmem'):
            base.toggleTexMem()
        elif wordIs('~verts'):
            base.toggleShowVertices()
        elif wordIs('~wire'):
            base.toggleWireframe()
        elif wordIs('~stereo'):
            base.toggleStereo()
        elif wordIs('~showfont'):
            self.showfont(word[9:])
        elif wordIs('~hidefont'):
            self.hidefont()
        elif wordIs('~guiPopup'):
            self.toggleGuiPopup()
        elif wordIs('~showCS') or wordIs('~showcs'):
            bitmask = self.getCSBitmask(word[7:])
            render.showCS(bitmask)
            self.csShown = 1
        elif wordIs('~hideCS') or wordIs('~hidecs'):
            bitmask = self.getCSBitmask(word[7:])
            render.hideCS(bitmask)
            self.csShown = 0
        elif wordIs('~cs'):
            bitmask = self.getCSBitmask(word[3:])
            if self.csShown:
                render.hideCS(bitmask)
                self.csShown = 0
            else:
                render.showCS(bitmask)
                self.csShown = 1
        elif wordIs('~showShadowCollisions'):
            self.showShadowCollisions()
        elif wordIs('~hideShadowCollisions'):
            self.hideShadowCollisions()
        elif wordIs('~showCollisions'):
            self.showCollisions()
        elif wordIs('~hideCollisions'):
            self.hideCollisions()
        elif wordIs('~showCameraCollisions'):
            self.showCameraCollisions()
        elif wordIs('~hideCameraCollisions'):
            self.hideCameraCollisions()
        elif wordIs('~collidespam'):
            n = Notify.ptr().getCategory(':collide')
            if hasattr(self, '_collideSpamSeverity'):
                n.setSeverity(self._collideSpamSeverity)
                del self._collideSpamSeverity
            else:
                self._collideSpamSeverity = n.getSeverity()
                n.setSeverity(NSSpam)
        elif wordIs('~notify'):
            args = word.split()
            n = Notify.ptr().getCategory(args[1])
            n.setSeverity({'error': NSError,
             'warning': NSWarning,
             'info': NSInfo,
             'debug': NSDebug,
             'spam': NSSpam}[args[2]])
        elif wordIs('~stress'):
            factor = word[7:]
            if factor:
                factor = float(factor)
                LOD.setStressFactor(factor)
                response = 'Set LOD stress factor to %s' % factor
            else:
                factor = LOD.getStressFactor()
                response = 'LOD stress factor is %s' % factor
            self.setMagicWordResponse(response)
        elif wordIs('~for'):
            self.forAnother(word, avId, zoneId)
        elif wordIs('~badname'):
            word = '~for %s ~badname' % word[9:]
            print 'word is %s' % word
            self.forAnother(word, avId, zoneId)
        elif wordIs('~avId'):
            self.setMagicWordResponse(str(localAvatar.doId))
        elif wordIs('~doId'):
            name = string.strip(word[6:])
            objs = self.identifyDistributedObjects(name)
            if len(objs) == 0:
                response = '%s is unknown.' % name
            else:
                response = ''
                for name, obj in objs:
                    response += '\n%s %d' % (name, obj.doId)

                response = response[1:]
            self.setMagicWordResponse(response)
        elif wordIs('~exec'):
            from otp.chat import ChatManager
            ChatManager.ChatManager.execChat = 1
        elif wordIs('~run'):
            self.toggleRun()
        elif wordIs('~runFaster'):
            if config.GetBool('want-running', 1):
                args = word.split()
                if len(args) > 1:
                    base.debugRunningMultiplier = float(args[1])
                else:
                    base.debugRunningMultiplier = 10
                inputState.set('debugRunning', True)
        elif wordIs('~who'):
            avIds = []
            for av in Avatar.Avatar.ActiveAvatars:
                if hasattr(av, 'getFriendsList'):
                    avIds.append(av.doId)

            self.d_setWho(avIds)
        elif wordIs('~sync'):
            tm = self.cr.timeManager
            if tm == None:
                response = 'No TimeManager.'
                self.setMagicWordResponse(response)
            else:
                tm.extraSkew = 0.0
                skew = string.strip(word[5:])
                if skew != '':
                    tm.extraSkew = float(skew)
                globalClockDelta.clear()
                tm.handleHotkey()
        elif wordIs('~period'):
            timeout = string.strip(word[7:])
            if timeout != '':
                seconds = int(timeout)
                self.cr.stopPeriodTimer()
                self.cr.resetPeriodTimer(seconds)
                self.cr.startPeriodTimer()
            if self.cr.periodTimerExpired:
                response = 'Period timer has expired.'
            elif self.cr.periodTimerStarted:
                elapsed = globalClock.getFrameTime() - self.cr.periodTimerStarted
                secondsRemaining = self.cr.periodTimerSecondsRemaining - elapsed
                response = 'Period timer expires in %s seconds.' % int(secondsRemaining)
            else:
                response = 'Period timer not set.'
            self.setMagicWordResponse(response)
        elif wordIs('~DIRECT'):
            args = word.split()
            fEnableLight = 0
            if len(args) > 1:
                if direct and args[1] == 'CAM':
                    direct.enable()
                    taskMgr.removeTasksMatching('updateSmartCamera*')
                    camera.wrtReparentTo(render)
                    direct.cameraControl.enableMouseFly()
                    self.setMagicWordResponse('Enabled DIRECT camera')
                    return
                elif args[1] == 'LIGHT':
                    fEnableLight = 1
            base.startTk()
            from direct.directtools import DirectSession
            if fEnableLight:
                direct.enableLight()
            else:
                direct.enable()
            self.setMagicWordResponse('Enabled DIRECT')
        elif wordIs('~TT'):
            if not direct:
                return
            args = word.split()
            if len(args) > 1:
                if args[1] == 'CAM':
                    direct.cameraControl.disableMouseFly()
                    camera.wrtReparentTo(base.localAvatar)
                    base.localAvatar.startUpdateSmartCamera()
                    self.setMagicWordResponse('Disabled DIRECT camera')
                    return
            direct.disable()
            camera.wrtReparentTo(base.localAvatar)
            base.localAvatar.startUpdateSmartCamera()
            self.setMagicWordResponse('Disabled DIRECT')
        elif wordIs('~net'):
            if self.cr.networkPlugPulled():
                self.cr.restoreNetworkPlug()
                self.cr.startHeartbeat()
                response = 'Network restored.'
            else:
                self.cr.pullNetworkPlug()
                self.cr.stopHeartbeat()
                response = 'Network disconnected.'
            self.setMagicWordResponse(response)
        elif wordIs('~disconnect'):
            base.cr.distributedDistrict.sendUpdate('broadcastMessage')
        elif wordIs('~model'):
            args = word.split()
            path = args[1]
            model = loader.loadModel(path)
            model.reparentTo(localAvatar)
            model.wrtReparentTo(render)
            self.setMagicWordResponse('loaded %s' % path)
        elif wordIs('~axis'):
            axis = loader.loadModel('models/misc/xyzAxis.bam')
            axis.reparentTo(render)
            axis.setPos(base.localAvatar, 0, 0, 0)
            axis.setHpr(render, 0, 0, 0)
            axis10 = loader.loadModel('models/misc/xyzAxis.bam')
            axis10.reparentTo(render)
            axis10.setPos(base.localAvatar, 0, 0, 0)
            axis10.setScale(10)
            axis10.setHpr(render, 0, 0, 0)
            axis10.setColorScale(1, 1, 1, 0.4)
            axis10.setTransparency(1)
        elif wordIs('~clearAxes') or wordIs('~clearAxis'):
            render.findAllMatches('**/xyzAxis.egg').detach()
        elif wordIs('~myAxis'):
            if hasattr(self, 'myAxis'):
                self.myAxis.detachNode()
                del self.myAxis
            else:
                self.myAxis = loader.loadModel('models/misc/xyzAxis.bam')
                self.myAxis.reparentTo(localAvatar)
        elif wordIs('~osd'):
            onScreenDebug.enabled = not onScreenDebug.enabled
        elif wordIs('~osdScale'):
            args = word.split()
            defScale = 0.05
            if len(args) > 1:
                scale = float(args[1])
            else:
                scale = 1.0
            onScreenDebug.onScreenText.setScale(defScale * scale)
        elif wordIs('~osdTaskMgr'):
            if taskMgr.osdEnabled():
                taskMgr.stopOsd()
            else:
                if not onScreenDebug.enabled:
                    onScreenDebug.enabled = True
                taskMgr.startOsd()
        elif wordIs('~fps'):
            self.doFps(word, avId, zoneId)
        elif wordIs('~sleep'):
            args = word.split()
            if len(args) > 1:
                s = float(args[1])
                base.setSleep(s)
                response = 'sleeping %s' % s
            else:
                base.setSleep(0.0)
                response = 'not sleeping'
            self.setMagicWordResponse(response)
        elif wordIs('~objects'):
            args = word.split()
            from direct.showbase import ObjectReport
            report = ObjectReport.ObjectReport('client ~objects')
            if 'all' in args:
                self.notify.info('printing full object set...')
                report.getObjectPool().printObjsByType(printReferrers='ref' in args)
            if hasattr(self, 'baselineObjReport'):
                self.notify.info('calculating diff from baseline ObjectReport...')
                self.lastDiff = self.baselineObjReport.diff(report)
                self.lastDiff.printOut(full='diff' in args or 'dif' in args)
            if 'baseline' in args or not hasattr(self, 'baselineObjReport'):
                self.notify.info('recording baseline ObjectReport...')
                if hasattr(self, 'baselineObjReport'):
                    self.baselineObjReport.destroy()
                self.baselineObjReport = report
            self.setMagicWordResponse('objects logged')
        elif wordIs('~objectcount'):

            def handleObjectCountDone(objectCount):
                self.setMagicWordResponse('object count logged')

            oc = ObjectCount('~objectcount', doneCallback=handleObjectCountDone)
        elif wordIs('~objecthg'):
            import gc
            objs = gc.get_objects()
            type2count = {}
            for obj in objs:
                tn = safeTypeName(obj)
                type2count.setdefault(tn, 0)
                type2count[tn] += 1

            count2type = invertDictLossless(type2count)
            counts = count2type.keys()
            counts.sort()
            counts.reverse()
            for count in counts:
                print '%s: %s' % (count, count2type[count])

            self.setMagicWordResponse('~aiobjecthg complete')
        elif wordIs('~containers'):
            args = word.split()
            limit = 30
            if 'full' in args:
                limit = None
            ContainerReport.ContainerReport('~containers', log=True, limit=limit, threaded=True)
        elif wordIs('~garbage'):
            args = word.split()
            full = 'full' in args
            safeMode = 'safe' in args
            delOnly = 'delonly' in args
            GarbageReport.GarbageLogger('~garbage', fullReport=full, threaded=True, safeMode=safeMode, delOnly=delOnly, doneCallback=self.garbageReportDone)
        elif wordIs('~guicreates'):
            base.printGuiCreates = True
            self.setMagicWordResponse('printing gui creation stacks')
        elif wordIs('~creategarbage'):
            GarbageReport._createGarbage()
        elif wordIs('~leakTask'):

            def leakTask(task):
                return task.cont

            taskMgr.add(leakTask, uniqueName('leakedTask'))
            leakTask = None
        elif wordIs('~leakmessage'):
            MessengerLeakDetector._leakMessengerObject()
            self.down_setMagicWordResponse(senderId, 'messenger leak object created')
        elif wordIs('~pstats'):
            args = word.split()
            hostname = None
            port = None
            if len(args) > 1:
                hostname = args[1]
            if len(args) > 2:
                port = int(args[2])
            base.wantStats = 1
            Task.TaskManager.pStatsTasks = 1
            result = base.createStats(hostname, port)
            connectionName = '%s' % hostname
            if port is not None:
                connectionName += ':%s' % port
            if result:
                response = 'connected client pstats to %s' % connectionName
            else:
                response = 'could not connect pstats to %s' % connectionName
            self.setMagicWordResponse(response)
        elif wordIs('~profile'):
            args = word.split()
            if len(args) > 1:
                num = int(args[1])
            else:
                num = 5
            session = taskMgr.getProfileSession('~profile')
            session.setLogAfterProfile(True)
            taskMgr.profileFrames(num, session)
            self.setMagicWordResponse('profiling %s client frames...' % num)
        elif wordIs('~frameprofile'):
            args = word.split()
            wasOn = bool(taskMgr.getProfileFrames())
            if len(args) > 1:
                setting = bool(int(args[1]))
            else:
                setting = not wasOn
            taskMgr.setProfileFrames(setting)
            self.setMagicWordResponse('frame profiling %s%s' % (choice(setting, 'ON', 'OFF'), choice(wasOn == setting, ' already', '')))
        elif wordIs('~taskprofile'):
            args = word.split()
            wasOn = bool(taskMgr.getProfileTasks())
            if len(args) > 1:
                setting = bool(int(args[1]))
            else:
                setting = not wasOn
            taskMgr.setProfileTasks(setting)
            self.setMagicWordResponse('task profiling %s%s' % (choice(setting, 'ON', 'OFF'), choice(wasOn == setting, ' already', '')))
        elif wordIs('~taskspikethreshold'):
            args = word.split()
            if len(args) > 1:
                threshold = float(args[1])
                response = 'task spike threshold set to %ss' % threshold
            else:
                threshold = TaskProfiler.GetDefaultSpikeThreshold()
                response = 'task spike threshold reset to %ss' % threshold
            TaskProfiler.SetSpikeThreshold(threshold)
            self.setMagicWordResponse(response)
        elif wordIs('~logtaskprofiles'):
            args = word.split()
            if len(args) > 1:
                name = args[1]
            else:
                name = None
            taskMgr.logTaskProfiles(name)
            response = 'logged task profiles%s' % choice(name, ' for %s' % name, '')
            self.setMagicWordResponse(response)
        elif wordIs('~taskprofileflush'):
            args = word.split()
            if len(args) > 1:
                name = args[1]
            else:
                name = None
            taskMgr.flushTaskProfiles(name)
            response = 'flushed AI task profiles%s' % choice(name, ' for %s' % name, '')
            self.setMagicWordResponse(response)
        elif wordIs('~dobjectcount'):
            base.cr.printObjectCount()
            self.setMagicWordResponse('logging client distributed object count...')
        elif wordIs('~taskmgr'):
            print taskMgr
            self.setMagicWordResponse('logging client taskMgr...')
        elif wordIs('~jobmgr'):
            print jobMgr
            self.setMagicWordResponse('logging client jobMgr...')
        elif wordIs('~jobtime'):
            args = word.split()
            if len(args) > 1:
                time = float(args[1])
            else:
                time = None
            response = ''
            if time is None:
                time = jobMgr.getDefaultTimeslice()
                response = 'reset client jobMgr timeslice to %s ms' % time
            else:
                response = 'set client jobMgr timeslice to %s ms' % time
                time = time / 1000.0
            jobMgr.setTimeslice(time)
            self.setMagicWordResponse(response)
        elif wordIs('~detectleaks'):
            started = self.cr.startLeakDetector()
            self.setMagicWordResponse(choice(started, 'leak detector started', 'leak detector already started'))
        elif wordIs('~taskthreshold'):
            args = word.split()
            if len(args) > 1.0:
                threshold = float(args[1])
            else:
                threshold = None
            response = ''
            if threshold is None:
                threshold = taskMgr.DefTaskDurationWarningThreshold
                response = 'reset task duration warning threshold to %s' % threshold
            else:
                response = 'set task duration warning threshold to %s' % threshold
            taskMgr.setTaskDurationWarningThreshold(threshold)
            self.setMagicWordResponse(response)
        elif wordIs('~messenger'):
            print messenger
            self.setMagicWordResponse('logging client messenger...')
        elif wordIs('~clientcrash'):
            DelayedCall(Functor(self.notify.error, '~clientcrash: simulating a client crash'))
        elif wordIs('~badDelete'):
            doId = 0
            while doId in base.cr.doId2do:
                doId += 1

            DelayedCall(Functor(base.cr.deleteObjectLocation, ScratchPad(doId=doId), 1, 1))
            self.setMagicWordResponse('doing bad delete')
        elif wordIs('~idTags'):
            messenger.send('nameTagShowAvId', [])
            base.idTags = 1
        elif wordIs('~nameTags'):
            messenger.send('nameTagShowName', [])
            base.idTags = 0
        elif wordIs('~hideNames'):
            if NametagGlobals.getMasterNametagsVisible():
                NametagGlobals.setMasterNametagsVisible(0)
            else:
                NametagGlobals.setMasterNametagsVisible(1)
        elif wordIs('~hideGui'):
            if aspect2d.isHidden():
                aspect2d.show()
            else:
                aspect2d.hide()
        elif wordIs('~flush'):
            base.cr.doDataCache.flush()
            base.cr.cache.flush()
            self.setMagicWordResponse('client object and data caches flushed')
        elif wordIs('~prof'):
            import time
            name = 'default'
            p = Point3()
            ts = time.time()
            for i in xrange(1000000):
                p.set(1, 2, 3)

            tf = time.time()
            dt = tf - ts
            response = 'prof(%s): %s secs' % (name, dt)
            print response
            self.setMagicWordResponse(response)
        elif wordIs('~gptc'):
            args = word.split()
            if len(args) > 1.0 and hasattr(self.cr, 'leakDetector'):
                gptcJob = self.cr.leakDetector.getPathsToContainers('~gptc', args[1], Functor(self._handleGPTCfinished, args[1]))
            else:
                self.setMagicWordResponse('error')
        elif wordIs('~gptcn'):
            args = word.split()
            if len(args) > 1.0 and hasattr(self.cr, 'leakDetector'):
                gptcnJob = self.cr.leakDetector.getPathsToContainersNamed('~gptcn', args[1], Functor(self._handleGPTCNfinished, args[1]))
            else:
                self.setMagicWordResponse('error')
        else:
            return 0
        return 1
    def doMagicWord(self, word, avId, zoneId):
        wordIs = self.getWordIs(word)
        print word
        if wordIs("~oobe"):
            base.oobe()
        elif wordIs("~oobeCull"):
            base.oobeCull()
        elif wordIs("~tex"):
            self.doTex(word)
        elif wordIs("~texmem"):
            base.toggleTexMem()
        elif wordIs("~verts"):
            base.toggleShowVertices()
        elif wordIs("~wire"):
            base.toggleWireframe()
        elif wordIs("~stereo"):
            base.toggleStereo()
        elif wordIs("~showfont"):
            self.showfont(word[9:])
        elif wordIs("~hidefont"):
            self.hidefont()
        elif wordIs("~guiPopup"):
            self.toggleGuiPopup()
        elif wordIs("~showCS") or wordIs("~showcs"):
            bitmask = self.getCSBitmask(word[7:])
            render.showCS(bitmask)
            self.csShown = 1
        elif wordIs("~hideCS") or wordIs("~hidecs"):
            bitmask = self.getCSBitmask(word[7:])
            render.hideCS(bitmask)
            self.csShown = 0
        elif wordIs("~cs"):
            bitmask = self.getCSBitmask(word[3:])
            if self.csShown:
                render.hideCS(bitmask)
                self.csShown = 0
            else:
                render.showCS(bitmask)
                self.csShown = 1
        elif wordIs("~showShadowCollisions"):
            self.showShadowCollisions()
        elif wordIs("~hideShadowCollisions"):
            self.hideShadowCollisions()
        elif wordIs("~showCollisions"):
            self.showCollisions()
        elif wordIs("~hideCollisions"):
            self.hideCollisions()
        elif wordIs("~showCameraCollisions"):
            self.showCameraCollisions()
        elif wordIs("~hideCameraCollisions"):
            self.hideCameraCollisions()
        elif wordIs("~collidespam"):
            n = Notify.ptr().getCategory(":collide")
            if hasattr(self, "_collideSpamSeverity"):
                n.setSeverity(self._collideSpamSeverity)
                del self._collideSpamSeverity
            else:
                self._collideSpamSeverity = n.getSeverity()
                n.setSeverity(NSSpam)
        elif wordIs("~notify"):
            args = word.split()
            n = Notify.ptr().getCategory(args[1])
            n.setSeverity(
                {"error": NSError, "warning": NSWarning, "info": NSInfo, "debug": NSDebug, "spam": NSSpam}[args[2]]
            )
        elif wordIs("~stress"):
            factor = word[7:]
            if factor:
                factor = float(factor)
                LOD.setStressFactor(factor)
                response = "Set LOD stress factor to %s" % factor
            else:
                factor = LOD.getStressFactor()
                response = "LOD stress factor is %s" % factor
            self.setMagicWordResponse(response)
        elif wordIs("~for"):
            self.forAnother(word, avId, zoneId)
        elif wordIs("~badname"):
            word = "~for %s ~badname" % word[9:]
            print "word is %s" % word
            self.forAnother(word, avId, zoneId)
        elif wordIs("~avId"):
            self.setMagicWordResponse(str(localAvatar.doId))
        elif wordIs("~doId"):
            name = string.strip(word[6:])
            objs = self.identifyDistributedObjects(name)
            if len(objs) == 0:
                response = "%s is unknown." % name
            else:
                response = ""
                for name, obj in objs:
                    response += "\n%s %d" % (name, obj.doId)

                response = response[1:]
            self.setMagicWordResponse(response)
        elif wordIs("~exec"):
            from otp.chat import ChatManager

            ChatManager.ChatManager.execChat = 1
        elif wordIs("~run"):
            self.toggleRun()
        elif wordIs("~runFaster"):
            if config.GetBool("want-running", 1):
                args = word.split()
                if len(args) > 1:
                    base.debugRunningMultiplier = float(args[1])
                else:
                    base.debugRunningMultiplier = 10
                inputState.set("debugRunning", True)
        elif wordIs("~who"):
            avIds = []
            for av in Avatar.Avatar.ActiveAvatars:
                if hasattr(av, "getFriendsList"):
                    avIds.append(av.doId)

            self.d_setWho(avIds)
        elif wordIs("~sync"):
            tm = self.cr.timeManager
            if tm == None:
                response = "No TimeManager."
                self.setMagicWordResponse(response)
            else:
                tm.extraSkew = 0.0
                skew = string.strip(word[5:])
                if skew != "":
                    tm.extraSkew = float(skew)
                globalClockDelta.clear()
                tm.handleHotkey()
        elif wordIs("~period"):
            timeout = string.strip(word[7:])
            if timeout != "":
                seconds = int(timeout)
                self.cr.stopPeriodTimer()
                self.cr.resetPeriodTimer(seconds)
                self.cr.startPeriodTimer()
            if self.cr.periodTimerExpired:
                response = "Period timer has expired."
            elif self.cr.periodTimerStarted:
                elapsed = globalClock.getFrameTime() - self.cr.periodTimerStarted
                secondsRemaining = self.cr.periodTimerSecondsRemaining - elapsed
                response = "Period timer expires in %s seconds." % int(secondsRemaining)
            else:
                response = "Period timer not set."
            self.setMagicWordResponse(response)
        elif wordIs("~DIRECT"):
            args = word.split()
            fEnableLight = 0
            if len(args) > 1:
                if direct and args[1] == "CAM":
                    direct.enable()
                    taskMgr.removeTasksMatching("updateSmartCamera*")
                    camera.wrtReparentTo(render)
                    direct.cameraControl.enableMouseFly()
                    self.setMagicWordResponse("Enabled DIRECT camera")
                    return
                elif args[1] == "LIGHT":
                    fEnableLight = 1
            base.startTk()
            from direct.directtools import DirectSession

            if fEnableLight:
                direct.enableLight()
            else:
                direct.enable()
            self.setMagicWordResponse("Enabled DIRECT")
        elif wordIs("~TT"):
            if not direct:
                return
            args = word.split()
            if len(args) > 1:
                if args[1] == "CAM":
                    direct.cameraControl.disableMouseFly()
                    camera.wrtReparentTo(base.localAvatar)
                    base.localAvatar.startUpdateSmartCamera()
                    self.setMagicWordResponse("Disabled DIRECT camera")
                    return
            direct.disable()
            camera.wrtReparentTo(base.localAvatar)
            base.localAvatar.startUpdateSmartCamera()
            self.setMagicWordResponse("Disabled DIRECT")
        elif wordIs("~net"):
            if self.cr.networkPlugPulled():
                self.cr.restoreNetworkPlug()
                self.cr.startHeartbeat()
                response = "Network restored."
            else:
                self.cr.pullNetworkPlug()
                self.cr.stopHeartbeat()
                response = "Network disconnected."
            self.setMagicWordResponse(response)
        elif wordIs("~disconnect"):
            base.cr.distributedDistrict.sendUpdate("broadcastMessage")
        elif wordIs("~model"):
            args = word.split()
            path = args[1]
            model = loader.loadModel(path)
            model.reparentTo(localAvatar)
            model.wrtReparentTo(render)
            self.setMagicWordResponse("loaded %s" % path)
        elif wordIs("~axis"):
            axis = loader.loadModel("models/misc/xyzAxis.bam")
            axis.reparentTo(render)
            axis.setPos(base.localAvatar, 0, 0, 0)
            axis.setHpr(render, 0, 0, 0)
            axis10 = loader.loadModel("models/misc/xyzAxis.bam")
            axis10.reparentTo(render)
            axis10.setPos(base.localAvatar, 0, 0, 0)
            axis10.setScale(10)
            axis10.setHpr(render, 0, 0, 0)
            axis10.setColorScale(1, 1, 1, 0.4)
            axis10.setTransparency(1)
        elif wordIs("~clearAxes") or wordIs("~clearAxis"):
            render.findAllMatches("**/xyzAxis.egg").detach()
        elif wordIs("~myAxis"):
            if hasattr(self, "myAxis"):
                self.myAxis.detachNode()
                del self.myAxis
            else:
                self.myAxis = loader.loadModel("models/misc/xyzAxis.bam")
                self.myAxis.reparentTo(localAvatar)
        elif wordIs("~osd"):
            onScreenDebug.enabled = not onScreenDebug.enabled
        elif wordIs("~osdScale"):
            args = word.split()
            defScale = 0.05
            if len(args) > 1:
                scale = float(args[1])
            else:
                scale = 1.0
            onScreenDebug.onScreenText.setScale(defScale * scale)
        elif wordIs("~osdTaskMgr"):
            if taskMgr.osdEnabled():
                taskMgr.stopOsd()
            else:
                if not onScreenDebug.enabled:
                    onScreenDebug.enabled = True
                taskMgr.startOsd()
        elif wordIs("~fps"):
            self.doFps(word, avId, zoneId)
        elif wordIs("~sleep"):
            args = word.split()
            if len(args) > 1:
                s = float(args[1])
                base.setSleep(s)
                response = "sleeping %s" % s
            else:
                base.setSleep(0.0)
                response = "not sleeping"
            self.setMagicWordResponse(response)
        elif wordIs("~objects"):
            args = word.split()
            from direct.showbase import ObjectReport

            report = ObjectReport.ObjectReport("client ~objects")
            if "all" in args:
                self.notify.info("printing full object set...")
                report.getObjectPool().printObjsByType(printReferrers="ref" in args)
            if hasattr(self, "baselineObjReport"):
                self.notify.info("calculating diff from baseline ObjectReport...")
                self.lastDiff = self.baselineObjReport.diff(report)
                self.lastDiff.printOut(full="diff" in args or "dif" in args)
            if "baseline" in args or not hasattr(self, "baselineObjReport"):
                self.notify.info("recording baseline ObjectReport...")
                if hasattr(self, "baselineObjReport"):
                    self.baselineObjReport.destroy()
                self.baselineObjReport = report
            self.setMagicWordResponse("objects logged")
        elif wordIs("~objectcount"):

            def handleObjectCountDone(objectCount):
                self.setMagicWordResponse("object count logged")

            oc = ObjectCount("~objectcount", doneCallback=handleObjectCountDone)
        elif wordIs("~objecthg"):
            import gc

            objs = gc.get_objects()
            type2count = {}
            for obj in objs:
                tn = safeTypeName(obj)
                type2count.setdefault(tn, 0)
                type2count[tn] += 1

            count2type = invertDictLossless(type2count)
            counts = count2type.keys()
            counts.sort()
            counts.reverse()
            for count in counts:
                print "%s: %s" % (count, count2type[count])

            self.setMagicWordResponse("~aiobjecthg complete")
        elif wordIs("~containers"):
            args = word.split()
            limit = 30
            if "full" in args:
                limit = None
            ContainerReport.ContainerReport("~containers", log=True, limit=limit, threaded=True)
        elif wordIs("~garbage"):
            args = word.split()
            full = "full" in args
            safeMode = "safe" in args
            delOnly = "delonly" in args
            GarbageReport.GarbageLogger(
                "~garbage",
                fullReport=full,
                threaded=True,
                safeMode=safeMode,
                delOnly=delOnly,
                doneCallback=self.garbageReportDone,
            )
        elif wordIs("~guicreates"):
            base.printGuiCreates = True
            self.setMagicWordResponse("printing gui creation stacks")
        elif wordIs("~creategarbage"):
            GarbageReport._createGarbage()
        elif wordIs("~leakTask"):

            def leakTask(task):
                return task.cont

            taskMgr.add(leakTask, uniqueName("leakedTask"))
            leakTask = None
        elif wordIs("~leakmessage"):
            MessengerLeakDetector._leakMessengerObject()
            self.down_setMagicWordResponse(senderId, "messenger leak object created")
        elif wordIs("~pstats"):
            args = word.split()
            hostname = None
            port = None
            if len(args) > 1:
                hostname = args[1]
            if len(args) > 2:
                port = int(args[2])
            base.wantStats = 1
            Task.TaskManager.pStatsTasks = 1
            result = base.createStats(hostname, port)
            connectionName = "%s" % hostname
            if port is not None:
                connectionName += ":%s" % port
            if result:
                response = "connected client pstats to %s" % connectionName
            else:
                response = "could not connect pstats to %s" % connectionName
            self.setMagicWordResponse(response)
        elif wordIs("~profile"):
            args = word.split()
            if len(args) > 1:
                num = int(args[1])
            else:
                num = 5
            session = taskMgr.getProfileSession("~profile")
            session.setLogAfterProfile(True)
            taskMgr.profileFrames(num, session)
            self.setMagicWordResponse("profiling %s client frames..." % num)
        elif wordIs("~frameprofile"):
            args = word.split()
            wasOn = bool(taskMgr.getProfileFrames())
            if len(args) > 1:
                setting = bool(int(args[1]))
            else:
                setting = not wasOn
            taskMgr.setProfileFrames(setting)
            self.setMagicWordResponse(
                "frame profiling %s%s" % (choice(setting, "ON", "OFF"), choice(wasOn == setting, " already", ""))
            )
        elif wordIs("~taskprofile"):
            args = word.split()
            wasOn = bool(taskMgr.getProfileTasks())
            if len(args) > 1:
                setting = bool(int(args[1]))
            else:
                setting = not wasOn
            taskMgr.setProfileTasks(setting)
            self.setMagicWordResponse(
                "task profiling %s%s" % (choice(setting, "ON", "OFF"), choice(wasOn == setting, " already", ""))
            )
        elif wordIs("~taskspikethreshold"):
            args = word.split()
            if len(args) > 1:
                threshold = float(args[1])
                response = "task spike threshold set to %ss" % threshold
            else:
                threshold = TaskProfiler.GetDefaultSpikeThreshold()
                response = "task spike threshold reset to %ss" % threshold
            TaskProfiler.SetSpikeThreshold(threshold)
            self.setMagicWordResponse(response)
        elif wordIs("~logtaskprofiles"):
            args = word.split()
            if len(args) > 1:
                name = args[1]
            else:
                name = None
            taskMgr.logTaskProfiles(name)
            response = "logged task profiles%s" % choice(name, " for %s" % name, "")
            self.setMagicWordResponse(response)
        elif wordIs("~taskprofileflush"):
            args = word.split()
            if len(args) > 1:
                name = args[1]
            else:
                name = None
            taskMgr.flushTaskProfiles(name)
            response = "flushed AI task profiles%s" % choice(name, " for %s" % name, "")
            self.setMagicWordResponse(response)
        elif wordIs("~dobjectcount"):
            base.cr.printObjectCount()
            self.setMagicWordResponse("logging client distributed object count...")
        elif wordIs("~taskmgr"):
            print taskMgr
            self.setMagicWordResponse("logging client taskMgr...")
        elif wordIs("~jobmgr"):
            print jobMgr
            self.setMagicWordResponse("logging client jobMgr...")
        elif wordIs("~jobtime"):
            args = word.split()
            if len(args) > 1:
                time = float(args[1])
            else:
                time = None
            response = ""
            if time is None:
                time = jobMgr.getDefaultTimeslice()
                response = "reset client jobMgr timeslice to %s ms" % time
            else:
                response = "set client jobMgr timeslice to %s ms" % time
                time = time / 1000.0
            jobMgr.setTimeslice(time)
            self.setMagicWordResponse(response)
        elif wordIs("~detectleaks"):
            started = self.cr.startLeakDetector()
            self.setMagicWordResponse(choice(started, "leak detector started", "leak detector already started"))
        elif wordIs("~taskthreshold"):
            args = word.split()
            if len(args) > 1.0:
                threshold = float(args[1])
            else:
                threshold = None
            response = ""
            if threshold is None:
                threshold = taskMgr.DefTaskDurationWarningThreshold
                response = "reset task duration warning threshold to %s" % threshold
            else:
                response = "set task duration warning threshold to %s" % threshold
            taskMgr.setTaskDurationWarningThreshold(threshold)
            self.setMagicWordResponse(response)
        elif wordIs("~messenger"):
            print messenger
            self.setMagicWordResponse("logging client messenger...")
        elif wordIs("~clientcrash"):
            DelayedCall(Functor(self.notify.error, "~clientcrash: simulating a client crash"))
        elif wordIs("~badDelete"):
            doId = 0
            while doId in base.cr.doId2do:
                doId += 1

            DelayedCall(Functor(base.cr.deleteObjectLocation, ScratchPad(doId=doId), 1, 1))
            self.setMagicWordResponse("doing bad delete")
        elif wordIs("~idTags"):
            messenger.send("nameTagShowAvId", [])
            base.idTags = 1
        elif wordIs("~nameTags"):
            messenger.send("nameTagShowName", [])
            base.idTags = 0
        elif wordIs("~hideNames"):
            if NametagGlobals.getMasterNametagsVisible():
                NametagGlobals.setMasterNametagsVisible(0)
            else:
                NametagGlobals.setMasterNametagsVisible(1)
        elif wordIs("~hideGui"):
            if aspect2d.isHidden():
                aspect2d.show()
            else:
                aspect2d.hide()
        elif wordIs("~flush"):
            base.cr.doDataCache.flush()
            base.cr.cache.flush()
            self.setMagicWordResponse("client object and data caches flushed")
        elif wordIs("~prof"):
            import time

            name = "default"
            p = Point3()
            ts = time.time()
            for i in xrange(1000000):
                p.set(1, 2, 3)

            tf = time.time()
            dt = tf - ts
            response = "prof(%s): %s secs" % (name, dt)
            print response
            self.setMagicWordResponse(response)
        elif wordIs("~gptc"):
            args = word.split()
            if len(args) > 1.0 and hasattr(self.cr, "leakDetector"):
                gptcJob = self.cr.leakDetector.getPathsToContainers(
                    "~gptc", args[1], Functor(self._handleGPTCfinished, args[1])
                )
            else:
                self.setMagicWordResponse("error")
        elif wordIs("~gptcn"):
            args = word.split()
            if len(args) > 1.0 and hasattr(self.cr, "leakDetector"):
                gptcnJob = self.cr.leakDetector.getPathsToContainersNamed(
                    "~gptcn", args[1], Functor(self._handleGPTCNfinished, args[1])
                )
            else:
                self.setMagicWordResponse("error")
        else:
            return 0
        return 1
Esempio n. 15
0
    def doMagicWord(self, word, avId, zoneId):
        wordIs = self.getWordIs(word)
        print word
        if wordIs('~oobe'):
            base.oobe()
        elif wordIs('~oobeCull'):
            base.oobeCull()
        elif wordIs('~tex'):
            self.doTex(word)
        elif wordIs('~texmem'):
            base.toggleTexMem()
        elif wordIs('~verts'):
            base.toggleShowVertices()
        elif wordIs('~wire'):
            base.toggleWireframe()
        elif wordIs('~stereo'):
            base.toggleStereo()
        elif wordIs('~showfont'):
            self.showfont(word[9:])
        elif wordIs('~hidefont'):
            self.hidefont()
        elif wordIs('~guiPopup'):
            self.toggleGuiPopup()
        elif wordIs('~showCS') or wordIs('~showcs'):
            bitmask = self.getCSBitmask(word[7:])
            render.showCS(bitmask)
            self.csShown = 1
        elif wordIs('~hideCS') or wordIs('~hidecs'):
            bitmask = self.getCSBitmask(word[7:])
            render.hideCS(bitmask)
            self.csShown = 0
        elif wordIs('~cs'):
            bitmask = self.getCSBitmask(word[3:])
            if self.csShown:
                render.hideCS(bitmask)
                self.csShown = 0
            else:
                render.showCS(bitmask)
                self.csShown = 1
        elif wordIs('~showShadowCollisions'):
            self.showShadowCollisions()
        elif wordIs('~hideShadowCollisions'):
            self.hideShadowCollisions()
        elif wordIs('~showCollisions'):
            self.showCollisions()
        elif wordIs('~hideCollisions'):
            self.hideCollisions()
        elif wordIs('~showCameraCollisions'):
            self.showCameraCollisions()
        elif wordIs('~hideCameraCollisions'):
            self.hideCameraCollisions()
        elif wordIs('~collidespam'):
            n = Notify.ptr().getCategory(':collide')
            if hasattr(self, '_collideSpamSeverity'):
                n.setSeverity(self._collideSpamSeverity)
                del self._collideSpamSeverity
            else:
                self._collideSpamSeverity = n.getSeverity()
                n.setSeverity(NSSpam)
        elif wordIs('~notify'):
            args = word.split()
            n = Notify.ptr().getCategory(args[1])
            n.setSeverity({
                'error': NSError,
                'warning': NSWarning,
                'info': NSInfo,
                'debug': NSDebug,
                'spam': NSSpam }[args[2]])
        elif wordIs('~stress'):
            factor = word[7:]
            if factor:
                factor = float(factor)
                LOD.setStressFactor(factor)
                response = 'Set LOD stress factor to %s' % factor
            else:
                factor = LOD.getStressFactor()
                response = 'LOD stress factor is %s' % factor
            self.setMagicWordResponse(response)
        elif wordIs('~for'):
            self.forAnother(word, avId, zoneId)
        elif wordIs('~badname'):
            word = '~for %s ~badname' % word[9:]
            print 'word is %s' % word
            self.forAnother(word, avId, zoneId)
        elif wordIs('~avId'):
            self.setMagicWordResponse(str(localAvatar.doId))
        elif wordIs('~doId'):
            name = string.strip(word[6:])
            objs = self.identifyDistributedObjects(name)
            if len(objs) == 0:
                response = '%s is unknown.' % name
            else:
                response = ''
                for (name, obj) in objs:
                    response += '\n%s %d' % (name, obj.doId)
                
                response = response[1:]
            self.setMagicWordResponse(response)
        elif wordIs('~exec'):
            ChatManager = ChatManager
            import otp.chat
            ChatManager.ChatManager.execChat = 1
        elif wordIs('~run'):
            self.toggleRun()
        elif wordIs('~runFaster'):
            if config.GetBool('want-running', 1):
                args = word.split()
                if len(args) > 1:
                    base.debugRunningMultiplier = float(args[1])
                else:
                    base.debugRunningMultiplier = 10
                inputState.set('debugRunning', True)
            
        elif wordIs('~who'):
            avIds = []
            for av in Avatar.Avatar.ActiveAvatars:
                if hasattr(av, 'getFriendsList'):
                    avIds.append(av.doId)
                    continue
            
            self.d_setWho(avIds)
        elif wordIs('~sync'):
            tm = self.cr.timeManager
            if tm == None:
                response = 'No TimeManager.'
                self.setMagicWordResponse(response)
            else:
                tm.extraSkew = 0.0
                skew = string.strip(word[5:])
                if skew != '':
                    tm.extraSkew = float(skew)
                
                globalClockDelta.clear()
                tm.handleHotkey()
        elif wordIs('~period'):
            timeout = string.strip(word[7:])
            if timeout != '':
                seconds = int(timeout)
                self.cr.stopPeriodTimer()
                self.cr.resetPeriodTimer(seconds)
                self.cr.startPeriodTimer()
            
            if self.cr.periodTimerExpired:
                response = 'Period timer has expired.'
            elif self.cr.periodTimerStarted:
                elapsed = globalClock.getFrameTime() - self.cr.periodTimerStarted
                secondsRemaining = self.cr.periodTimerSecondsRemaining - elapsed
                response = 'Period timer expires in %s seconds.' % int(secondsRemaining)
            else:
                response = 'Period timer not set.'
            self.setMagicWordResponse(response)
        elif wordIs('~DIRECT'):
            args = word.split()
            fEnableLight = 0
            if len(args) > 1:
                if direct and args[1] == 'CAM':
                    direct.enable()
                    taskMgr.removeTasksMatching('updateSmartCamera*')
                    camera.wrtReparentTo(render)
                    direct.cameraControl.enableMouseFly()
                    self.setMagicWordResponse('Enabled DIRECT camera')
                    return None
                elif args[1] == 'LIGHT':
                    fEnableLight = 1
                
            
            base.startTk()
            DirectSession = DirectSession
            import direct.directtools
            if fEnableLight:
                direct.enableLight()
            else:
                direct.enable()
            self.setMagicWordResponse('Enabled DIRECT')
        elif wordIs('~TT'):
            if not direct:
                return None
            
            args = word.split()
            if len(args) > 1:
                if args[1] == 'CAM':
                    direct.cameraControl.disableMouseFly()
                    camera.wrtReparentTo(base.localAvatar)
                    base.localAvatar.startUpdateSmartCamera()
                    self.setMagicWordResponse('Disabled DIRECT camera')
                    return None
                
            
            direct.disable()
            camera.wrtReparentTo(base.localAvatar)
            base.localAvatar.startUpdateSmartCamera()
            self.setMagicWordResponse('Disabled DIRECT')
        elif wordIs('~net'):
            if self.cr.networkPlugPulled():
                self.cr.restoreNetworkPlug()
                self.cr.startHeartbeat()
                response = 'Network restored.'
            else:
                self.cr.pullNetworkPlug()
                self.cr.stopHeartbeat()
                response = 'Network disconnected.'
            self.setMagicWordResponse(response)
        elif wordIs('~disconnect'):
            base.cr.distributedDistrict.sendUpdate('broadcastMessage')
        elif wordIs('~model'):
            args = word.split()
            path = args[1]
            model = loader.loadModel(path)
            model.reparentTo(localAvatar)
            model.wrtReparentTo(render)
            self.setMagicWordResponse('loaded %s' % path)
        elif wordIs('~axis'):
            axis = loader.loadModel('models/misc/xyzAxis.bam')
            axis.reparentTo(render)
            axis.setPos(base.localAvatar, 0, 0, 0)
            axis.setHpr(render, 0, 0, 0)
            axis10 = loader.loadModel('models/misc/xyzAxis.bam')
            axis10.reparentTo(render)
            axis10.setPos(base.localAvatar, 0, 0, 0)
            axis10.setScale(10)
            axis10.setHpr(render, 0, 0, 0)
            axis10.setColorScale(1, 1, 1, 0.40000000000000002)
            axis10.setTransparency(1)
        elif wordIs('~clearAxes') or wordIs('~clearAxis'):
            render.findAllMatches('**/xyzAxis.egg').detach()
        elif wordIs('~myAxis'):
            if hasattr(self, 'myAxis'):
                self.myAxis.detachNode()
                del self.myAxis
            else:
                self.myAxis = loader.loadModel('models/misc/xyzAxis.bam')
                self.myAxis.reparentTo(localAvatar)
        elif wordIs('~osd'):
            onScreenDebug.enabled = not (onScreenDebug.enabled)
        elif wordIs('~osdScale'):
            args = word.split()
            defScale = 0.050000000000000003
            if len(args) > 1:
                scale = float(args[1])
            else:
                scale = 1.0
            onScreenDebug.onScreenText.setScale(defScale * scale)
        elif wordIs('~osdTaskMgr'):
            if taskMgr.osdEnabled():
                taskMgr.stopOsd()
            elif not onScreenDebug.enabled:
                onScreenDebug.enabled = True
            
            taskMgr.startOsd()
        elif wordIs('~fps'):
            self.doFps(word, avId, zoneId)
        elif wordIs('~sleep'):
            args = word.split()
            if len(args) > 1:
                s = float(args[1])
                base.setSleep(s)
                response = 'sleeping %s' % s
            else:
                base.setSleep(0.0)
                response = 'not sleeping'
            self.setMagicWordResponse(response)
        elif wordIs('~objects'):
            args = word.split()
            ObjectReport = ObjectReport
            import direct.showbase
            report = ObjectReport.ObjectReport('client ~objects')
            if 'all' in args:
                self.notify.info('printing full object set...')
                report.getObjectPool().printObjsByType(printReferrers = 'ref' in args)
            
            if hasattr(self, 'baselineObjReport'):
                self.notify.info('calculating diff from baseline ObjectReport...')
                self.lastDiff = self.baselineObjReport.diff(report)
                if not 'diff' in args:
                    pass
                self.lastDiff.printOut(full = 'dif' in args)
            
            if 'baseline' in args or not hasattr(self, 'baselineObjReport'):
                self.notify.info('recording baseline ObjectReport...')
                if hasattr(self, 'baselineObjReport'):
                    self.baselineObjReport.destroy()
                
                self.baselineObjReport = report
            
            self.setMagicWordResponse('objects logged')
        elif wordIs('~objectcount'):
            
            def handleObjectCountDone(objectCount):
                self.setMagicWordResponse('object count logged')

            oc = ObjectCount('~objectcount', doneCallback = handleObjectCountDone)
        elif wordIs('~objecthg'):
            import gc as gc
            objs = gc.get_objects()
            type2count = { }
            for obj in objs:
                tn = safeTypeName(obj)
                type2count.setdefault(tn, 0)
                type2count[tn] += 1
            
            count2type = invertDictLossless(type2count)
            counts = count2type.keys()
            counts.sort()
            counts.reverse()
            for count in counts:
                print '%s: %s' % (count, count2type[count])
            
            self.setMagicWordResponse('~aiobjecthg complete')
        elif wordIs('~containers'):
            args = word.split()
            limit = 30
            if 'full' in args:
                limit = None
            
            ContainerReport.ContainerReport('~containers', log = True, limit = limit, threaded = True)
        elif wordIs('~garbage'):
            args = word.split()
            full = 'full' in args
            safeMode = 'safe' in args
            delOnly = 'delonly' in args
            cycleLimit = None
            for arg in args:
                
                try:
                    cycleLimit = int(arg)
                continue
                continue

            
            GarbageReport.GarbageLogger('~garbage', fullReport = full, threaded = True, safeMode = safeMode, delOnly = delOnly, cycleLimit = cycleLimit, doneCallback = self.garbageReportDone)
        elif wordIs('~guicreates'):
            base.printGuiCreates = True
            self.setMagicWordResponse('printing gui creation stacks')
        elif wordIs('~creategarbage'):
            args = word.split()
            num = 1
            if len(args) > 1:
                num = int(args[1])
            
            GarbageReport._createGarbage(num)
        elif wordIs('~leakTask'):
            
            def leakTask(task):
                return task.cont

            taskMgr.add(leakTask, uniqueName('leakedTask'))
            leakTask = None
        elif wordIs('~leakmessage'):
            MessengerLeakDetector._leakMessengerObject()
            self.down_setMagicWordResponse(senderId, 'messenger leak object created')
        elif wordIs('~pstats'):
            args = word.split()
            hostname = None
            port = None
            if len(args) > 1:
                hostname = args[1]
            
            if len(args) > 2:
                port = int(args[2])
            
            base.wantStats = 1
            Task.TaskManager.pStatsTasks = 1
            result = base.createStats(hostname, port)
            connectionName = '%s' % hostname
            if port is not None:
                connectionName += ':%s' % port
            
            if result:
                response = 'connected client pstats to %s' % connectionName
            else:
                response = 'could not connect pstats to %s' % connectionName
            self.setMagicWordResponse(response)
        elif wordIs('~profile'):
            args = word.split()
            if len(args) > 1:
                num = int(args[1])
            else:
                num = 5
            session = taskMgr.getProfileSession('~profile')
            session.setLogAfterProfile(True)
            taskMgr.profileFrames(num, session)
            self.setMagicWordResponse('profiling %s client frames...' % num)
        elif wordIs('~frameprofile'):
            args = word.split()
            wasOn = bool(taskMgr.getProfileFrames())
            if len(args) > 1:
                setting = bool(int(args[1]))
            else:
                setting = not wasOn
            taskMgr.setProfileFrames(setting)
            self.setMagicWordResponse('frame profiling %s%s' % (choice(setting, 'ON', 'OFF'), choice(wasOn == setting, ' already', '')))
        elif wordIs('~taskprofile'):
            args = word.split()
            wasOn = bool(taskMgr.getProfileTasks())
            if len(args) > 1:
                setting = bool(int(args[1]))
            else:
                setting = not wasOn
            taskMgr.setProfileTasks(setting)
            self.setMagicWordResponse('task profiling %s%s' % (choice(setting, 'ON', 'OFF'), choice(wasOn == setting, ' already', '')))
        elif wordIs('~taskspikethreshold'):
            args = word.split()
            if len(args) > 1:
                threshold = float(args[1])
                response = 'task spike threshold set to %ss' % threshold
            else:
                threshold = TaskProfiler.GetDefaultSpikeThreshold()
                response = 'task spike threshold reset to %ss' % threshold
            TaskProfiler.SetSpikeThreshold(threshold)
            self.setMagicWordResponse(response)
        elif wordIs('~logtaskprofiles'):
            args = word.split()
            if len(args) > 1:
                name = args[1]
            else:
                name = None
            taskMgr.logTaskProfiles(name)
            response = 'logged task profiles%s' % choice(name, ' for %s' % name, '')
            self.setMagicWordResponse(response)
        elif wordIs('~taskprofileflush'):
            args = word.split()
            if len(args) > 1:
                name = args[1]
            else:
                name = None
            taskMgr.flushTaskProfiles(name)
            response = 'flushed AI task profiles%s' % choice(name, ' for %s' % name, '')
            self.setMagicWordResponse(response)
        elif wordIs('~dobjectcount'):
            base.cr.printObjectCount()
            self.setMagicWordResponse('logging client distributed object count...')
        elif wordIs('~taskmgr'):
            print taskMgr
            self.setMagicWordResponse('logging client taskMgr...')
        elif wordIs('~jobmgr'):
            print jobMgr
            self.setMagicWordResponse('logging client jobMgr...')
        elif wordIs('~jobtime'):
            args = word.split()
            if len(args) > 1:
                time = float(args[1])
            else:
                time = None
            response = ''
            if time is None:
                time = jobMgr.getDefaultTimeslice()
                response = 'reset client jobMgr timeslice to %s ms' % time
            else:
                response = 'set client jobMgr timeslice to %s ms' % time
                time = time / 1000.0
            jobMgr.setTimeslice(time)
            self.setMagicWordResponse(response)
        elif wordIs('~detectleaks'):
            started = self.cr.startLeakDetector()
            self.setMagicWordResponse(choice(started, 'leak detector started', 'leak detector already started'))
        elif wordIs('~taskthreshold'):
            args = word.split()
            if len(args) > 1.0:
                threshold = float(args[1])
            else:
                threshold = None
            response = ''
            if threshold is None:
                threshold = taskMgr.DefTaskDurationWarningThreshold
                response = 'reset task duration warning threshold to %s' % threshold
            else:
                response = 'set task duration warning threshold to %s' % threshold
            taskMgr.setTaskDurationWarningThreshold(threshold)
            self.setMagicWordResponse(response)
        elif wordIs('~messenger'):
            print messenger
            self.setMagicWordResponse('logging client messenger...')
        elif wordIs('~clientcrash'):
            DelayedCall(Functor(self.notify.error, '~clientcrash: simulating a client crash'))
        elif wordIs('~badDelete'):
            doId = 0
            while doId in base.cr.doId2do:
                doId += 1
            DelayedCall(Functor(base.cr.deleteObjectLocation, ScratchPad(doId = doId), 1, 1))
            self.setMagicWordResponse('doing bad delete')
        elif wordIs('~idTags'):
            messenger.send('nameTagShowAvId', [])
            base.idTags = 1
        elif wordIs('~nameTags'):
            messenger.send('nameTagShowName', [])
            base.idTags = 0
        elif wordIs('~hideNames'):
            if NametagGlobals.getMasterNametagsVisible():
                NametagGlobals.setMasterNametagsVisible(0)
            else:
                NametagGlobals.setMasterNametagsVisible(1)
        elif wordIs('~hideGui'):
            if aspect2d.isHidden():
                aspect2d.show()
            else:
                aspect2d.hide()
        elif wordIs('~flush'):
            base.cr.doDataCache.flush()
            base.cr.cache.flush()
            self.setMagicWordResponse('client object and data caches flushed')
        elif wordIs('~prof'):
            import time as time
            name = 'default'
            p = Point3()
            ts = time.time()
            for i in xrange(1000000):
                p.set(1, 2, 3)
            
            tf = time.time()
            dt = tf - ts
            response = 'prof(%s): %s secs' % (name, dt)
            print response
            self.setMagicWordResponse(response)
        elif wordIs('~gptc'):
            args = word.split()
            if len(args) > 1.0 and hasattr(self.cr, 'leakDetector'):
                gptcJob = self.cr.leakDetector.getPathsToContainers('~gptc', args[1], Functor(self._handleGPTCfinished, args[1]))
            else:
                self.setMagicWordResponse('error')
        elif wordIs('~gptcn'):
            args = word.split()
            if len(args) > 1.0 and hasattr(self.cr, 'leakDetector'):
                gptcnJob = self.cr.leakDetector.getPathsToContainersNamed('~gptcn', args[1], Functor(self._handleGPTCNfinished, args[1]))
            else:
                self.setMagicWordResponse('error')
        else:
            return 0
        return 1
    def delete(self):
        self._doPlayerExit()
        if __dev__:
            GarbageReport.checkForGarbageLeaks()

        DistributedAvatarAI.DistributedAvatarAI.delete(self)
Esempio n. 17
0
    def doMagicWord(self, word, avId, zoneId):
        wordIs = self.getWordIs(word)

        print word
        if wordIs("~oobe"):
            base.oobe()
        elif wordIs("~oobeCull"):
            base.oobeCull()
        elif wordIs("~tex"):
            self.doTex(word)
        elif wordIs("~texmem"):
            base.toggleTexMem()
        elif wordIs("~verts"):
            base.toggleShowVertices()
        elif wordIs("~wire"):
            base.toggleWireframe()
        elif wordIs("~stereo"):
            base.toggleStereo()
        elif wordIs("~showfont"):
            self.showfont(word[9:])
        elif wordIs("~hidefont"):
            self.hidefont()
        elif wordIs("~guiPopup"):
            self.toggleGuiPopup()

        elif wordIs("~showCS") or wordIs("~showcs"):
            bitmask = self.getCSBitmask(word[7:])
            render.showCS(bitmask)
            self.csShown = 1

        elif wordIs("~hideCS") or wordIs("~hidecs"):
            bitmask = self.getCSBitmask(word[7:])
            render.hideCS(bitmask)
            self.csShown = 0

        elif wordIs("~cs"):
            # Toggle hide/show collision solids:
            # (Also a shorthand for ~hideCS and ~showCS).
            bitmask = self.getCSBitmask(word[3:])
            if self.csShown:
                render.hideCS(bitmask)
                self.csShown = 0
            else:
                render.showCS(bitmask)
                self.csShown = 1

        elif wordIs("~showShadowCollisions"):
            self.showShadowCollisions()

        elif wordIs("~hideShadowCollisions"):
            self.hideShadowCollisions()

        elif wordIs("~showCollisions"):
            self.showCollisions()

        elif wordIs("~hideCollisions"):
            self.hideCollisions()

        elif wordIs("~showCameraCollisions"):
            self.showCameraCollisions()

        elif wordIs("~hideCameraCollisions"):
            self.hideCameraCollisions()

        elif wordIs("~collidespam"):
            n = Notify.ptr().getCategory(':collide')
            if hasattr(self, '_collideSpamSeverity'):
                n.setSeverity(self._collideSpamSeverity)
                del self._collideSpamSeverity
            else:
                self._collideSpamSeverity = n.getSeverity()
                n.setSeverity(NSSpam)

        elif wordIs("~notify"):
            args = word.split()
            n = Notify.ptr().getCategory(args[1])
            n.setSeverity({
                'error': NSError,
                'warning': NSWarning,
                'info': NSInfo,
                'debug': NSDebug,
                'spam': NSSpam,
            }[args[2]])

        # MPG we probably need generic versions of these
        #elif wordIs("~listen"):
        #    base.localAvatar.garbleChat = 0

        #elif wordIs("~nochat") or wordIs("~chat") or wordIs("~superchat"):
        #    base.localAvatar.garbleChat = 1

        elif wordIs("~stress"):
            factor = word[7:]
            if factor:
                factor = float(factor)
                LOD.setStressFactor(factor)
                response = "Set LOD stress factor to %s" % (factor)
            else:
                factor = LOD.getStressFactor()
                response = "LOD stress factor is %s" % (factor)

            self.setMagicWordResponse(response)

        elif wordIs("~for"):
            self.forAnother(word, avId, zoneId)

        elif wordIs("~badname"):
            # ~badname with an argument becomes ~for ... ~badname
            word = "~for %s ~badname" % (word[9:])
            print "word is %s" % (word)
            self.forAnother(word, avId, zoneId)

        elif wordIs('~avId'):
            self.setMagicWordResponse(str(localAvatar.doId))

        elif wordIs("~doId"):
            name = string.strip(word[6:])

            objs = self.identifyDistributedObjects(name)
            if (len(objs) == 0):
                response = "%s is unknown." % (name)
            else:
                response = ""
                for name, obj in objs:
                    response += "\n%s %d" % (name, obj.doId)
                response = response[1:]

            self.setMagicWordResponse(response)

        # MPG - need generic versions of these
        #elif wordIs("~collisions_on"):
        #    base.localAvatar.collisionsOn()

        #elif wordIs("~collisions_off"):
        #    base.localAvatar.collisionsOff()

        #elif wordIs('~addCameraPosition'):
        #    base.localAvatar.addCameraPosition()

        #elif wordIs('~removeCameraPosition'):
        #    base.localAvatar.removeCameraPosition()

        #elif wordIs('~printCameraPosition'):
        #    base.localAvatar.printCameraPosition(
        #        base.localAvatar.cameraIndex)

        #elif wordIs('~printCameraPositions'):
        #    base.localAvatar.printCameraPositions()

        elif wordIs("~exec"):
            # Enable execChat.
            from otp.chat import ChatManager
            ChatManager.ChatManager.execChat = 1

        elif wordIs("~run"):
            self.toggleRun()

        elif wordIs("~runFaster"):
            if (config.GetBool("want-running", 1)):
                args = word.split()
                if (len(args) > 1):
                    base.debugRunningMultiplier = float(args[1])
                else:
                    base.debugRunningMultiplier = 10
                inputState.set("debugRunning", True)

        elif wordIs("~who"):
            # Get all the nearby avIds and send them to the AI.
            avIds = []
            for av in Avatar.Avatar.ActiveAvatars:
                # If the avatar has a friends list, it's probably a
                # real avatar and not an NPC.
                if hasattr(av, "getFriendsList"):
                    avIds.append(av.doId)
            self.d_setWho(avIds)

        elif wordIs("~sync"):
            # Sync with the AI, like F6, but rather than accumulating
            # sync informatoin, throw away whatever information was
            # there from before.  If a second parameter is supplied,
            # it is a number of seconds of temporary extra skew to
            # apply; the default is 0.

            tm = self.cr.timeManager
            if tm == None:
                response = "No TimeManager."
                self.setMagicWordResponse(response)
            else:
                tm.extraSkew = 0.0
                skew = string.strip(word[5:])
                if skew != "":
                    tm.extraSkew = float(skew)
                globalClockDelta.clear()
                tm.handleHotkey()

        elif wordIs("~period"):
            # Reset the period timer to expire in the indicated number
            # of seconds, or with no parameter, report the number of
            # seconds remaining.

            timeout = string.strip(word[7:])
            if timeout != "":
                seconds = int(timeout)
                self.cr.stopPeriodTimer()
                self.cr.resetPeriodTimer(seconds)
                self.cr.startPeriodTimer()

            # Now report the number of seconds remaining.
            if self.cr.periodTimerExpired:
                response = "Period timer has expired."

            elif self.cr.periodTimerStarted:
                elapsed = globalClock.getFrameTime(
                ) - self.cr.periodTimerStarted
                secondsRemaining = self.cr.periodTimerSecondsRemaining - elapsed
                response = "Period timer expires in %s seconds." % (
                    int(secondsRemaining))
            else:
                response = "Period timer not set."

            self.setMagicWordResponse(response)

        elif wordIs("~DIRECT"):
            args = word.split()
            fEnableLight = 0
            if len(args) > 1:
                if direct and (args[1] == 'CAM'):
                    direct.enable()
                    taskMgr.removeTasksMatching('updateSmartCamera*')
                    camera.wrtReparentTo(render)
                    direct.cameraControl.enableMouseFly()
                    self.setMagicWordResponse("Enabled DIRECT camera")
                    return
                elif args[1] == 'LIGHT':
                    fEnableLight = 1
            # Start up DIRECT
            base.startTk()
            from direct.directtools import DirectSession
            if fEnableLight:
                direct.enableLight()
            else:
                direct.enable()
            self.setMagicWordResponse("Enabled DIRECT")

        elif wordIs("~TT"):
            if not direct:
                return
            args = word.split()
            if len(args) > 1:
                if (args[1] == 'CAM'):
                    direct.cameraControl.disableMouseFly()
                    camera.wrtReparentTo(base.localAvatar)
                    base.localAvatar.startUpdateSmartCamera()
                    self.setMagicWordResponse("Disabled DIRECT camera")
                    return
            # Return to toontown mode
            direct.disable()
            camera.wrtReparentTo(base.localAvatar)
            base.localAvatar.startUpdateSmartCamera()
            self.setMagicWordResponse("Disabled DIRECT")

        elif wordIs("~net"):
            # Simulate pulling or restoring the network plug.
            if self.cr.networkPlugPulled():
                self.cr.restoreNetworkPlug()
                self.cr.startHeartbeat()
                response = "Network restored."
            else:
                self.cr.pullNetworkPlug()
                self.cr.stopHeartbeat()
                response = "Network disconnected."
            self.setMagicWordResponse(response)

        elif wordIs('~disconnect'):
            # force a simulated disconnect
            # you can also do this from the OTP webpage
            base.cr.distributedDistrict.sendUpdate('broadcastMessage')

        elif wordIs("~model"):
            # load a model into the scene graph at the location of localAvatar
            args = word.split()
            path = args[1]
            model = loader.loadModel(path)
            model.reparentTo(localAvatar)
            model.wrtReparentTo(render)
            self.setMagicWordResponse('loaded %s' % path)

        elif wordIs("~axis"):
            # Show a 10 foot and 100 foot axis at the spot of the avatar
            # axis aligned to render
            axis = loader.loadModel("models/misc/xyzAxis.bam")
            axis.reparentTo(render)
            axis.setPos(base.localAvatar, 0, 0, 0)
            axis.setHpr(render, 0, 0, 0)
            axis10 = loader.loadModel("models/misc/xyzAxis.bam")
            axis10.reparentTo(render)
            axis10.setPos(base.localAvatar, 0, 0, 0)
            axis10.setScale(10)
            axis10.setHpr(render, 0, 0, 0)
            axis10.setColorScale(1, 1, 1, 0.4)
            axis10.setTransparency(1)

        elif (wordIs("~clearAxes") or wordIs("~clearAxis")):
            # Remove the effects of ~axis calls
            render.findAllMatches("**/xyzAxis.egg").detach()

        elif wordIs("~myAxis"):
            if hasattr(self, 'myAxis'):
                self.myAxis.detachNode()
                del self.myAxis
            else:
                self.myAxis = loader.loadModel("models/misc/xyzAxis.bam")
                self.myAxis.reparentTo(localAvatar)

        elif (wordIs("~osd")):
            onScreenDebug.enabled = not onScreenDebug.enabled

        elif wordIs("~osdScale"):
            args = word.split()
            defScale = .05
            if len(args) > 1:
                scale = float(args[1])
            else:
                scale = 1.
            onScreenDebug.onScreenText.setScale(defScale * scale)

        elif wordIs('~osdTaskMgr'):
            if taskMgr.osdEnabled():
                taskMgr.stopOsd()
            else:
                if not onScreenDebug.enabled:
                    onScreenDebug.enabled = True
                taskMgr.startOsd()

        elif wordIs("~fps"):
            self.doFps(word, avId, zoneId)

        elif wordIs("~sleep"):
            args = word.split()
            if len(args) > 1:
                s = float(args[1])
                base.setSleep(s)
                response = 'sleeping %s' % s
            else:
                base.setSleep(0.0)
                response = 'not sleeping'
            self.setMagicWordResponse(response)

        elif wordIs('~objects'):
            args = word.split()
            from direct.showbase import ObjectReport
            report = ObjectReport.ObjectReport('client ~objects')

            if 'all' in args:
                self.notify.info('printing full object set...')
                report.getObjectPool().printObjsByType(
                    printReferrers='ref' in args)

            if hasattr(self, 'baselineObjReport'):
                self.notify.info(
                    'calculating diff from baseline ObjectReport...')
                self.lastDiff = self.baselineObjReport.diff(report)
                self.lastDiff.printOut(full=('diff' in args or 'dif' in args))

            if 'baseline' in args or not hasattr(self, 'baselineObjReport'):
                self.notify.info('recording baseline ObjectReport...')
                if hasattr(self, 'baselineObjReport'):
                    self.baselineObjReport.destroy()
                self.baselineObjReport = report

            self.setMagicWordResponse('objects logged')

        elif wordIs('~objecthg'):
            import gc
            objs = gc.get_objects()
            type2count = {}
            for obj in objs:
                tn = safeTypeName(obj)
                type2count.setdefault(tn, 0)
                type2count[tn] += 1
            count2type = invertDictLossless(type2count)
            counts = count2type.keys()
            counts.sort()
            counts.reverse()
            for count in counts:
                print '%s: %s' % (count, count2type[count])
            self.setMagicWordResponse('~aiobjecthg complete')

        elif wordIs('~containers'):
            args = word.split()
            limit = 30
            if 'full' in args:
                limit = None
            ContainerReport.ContainerReport('~containers',
                                            log=True,
                                            limit=limit,
                                            threaded=True)

        elif wordIs('~garbage'):
            args = word.split()
            # it can take a LOOONG time to print out the garbage referrers and referents
            # by reference (as opposed to by number)
            full = 'full' in args
            safeMode = 'safe' in args
            delOnly = 'delonly' in args
            # This does a garbage collection and dumps the list of leaked (uncollectable) objects to the log.
            GarbageReport.GarbageLogger('~garbage',
                                        fullReport=full,
                                        threaded=True,
                                        safeMode=safeMode,
                                        delOnly=delOnly,
                                        doneCallback=self.garbageReportDone)
            # this is coming back from the AI
            #self.setMagicWordResponse('garbage logged')

        elif wordIs('~guicreates'):
            base.printGuiCreates = True
            self.setMagicWordResponse('printing gui creation stacks')

        elif wordIs("~creategarbage"):
            GarbageReport._createGarbage()
            # this is coming back from the AI
            #self.setMagicWordResponse(senderId, 'leaked garbage created')

        elif wordIs('~leakTask'):

            def leakTask(task):
                return task.cont

            taskMgr.add(leakTask, uniqueName('leakedTask'))
            leakTask = None
            # this is coming back from the AI
            #self.setMagicWordResponse(senderId, 'leaked task created')

        elif wordIs('~leakmessage'):
            MessengerLeakDetector._leakMessengerObject()
            self.down_setMagicWordResponse(senderId,
                                           'messenger leak object created')

        elif wordIs('~pstats'):
            args = word.split()
            hostname = None
            port = None
            if len(args) > 1:
                hostname = args[1]
            if len(args) > 2:
                port = int(args[2])
            # make sure pstats is enabled
            base.wantStats = 1
            Task.TaskManager.pStatsTasks = 1
            result = base.createStats(hostname, port)
            connectionName = '%s' % hostname
            if port is not None:
                connectionName += ':%s' % port
            if result:
                response = 'connected client pstats to %s' % connectionName
            else:
                response = 'could not connect pstats to %s' % connectionName
            self.setMagicWordResponse(response)

        elif wordIs('~profile'):
            args = word.split()
            if len(args) > 1:
                num = int(args[1])
            else:
                num = 5
            session = taskMgr.getProfileSession('~profile')
            session.setLogAfterProfile(True)
            taskMgr.profileFrames(num, session)
            self.setMagicWordResponse('profiling %s client frames...' % num)

        elif wordIs('~frameprofile'):
            args = word.split()
            wasOn = bool(taskMgr.getProfileFrames())
            if len(args) > 1:
                setting = bool(int(args[1]))
            else:
                setting = not wasOn
            taskMgr.setProfileFrames(setting)
            self.setMagicWordResponse(
                'frame profiling %s%s' %
                (choice(setting, 'ON',
                        'OFF'), choice(wasOn == setting, ' already', '')))

        elif wordIs('~taskprofile'):
            args = word.split()
            wasOn = bool(taskMgr.getProfileTasks())
            if len(args) > 1:
                setting = bool(int(args[1]))
            else:
                setting = not wasOn
            taskMgr.setProfileTasks(setting)
            self.setMagicWordResponse(
                'task profiling %s%s' %
                (choice(setting, 'ON',
                        'OFF'), choice(wasOn == setting, ' already', '')))

        elif wordIs('~taskspikethreshold'):
            args = word.split()
            if len(args) > 1:
                threshold = float(args[1])
                response = 'task spike threshold set to %ss' % threshold
            else:
                threshold = TaskProfiler.GetDefaultSpikeThreshold()
                response = 'task spike threshold reset to %ss' % threshold
            TaskProfiler.SetSpikeThreshold(threshold)
            self.setMagicWordResponse(response)

        elif wordIs('~logtaskprofiles'):
            args = word.split()
            if len(args) > 1:
                name = args[1]
            else:
                name = None
            taskMgr.logTaskProfiles(name)
            response = 'logged task profiles%s' % choice(
                name, ' for %s' % name, '')
            self.setMagicWordResponse(response)

        elif wordIs('~taskprofileflush'):
            args = word.split()
            if len(args) > 1:
                name = args[1]
            else:
                name = None
            taskMgr.flushTaskProfiles(name)
            response = 'flushed AI task profiles%s' % choice(
                name, ' for %s' % name, '')
            self.setMagicWordResponse(response)

        elif wordIs('~objectcount'):
            base.cr.printObjectCount()
            self.setMagicWordResponse(
                'logging client distributed object count...')

        elif wordIs('~taskmgr'):
            print taskMgr
            self.setMagicWordResponse('logging client taskMgr...')

        elif wordIs('~jobmgr'):
            print jobMgr
            self.setMagicWordResponse('logging client jobMgr...')

        elif wordIs('~jobtime'):
            args = word.split()
            if len(args) > 1:
                time = float(args[1])
            else:
                time = None
            response = ''
            if time is None:
                time = jobMgr.getDefaultTimeslice()
                response = 'reset client jobMgr timeslice to %s ms' % time
            else:
                response = 'set client jobMgr timeslice to %s ms' % time
                time = time / 1000.
            jobMgr.setTimeslice(time)
            self.setMagicWordResponse(response)

        elif wordIs('~detectleaks'):
            started = self.cr.startLeakDetector()
            self.setMagicWordResponse(
                choice(
                    started,
                    'leak detector started',
                    'leak detector already started',
                ))

        elif wordIs('~taskthreshold'):
            args = word.split()
            if len(args) > 1.:
                threshold = float(args[1])
            else:
                threshold = None
            response = ''
            if threshold is None:
                threshold = taskMgr.DefTaskDurationWarningThreshold
                response = 'reset task duration warning threshold to %s' % threshold
            else:
                response = 'set task duration warning threshold to %s' % threshold
            taskMgr.setTaskDurationWarningThreshold(threshold)
            self.setMagicWordResponse(response)

        elif wordIs('~messenger'):
            print messenger
            self.setMagicWordResponse('logging client messenger...')

        elif wordIs('~clientcrash'):
            # if we call notify.error directly, the magic word mgr will catch it
            # self.notify.error doesn't seem to work either
            DelayedCall(
                Functor(self.notify.error,
                        '~clientcrash: simulating a client crash'))

        elif wordIs('~badDelete'):
            doId = 0
            while doId in base.cr.doId2do:
                doId += 1
            # location (0,0) is special, pass in (1,1)
            # deleteObjectLocation expects a DO, pass in a ScratchPad instead
            # we must delay the call because magicWordMgr is in a big try/except block
            DelayedCall(
                Functor(base.cr.deleteObjectLocation, ScratchPad(doId=doId), 1,
                        1))
            self.setMagicWordResponse('doing bad delete')

        elif wordIs("~idTags"):
            messenger.send('nameTagShowAvId', [])
            base.idTags = 1

        elif wordIs("~nameTags"):
            messenger.send('nameTagShowName', [])
            base.idTags = 0

        elif wordIs("~hideNames"):
            # note do ~hideNames before ~hideGui if you want both off
            if NametagGlobals.getMasterNametagsVisible():
                NametagGlobals.setMasterNametagsVisible(0)
            else:
                NametagGlobals.setMasterNametagsVisible(1)

        elif wordIs("~hideGui"):
            if aspect2d.isHidden():
                aspect2d.show()
            else:
                aspect2d.hide()

        elif wordIs('~flush'):
            base.cr.doDataCache.flush()
            base.cr.cache.flush()
            self.setMagicWordResponse('client object and data caches flushed')

        elif wordIs('~prof'):
            import time

            ### set up ###
            name = 'default'
            p = Point3()
            ##############

            ts = time.time()
            for i in xrange(1000000):

                ### code to be timed ###
                p.set(1, 2, 3)
                ########################

            tf = time.time()
            dt = tf - ts
            response = 'prof(%s): %s secs' % (name, dt)
            print response
            self.setMagicWordResponse(response)

        elif wordIs('~gptc'):
            args = word.split()
            if len(args) > 1. and hasattr(self.cr, 'leakDetector'):
                gptcJob = self.cr.leakDetector.getPathsToContainers(
                    '~gptc', args[1], Functor(self._handleGPTCfinished,
                                              args[1]))
            else:
                self.setMagicWordResponse('error')

        elif wordIs('~gptcn'):
            args = word.split()
            if len(args) > 1. and hasattr(self.cr, 'leakDetector'):
                gptcnJob = self.cr.leakDetector.getPathsToContainersNamed(
                    '~gptcn', args[1],
                    Functor(self._handleGPTCNfinished, args[1]))
            else:
                self.setMagicWordResponse('error')

        else:
            # Not a magic word I know!
            return 0

        return 1