def __handleUnexpectedExit(self, avId): self.notify.warning('avatar:' + str(avId) + ' has exited unexpectedly') # Only do customer work with the busy id if (self.customerId == avId): taskMgr.remove(self.uniqueName('clearMovie')) toon = self.air.doId2do.get(avId) if (toon == None): toon = DistributedToonAI.DistributedToonAI(self.air) toon.doId = avId if self.customerDNA: toon.b_setDNAString(self.customerDNA.makeNetString()) # Force a database write since the toon is gone and might # have missed the distributed update. db = DatabaseObject.DatabaseObject(self.air, avId) db.storeObject(toon, ["setDNAString"]) else: self.notify.warning('invalid customer avId: %s, customerId: %s ' % (avId, self.customerId)) # Only do busy work with the busy id # Warning: send the clear movie at the end of this transaction because # it clears out all the useful values needed here if (self.busy == avId): self.sendClearMovie(None) else: self.notify.warning('not busy with avId: %s, busy: %s ' % (avId, self.busy))
def lookupHouse(self): # Looks up the avatar's house information so we can figure out # how much stuff is in the attic. We need to tell this # information to the client so it can warn the user if he's in # danger of overfilling it. if not self.av.houseId: self.notify.warning("Avatar %s has no houseId." % (self.av.doId)) self.sendCatalog(0) return # Maybe the house is already instantiated. This will be true # when the avatar is calling from his own house, for instance. house = self.air.doId2do.get(self.av.houseId) if house: assert(self.notify.debug("House %s is already instantiated." % (self.av.houseId))) numAtticItems = len(house.atticItems) + len(house.atticWallpaper) + len(house.atticWindows) numHouseItems = numAtticItems + len(house.interiorItems) self.sendCatalog(numHouseItems) return # All right, we have to query the database to get the attic # information. What a nuisance. assert(self.notify.debug("Querying database for house %s." % (self.av.houseId))) gotHouseEvent = self.uniqueName("gotHouse") self.acceptOnce(gotHouseEvent, self.__gotHouse) db = DatabaseObject.DatabaseObject(self.air, self.av.houseId) db.doneEvent = gotHouseEvent db.getFields(['setAtticItems', 'setAtticWallpaper', 'setAtticWindows', 'setInteriorItems'])
def checkOwner(self): # Checks whether the owner still exists, and checks whether # he's got stuff waiting in his mailbox. self.notify.debug("__checkOwner: %s" % (self.doId)) if self.ownerId == 0: # No owner. Duh. self.d_setHouseReady() return owner = self.air.doId2do.get(self.ownerId) if owner and hasattr(owner, "onOrder"): # The avatar is in the live database. hp = owner.getMaxHp() #self.b_setCannonEnabled(1) self.__checkMailbox(owner.onOrder, owner.mailboxContents, 1, owner.awardMailboxContents, owner.numMailItems, owner.getNumInvitesToShowInMailbox()) else: # We have to go query the database for the avatar's info. gotAvEvent = self.uniqueName("gotAvatar") self.acceptOnce(gotAvEvent, self.__gotOwnerAv) db = DatabaseObject.DatabaseObject(self.air, self.ownerId) db.doneEvent = gotAvEvent db.getFields([ 'setDeliverySchedule', 'setMailboxContents', 'setMaxHp', 'setAwardMailboxContents' ])
def deletePetObject(self, petId): """ USE WITH CAUTION, this could delete any DB record (such as Toons or Houses) """ assert petId != 0 PetManagerAI.notify.warning('deleting pet %s' % petId) self.air.writeServerEvent('deletePetObject', petId, '') dbo = DatabaseObject.DatabaseObject(self.air, petId) dbo.deleteObject()
def enterAvatar(self): self.notify.debug("enterAvatar") avId = self.air.getAvatarIdFromSender() # this avatar has come within range assert (self.debugPrint("avatar opening closet: " + str(avId))) # If the closet is already being used, free this avatar if self.busy > 0: self.freeAvatar(avId) return # Store the original customer DNA so we can revert if a disconnect # happens av = self.air.doId2do.get(avId) if not av: return #something has gone horridly wrong lets not crash the ai self.customerDNA = ToonDNA.ToonDNA() self.customerDNA.makeFromNetString(av.getDNAString()) self.customerId = avId self.busy = avId print( "av %s: entering closet with shirt(%s,%s,%s,%s) and shorts(%s,%s)" % (avId, self.customerDNA.topTex, self.customerDNA.topTexColor, self.customerDNA.sleeveTex, self.customerDNA.sleeveTexColor, self.customerDNA.botTex, self.customerDNA.botTexColor)) # Handle unexpected exit self.acceptOnce(self.air.getAvatarExitEvent(avId), self.__handleUnexpectedExit, extraArgs=[avId]) self.acceptOnce("bootAvFromEstate-" + str(avId), self.__handleBootMessage, extraArgs=[avId]) # Find the owner of the closet if self.ownerId: self.ownerAv = None if self.air.doId2do.has_key(self.ownerId): self.ownerAv = self.air.doId2do[self.ownerId] self.__openCloset() else: gotAvEvent = self.uniqueName("gotAvatar") self.accept(gotAvEvent, self.__gotOwnerAv) aidc = self.air.dclassesByName['DistributedToonAI'] db = DatabaseObject.DatabaseObject(simbase.air, self.ownerId) db.doneEvent = gotAvEvent db.getFields(db.getDatabaseFields(aidc)) else: print "this house has no owner, therefore we can't use the closet" # send a reset message to the client. same as a completed purchase self.completePurchase(avId)
def checkAvatarThenGift(self, targetDoID, sAvId, item, context): # Requests a particular avatar. The avatar will be requested # from the database and stored in self.rav when the response is # heard back from the database, at some time in the future. #self.rAv = None checkMessage = "gift check %s" % (targetDoID) self.acceptOnce(("gift check %s" % (targetDoID)), self.__gotAvGiftCheck, [targetDoID, sAvId, item, context]) db = DatabaseObject.DatabaseObject(self.air, targetDoID) db.doneEvent = checkMessage fields = ['setDNAString'] db.getFields(fields)
def __handleUnexpectedExit(self, avId): self.notify.warning('avatar:' + str(avId) + ' has exited unexpectedly') if self.customerId == avId: toon = self.air.doId2do.get(avId) if toon == None: toon = DistributedToonAI.DistributedToonAI(self.air) toon.doId = avId if self.customerDNA: toon.b_setDNAString(self.customerDNA.makeNetString()) db = DatabaseObject.DatabaseObject(self.air, avId) db.storeObject(toon, ['setDNAString']) else: self.notify.warning('invalid customer avId: %s, customerId: %s ' % (avId, self.customerId)) if self.busy == avId: self.sendClearMovie(None) else: self.notify.warning('not busy with avId: %s, busy: %s ' % (avId, self.busy))
def createNewPetObject(self, callback): """ creates a new pet object in the DB """ # callback must accept (success, petId) # petId is undefined if !success doneEvent = 'createPetObject-%s' % self._getNextSerialNum() dbo = DatabaseObject.DatabaseObject(self.air, doneEvent=doneEvent) def handleCreateNewPet(dbo, retCode, callback=callback): success = (retCode == 0) if success: petId = dbo.doId else: PetManagerAI.notify.warning('pet creation failed') petId = None callback(success, petId) self.acceptOnce(doneEvent, handleCreateNewPet) dbo.createObject(ToontownAIMsgTypes.DBSERVER_PET_OBJECT_TYPE)
def getPetObject(self, petId, callback): """get an instance of a pet callback must accept (success, pet) pet is undefined if !success On success, pet MUST be instantiated with DistributedObjectAI.generateWithRequiredAndId, using the correct pet doId. """ doneEvent = 'readPet-%s' % self._getNextSerialNum() dbo = DatabaseObject.DatabaseObject(self.air, petId, doneEvent=doneEvent) pet = dbo.readPet() def handlePetRead(dbo, retCode, callback=callback, pet=pet): success = (retCode == 0) if not success: PetManagerAI.notify.warning('pet DB read failed') pet = None callback(success, pet) self.acceptOnce(doneEvent, handlePetRead)