def getItems(self): items = CatalogItemList(store=CatalogItem.Customization|CatalogItem.Location) for item in self.items: items.append(item.catalogItem) return items.getBlob()
def getItems(self): items = CatalogItemList(store=CatalogItem.Customization|CatalogItem.Location) for item in self.items: items.append(item.catalogItem) return items.getBlob()
class DNAFurnitureReaderAI: # This object processes the house_interior*.dna files and produces a # CatalogItemList representing the furniture in the DNA file. The resulting # list is passed to the FurnitureManager in order to initialize a blank # house to the default furniture arrangement. notify = directNotify.newCategory("DNAFurnitureReaderAI") def __init__(self, dnaData, gender, phonePos): self.dnaData = dnaData self.gender = gender self.phonePos = phonePos self.itemList = None def buildList(self): self.itemList = CatalogItemList(store=(CatalogItem.Customization | CatalogItem.Location)) # Find the interior node: for i in xrange(self.dnaData.getNumChildren()): child = self.dnaData.at(i) if child.getName() == 'interior': interior = child break else: self.notify.error('Could not find "interior" in DNA!') self.itemList.append(CatalogFurnitureItem(1399, posHpr=self.phonePos)) # Every child in the interior node is a prop, thus: for i in xrange(interior.getNumChildren()): child = interior.at(i) code = child.getCode() if code not in DNA2Furniture: self.notify.warning('Unrecognized furniture code %r!' % code) continue itemId = DNA2Furniture[code] if itemId is None: continue if hasattr(itemId, '__getitem__'): itemId = itemId[self.gender] x, y, z = child.getPos() h, p, r = child.getHpr() self.itemList.append( CatalogFurnitureItem(itemId, posHpr=(x, y, z, h, p, r))) def getList(self): if not self.itemList: self.buildList() return self.itemList def getBlob(self): return self.getList().getBlob()
class DNAFurnitureReaderAI: # This object processes the house_interior*.dna files and produces a # CatalogItemList representing the furniture in the DNA file. The resulting # list is passed to the FurnitureManager in order to initialize a blank # house to the default furniture arrangement. notify = directNotify.newCategory("DNAFurnitureReaderAI") def __init__(self, dnaData, gender, phonePos): self.dnaData = dnaData self.gender = gender self.phonePos = phonePos self.itemList = None def buildList(self): self.itemList = CatalogItemList(store=(CatalogItem.Customization | CatalogItem.Location)) # Find the interior node: for i in xrange(self.dnaData.getNumChildren()): child = self.dnaData.at(i) if child.getName() == 'interior': interior = child break else: self.notify.error('Could not find "interior" in DNA!') self.itemList.append(CatalogFurnitureItem(1399, posHpr=self.phonePos)) # Every child in the interior node is a prop, thus: for i in xrange(interior.getNumChildren()): child = interior.at(i) code = child.getCode() if code not in DNA2Furniture: self.notify.warning('Unrecognized furniture code %r!' % code) continue itemId = DNA2Furniture[code] if itemId is None: continue if hasattr(itemId, '__getitem__'): itemId = itemId[self.gender] x, y, z = child.getPos() h, p, r = child.getHpr() self.itemList.append(CatalogFurnitureItem(itemId, posHpr=(x, y, z, h, p, r))) def getList(self): if not self.itemList: self.buildList() return self.itemList def getBlob(self): return self.getList().getBlob()
def createInterior(self): self.houseInterior = random.choice(HouseGlobals.interiors) self.dnaData = self.air.loadDNAFileAI(self.dnaStore, self.houseInterior[0]) furnitureData = {} for i in xrange(self.dnaData.getNumChildren()): node = self.dnaData.at(i) if node.getName() == 'interior': for j in xrange(node.getNumChildren()): obj = node.at(j) objName = obj.getName() x, y, z = obj.getPos() h, p, r = obj.getHpr() code = obj.getCode() furnitureData[objName] = { 'code': code, 'posHpr': (x, y, z, h, 0, 0), 'scale': obj.getScale(), 'itemId': code2furnitureId.get(code, 0) } furnitureData['phone'] = { 'code': 'phone', 'posHpr': (-11, 2, 0, 0, 0, 0), 'scale': 'phone', 'itemId': code2furnitureId.get('phone', 0) } interiorItems = CatalogItemList(store=CatalogItem.Customization | CatalogItem.Location) ignoredItems = ['house_interiorA_DNARoot', 'GardenA_DNARoot'] for name, data in furnitureData.iteritems(): itemId = data.get('itemId', 0) if itemId == 0: if name not in ignoredItems: self.notify.warning( 'Tried to generate item %s but the ID was not found!' % name) continue if name == 'closetBoy_DNARoot' and self.gender == 'f': itemId += 10 newItem = CatalogFurnitureItem(itemId, posHpr=data.get('posHpr')) interiorItems.append(newItem) self.house.b_setInteriorItems(interiorItems.getBlob()) self.house.b_setInteriorWindows(defaultWindows.getBlob()) self.house.b_setInteriorWallpaper(defaultWallpaper.getBlob()) self.furnitureManager.wallpaper = self.house.interiorWallpaper self.furnitureManager.windows = self.house.interiorWindows self.furnitureManager.loadFurniture() self.furnitureManager.saveFurniture()
def setItems(self, items): # Decode the blob: items = CatalogItemList(items, store=CatalogItem.Customization | CatalogItem.Location) # Throw out our old items: for item in self.items: item.destroy() self.items = [] items.removeDuplicates(FLCloset) # Due to a bug, some people are missing their closets... hasCloset = False for item in items: if item.getFlags() & FLCloset: hasCloset = True break if not hasCloset and self.ownerId != 0: item = CatalogFurnitureItem(500) # the basic closet... item.posHpr = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0) items.append(item) # Since we have modified the items list, should we save it back to the house? for item in items: if item.getFlags() & FLTrunk: if self.house.gender is 0: if item.furnitureType - 4000 < 10: item.furnitureType += 10 elif item.furnitureType - 4000 > 10: item.furnitureType -= 10 do = DistributedTrunkAI(self.air, self, item) elif item.getFlags() & FLCloset: if self.house.gender is 0: if item.furnitureType - 500 < 10: item.furnitureType += 10 elif item.furnitureType - 500 > 10: item.furnitureType -= 10 do = DistributedClosetAI(self.air, self, item) elif item.getFlags() & FLBank: continue # We dont want banks in the estates. elif item.getFlags() & FLPhone: do = DistributedPhoneAI(self.air, self, item) else: do = DistributedFurnitureItemAI(self.air, self, item) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do)
def setItems(self, items): # Decode the blob: items = CatalogItemList(items, store=CatalogItem.Customization|CatalogItem.Location) # Throw out our old items: for item in self.items: item.destroy() self.items = [] items.removeDuplicates(FLCloset) # Due to a bug, some people are missing their closets... hasCloset = False for item in items: if item.getFlags() & FLCloset: hasCloset = True break if not hasCloset and self.ownerId != 0: item = CatalogFurnitureItem(500) # the basic closet... item.posHpr = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0) items.append(item) # Since we have modified the items list, should we save it back to the house? for item in items: if item.getFlags() & FLTrunk: if self.house.gender is 0: if item.furnitureType - 4000 < 10: item.furnitureType += 10 elif item.furnitureType - 4000 > 10: item.furnitureType -= 10 do = DistributedTrunkAI(self.air, self, item) elif item.getFlags() & FLCloset: if self.house.gender is 0: if item.furnitureType - 500 < 10: item.furnitureType += 10 elif item.furnitureType - 500 > 10: item.furnitureType -= 10 do = DistributedClosetAI(self.air, self, item) elif item.getFlags() & FLBank: continue # We dont want banks in the estates. elif item.getFlags() & FLPhone: do = DistributedPhoneAI(self.air, self, item) else: do = DistributedFurnitureItemAI(self.air, self, item) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do)
class DNAFurnitureReaderAI: notify = DirectNotifyGlobal.directNotify.newCategory( 'DNAFurnitureReaderAI') def __init__(self, dnaData): self.dnaData = dnaData self.itemList = None return def buildList(self): self.itemList = CatalogItemList(store=CatalogItem.Customization | CatalogItem.Location) for i in xrange(self.dnaData.getNumChildren()): child = self.dnaData.at(i) if child.getName() == 'interior': interior = child break else: self.notify.error('Could not find "interior" in DNA!') for i in xrange(interior.getNumChildren()): child = interior.at(i) code = child.getCode() if code not in DNA2Furniture: self.notify.warning('Unrecognized furniture code %r!' % code) continue itemId = DNA2Furniture[code] if itemId is None: continue x, y, z = child.getPos() h, p, r = child.getHpr() self.itemList.append( CatalogFurnitureItem(itemId, posHpr=(x, y, z, h, p, r))) return def getList(self): if not self.itemList: self.buildList() return self.itemList def getBlob(self): return self.getList().getBlob()
class DistributedHouseAI(DistributedObjectAI): notify = directNotify.newCategory("DistributedHouseAI") def __init__(self, air): DistributedObjectAI.__init__(self, air) self.houseType = 0 self.gardenPos = 0 self.avatarId = 0 self.name = '' self.color = 0 self.housePos = 0 self.gender = 1 self.isInteriorInitialized = 1 self.atticItems = CatalogItemList(store=Customization) self.interiorItems = CatalogItemList(store=Customization) self.interiorWallpaper = CatalogItemList(store=Customization) self.atticWallpaper = CatalogItemList(store=Customization) self.interiorWindows = CatalogItemList(store=Customization) self.atticWindows = CatalogItemList(store=Customization) self.deletedItems = CatalogItemList(store=Customization) def announceGenerate(self): DistributedObjectAI.announceGenerate(self) self.interiorZone = self.air.allocateZone() self.door = DistributedHouseDoorAI(self.air, self.getDoId(), DoorTypes.EXT_STANDARD) self.door.setSwing(3) self.door.generateWithRequired(self.zoneId) self.interiorDoor = DistributedHouseDoorAI(self.air, self.getDoId(), DoorTypes.INT_STANDARD) self.interiorDoor.setSwing(3) self.interiorDoor.setOtherDoor(self.door) self.interiorDoor.generateWithRequired(self.interiorZone) self.door.setOtherDoor(self.interiorDoor) self.interior = DistributedHouseInteriorAI(self.air, self) self.interior.setHouseIndex(self.housePos) self.interior.setHouseId(self.getDoId()) self.interior.generateWithRequired(self.interiorZone) if self.avatarId: self.mailbox = DistributedMailboxAI(self.air, self) self.mailbox.generateWithRequired(self.zoneId) if not self.isInteriorInitialized: self.notify.info('Initializing interior...') self.interior.initialize() self.b_setInteriorInitialized(1) self.sendUpdate('setHouseReady', []) def delete(self): self.door.requestDelete() self.interiorDoor.requestDelete() self.interior.requestDelete() if self.avatarId: self.mailbox.requestDelete() self.air.deallocateZone(self.interiorZone) DistributedObjectAI.delete(self) def setHousePos(self, pos): self.housePos = pos def d_setHousePos(self, pos): self.sendUpdate('setHousePos', [pos]) def b_setHousePos(self, pos): self.setHousePos(pos) self.d_setHousePos(pos) def getHousePos(self): return self.housePos def setHouseType(self, type): self.houseType = type def d_setHouseType(self, type): self.sendUpdate('setHouseType', [type]) def b_setHouseType(self, type): self.setHouseType(type) self.d_setHouseType(type) def getHouseType(self): return self.houseType def setGardenPos(self, pos): self.gardenPos = pos def d_setGardenPos(self, pos): self.sendUpdate('setGardenPos', [pos]) def b_setGardenPos(self, pos): self.setGardenPow(pos) self.d_setGardenPos(pos) def getGardenPos(self): return self.gardenPos def setAvatarId(self, avId): self.avatarId = avId def d_setAvatarId(self, avId): self.sendUpdate('setAvatarId', [avId]) def b_setAvatarId(self, avId): self.setAvatarId(avId) self.d_setAvatarId(avId) def getAvatarId(self): return self.avatarId def setName(self, name): self.name = name def d_setName(self, name): self.sendUpdate('setName', [name]) def b_setName(self, name): self.setName(name) self.d_setName(name) def getName(self): return self.name def setColor(self, color): self.color = color def d_setColor(self, color): self.sendUpdate('setColor', [color]) def b_setColor(self, color): self.setColor(color) self.d_setColor(color) def getColor(self): return self.color def setGender(self, genderIndex): self.gender = genderIndex def getGender(self): return self.gender def setAtticItems(self, atticItems): self.atticItems = CatalogItemList(atticItems, store=Customization) def d_setAtticItems(self, atticItems): self.sendUpdate('setAtticItems', [atticItems]) def b_setAtticItems(self, atticItems): self.setAtticItems(atticItems) self.d_setAtticItems(atticItems) def getAtticItems(self): return self.atticItems.getBlob() def setInteriorItems(self, interiorItems): self.interiorItems = CatalogItemList(interiorItems, store=Customization | Location) def d_setInteriorItems(self, interiorItems): self.sendUpdate('setInteriorItems', [interiorItems]) def b_setInteriorItems(self, interiorItems): self.setInteriorItems(interiorItems) self.d_setInteriorItems(interiorItems) def getInteriorItems(self): return self.interiorItems.getBlob() def setAtticWallpaper(self, atticWallpaper): self.atticWallpaper = CatalogItemList(atticWallpaper, store=Customization) def d_setAtticWallpaper(self, atticWallpaper): self.sendUpdate('setAtticWallpaper', [atticWallpaper]) def b_setAtticWallpaper(self, atticWallpaper): self.setAtticWallpaper(atticWallpaper) self.d_setAtticWallpaper(atticWallpaper) def getAtticWallpaper(self): return self.atticWallpaper.getBlob() def setInteriorWallpaper(self, interiorWallpaper): self.interiorWallpaper = CatalogItemList(interiorWallpaper, store=Customization) def d_setInteriorWallpaper(self, interiorWallpaper): self.sendUpdate('setInteriorWallpaper', [interiorWallpaper]) def b_setInteriorWallpaper(self, interiorWallpaper): self.setInteriorWallpaper(interiorWallpaper) self.d_setInteriorWallpaper(interiorWallpaper) def getInteriorWallpaper(self): return self.interiorWallpaper.getBlob() def setAtticWindows(self, atticWindows): self.atticWindows = CatalogItemList(atticWindows, store=Customization) def d_setAtticWindows(self, atticWindows): self.sendUpdate('setAtticWindows', [atticWindows]) def b_setAtticWindows(self, atticWindows): self.setAtticWindows(atticWindows) self.d_setAtticWindows(atticWindows) def getAtticWindows(self): return self.atticWindows.getBlob() def setInteriorWindows(self, interiorWindows): self.interiorWindows = CatalogItemList(interiorWindows, store=Customization | WindowPlacement) def d_setInteriorWindows(self, interiorWindows): self.sendUpdate('setInteriorWindows', [interiorWindows]) def b_setInteriorWindows(self, interiorWindows): self.setInteriorWindows(interiorWindows) self.d_setInteriorWindows(interiorWindows) def getInteriorWindows(self): return self.interiorWindows.getBlob() def setDeletedItems(self, deletedItems): self.deletedItems = CatalogItemList(deletedItems, store=Customization) def d_setDeletedItems(self, deletedItems): self.sendUpdate('setDeletedItems', [deletedItems]) def b_setDeletedItems(self, deletedItems): self.setDeletedItems(deletedItems) self.d_setDeletedItems(deletedItems) def getDeletedItems(self): return self.deletedItems.getBlob() def setInteriorInitialized(self, initialized): self.isInteriorInitialized = initialized def d_setInteriorInitialized(self, initialized): self.sendUpdate('setInteriorInitialized', [initialized]) def b_setInteriorInitialized(self, initialized): self.setInteriorInitialized(initialized) self.d_setInteriorInitialized(initialized) def getInteriorInitialized(self): return self.isInteriorInitialized def setCannonEnabled(self, todo0): pass def getCannonEnabled(self): return 0 def setHouseReady(self): pass def addAtticItem(self, item): self.interior.furnitureManager.saveToHouse() if item.getFlags() & FLTrunk: self.atticItems.append(item) elif item.replacesExisting() and item.hasExisting(): if item.getFlags() & FLCloset: closets = ClosetToClothes.keys() for itItem in self.interiorItems: if itItem.furnitureType in closets: posHpr = itItem.posHpr self.interiorItems.remove(itItem) item.posHpr = posHpr self.interiorItems.append(item) break for itItem in self.atticItems: if itItem.furnitureType in closets: self.atticItems.remove(itItem) self.atticItems.append(item) break else: self.atticItems.append(item) self.d_setAtticItems(self.atticItems.getBlob()) self.d_setInteriorItems(self.interiorItems.getBlob()) self.interior.furnitureManager.loadFromHouse() def addWindow(self, item): self.interior.furnitureManager.saveToHouse() self.atticWindows.append(item) self.d_setAtticWindows(self.atticWindows.getBlob()) self.interior.furnitureManager.loadFromHouse() def addWallpaper(self, item): self.interior.furnitureManager.saveToHouse() self.atticWallpaper.append(item) self.d_setAtticWallpaper(self.atticWallpaper.getBlob()) self.interior.furnitureManager.loadFromHouse()
class DistributedFurnitureManagerAI(DistributedObjectAI): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedFurnitureManagerAI') def __init__(self, air, house, interior): DistributedObjectAI.__init__(self, air) self.house = house self.interior = interior self.director = None self.ownerId = house.avatarId self.ownerName = house.name self.avId = None self.atticItems = None self.atticWallpaper = None self.wallpaper = None self.atticWindows = None self.windows = None self.deletedItems = None self.items = [] self.loadFromHouse() def announceGenerate(self): DistributedObjectAI.announceGenerate(self) for item in self.items: item.generateWithRequired(self.zoneId) def delete(self): for item in self.items: item.destroy() DistributedObjectAI.delete(self) def loadFromHouse(self): self.b_setAtticItems(self.house.getAtticItems()) self.b_setAtticWallpaper(self.house.getAtticWallpaper()) self.b_setAtticWindows(self.house.getAtticWindows()) self.b_setDeletedItems(self.house.getDeletedItems()) self.wallpaper = CatalogItemList(self.house.getInteriorWallpaper(), store=CatalogItem.Customization) self.applyWallpaper() self.windows = CatalogItemList(self.house.getInteriorWindows(), store=CatalogItem.Customization | CatalogItem.WindowPlacement) self.applyWindows() self.setItems(self.house.getInteriorItems()) def saveToHouse(self): self.house.b_setAtticItems(self.getAtticItems()) self.house.b_setAtticWallpaper(self.getAtticWallpaper()) self.house.b_setAtticWindows(self.getAtticWindows()) self.house.b_setDeletedItems(self.getDeletedItems()) self.house.b_setInteriorWallpaper(self.wallpaper.getBlob()) self.house.b_setInteriorWindows(self.windows.getBlob()) self.house.b_setInteriorItems(self.getItems()) def applyWallpaper(self): self.interior.b_setWallpaper(self.wallpaper.getBlob()) def applyWindows(self): self.interior.b_setWindows(self.windows.getBlob()) def setItems(self, items): items = CatalogItemList(items, store=CatalogItem.Customization | CatalogItem.Location) for item in self.items: item.destroy() self.items = [] for item in items: if item.getHashContents() in (1300, 1310, 1320, 1330, 1340, 1350): do = DistributedBankAI(self.air, self, item) elif 500 <= item.getHashContents() <= 518: do = DistributedClosetAI(self.air, self, item) do.setOwnerId(self.avId) elif item.getHashContents() == 1399: do = DistributedPhoneAI(self.air, self, item) elif item.getHashContents() in (4000, 4010): do = DistributedTrunkAI(self.air, self, item) do.setOwnerId(self.avId) else: do = DistributedFurnitureItemAI(self.air, self, item) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) def getItems(self): items = CatalogItemList(store=CatalogItem.Customization | CatalogItem.Location) for item in self.items: items.append(item.catalogItem) return items.getBlob() def setOwnerId(self, ownerId): self.ownerId = ownerId def d_setOwnerId(self, ownerId): self.sendUpdate('setOwnerId', [ownerId]) def b_setOwnerId(self, ownerId): self.setOwnerId(ownerId) self.d_setOwnerId(ownerId) def getOwnerId(self): return self.ownerId def setOwnerName(self, ownerName): self.ownerName = ownerName def d_setOwnerName(self, ownerName): self.sendUpdate('setOwnerName', [ownerName]) def b_setOwnerName(self, ownerName): self.setOwnerName(ownerName) self.d_setOwnerName(ownerName) def getOwnerName(self): return self.ownerName def getInteriorId(self): return self.interior.doId def setAtticItems(self, items): self.atticItems = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticItems(self, items): self.sendUpdate('setAtticItems', [items]) def b_setAtticItems(self, items): self.setAtticItems(items) if self.isGenerated(): self.d_setAtticItems(items) def getAtticItems(self): return self.atticItems.getBlob() def setAtticWallpaper(self, items): self.atticWallpaper = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticWallpaper(self, items): self.sendUpdate('setAtticWallpaper', [items]) def b_setAtticWallpaper(self, items): self.setAtticWallpaper(items) if self.isGenerated(): self.d_setAtticWallpaper(items) def getAtticWallpaper(self): return self.atticWallpaper.getBlob() def setAtticWindows(self, items): self.atticWindows = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticWindows(self, items): self.sendUpdate('setAtticWindows', [items]) def b_setAtticWindows(self, items): self.setAtticWindows(items) if self.isGenerated(): self.d_setAtticWindows(items) def getAtticWindows(self): return self.atticWindows.getBlob() def setDeletedItems(self, items): self.deletedItems = CatalogItemList(items, store=CatalogItem.Customization) def d_setDeletedItems(self, items): self.sendUpdate('setDeletedItems', [items]) def b_setDeletedItems(self, items): self.setDeletedItems(items) if self.isGenerated(): self.d_setDeletedItems(items) def getDeletedItems(self): return self.deletedItems.getBlob() def suggestDirector(self, directorId): senderId = self.air.getAvatarIdFromSender() if self.ownerId != senderId: self.air.writeServerEvent('suspicious', avId=senderId, issue='Tried to move furniture, but not the house owner!') return if senderId != directorId and directorId != 0: self.air.writeServerEvent('suspicious', avId=senderId, issue='Tried to make someone else (%d) move their furniture!' % directorId) return director = self.air.doId2do.get(directorId) if directorId and not director: self.air.writeServerEvent('suspicious', avId=directorId, issue='Tried to move furniture without being on the shard!') return if self.director: self.director.b_setGhostMode(0) if director: if director.zoneId != self.zoneId: self.air.writeServerEvent('suspicious', avId=directorId, issue='Tried to become director from another zone!') return director.b_setGhostMode(1) self.director = director self.sendUpdate('setDirector', [directorId]) self.saveToHouse() def avatarEnter(self): pass def avatarExit(self): pass def moveItemToAttic(self, doId): item = self.getItemObject(doId) self.atticItems.append(item.catalogItem) self.d_setAtticItems(self.getAtticItems()) item.destroy() self.items.remove(item) return ToontownGlobals.FM_MovedItem def moveItemFromAttic(self, index, x, y, z, h, p, r): item = self.getAtticFurniture(self.atticItems, index) self.atticItems.remove(item) self.d_setAtticItems(self.getAtticItems()) item.posHpr = (x, y, z, h, p, r) if item.getFlags() & FLTrunk: if self.house.gender is 0: if item.furnitureType - 4000 < 10: item.furnitureType += 10 elif item.furnitureType - 4000 > 10: item.furnitureType -= 10 do = DistributedTrunkAI(self.air, self, item) elif item.getFlags() & FLCloset: if self.house.gender is 0: if item.furnitureType - 500 < 10: item.furnitureType += 10 elif item.furnitureType - 500 > 10: item.furnitureType -= 10 do = DistributedClosetAI(self.air, self, item) elif item.getFlags() & FLBank: do = DistributedBankAI(self.air, self, item) elif item.getFlags() & FLPhone: do = DistributedPhoneAI(self.air, self, item) else: do = DistributedFurnitureItemAI(self.air, self, item) do.generateWithRequired(self.zoneId) self.items.append(do) return ToontownGlobals.FM_MovedItem, do.doId def deleteItemFromAttic(self, blob, index): item = self.getAtticFurniture(self.atticItems, index) if item is None: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to delete an invalid item at index %s' % index) return ToontownGlobals.FM_InvalidIndex self.atticItems.remove(item) self.d_setAtticItems(self.getAtticItems()) return ToontownGlobals.FM_DeletedItem def deleteItemFromRoom(self, blob, doId): pass def moveWallpaperFromAttic(self, index, room): retcode = ToontownGlobals.FM_SwappedItem wallpaper = self.getAtticFurniture(self.atticWallpaper, index) if wallpaper is None: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Invalid wallpaper at index %s' % index) return ToontownGlobals.FM_InvalidIndex if room > 1: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to apply a wallpaper in an invalid room %d!' % room) return ToontownGlobals.FM_InvalidItem interiorIndex = room * 4 if isinstance(wallpaper, CatalogMouldingItem): interiorIndex += 1 elif isinstance(wallpaper, CatalogFlooringItem): interiorIndex += 2 elif isinstance(wallpaper, CatalogWainscotingItem): interiorIndex += 3 atticIndex = self.atticWallpaper.index(wallpaper) self.atticWallpaper[atticIndex] = self.wallpaper[interiorIndex] self.d_setAtticWallpaper(self.getAtticWallpaper()) self.wallpaper[interiorIndex] = wallpaper self.applyWallpaper() return retcode def deleteWallpaperFromAttic(self, blob, index): wallpaper = self.getAtticFurniture(self.atticWallpaper, index) self.atticWallpaper.remove(wallpaper) self.b_setAtticWallpaper(self.getAtticWallpaper()) def moveWindowToAttic(self, slot): window = self.getWindow(slot) if window is None: return ToontownGlobals.FM_InvalidIndex self.windows.remove(window) self.applyWindows() self.atticWindows.append(window) self.d_setAtticWindows(self.getAtticWindows()) return ToontownGlobals.FM_MovedItem def moveWindowFromAttic(self, index, slot): retcode = ToontownGlobals.FM_MovedItem window = self.getAtticFurniture(self.atticWindows, index) if slot > 5: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to move window to invalid slot %d!' % slot) return ToontownGlobals.FM_HouseFull if self.getWindow(slot): self.moveWindowToAttic(slot) retcode = ToontownGlobals.FM_SwappedItem self.atticWindows.remove(window) self.d_setAtticWindows(self.getAtticWindows()) window.placement = slot self.windows.append(window) self.applyWindows() return retcode def moveWindow(self, fromSlot, toSlot): retcode = ToontownGlobals.FM_MovedItem window = self.getWindow(fromSlot) if window is None: return ToontownGlobals.FM_InvalidIndex if toSlot > 5: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='DistributedfTried to move window to invalid slot %d!' % toSlot) return ToontownGlobals.FM_HouseFull if self.getWindow(toSlot): self.moveWindowToAttic(toSlot) retcode = ToontownGlobals.FM_SwappedItem window.placement = toSlot self.applyWindows() return retcode def deleteWindowFromAttic(self, blob, index): window = self.getAtticFurniture(self.atticWindows, index) if window is None: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to delete an invalid window at index %s' % index) return ToontownGlobals.FM_InvalidIndex self.atticWindows.remove(window) self.d_setAtticWindows(self.getAtticWindows()) return ToontownGlobals.FM_DeletedItem def recoverDeletedItem(self, blob, index): pass def handleMessage(self, func, response, *args): context = args[-1] args = args[:-1] senderId = self.air.getAvatarIdFromSender() if not self.director or senderId != self.director.doId: self.air.writeServerEvent('suspicious', avId=senderId, issue='Sent furniture management request without being the director.') retval = ToontownGlobals.FM_NotDirector else: try: retval = func(*args) or 0 except FurnitureError as e: retval = e.code if response == 'moveItemFromAtticResponse': if type(retval) == tuple: retval, doId = retval else: doId = 0 taskMgr.doMethodLater(1, self.sendUpdateToAvatarId, self.uniqueName('send-attic-response'), extraArgs=[senderId, response, [retval, doId, context]]) else: self.sendUpdateToAvatarId(senderId, response, [retval, context]) def moveItemToAtticMessage(self, doId, context): self.handleMessage(self.moveItemToAttic, 'moveItemToAtticResponse', doId, context) def moveItemFromAtticMessage(self, index, x, y, z, h, p, r, context): self.handleMessage(self.moveItemFromAttic, 'moveItemFromAtticResponse', index, x, y, z, h, p, r, context) def deleteItemFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteItemFromAttic, 'deleteItemFromAtticResponse', blob, index, context) def deleteItemFromRoomMessage(self, blob, doId, context): self.handleMessage(self.deleteItemFromRoom, 'deleteItemFromRoomResponse', blob, doId, context) def moveWallpaperFromAtticMessage(self, index, room, context): self.handleMessage(self.moveWallpaperFromAttic, 'moveWallpaperFromAtticResponse', index, room, context) def deleteWallpaperFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteWallpaperFromAttic, 'deleteWallpaperFromAtticResponse', blob, index, context) def moveWindowToAtticMessage(self, slot, context): self.handleMessage(self.moveWindowToAttic, 'moveWindowToAtticResponse', slot, context) def moveWindowFromAtticMessage(self, index, slot, context): self.handleMessage(self.moveWindowFromAttic, 'moveWindowFromAtticResponse', index, slot, context) def moveWindowMessage(self, fromSlot, toSlot, context): self.handleMessage(self.moveWindow, 'moveWindowResponse', fromSlot, toSlot, context) def deleteWindowFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteWindowFromAttic, 'deleteWindowFromAtticResponse', blob, index, context) def recoverDeletedItemMessage(self, blob, index, context): self.handleMessage(self.recoverDeletedItem, 'recoverDeletedItemResponse', blob, index, context) def getItemObject(self, doId): item = self.air.doId2do.get(doId) if item is None: raise FurnitureError(ToontownGlobals.FM_InvalidItem) if item not in self.items: raise FurnitureError(ToontownGlobals.FM_InvalidItem) return item def getAtticFurniture(self, attic, index): if index >= len(attic): raise FurnitureError(ToontownGlobals.FM_InvalidIndex) return attic[index] def getWindow(self, slot): for window in self.windows: if window.placement == slot: return window
class DistributedHouseAI(DistributedObjectAI): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedHouseAI') def __init__(self, air): DistributedObjectAI.__init__(self, air) self.houseType = 0 self.gardenPos = 0 self.avatarId = 0 self.name = '' self.color = 0 self.housePos = 0 self.gender = 1 self.isInteriorInitialized = 1 self.atticItems = CatalogItemList(store=Customization) self.interiorItems = CatalogItemList(store=Customization) self.interiorWallpaper = CatalogItemList(store=Customization) self.atticWallpaper = CatalogItemList(store=Customization) self.interiorWindows = CatalogItemList(store=Customization) self.atticWindows = CatalogItemList(store=Customization) self.deletedItems = CatalogItemList(store=Customization) def announceGenerate(self): DistributedObjectAI.announceGenerate(self) self.interiorZone = self.air.allocateZone(owner=self.air.estateManager) self.door = DistributedHouseDoorAI(self.air, self.getDoId(), DoorTypes.EXT_STANDARD) self.door.setSwing(3) self.door.generateWithRequired(self.zoneId) self.interiorDoor = DistributedHouseDoorAI(self.air, self.getDoId(), DoorTypes.INT_STANDARD) self.interiorDoor.setSwing(3) self.interiorDoor.setOtherDoor(self.door) self.interiorDoor.generateWithRequired(self.interiorZone) self.door.setOtherDoor(self.interiorDoor) self.interior = DistributedHouseInteriorAI(self.air, self) self.interior.setHouseIndex(self.housePos) self.interior.setHouseId(self.getDoId()) self.interior.generateWithRequired(self.interiorZone) if self.avatarId: self.mailbox = DistributedMailboxAI(self.air, self) self.mailbox.generateWithRequired(self.zoneId) if not self.isInteriorInitialized: self.notify.info('Initializing interior...') self.interior.initialize() self.b_setInteriorInitialized(1) self.sendUpdate('setHouseReady', []) def delete(self): self.door.requestDelete() self.interiorDoor.requestDelete() self.interior.requestDelete() if self.avatarId: self.mailbox.requestDelete() self.air.deallocateZone(self.interiorZone) DistributedObjectAI.delete(self) def setHousePos(self, pos): self.housePos = pos def d_setHousePos(self, pos): self.sendUpdate('setHousePos', [pos]) def b_setHousePos(self, pos): self.setHousePos(pos) self.d_setHousePos(pos) def getHousePos(self): return self.housePos def setHouseType(self, type): self.houseType = type def d_setHouseType(self, type): self.sendUpdate('setHouseType', [type]) def b_setHouseType(self, type): self.setHouseType(type) self.d_setHouseType(type) def getHouseType(self): return self.houseType def setGardenPos(self, pos): self.gardenPos = pos def d_setGardenPos(self, pos): self.sendUpdate('setGardenPos', [pos]) def b_setGardenPos(self, pos): self.setGardenPow(pos) self.d_setGardenPos(pos) def getGardenPos(self): return self.gardenPos def setAvatarId(self, avId): self.avatarId = avId def d_setAvatarId(self, avId): self.sendUpdate('setAvatarId', [avId]) def b_setAvatarId(self, avId): self.setAvatarId(avId) self.d_setAvatarId(avId) def getAvatarId(self): return self.avatarId def setName(self, name): self.name = name def d_setName(self, name): self.sendUpdate('setName', [name]) def b_setName(self, name): self.setName(name) self.d_setName(name) def getName(self): return self.name def setColor(self, color): self.color = color def d_setColor(self, color): self.sendUpdate('setColor', [color]) def b_setColor(self, color): self.setColor(color) self.d_setColor(color) def getColor(self): return self.color def setGender(self, genderIndex): self.gender = genderIndex def getGender(self): return self.gender def setAtticItems(self, atticItems): self.atticItems = CatalogItemList(atticItems, store=Customization) def d_setAtticItems(self, atticItems): self.sendUpdate('setAtticItems', [atticItems]) def b_setAtticItems(self, atticItems): self.setAtticItems(atticItems) self.d_setAtticItems(atticItems) def getAtticItems(self): return self.atticItems.getBlob() def setInteriorItems(self, interiorItems): self.interiorItems = CatalogItemList(interiorItems, store=Customization | Location) def d_setInteriorItems(self, interiorItems): self.sendUpdate('setInteriorItems', [interiorItems]) def b_setInteriorItems(self, interiorItems): self.setInteriorItems(interiorItems) self.d_setInteriorItems(interiorItems) def getInteriorItems(self): return self.interiorItems.getBlob() def setAtticWallpaper(self, atticWallpaper): self.atticWallpaper = CatalogItemList(atticWallpaper, store=Customization) def d_setAtticWallpaper(self, atticWallpaper): self.sendUpdate('setAtticWallpaper', [atticWallpaper]) def b_setAtticWallpaper(self, atticWallpaper): self.setAtticWallpaper(atticWallpaper) self.d_setAtticWallpaper(atticWallpaper) def getAtticWallpaper(self): return self.atticWallpaper.getBlob() def setInteriorWallpaper(self, interiorWallpaper): self.interiorWallpaper = CatalogItemList(interiorWallpaper, store=Customization) def d_setInteriorWallpaper(self, interiorWallpaper): self.sendUpdate('setInteriorWallpaper', [interiorWallpaper]) def b_setInteriorWallpaper(self, interiorWallpaper): self.setInteriorWallpaper(interiorWallpaper) self.d_setInteriorWallpaper(interiorWallpaper) def getInteriorWallpaper(self): return self.interiorWallpaper.getBlob() def setAtticWindows(self, atticWindows): self.atticWindows = CatalogItemList(atticWindows, store=Customization) def d_setAtticWindows(self, atticWindows): self.sendUpdate('setAtticWindows', [atticWindows]) def b_setAtticWindows(self, atticWindows): self.setAtticWindows(atticWindows) self.d_setAtticWindows(atticWindows) def getAtticWindows(self): return self.atticWindows.getBlob() def setInteriorWindows(self, interiorWindows): self.interiorWindows = CatalogItemList(interiorWindows, store=Customization | WindowPlacement) def d_setInteriorWindows(self, interiorWindows): self.sendUpdate('setInteriorWindows', [interiorWindows]) def b_setInteriorWindows(self, interiorWindows): self.setInteriorWindows(interiorWindows) self.d_setInteriorWindows(interiorWindows) def getInteriorWindows(self): return self.interiorWindows.getBlob() def setDeletedItems(self, deletedItems): self.deletedItems = CatalogItemList(deletedItems, store=Customization) def d_setDeletedItems(self, deletedItems): self.sendUpdate('setDeletedItems', [deletedItems]) def b_setDeletedItems(self, deletedItems): self.setDeletedItems(deletedItems) self.d_setDeletedItems(deletedItems) def getDeletedItems(self): return self.deletedItems.getBlob() def setInteriorInitialized(self, initialized): self.isInteriorInitialized = initialized def d_setInteriorInitialized(self, initialized): self.sendUpdate('setInteriorInitialized', [initialized]) def b_setInteriorInitialized(self, initialized): self.setInteriorInitialized(initialized) self.d_setInteriorInitialized(initialized) def getInteriorInitialized(self): return self.isInteriorInitialized def setCannonEnabled(self, todo0): pass def getCannonEnabled(self): return 0 def setHouseReady(self): pass def addAtticItem(self, item): self.interior.furnitureManager.saveToHouse() if item.getFlags() & FLTrunk: self.atticItems.append(item) if item.replacesExisting() and item.hasExisting(): if item.getFlags() & FLCloset: closets = ClosetToClothes.keys() for itItem in self.interiorItems: if itItem.furnitureType in closets: posHpr = itItem.posHpr self.interiorItems.remove(itItem) item.posHpr = posHpr self.interiorItems.append(item) break for itItem in self.atticItems: if itItem.furnitureType in closets: self.atticItems.remove(itItem) self.atticItems.append(item) break else: self.atticItems.append(item) self.d_setAtticItems(self.atticItems.getBlob()) self.d_setInteriorItems(self.interiorItems.getBlob()) self.interior.furnitureManager.loadFromHouse() def addWindow(self, item): self.interior.furnitureManager.saveToHouse() self.atticWindows.append(item) self.d_setAtticWindows(self.atticWindows.getBlob()) self.interior.furnitureManager.loadFromHouse() def addWallpaper(self, item): self.interior.furnitureManager.saveToHouse() self.atticWallpaper.append(item) self.d_setAtticWallpaper(self.atticWallpaper.getBlob()) self.interior.furnitureManager.loadFromHouse()
class DistributedHouseAI(DistributedObjectAI): notify = directNotify.newCategory('DistributedHouseAI') def __init__(self, air): DistributedObjectAI.__init__(self, air) self.houseType = 0 self.gardenPos = 0 self.avatarId = 0 self.name = '' self.color = 0 self.housePos = 0 self.gender = 1 self.isInteriorInitialized = 1 self.gardenManager = None self.gardenData = '' self.atticItems = CatalogItemList(store=Customization) self.interiorItems = CatalogItemList(store=Customization) self.interiorWallpaper = CatalogItemList(store=Customization) self.atticWallpaper = CatalogItemList(store=Customization) self.interiorWindows = CatalogItemList(store=Customization) self.atticWindows = CatalogItemList(store=Customization) self.deletedItems = CatalogItemList(store=Customization) def announceGenerate(self): DistributedObjectAI.announceGenerate(self) self.interiorZone = self.air.allocateZone() self.door = DistributedHouseDoorAI(self.air, self.getDoId(), DoorTypes.EXT_STANDARD) self.door.setSwing(3) self.door.generateWithRequired(self.zoneId) self.interiorDoor = DistributedHouseDoorAI(self.air, self.getDoId(), DoorTypes.INT_STANDARD) self.interiorDoor.setSwing(3) self.interiorDoor.setOtherDoor(self.door) self.interiorDoor.generateWithRequired(self.interiorZone) self.door.setOtherDoor(self.interiorDoor) self.interior = DistributedHouseInteriorAI(self.air, self) self.interior.setHouseIndex(self.housePos) self.interior.setHouseId(self.getDoId()) self.interior.generateWithRequired(self.interiorZone) if self.avatarId: self.mailbox = DistributedMailboxAI(self.air, self) self.mailbox.generateWithRequired(self.zoneId) self.createGardenManager() if not self.isInteriorInitialized: self.notify.info('Initializing interior...') self.interior.initialize() self.b_setInteriorInitialized(1) self.sendUpdate('setHouseReady', []) def delete(self): self.door.requestDelete() self.interiorDoor.requestDelete() self.interior.requestDelete() if self.avatarId: self.mailbox.requestDelete() if self.gardenManager is not None: self.gardenManager.delete() self.air.deallocateZone(self.interiorZone) DistributedObjectAI.delete(self) def setHousePos(self, pos): self.housePos = pos def d_setHousePos(self, pos): self.sendUpdate('setHousePos', [pos]) def b_setHousePos(self, pos): self.setHousePos(pos) self.d_setHousePos(pos) def getHousePos(self): return self.housePos def setHouseType(self, type): self.houseType = type def d_setHouseType(self, type): self.sendUpdate('setHouseType', [type]) def b_setHouseType(self, type): self.setHouseType(type) self.d_setHouseType(type) def getHouseType(self): return self.houseType def setGardenPos(self, pos): self.gardenPos = pos def d_setGardenPos(self, pos): self.sendUpdate('setGardenPos', [pos]) def b_setGardenPos(self, pos): self.setGardenPos(pos) self.d_setGardenPos(pos) def getGardenPos(self): return self.gardenPos def setAvatarId(self, avId): self.avatarId = avId def d_setAvatarId(self, avId): self.sendUpdate('setAvatarId', [avId]) def b_setAvatarId(self, avId): self.setAvatarId(avId) self.d_setAvatarId(avId) def getAvatarId(self): return self.avatarId def setName(self, name): self.name = name def d_setName(self, name): self.sendUpdate('setName', [name]) def b_setName(self, name): self.setName(name) self.d_setName(name) def getName(self): return self.name def setColor(self, color): self.color = color def d_setColor(self, color): self.sendUpdate('setColor', [color]) def b_setColor(self, color): self.setColor(color) self.d_setColor(color) def getColor(self): return self.color def setGender(self, genderIndex): self.gender = genderIndex def getGender(self): return self.gender def setAtticItems(self, atticItems): self.atticItems = CatalogItemList(atticItems, store=Customization) def d_setAtticItems(self, atticItems): self.sendUpdate('setAtticItems', [atticItems]) def b_setAtticItems(self, atticItems): self.setAtticItems(atticItems) self.d_setAtticItems(atticItems) def getAtticItems(self): return self.atticItems.getBlob() def setInteriorItems(self, interiorItems): self.interiorItems = CatalogItemList(interiorItems, store=Customization | Location) def d_setInteriorItems(self, interiorItems): self.sendUpdate('setInteriorItems', [interiorItems]) def b_setInteriorItems(self, interiorItems): self.setInteriorItems(interiorItems) self.d_setInteriorItems(interiorItems) def getInteriorItems(self): return self.interiorItems.getBlob() def setAtticWallpaper(self, atticWallpaper): self.atticWallpaper = CatalogItemList(atticWallpaper, store=Customization) def d_setAtticWallpaper(self, atticWallpaper): self.sendUpdate('setAtticWallpaper', [atticWallpaper]) def b_setAtticWallpaper(self, atticWallpaper): self.setAtticWallpaper(atticWallpaper) self.d_setAtticWallpaper(atticWallpaper) def getAtticWallpaper(self): return self.atticWallpaper.getBlob() def setInteriorWallpaper(self, interiorWallpaper): self.interiorWallpaper = CatalogItemList(interiorWallpaper, store=Customization) def d_setInteriorWallpaper(self, interiorWallpaper): self.sendUpdate('setInteriorWallpaper', [interiorWallpaper]) def b_setInteriorWallpaper(self, interiorWallpaper): self.setInteriorWallpaper(interiorWallpaper) self.d_setInteriorWallpaper(interiorWallpaper) def getInteriorWallpaper(self): return self.interiorWallpaper.getBlob() def setAtticWindows(self, atticWindows): self.atticWindows = CatalogItemList(atticWindows, store=Customization) def d_setAtticWindows(self, atticWindows): self.sendUpdate('setAtticWindows', [atticWindows]) def b_setAtticWindows(self, atticWindows): self.setAtticWindows(atticWindows) self.d_setAtticWindows(atticWindows) def getAtticWindows(self): return self.atticWindows.getBlob() def setInteriorWindows(self, interiorWindows): self.interiorWindows = CatalogItemList(interiorWindows, store=Customization | WindowPlacement) def d_setInteriorWindows(self, interiorWindows): self.sendUpdate('setInteriorWindows', [interiorWindows]) def b_setInteriorWindows(self, interiorWindows): self.setInteriorWindows(interiorWindows) self.d_setInteriorWindows(interiorWindows) def getInteriorWindows(self): return self.interiorWindows.getBlob() def setDeletedItems(self, deletedItems): self.deletedItems = CatalogItemList(deletedItems, store=Customization) def d_setDeletedItems(self, deletedItems): self.sendUpdate('setDeletedItems', [deletedItems]) def b_setDeletedItems(self, deletedItems): self.setDeletedItems(deletedItems) self.d_setDeletedItems(deletedItems) def getDeletedItems(self): return self.deletedItems.getBlob() def setInteriorInitialized(self, initialized): self.isInteriorInitialized = initialized def d_setInteriorInitialized(self, initialized): self.sendUpdate('setInteriorInitialized', [initialized]) def b_setInteriorInitialized(self, initialized): self.setInteriorInitialized(initialized) self.d_setInteriorInitialized(initialized) def getInteriorInitialized(self): return self.isInteriorInitialized def setCannonEnabled(self, todo0): pass def getCannonEnabled(self): return 0 def setHouseReady(self): pass def addAtticItem(self, item): self.interior.furnitureManager.saveToHouse() if item.getFlags() & FLTrunk: self.atticItems.append(item) elif item.replacesExisting() and item.hasExisting(): if item.getFlags() & FLCloset: closets = list(ClosetToClothes.keys()) for itItem in self.interiorItems: if itItem.furnitureType in closets: posHpr = itItem.posHpr self.interiorItems.remove(itItem) item.posHpr = posHpr self.interiorItems.append(item) break for itItem in self.atticItems: if itItem.furnitureType in closets: self.atticItems.remove(itItem) self.atticItems.append(item) break else: self.atticItems.append(item) self.d_setAtticItems(self.atticItems.getBlob()) self.d_setInteriorItems(self.interiorItems.getBlob()) self.interior.furnitureManager.loadFromHouse() def addWindow(self, item): self.interior.furnitureManager.saveToHouse() self.atticWindows.append(item) self.d_setAtticWindows(self.atticWindows.getBlob()) self.interior.furnitureManager.loadFromHouse() def addWallpaper(self, item): self.interior.furnitureManager.saveToHouse() self.atticWallpaper.append(item) self.d_setAtticWallpaper(self.atticWallpaper.getBlob()) self.interior.furnitureManager.loadFromHouse() def setGardenData(self, gardenData): self.gardenData = gardenData def d_setGardenData(self, gardenData): self.sendUpdate('setGardenData', [gardenData]) def b_setGardenData(self, gardenData): self.setGardenData(gardenData) self.d_setGardenData(gardenData) def getGardenData(self): return self.gardenData def hasGardenData(self): return self.gardenData != b'' def placeStarterGarden(self): av = self.air.doId2do.get(self.avatarId) if av is None: return if av.getGardenStarted(): self.notify.warning( 'Avatar %s tried to start their garden twice!' % self.avatarId) return # State that the avatar has started gardening av.b_setGardenStarted(1) # Create the GardenManagerAI self.gardenManager = GardenManagerAI(self.air, self) self.gardenManager.loadGarden() def createGardenManager(self): if not self.avatarId: return av = self.air.doId2do.get(self.avatarId) if av is not None: if av.getGardenStarted(): self.gardenManager = GardenManagerAI(self.air, self) self.gardenManager.loadGarden() return def __gotOwner(dclass, fields, self=self): if dclass != self.air.dclassesByName['DistributedToonAI']: return gardenStarted = fields['setGardenStarted'][0] if gardenStarted: self.gardenManager = GardenManagerAI(self.air, self) self.gardenManager.loadGarden() self.air.dbInterface.queryObject(self.air.dbId, self.avatarId, __gotOwner)
def setItems(self, items): items = CatalogItemList(items, store=CatalogItem.Customization | CatalogItem.Location) for item in self.items: item.destroy() self.items = [] items.removeDuplicates(FLCloset) items.removeDuplicates(FLPhone) items.removeDuplicates(FLBank) hasCloset = False for item in items: try: if item.getFlags() & FLCloset: hasCloset = True break except: pass hasAGodDamnPhone = False for killme in items: try: if killme.getFlags() & FLPhone: hasAGodDamnPhone = True break except: pass if not hasAGodDamnPhone and self.ownerId != 0: phone = CatalogFurnitureItem(1399) phone.posHpr = (-5, 0, 0, 0, 0, 0) items.append(phone) print 'spawned a phone for someone' hasBank = False for bank in items: try: if bank.getFlags() & FLBank: hasBank = True break except: pass if not hasBank and self.ownerId != 0: bank = CatalogFurnitureItem(1300) bank.posHpr = (5, 0, 0, 0, 0, 0) items.append(bank) print 'spawned a bank for someone' if not hasCloset and self.ownerId != 0: item = CatalogFurnitureItem(500) item.posHpr = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0) items.append(item) print 'spawned a closet for someone' for item in items: try: if item.getFlags() & FLTrunk: if self.house.gender is 0: if item.furnitureType - 4000 < 10: item.furnitureType += 10 elif item.furnitureType - 4000 > 10: item.furnitureType -= 10 do = DistributedTrunkAI(self.air, self, item) elif item.getFlags() & FLCloset: if self.house.gender is 0: if item.furnitureType - 500 < 10: item.furnitureType += 10 elif item.furnitureType - 500 > 10: item.furnitureType -= 10 do = DistributedClosetAI(self.air, self, item) elif item.getFlags() & FLBank: do = DistributedBankAI(self.air, self, item) elif item.getFlags() & FLPhone: do = DistributedPhoneAI(self.air, self, item) else: do = DistributedFurnitureItemAI(self.air, self, item) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) except: print 'another user with a broken estate hurray!!!!!!!!!!!!!!!!!!'
class DistributedFurnitureManagerAI(DistributedObjectAI): notify = DirectNotifyGlobal.directNotify.newCategory( 'DistributedFurnitureManagerAI') serverDataFolder = simbase.config.GetString('server-data-folder', '') def __init__(self, air, house, interior): DistributedObjectAI.__init__(self, air) self.house = house self.interior = interior self.ownerId = 0 self.ownerName = '' self.interiorId = 0 self.atticItems = CatalogItemList(store=CatalogItem.Customization) self.atticWallpaper = CatalogItemList(store=CatalogItem.Customization) self.atticWindows = CatalogItemList(store=CatalogItem.Customization) self.deletedItems = CatalogItemList(store=CatalogItem.Customization) self.wallpaper = CatalogItemList(store=CatalogItem.Customization) self.windows = CatalogItemList(store=CatalogItem.Customization | CatalogItem.WindowPlacement) self.items = [] self.director = 0 self.deletedItemsFilename = '' self.day2deletedItems = {} def announceGenerate(self): DistributedObjectAI.announceGenerate(self) self.deletedItemsFilename = self.getDeletedItemsFilename() self.day2deletedItems = self.loadDeletedItems() taskMgr.add(self.__deletedItemsTask, self.uniqueName('deleted-items-task')) def delete(self): for item in self.items[:]: item.requestDelete() self.items.remove(item) taskMgr.remove(self.uniqueName('deleted-items-task')) DistributedObjectAI.delete(self) def setOwnerId(self, ownerId): self.ownerId = ownerId def d_setOwnerId(self, ownerId): self.sendUpdate('setOwnerId', [ownerId]) def b_setOwnerId(self, ownerId): self.setOwnerId(ownerId) self.d_setOwnerId(ownerId) def getOwnerId(self): return self.ownerId def setOwnerName(self, ownerName): self.ownerName = ownerName def d_setOwnerName(self, ownerName): self.sendUpdate('setOwnerName', [ownerName]) def b_setOwnerName(self, ownerName): self.setOwnerName(ownerName) self.d_setOwnerName(ownerName) def getOwnerName(self): return self.ownerName def setInteriorId(self, interiorId): self.interiorId = interiorId def d_setInteriorId(self, interiorId): self.sendUpdate('setInteriorId', [interiorId]) def b_setInteriorId(self, interiorId): self.setInteriorId(interiorId) self.d_setInteriorId(interiorId) def getInteriorId(self): return self.interiorId def setAtticItems(self, atticItems): self.atticItems = CatalogItemList(atticItems, store=CatalogItem.Customization) def d_setAtticItems(self, atticItems): self.sendUpdate('setAtticItems', [atticItems]) def b_setAtticItems(self, atticItems): self.setAtticItems(atticItems) self.d_setAtticItems(atticItems) def getAtticItems(self): return self.atticItems.getBlob() def setAtticWallpaper(self, atticWallpaper): self.atticWallpaper = CatalogItemList(atticWallpaper, store=CatalogItem.Customization) def d_setAtticWallpaper(self, atticWallpaper): self.sendUpdate('setAtticWallpaper', [atticWallpaper]) def b_setAtticWallpaper(self, atticWallpaper): self.setAtticWallpaper(atticWallpaper) self.d_setAtticWallpaper(atticWallpaper) def getAtticWallpaper(self): return self.atticWallpaper.getBlob() def setAtticWindows(self, atticWindows): self.atticWindows = CatalogItemList(atticWindows, store=CatalogItem.Customization) def d_setAtticWindows(self, atticWindows): self.sendUpdate('setAtticWindows', [atticWindows]) def b_setAtticWindows(self, atticWindows): self.setAtticWindows(atticWindows) self.d_setAtticWindows(atticWindows) def getAtticWindows(self): return self.atticWindows.getBlob() def setDeletedItems(self, deletedItems): self.deletedItems = CatalogItemList(deletedItems, store=CatalogItem.Customization) def d_setDeletedItems(self, deletedItems): self.sendUpdate('setDeletedItems', [deletedItems]) def b_setDeletedItems(self, deletedItems): self.setDeletedItems(deletedItems) self.d_setDeletedItems(deletedItems) def getDeletedItems(self): return self.deletedItems.getBlob() def suggestDirector(self, avId): if avId and avId != self.ownerId: self.air.writeServerEvent( 'suspicious', avId, "av tried to manage furniture in someone else's house") return av = self.air.doId2do.get(avId) director = self.air.doId2do.get(self.director) if director: director.b_setGhostMode(0) else: av.b_setGhostMode(1) self.b_setDirector(avId) self.saveFurniture() def setDirector(self, director): self.director = director def d_setDirector(self, director): self.sendUpdate('setDirector', [director]) def b_setDirector(self, director): self.setDirector(director) self.d_setDirector(director) def getDirector(self): return self.director def moveItemToAtticMessage(self, itemId, context): avId = self.air.getAvatarIdFromSender() owner = self._verifyOwner(avId, 'moveItemToAttic', context) if not owner: return item = self.air.doId2do.get(itemId) if not item or item not in self.items: self.sendUpdateToAvatarId( avId, 'moveItemToAtticResponse', [ToontownGlobals.FM_InvalidItem, context]) self.atticItems.append(item.catalogItem) self.b_setAtticItems(self.getAtticItems()) item.requestDelete() self.items.remove(item) self.sendUpdateToAvatarId(avId, 'moveItemToAtticResponse', [ToontownGlobals.FM_MovedItem, context]) def moveItemFromAtticMessage(self, index, x, y, z, h, p, r, context): avId = self.air.getAvatarIdFromSender() owner = self._verifyOwner(avId, 'moveItemFromAttic', context) if not owner: return try: item = self.atticItems[index] except KeyError: self.air.writeServerEvent( 'suspicious', avId, 'av tried to move nonexistent attic item') self.sendUpdateToAvatarId( avId, 'moveItemFromAtticResponse', [ToontownGlobals.FM_InvalidIndex, context]) return del self.atticItems[index] self.b_setAtticItems(self.getAtticItems()) item.posHpr = (x, y, z, h, p, r) obj = self.generateItem(item) self.sendUpdateToAvatarId( avId, 'moveItemFromAtticResponse', [ToontownGlobals.FM_MovedItem, obj.doId, context]) def deleteItemFromAtticMessage(self, blob, index, context): avId = self.air.getAvatarIdFromSender() owner = self._verifyOwner(avId, 'deleteItemFromAttic', context) if not owner: return try: item = self.atticItems[index] except KeyError: self.air.writeServerEvent( 'suspicious', avId, 'av tried to delete nonexistent attic item') self.sendUpdateToAvatarId( avId, 'deleteItemFromAtticResponse', [ToontownGlobals.FM_InvalidIndex, context]) return if not item.isDeletable(): self.sendUpdateToAvatarId( avId, 'deleteItemFromAtticResponse', [ToontownGlobals.FM_NondeletableItem, context]) return del self.atticItems[index] self.b_setAtticItems(self.getAtticItems()) self._deleteItem(item) self.sendUpdateToAvatarId(avId, 'deleteItemFromAtticResponse', [ToontownGlobals.FM_DeletedItem, context]) def deleteItemFromRoomMessage(self, blob, itemId, context): avId = self.air.getAvatarIdFromSender() owner = self._verifyOwner(avId, 'deleteItemFromRoom', context) if not owner: return item = self.air.doId2do.get(itemId) if not item or item not in self.items: self.sendUpdateToAvatarId( avId, 'deleteItemFromRoomResponse', [ToontownGlobals.FM_InvalidItem, context]) return if not item.catalogItem.isDeletable(): self.sendUpdateToAvatarId( avId, 'deleteItemFromRoomResponse', [ToontownGlobals.FM_NondeletableItem, context]) return self.items.remove(item) self._deleteItem(item.catalogItem) item.requestDelete() self.sendUpdateToAvatarId(avId, 'deleteItemFromRoomResponse', [ToontownGlobals.FM_DeletedItem, context]) def moveWallpaperFromAtticMessage(self, index, room, context): avId = self.air.getAvatarIdFromSender() owner = self._verifyOwner(avId, 'moveWallpaperFromAttic', context) if not owner: return try: item = self.atticWallpaper[index] except KeyError: self.air.writeServerEvent( 'suspicious', avId, 'av tried to move nonexistent wallpaper') self.sendUpdateToAvatarId( avId, 'moveWallpaperFromAtticResponse', [ToontownGlobals.FM_InvalidIndex, context]) return slot = room * CatalogSurfaceItem.NUM_ST_TYPES + item.getSurfaceType() self.atticWallpaper[index] = self.wallpaper[slot] self.b_setAtticWallpaper(self.getAtticWallpaper()) self.wallpaper[slot] = item self.house.interior.b_setWallpaper(self.wallpaper.getBlob()) self.sendUpdateToAvatarId(avId, 'moveWallpaperFromAtticResponse', [ToontownGlobals.FM_SwappedItem, context]) def deleteWallpaperFromAtticMessage(self, blob, index, context): avId = self.air.getAvatarIdFromSender() owner = self._verifyOwner(avId, 'deleteWallpaperFromAttic', context) if not owner: return try: item = self.atticWallpaper[index] except KeyError: self.air.writeServerEvent( 'suspicious', avId, 'av tried to delete nonexistent wallpaper') self.sendUpdateToAvatarId( avId, 'deleteWallpaperFromAtticResponse', [ToontownGlobals.FM_InvalidIndex, context]) return del self.atticWallpaper[index] self.b_setAtticWallpaper(self.getAtticWallpaper()) self._deleteItem(item) self.sendUpdateToAvatarId(avId, 'deleteWallpaperFromAtticResponse', [ToontownGlobals.FM_DeletedItem, context]) def moveWindowToAtticMessage(self, slot, context): pass def moveWindowFromAtticMessage(self, index, slot, context): avId = self.air.getAvatarIdFromSender() owner = self._verifyOwner(avId, 'moveWindowFromAttic', context) if not owner: return else: try: item = self.atticWindows[index] except KeyError: self.air.writeServerEvent( 'suspicious', avId, 'av tried to move nonexistent window') self.sendUpdateToAvatarId( avId, 'moveWindowFromAtticResponse', [ToontownGlobals.FM_InvalidIndex, context]) return if slot > 5: self.air.writeServerEvent( 'suspicious', avId, 'av tried to put window in invalid slot!') return item.placement = slot oldWindow = None windowIndex = None for i, window in enumerate(self.windows): if window.placement == slot: oldWindow = window windowIndex = i if not oldWindow: self.sendUpdateToAvatarId( avId, 'moveWindowFromAtticResponse', [ToontownGlobals.FM_InvalidIndex, context]) return self.atticWindows[index] = oldWindow self.d_setAtticWindows(self.getAtticWindows()) self.windows[windowIndex] = item self.house.interior.b_setWindows(self.windows.getBlob()) self.sendUpdateToAvatarId( avId, 'moveWindowFromAtticResponse', [ToontownGlobals.FM_SwappedItem, context]) return def moveWindowMessage(self, fromSlot, toSlot, context): pass def deleteWindowFromAtticMessage(self, blob, index, context): avId = self.air.getAvatarIdFromSender() owner = self._verifyOwner(avId, 'deleteWindowFromAttic', context) if not owner: return try: item = self.atticWindows[index] except KeyError: self.air.writeServerEvent('suspicious', avId, 'av tried to delete nonexistent window') self.sendUpdateToAvatarId( avId, 'deleteWindowFromAtticResponse', [ToontownGlobals.FM_InvalidIndex, context]) return del self.atticWindows[index] self.d_setAtticWindows(self.getAtticWindows()) self._deleteItem(item) self.sendUpdateToAvatarId(avId, 'deleteWindowFromAtticResponse', [ToontownGlobals.FM_DeletedItem, context]) def recoverDeletedItemMessage(self, blob, index, context): avId = self.air.getAvatarIdFromSender() owner = self._verifyOwner(avId, 'recoverDeletedItem', context) if not owner: return numItems = len(self.atticItems) + len(self.atticWallpaper) + len( self.atticWindows) + len(self.items) if numItems + 1 > ToontownGlobals.MaxHouseItems: self.sendUpdateToAvatarId(avId, 'recoverDeletedItemResponse', [ToontownGlobals.FM_HouseFull, context]) return try: item = self.deletedItems[index] except KeyError: self.air.writeServerEvent('suspicious', avId, 'av tried to recover nonexistent item') self.sendUpdateToAvatarId( avId, 'recoverDeletedItemResponse', [ToontownGlobals.FM_InvalidIndex, context]) return type2attic = { CatalogSurfaceItem.CatalogSurfaceItem: (self.atticWallpaper, self.b_setAtticWallpaper, self.getAtticWallpaper), CatalogFurnitureItem.CatalogFurnitureItem: (self.atticItems, self.b_setAtticItems, self.getAtticItems), CatalogWindowItem.CatalogWindowItem: (self.atticWindows, self.b_setAtticWindows, self.getAtticWindows) } for itemType in type2attic.keys(): if isinstance(item, itemType): attic, setter, getter = type2attic[itemType] attic.append(item) setter(getter()) del self.deletedItems[index] self.b_setDeletedItems(self.getDeletedItems()) self.removeDeletedItemBlob(item.getBlob().encode('base64')) self.sendUpdateToAvatarId( avId, 'recoverDeletedItemResponse', [ToontownGlobals.FM_RecoveredItem, context]) def loadFurniture(self): for item in CatalogItemList(self.house.getInteriorItems(), store=CatalogItem.Customization | CatalogItem.Location): self.generateItem(item) self.wallpaper = CatalogItemList(self.house.getInteriorWallpaper(), store=CatalogItem.Customization) self.house.b_setInteriorWallpaper(self.house.getInteriorWallpaper()) self.interior.b_setWallpaper(self.house.getInteriorWallpaper()) self.windows = CatalogItemList(self.house.getInteriorWindows(), store=CatalogItem.Customization | CatalogItem.WindowPlacement) self.house.b_setInteriorWindows(self.house.getInteriorWindows()) self.interior.b_setWindows(self.house.getInteriorWindows()) self.b_setAtticItems(self.house.getAtticItems()) self.b_setAtticWallpaper(self.house.getAtticWallpaper()) self.b_setAtticWindows(self.house.getAtticWindows()) self.b_setDeletedItems(self.house.getDeletedItems()) def generateItem(self, item): itemId = item.furnitureType if itemId == 1399: furnitureClass = DistributedPhoneAI elif item.getFlags() & CatalogFurnitureItem.FLCloset: furnitureClass = DistributedClosetAI elif item.getFlags() & CatalogFurnitureItem.FLBank: furnitureClass = DistributedBankAI elif item.getFlags() & CatalogFurnitureItem.FLTrunk: furnitureClass = DistributedTrunkAI else: furnitureClass = DistributedFurnitureItemAI obj = furnitureClass(self.air, self.house, self, item) obj.generateWithRequired(self.interior.zoneId) self.items.append(obj) return obj def saveFurniture(self): self.house.b_setInteriorItems(self.getNewItems()) self.house.b_setInteriorWallpaper(self.wallpaper.getBlob()) self.house.b_setInteriorWindows(self.windows.getBlob()) self.interior.b_setWindows(self.windows.getBlob()) self.interior.b_setWallpaper(self.wallpaper.getBlob()) self.house.b_setAtticItems(self.getAtticItems()) self.b_setAtticItems(self.getAtticItems()) self.house.b_setAtticWallpaper(self.getAtticWallpaper()) self.b_setAtticWallpaper(self.getAtticWallpaper()) self.house.b_setAtticWindows(self.getAtticWindows()) self.b_setAtticWindows(self.getAtticWindows()) self.house.b_setDeletedItems(self.getDeletedItems()) self.b_setDeletedItems(self.getDeletedItems()) def getNewItems(self): items = CatalogItemList(store=CatalogItem.Customization | CatalogItem.Location) for item in self.items: items.append(item.catalogItem) return items.getBlob() def _verifyOwner(self, avId, message, context): if self.house.avatarId != avId: self.air.writeServerEvent( 'suspicious', avId, 'av tried to send perform furniture management operation %s while not owner!' % message) self.sendUpdateToAvatarId(avId, message + 'Response', [ToontownGlobals.FM_NotOwner, context]) return False if self.director != avId: self.sendUpdateToAvatarId( avId, message + 'Response', [ToontownGlobals.FM_NotDirector, context]) return False return True def _deleteItem(self, item): self.deletedItems.append(item) if len(self.deletedItems) > ToontownGlobals.ExtraDeletedItems: del self.deletedItems[0] self.b_setDeletedItems(self.getDeletedItems()) self.addDeletedItemBlob(item.getBlob().encode('base64')) def getNumItems(self): numItems = len(self.house.interiorItems) + len( self.house.atticItems) + len(self.house.atticWallpaper) + len( self.house.atticWindows) + len( self.house.interiorWallpaper) + len( self.house.interiorWindows) return numItems def getDeletedItemsFilename(self): return '%s%s%s%s.json' % (self.serverDataFolder, 'houses/', 'deletedItems_', self.house.getDoId()) def loadDeletedItems(self): try: deletedItemsFile = open(self.deletedItemsFilename, 'r') deletedItemsData = json.load(deletedItemsFile) return deletedItemsData except: return {} def updateDeletedItemsFile(self): try: if not os.path.exists(os.path.dirname(self.deletedItemsFilename)): os.makedirs(os.path.dirname(self.deletedItemsFilename)) deletedItemsFile = open(self.deletedItemsFilename, 'w') deletedItemsFile.seek(0) json.dump(self.day2deletedItems, deletedItemsFile) deletedItemsFile.close() except: pass def addDeletedItemBlob(self, deletedItemBlob, dayId=None): if dayId is None: dayId = getDayId() dayId = str(dayId) if dayId not in self.day2deletedItems.keys(): self.day2deletedItems[dayId] = [] self.day2deletedItems[dayId].append(deletedItemBlob) self.updateDeletedItemsFile() return def removeDeletedItemBlob(self, deletedItemBlob, dayId=None): if not self.day2deletedItems.keys(): return else: if dayId is None: dayId = getDayId() dayId = str(dayId) if dayId not in self.day2deletedItems.keys(): dayId = min(self.day2deletedItems.keys()) elif not self.day2deletedItems[dayId]: del self.day2deletedItems[dayId] dayId = min(self.day2deletedItems.keys()) dayId = str(dayId) if dayId in self.day2deletedItems.keys( ) and deletedItemBlob in self.day2deletedItems[dayId]: self.day2deletedItems[dayId].remove(deletedItemBlob) if not self.day2deletedItems[dayId]: del self.day2deletedItems[dayId] self.updateDeletedItemsFile() return def __deletedItemsTask(self, task): changesMade = False dayId = getDayId() for deletedItemDay, deletedItemBlobs in self.day2deletedItems.items(): if not deletedItemBlobs or type(deletedItemBlobs) != list: del self.day2deletedItems[deletedItemDay] changesMade = True continue try: deletedItemDayId = int(deletedItemDay) except: del self.day2deletedItems[deletedItemDay] changesMade = True continue if deletedItemDayId + int( ToontownGlobals.DeletedItemLifetime / 60 / 24) <= dayId: for deletedItemBlob in deletedItemBlobs[:]: try: deletedItem = CatalogItem.getItem( deletedItemBlob.decode('base64')) except: self.day2deletedItems[deletedItemDay].remove( deletedItemBlob) if not self.day2deletedItems[deletedItemDay]: del self.day2deletedItems[deletedItemDay] changesMade = True continue if isinstance(deletedItem, CatalogInvalidItem.CatalogInvalidItem): self.day2deletedItems[deletedItemDay].remove( deletedItemBlob) if not self.day2deletedItems[deletedItemDay]: del self.day2deletedItems[deletedItemDay] changesMade = True continue if deletedItem not in self.deletedItems: self.day2deletedItems[deletedItemDay].remove( deletedItemBlob) if not self.day2deletedItems[deletedItemDay]: del self.day2deletedItems[deletedItemDay] changesMade = True continue index = self.deletedItems.index(deletedItem) del self.deletedItems[index] self.b_setDeletedItems(self.getDeletedItems()) self.day2deletedItems[deletedItemDay].remove( deletedItemBlob) if not self.day2deletedItems[deletedItemDay]: del self.day2deletedItems[deletedItemDay] changesMade = True if changesMade: self.updateDeletedItemsFile() tomorrow = self.air.toontownTimeManager.getCurServerDateTime().now( tz=self.air.toontownTimeManager.serverTimeZone ) + datetime.timedelta(1) midnight = datetime.datetime( year=tomorrow.year, month=tomorrow.month, day=tomorrow.day, hour=0, minute=0, second=0, tzinfo=self.air.toontownTimeManager.serverTimeZone) secondsUntilMidnight = ( midnight - self.air.toontownTimeManager.getCurServerDateTime().now( tz=self.air.toontownTimeManager.serverTimeZone)).seconds task.delayTime = secondsUntilMidnight return task.again
class DistributedHouseAI(DistributedObjectAI): notify = directNotify.newCategory('DistributedHouseAI') def __init__(self, air): DistributedObjectAI.__init__(self, air) self.houseType = 0 self.gardenPos = 0 self.avatarId = 0 self.name = '' self.color = 0 self.housePos = 0 self.gender = 1 self.isInteriorInitialized = 1 self.gardenManager = None self.gardenData = '' self.atticItems = CatalogItemList(store=Customization) self.interiorItems = CatalogItemList(store=Customization) self.interiorWallpaper = CatalogItemList(store=Customization) self.atticWallpaper = CatalogItemList(store=Customization) self.interiorWindows = CatalogItemList(store=Customization) self.atticWindows = CatalogItemList(store=Customization) self.deletedItems = CatalogItemList(store=Customization) def announceGenerate(self): DistributedObjectAI.announceGenerate(self) self.interiorZone = self.air.allocateZone() self.door = DistributedHouseDoorAI(self.air, self.getDoId(), DoorTypes.EXT_STANDARD) self.door.setSwing(3) self.door.generateWithRequired(self.zoneId) self.interiorDoor = DistributedHouseDoorAI(self.air, self.getDoId(), DoorTypes.INT_STANDARD) self.interiorDoor.setSwing(3) self.interiorDoor.setOtherDoor(self.door) self.interiorDoor.generateWithRequired(self.interiorZone) self.door.setOtherDoor(self.interiorDoor) self.interior = DistributedHouseInteriorAI(self.air, self) self.interior.setHouseIndex(self.housePos) self.interior.setHouseId(self.getDoId()) self.interior.generateWithRequired(self.interiorZone) if self.avatarId: self.mailbox = DistributedMailboxAI(self.air, self) self.mailbox.generateWithRequired(self.zoneId) if config.GetBool('want-gardening', False): self.createGardenManager() if not self.isInteriorInitialized: self.notify.info('Initializing interior...') self.interior.initialize() self.b_setInteriorInitialized(1) self.sendUpdate('setHouseReady', []) def delete(self): self.door.requestDelete() self.interiorDoor.requestDelete() self.interior.requestDelete() if self.avatarId: self.mailbox.requestDelete() if self.gardenManager is not None: self.gardenManager.delete() self.air.deallocateZone(self.interiorZone) DistributedObjectAI.delete(self) def setHousePos(self, pos): self.housePos = pos def d_setHousePos(self, pos): self.sendUpdate('setHousePos', [pos]) def b_setHousePos(self, pos): self.setHousePos(pos) self.d_setHousePos(pos) def getHousePos(self): return self.housePos def setHouseType(self, type): self.houseType = type def d_setHouseType(self, type): self.sendUpdate('setHouseType', [type]) def b_setHouseType(self, type): self.setHouseType(type) self.d_setHouseType(type) def getHouseType(self): return self.houseType def setGardenPos(self, pos): self.gardenPos = pos def d_setGardenPos(self, pos): self.sendUpdate('setGardenPos', [pos]) def b_setGardenPos(self, pos): self.setGardenPos(pos) self.d_setGardenPos(pos) def getGardenPos(self): return self.gardenPos def setAvatarId(self, avId): self.avatarId = avId def d_setAvatarId(self, avId): self.sendUpdate('setAvatarId', [avId]) def b_setAvatarId(self, avId): self.setAvatarId(avId) self.d_setAvatarId(avId) def getAvatarId(self): return self.avatarId def setName(self, name): self.name = name def d_setName(self, name): self.sendUpdate('setName', [name]) def b_setName(self, name): self.setName(name) self.d_setName(name) def getName(self): return self.name def setColor(self, color): self.color = color def d_setColor(self, color): self.sendUpdate('setColor', [color]) def b_setColor(self, color): self.setColor(color) self.d_setColor(color) def getColor(self): return self.color def setGender(self, genderIndex): self.gender = genderIndex def getGender(self): return self.gender def setAtticItems(self, atticItems): self.atticItems = CatalogItemList(atticItems, store=Customization) def d_setAtticItems(self, atticItems): self.sendUpdate('setAtticItems', [atticItems]) def b_setAtticItems(self, atticItems): self.setAtticItems(atticItems) self.d_setAtticItems(atticItems) def getAtticItems(self): return self.atticItems.getBlob() def setInteriorItems(self, interiorItems): self.interiorItems = CatalogItemList(interiorItems, store=Customization | Location) def d_setInteriorItems(self, interiorItems): self.sendUpdate('setInteriorItems', [interiorItems]) def b_setInteriorItems(self, interiorItems): self.setInteriorItems(interiorItems) self.d_setInteriorItems(interiorItems) def getInteriorItems(self): return self.interiorItems.getBlob() def setAtticWallpaper(self, atticWallpaper): self.atticWallpaper = CatalogItemList(atticWallpaper, store=Customization) def d_setAtticWallpaper(self, atticWallpaper): self.sendUpdate('setAtticWallpaper', [atticWallpaper]) def b_setAtticWallpaper(self, atticWallpaper): self.setAtticWallpaper(atticWallpaper) self.d_setAtticWallpaper(atticWallpaper) def getAtticWallpaper(self): return self.atticWallpaper.getBlob() def setInteriorWallpaper(self, interiorWallpaper): self.interiorWallpaper = CatalogItemList(interiorWallpaper, store=Customization) def d_setInteriorWallpaper(self, interiorWallpaper): self.sendUpdate('setInteriorWallpaper', [interiorWallpaper]) def b_setInteriorWallpaper(self, interiorWallpaper): self.setInteriorWallpaper(interiorWallpaper) self.d_setInteriorWallpaper(interiorWallpaper) def getInteriorWallpaper(self): return self.interiorWallpaper.getBlob() def setAtticWindows(self, atticWindows): self.atticWindows = CatalogItemList(atticWindows, store=Customization) def d_setAtticWindows(self, atticWindows): self.sendUpdate('setAtticWindows', [atticWindows]) def b_setAtticWindows(self, atticWindows): self.setAtticWindows(atticWindows) self.d_setAtticWindows(atticWindows) def getAtticWindows(self): return self.atticWindows.getBlob() def setInteriorWindows(self, interiorWindows): self.interiorWindows = CatalogItemList(interiorWindows, store=Customization | WindowPlacement) def d_setInteriorWindows(self, interiorWindows): self.sendUpdate('setInteriorWindows', [interiorWindows]) def b_setInteriorWindows(self, interiorWindows): self.setInteriorWindows(interiorWindows) self.d_setInteriorWindows(interiorWindows) def getInteriorWindows(self): return self.interiorWindows.getBlob() def setDeletedItems(self, deletedItems): self.deletedItems = CatalogItemList(deletedItems, store=Customization) def d_setDeletedItems(self, deletedItems): self.sendUpdate('setDeletedItems', [deletedItems]) def b_setDeletedItems(self, deletedItems): self.setDeletedItems(deletedItems) self.d_setDeletedItems(deletedItems) def getDeletedItems(self): return self.deletedItems.getBlob() def setInteriorInitialized(self, initialized): self.isInteriorInitialized = initialized def d_setInteriorInitialized(self, initialized): self.sendUpdate('setInteriorInitialized', [initialized]) def b_setInteriorInitialized(self, initialized): self.setInteriorInitialized(initialized) self.d_setInteriorInitialized(initialized) def getInteriorInitialized(self): return self.isInteriorInitialized def setCannonEnabled(self, todo0): pass def getCannonEnabled(self): return 0 def setHouseReady(self): pass def addAtticItem(self, item): self.interior.furnitureManager.saveToHouse() if item.getFlags() & FLTrunk: self.atticItems.append(item) elif item.replacesExisting() and item.hasExisting(): if item.getFlags() & FLCloset: closets = ClosetToClothes.keys() for itItem in self.interiorItems: if itItem.furnitureType in closets: posHpr = itItem.posHpr self.interiorItems.remove(itItem) item.posHpr = posHpr self.interiorItems.append(item) break for itItem in self.atticItems: if itItem.furnitureType in closets: self.atticItems.remove(itItem) self.atticItems.append(item) break else: self.atticItems.append(item) self.d_setAtticItems(self.atticItems.getBlob()) self.d_setInteriorItems(self.interiorItems.getBlob()) self.interior.furnitureManager.loadFromHouse() def addWindow(self, item): self.interior.furnitureManager.saveToHouse() self.atticWindows.append(item) self.d_setAtticWindows(self.atticWindows.getBlob()) self.interior.furnitureManager.loadFromHouse() def addWallpaper(self, item): self.interior.furnitureManager.saveToHouse() self.atticWallpaper.append(item) self.d_setAtticWallpaper(self.atticWallpaper.getBlob()) self.interior.furnitureManager.loadFromHouse() def setGardenData(self, gardenData): self.gardenData = gardenData def d_setGardenData(self, gardenData): self.sendUpdate('setGardenData', [gardenData]) def b_setGardenData(self, gardenData): self.setGardenData(gardenData) self.d_setGardenData(gardenData) def getGardenData(self): return self.gardenData def hasGardenData(self): return self.gardenData != '' def placeStarterGarden(self): av = self.air.doId2do.get(self.avatarId) if av is None: return if av.getGardenStarted(): self.notify.warning('Avatar %s tried to start their garden twice!' % self.avatarId) return # State that the avatar has started gardening av.b_setGardenStarted(1) # Create the GardenManagerAI self.gardenManager = GardenManagerAI(self.air, self) self.gardenManager.loadGarden() def createGardenManager(self): if not self.avatarId: return av = self.air.doId2do.get(self.avatarId) if av is not None: if av.getGardenStarted(): self.gardenManager = GardenManagerAI(self.air, self) self.gardenManager.loadGarden() return def __gotOwner(dclass, fields, self=self): if dclass != self.air.dclassesByName['DistributedToonAI']: return gardenStarted = fields['setGardenStarted'][0] if gardenStarted: self.gardenManager = GardenManagerAI(self.air, self) self.gardenManager.loadGarden() self.air.dbInterface.queryObject(self.air.dbId, self.avatarId, __gotOwner)
class DistributedFurnitureManagerAI(DistributedObjectAI): notify = directNotify.newCategory("DistributedFurnitureManagerAI") def __init__(self, air, house, interior): DistributedObjectAI.__init__(self, air) self.house = house self.interior = interior self.director = None self.ownerId = house.avatarId self.ownerName = house.name self.atticItems = None self.atticWallpaper = None self.wallpaper = None self.atticWindows = None self.windows = None self.deletedItems = None self.items = [] # Initialize the above variables: self.loadFromHouse() def announceGenerate(self): DistributedObjectAI.announceGenerate(self) for item in self.items: item.generateWithRequired(self.zoneId) def delete(self): for item in self.items: item.destroy() DistributedObjectAI.delete(self) def loadFromHouse(self): self.b_setAtticItems(self.house.getAtticItems()) self.b_setAtticWallpaper(self.house.getAtticWallpaper()) self.b_setAtticWindows(self.house.getAtticWindows()) self.b_setDeletedItems(self.house.getDeletedItems()) self.wallpaper = CatalogItemList(self.house.getInteriorWallpaper(), store=CatalogItem.Customization) self.applyWallpaper() self.windows = CatalogItemList(self.house.getInteriorWindows(), store=CatalogItem.Customization | CatalogItem.WindowPlacement) self.applyWindows() self.setItems(self.house.getInteriorItems()) def saveToHouse(self): self.house.b_setAtticItems(self.getAtticItems()) self.house.b_setAtticWallpaper(self.getAtticWallpaper()) self.house.b_setAtticWindows(self.getAtticWindows()) self.house.b_setDeletedItems(self.getDeletedItems()) self.house.b_setInteriorWallpaper(self.wallpaper.getBlob()) self.house.b_setInteriorWindows(self.windows.getBlob()) self.house.b_setInteriorItems(self.getItems()) def applyWallpaper(self): self.interior.b_setWallpaper(self.wallpaper.getBlob()) def applyWindows(self): self.interior.b_setWindows(self.windows.getBlob()) def setItems(self, items): # Decode the blob: items = CatalogItemList(items, store=CatalogItem.Customization|CatalogItem.Location) # Throw out our old items: for item in self.items: item.destroy() self.items = [] items.removeDuplicates(FLCloset) # Due to a bug, some people are missing their closets... hasCloset = False for item in items: if item.getFlags() & FLCloset: hasCloset = True break if not hasCloset: item = CatalogFurnitureItem(500) # the basic closet... item.posHpr = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0) items.append(item) # Since we have modified the items list, should we save it back to the house? for item in items: if item.getFlags() & FLTrunk: if self.house.gender is 0: if item.furnitureType - 4000 < 10: item.furnitureType += 10 elif item.furnitureType - 4000 > 10: item.furnitureType -= 10 do = DistributedTrunkAI(self.air, self, item) elif item.getFlags() & FLCloset: if self.house.gender is 0: if item.furnitureType - 500 < 10: item.furnitureType += 10 elif item.furnitureType - 500 > 10: item.furnitureType -= 10 do = DistributedClosetAI(self.air, self, item) elif item.getFlags() & FLBank: continue # We dont want banks in the estates. elif item.getFlags() & FLPhone: do = DistributedPhoneAI(self.air, self, item) else: do = DistributedFurnitureItemAI(self.air, self, item) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) def getItems(self): items = CatalogItemList(store=CatalogItem.Customization|CatalogItem.Location) for item in self.items: items.append(item.catalogItem) return items.getBlob() def setOwnerId(self, ownerId): self.ownerId = ownerId def d_setOwnerId(self, ownerId): self.sendUpdate('setOwnerId', [ownerId]) def b_setOwnerId(self, ownerId): self.setOwnerId(ownerId) self.d_setOwnerId(ownerId) def getOwnerId(self): return self.ownerId def setOwnerName(self, ownerName): self.ownerName = ownerName def d_setOwnerName(self, ownerName): self.sendUpdate('setOwnerName', [ownerName]) def b_setOwnerName(self, ownerName): self.setOwnerName(ownerName) self.d_setOwnerName(ownerName) def getOwnerName(self): return self.ownerName def getInteriorId(self): return self.interior.doId def setAtticItems(self, items): self.atticItems = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticItems(self, items): self.sendUpdate('setAtticItems', [items]) def b_setAtticItems(self, items): self.setAtticItems(items) if self.isGenerated(): self.d_setAtticItems(items) def getAtticItems(self): return self.atticItems.getBlob() def setAtticWallpaper(self, items): self.atticWallpaper = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticWallpaper(self, items): self.sendUpdate('setAtticWallpaper', [items]) def b_setAtticWallpaper(self, items): self.setAtticWallpaper(items) if self.isGenerated(): self.d_setAtticWallpaper(items) def getAtticWallpaper(self): return self.atticWallpaper.getBlob() def setAtticWindows(self, items): self.atticWindows = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticWindows(self, items): self.sendUpdate('setAtticWindows', [items]) def b_setAtticWindows(self, items): self.setAtticWindows(items) if self.isGenerated(): self.d_setAtticWindows(items) def getAtticWindows(self): return self.atticWindows.getBlob() def setDeletedItems(self, items): self.deletedItems = CatalogItemList(items, store=CatalogItem.Customization) def d_setDeletedItems(self, items): self.sendUpdate('setDeletedItems', [items]) def b_setDeletedItems(self, items): self.setDeletedItems(items) if self.isGenerated(): self.d_setDeletedItems(items) def getDeletedItems(self): return self.deletedItems.getBlob() def suggestDirector(self, directorId): senderId = self.air.getAvatarIdFromSender() if self.ownerId != senderId: self.air.writeServerEvent('suspicious', avId=senderId, issue='Tried to move furniture, but not the house owner!') return if senderId != directorId and directorId != 0: self.air.writeServerEvent('suspicious', avId=senderId, issue='Tried to make someone else (%d) move their furniture!' % directorId) return director = self.air.doId2do.get(directorId) if directorId and not director: self.air.writeServerEvent('suspicious', avId=directorId, issue='Tried to move furniture without being on the shard!') return if self.director: self.director.b_setGhostMode(0) if director: if director.zoneId != self.zoneId: self.air.writeServerEvent('suspicious', avId=directorId, issue='Tried to become director from another zone!') return director.b_setGhostMode(1) self.director = director self.sendUpdate('setDirector', [directorId]) # Let's also save the furniture to the house (and thus to the DB) while # we're at it... self.saveToHouse() def avatarEnter(self): pass def avatarExit(self): pass # Furniture-manipulation: def moveItemToAttic(self, doId): item = self.getItemObject(doId) self.atticItems.append(item.catalogItem) self.d_setAtticItems(self.getAtticItems()) item.destroy() self.items.remove(item) return ToontownGlobals.FM_MovedItem def moveItemFromAttic(self, index, x, y, z, h, p, r): item = self.getAtticFurniture(self.atticItems, index) self.atticItems.remove(item) self.d_setAtticItems(self.getAtticItems()) item.posHpr = (x, y, z, h, p, r) if item.getFlags() & FLTrunk: if self.house.gender is 0: if item.furnitureType - 4000 < 10: item.furnitureType += 10 elif item.furnitureType - 4000 > 10: item.furnitureType -= 10 do = DistributedTrunkAI(self.air, self, item) elif item.getFlags() & FLCloset: if self.house.gender is 0: if item.furnitureType - 500 < 10: item.furnitureType += 10 elif item.furnitureType - 500 > 10: item.furnitureType -= 10 do = DistributedClosetAI(self.air, self, item) elif item.getFlags() & FLBank: pass # We don't want banks in the estates elif item.getFlags() & FLPhone: do = DistributedPhoneAI(self.air, self, item) else: do = DistributedFurnitureItemAI(self.air, self, item) do.generateWithRequired(self.zoneId) self.items.append(do) return (ToontownGlobals.FM_MovedItem, do.doId) def deleteItemFromAttic(self, blob, index): item = self.getAtticFurniture(self.atticItems, index) if item is None: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to delete an invalid item at index %s' % index) return ToontownGlobals.FM_InvalidIndex self.atticItems.remove(item) self.d_setAtticItems(self.getAtticItems()) return ToontownGlobals.FM_DeletedItem def deleteItemFromRoom(self, blob, doId): pass def moveWallpaperFromAttic(self, index, room): return ToontownGlobals.FM_InvalidIndex retcode = ToontownGlobals.FM_SwappedItem wallpaper = self.getAtticFurniture(self.atticWallpaper, index) if wallpaper is None: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Invalid wallpaper at index %s' % index) return ToontownGlobals.FM_InvalidIndex if room > 1: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to apply a wallpaper in an invalid room %d!' % room) return ToontownGlobals.FM_InvalidItem interiorIndex = room + wallpaper.getSurfaceType() interiorIndex += wallpaper.getSurfaceType() - 1 print room print interiorIndex atticIndex = self.atticWallpaper.index(wallpaper) self.atticWallpaper[atticIndex] = self.wallpaper[interiorIndex] self.d_setAtticWallpaper(self.getAtticWallpaper()) self.wallpaper[interiorIndex] = wallpaper self.applyWallpaper() return retcode def deleteWallpaperFromAttic(self, blob, index): return # TODO wallpaper = self.getAtticFurniture(blob, index) self.atticWallpaper.remove(wallpaper) self.b_setAtticWallpaper(self.getAtticWallpaper()) def moveWindowToAttic(self, slot): window = self.getWindow(slot) if window is None: return ToontownGlobals.FM_InvalidIndex self.windows.remove(window) self.applyWindows() self.atticWindows.append(window) self.d_setAtticWindows(self.getAtticWindows()) return ToontownGlobals.FM_MovedItem def moveWindowFromAttic(self, index, slot): retcode = ToontownGlobals.FM_MovedItem window = self.getAtticFurniture(self.atticWindows, index) if slot > 5: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to move window to invalid slot %d!' % slot) return ToontownGlobals.FM_HouseFull if self.getWindow(slot): self.moveWindowToAttic(slot) retcode = ToontownGlobals.FM_SwappedItem self.atticWindows.remove(window) self.d_setAtticWindows(self.getAtticWindows()) window.placement = slot self.windows.append(window) self.applyWindows() return retcode def moveWindow(self, fromSlot, toSlot): retcode = ToontownGlobals.FM_MovedItem window = self.getWindow(fromSlot) if window is None: return ToontownGlobals.FM_InvalidIndex if toSlot > 5: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='DistributedfTried to move window to invalid slot %d!' % toSlot) return ToontownGlobals.FM_HouseFull if self.getWindow(toSlot): self.moveWindowToAttic(toSlot) retcode = ToontownGlobals.FM_SwappedItem window.placement = toSlot self.applyWindows() return retcode def deleteWindowFromAttic(self, blob, index): window = self.getAtticFurniture(self.atticWindows, index) if window is None: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to delete an invalid window at index %s' % index) return ToontownGlobals.FM_InvalidIndex self.atticWindows.remove(window) self.d_setAtticWindows(self.getAtticWindows()) return ToontownGlobals.FM_DeletedItem def recoverDeletedItem(self, blob, index): pass def handleMessage(self, func, response, *args): context = args[-1] args = args[:-1] senderId = self.air.getAvatarIdFromSender() if not self.director or senderId != self.director.doId: self.air.writeServerEvent('suspicious', avId=senderId, issue='Sent furniture management request without' ' being the director.') retval = ToontownGlobals.FM_NotDirector else: try: retval = func(*args) or 0 except FurnitureError as e: retval = e.code if response == 'moveItemFromAtticResponse': if type(retval) == tuple: retval, doId = retval else: doId = 0 taskMgr.doMethodLater(1, self.sendUpdateToAvatarId, self.uniqueName('send-attic-response'), extraArgs=[senderId, response, [retval, doId, context]]) else: self.sendUpdateToAvatarId(senderId, response, [retval, context]) def moveItemToAtticMessage(self, doId, context): self.handleMessage(self.moveItemToAttic, 'moveItemToAtticResponse', doId, context) def moveItemFromAtticMessage(self, index, x, y, z, h, p, r, context): self.handleMessage(self.moveItemFromAttic, 'moveItemFromAtticResponse', index, x, y, z, h, p, r, context) def deleteItemFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteItemFromAttic, 'deleteItemFromAtticResponse', blob, index, context) def deleteItemFromRoomMessage(self, blob, doId, context): self.handleMessage(self.deleteItemFromRoom, 'deleteItemFromRoomResponse', blob, doId, context) def moveWallpaperFromAtticMessage(self, index, room, context): self.handleMessage(self.moveWallpaperFromAttic, 'moveWallpaperFromAtticResponse', index, room, context) def deleteWallpaperFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteWallpaperFromAttic, 'deleteWallpaperFromAtticResponse', blob, index, context) def moveWindowToAtticMessage(self, slot, context): self.handleMessage(self.moveWindowToAttic, 'moveWindowToAtticResponse', slot, context) def moveWindowFromAtticMessage(self, index, slot, context): self.handleMessage(self.moveWindowFromAttic, 'moveWindowFromAtticResponse', index, slot, context) def moveWindowMessage(self, fromSlot, toSlot, context): self.handleMessage(self.moveWindow, 'moveWindowResponse', fromSlot, toSlot, context) def deleteWindowFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteWindowFromAttic, 'deleteWindowFromAtticResponse', blob, index, context) def recoverDeletedItemMessage(self, blob, index, context): self.handleMessage(self.recoverDeletedItem, 'recoverDeletedItemResponse', blob, index, context) def getItemObject(self, doId): item = self.air.doId2do.get(doId) if item is None: raise FurnitureError(ToontownGlobals.FM_InvalidItem) if item not in self.items: raise FurnitureError(ToontownGlobals.FM_InvalidItem) return item def getAtticFurniture(self, attic, index): if index >= len(attic): raise FurnitureError(ToontownGlobals.FM_InvalidIndex) return attic[index] def getWindow(self, slot): for window in self.windows: if window.placement == slot: return window return None
class DistributedFurnitureManagerAI(DistributedObjectAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedFurnitureManagerAI") def __init__(self, air, house, interior): DistributedObjectAI.__init__(self, air) self.house = house self.interior = interior self.director = None self.ownerId = house.avatarId self.ownerName = house.name self.atticItems = None self.atticWallpaper = None self.wallpaper = None self.atticWindows = None self.windows = None self.deletedItems = None self.items = [] # Initialize the above variables: self.loadFromHouse() def announceGenerate(self): DistributedObjectAI.announceGenerate(self) for item in self.items: item.generateWithRequired(self.zoneId) def loadFromHouse(self): self.b_setAtticItems(self.house.getAtticItems()) self.b_setAtticWallpaper(self.house.getAtticWallpaper()) self.b_setAtticWindows(self.house.getAtticWindows()) self.b_setDeletedItems(self.house.getDeletedItems()) self.wallpaper = CatalogItemList(self.house.getInteriorWallpaper(), store=CatalogItem.Customization) self.applyWallpaper() self.windows = CatalogItemList(self.house.getInteriorWindows(), store=CatalogItem.Customization | CatalogItem.WindowPlacement) self.applyWindows() self.setItems(self.house.getInteriorItems()) def saveToHouse(self): self.house.b_setAtticItems(self.getAtticItems()) self.house.b_setAtticWallpaper(self.getAtticWallpaper()) self.house.b_setAtticWindows(self.getAtticWindows()) self.house.b_setDeletedItems(self.getDeletedItems()) self.house.b_setInteriorWallpaper(self.wallpaper.getBlob()) self.house.b_setInteriorWindows(self.windows.getBlob()) self.house.b_setInteriorItems(self.getItems()) def applyWallpaper(self): self.interior.b_setWallpaper(self.wallpaper.getBlob()) def applyWindows(self): self.interior.b_setWindows(self.windows.getBlob()) def setItems(self, items): # Decode the blob: items = CatalogItemList(items, store=CatalogItem.Customization|CatalogItem.Location) # Throw out our old items: for item in self.items: item.destroy() self.items = [] for item in items: if item.furnitureType in furnitureId2Do: do = furnitureId2Do[item.furnitureType](self.air, self, item, self.ownerId) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) else: do = DistributedFurnitureItemAI(self.air, self, item) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) def getItems(self): items = CatalogItemList(store=CatalogItem.Customization|CatalogItem.Location) for item in self.items: items.append(item.catalogItem) return items.getBlob() def setOwnerId(self, ownerId): self.ownerId = ownerId def d_setOwnerId(self, ownerId): self.sendUpdate('setOwnerId', [ownerId]) def b_setOwnerId(self, ownerId): self.setOwnerId(ownerId) self.d_setOwnerId(ownerId) def getOwnerId(self): return self.ownerId def setOwnerName(self, ownerName): self.ownerName = ownerName def d_setOwnerName(self, ownerName): self.sendUpdate('setOwnerName', [ownerName]) def b_setOwnerName(self, ownerName): self.setOwnerName(ownerName) self.d_setOwnerName(ownerName) def getOwnerName(self): return self.ownerName def getInteriorId(self): return self.interior.doId def setAtticItems(self, items): self.atticItems = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticItems(self, items): self.sendUpdate('setAtticItems', [items]) def b_setAtticItems(self, items): self.setAtticItems(items) if self.isGenerated(): self.d_setAtticItems(items) def getAtticItems(self): return self.atticItems.getBlob() def setAtticWallpaper(self, items): self.atticWallpaper = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticWallpaper(self, items): self.sendUpdate('setAtticWallpaper', [items]) def b_setAtticWallpaper(self, items): self.setAtticWallpaper(items) if self.isGenerated(): self.d_setAtticWallpaper(items) def getAtticWallpaper(self): return self.atticWallpaper.getBlob() def setAtticWindows(self, items): self.atticWindows = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticWindows(self, items): self.sendUpdate('setAtticWindows', [items]) def b_setAtticWindows(self, items): self.setAtticWindows(items) if self.isGenerated(): self.d_setAtticWindows(items) def getAtticWindows(self): return self.atticWindows.getBlob() def setDeletedItems(self, items): self.deletedItems = CatalogItemList(items, store=CatalogItem.Customization) def d_setDeletedItems(self, items): self.sendUpdate('setDeletedItems', [items]) def b_setDeletedItems(self, items): self.setDeletedItems(items) if self.isGenerated(): self.d_setDeletedItems(items) def getDeletedItems(self): return self.deletedItems.getBlob() def suggestDirector(self, directorId): senderId = self.air.getAvatarIdFromSender() if self.ownerId != senderId: self.air.writeServerEvent('suspicious', senderId, 'Tried to move furniture, but not the house owner!') return if senderId != directorId and directorId != 0: self.air.writeServerEvent('suspicious', senderId, 'Tried to make someone else (%d) move their furniture!' % directorId) return director = self.air.doId2do.get(directorId) if directorId and not director: self.air.writeServerEvent('suspicious', directorId, 'Tried to move furniture without being on the shard!') return if self.director: self.director.b_setGhostMode(0) if director: director.b_setGhostMode(1) self.director = director self.sendUpdate('setDirector', [directorId]) # Let's also save the furniture to the house (and thus to the DB) while # we're at it... self.saveToHouse() def avatarEnter(self): pass def avatarExit(self): pass # Furniture-manipulation: def moveItemToAttic(self, doId): item = self.getItemObject(doId) self.atticItems.append(item.catalogItem) self.d_setAtticItems(self.getAtticItems()) item.destroy() self.items.remove(item) return ToontownGlobals.FM_MovedItem def moveItemFromAttic(self, index, x, y, z, h, p, r): item = self.getAtticFurniture(self.atticItems, index) self.atticItems.remove(item) self.d_setAtticItems(self.getAtticItems()) item.posHpr = (x, y, z, h, p, r) if item.furnitureType in furnitureId2Do: do = furnitureId2Do[item.furnitureType](self.air, self, item, self.ownerId) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) else: do = DistributedFurnitureItemAI(self.air, self, item) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) return (ToontownGlobals.FM_MovedItem, do.doId) def deleteItemFromAttic(self, blob, index): pass def deleteItemFromRoom(self, blob, doId): pass def moveWallpaperFromAttic(self, index, room): pass def deleteWallpaperFromAttic(self, blob, index): pass def moveWindowToAttic(self, slot): window = self.getWindow(slot) if window is None: return ToontownGlobals.FM_InvalidIndex self.windows.remove(window) self.applyWindows() self.atticWindows.append(window) self.d_setAtticWindows(self.getAtticWindows()) return ToontownGlobals.FM_MovedItem def moveWindowFromAttic(self, index, slot): retcode = ToontownGlobals.FM_MovedItem window = self.getAtticFurniture(self.atticWindows, index) if slot > 5: # This is not a valid slot! HACKER!!! self.air.writeServerEvent('suspicious', self.air.getAvatarIdFromSender(), 'Tried to move window to invalid slot %d!' % slot) return ToontownGlobals.FM_HouseFull if self.getWindow(slot): # Already a window there, swap 'er out. self.moveWindowToAttic(slot) retcode = ToontownGlobals.FM_SwappedItem self.atticWindows.remove(window) self.d_setAtticWindows(self.getAtticWindows()) window.placement = slot self.windows.append(window) self.applyWindows() return retcode def moveWindow(self, fromSlot, toSlot): retcode = ToontownGlobals.FM_MovedItem window = self.getWindow(fromSlot) if window is None: return ToontownGlobals.FM_InvalidIndex if toSlot > 5: # This is not a valid slot! HACKER!!! self.air.writeServerEvent('suspicious', self.air.getAvatarIdFromSender(), 'Tried to move window to invalid slot %d!' % toSlot) return ToontownGlobals.FM_HouseFull if self.getWindow(toSlot): # Already a window there, swap 'er out. self.moveWindowToAttic(toSlot) retcode = ToontownGlobals.FM_SwappedItem window.placement = toSlot self.applyWindows() return retcode def deleteWindowFromAttic(self, blob, index): pass def recoverDeletedItem(self, blob, index): pass # Network handlers for the above: def handleMessage(self, func, response, *args): context = args[-1] args = args[:-1] senderId = self.air.getAvatarIdFromSender() if not self.director or senderId != self.director.doId: self.air.writeServerEvent('suspicious', senderId, 'Sent furniture management request without' ' being the director.') retval = ToontownGlobals.FM_NotDirector else: try: retval = func(*args) or 0 except FurnitureError as e: retval = e.code if response == 'moveItemFromAtticResponse': # This message actually includes a doId; we split the retval apart # if it's a tuple, otherwise it falls back to 0. if type(retval) == tuple: retval, doId = retval else: doId = 0 # Brief delay; this is to give the State Server time to finish # processing the new furniture item appearing before we hit the # client with the doId: taskMgr.doMethodLater(5, self.sendUpdateToAvatarId, self.uniqueName('send-attic-response'), extraArgs=[senderId, response, [retval, doId, context]]) else: self.sendUpdateToAvatarId(senderId, response, [retval, context]) def moveItemToAtticMessage(self, doId, context): self.handleMessage(self.moveItemToAttic, 'moveItemToAtticResponse', doId, context) def moveItemFromAtticMessage(self, index, x, y, z, h, p, r, context): self.handleMessage(self.moveItemFromAttic, 'moveItemFromAtticResponse', index, x, y, z, h, p, r, context) def deleteItemFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteItemFromAttic, 'deleteItemFromAtticResponse', blob, index, context) def deleteItemFromRoomMessage(self, blob, doId, context): self.handleMessage(self.deleteItemFromRoom, 'deleteItemFromRoomResponse', blob, doId, context) def moveWallpaperFromAtticMessage(self, index, room, context): self.handleMessage(self.moveWallpaperFromAttic, 'moveWallpaperFromAtticResponse', index, room, context) def deleteWallpaperFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteWallpaperFromAttic, 'deleteWallpaperFromAtticResponse', blob, index, context) def moveWindowToAtticMessage(self, slot, context): self.handleMessage(self.moveWindowToAttic, 'moveWindowToAtticResponse', slot, context) def moveWindowFromAtticMessage(self, index, slot, context): self.handleMessage(self.moveWindowFromAttic, 'moveWindowFromAtticResponse', index, slot, context) def moveWindowMessage(self, fromSlot, toSlot, context): self.handleMessage(self.moveWindow, 'moveWindowResponse', fromSlot, toSlot, context) def deleteWindowFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteWindowFromAttic, 'deleteWindowFromAtticResponse', blob, index, context) def recoverDeletedItemMessage(self, blob, index, context): self.handleMessage(self.recoverDeletedItem, 'recoverDeletedItemResponse', blob, index, context) # Functions to safely process data off the wire: def getItemObject(self, doId): item = self.air.doId2do.get(doId) if item is None: raise FurnitureError(ToontownGlobals.FM_InvalidItem) if item not in self.items: raise FurnitureError(ToontownGlobals.FM_InvalidItem) return item def getAtticFurniture(self, attic, index): if index >= len(attic): raise FurnitureError(ToontownGlobals.FM_InvalidIndex) return attic[index] def getWindow(self, slot): for window in self.windows: if window.placement == slot: return window return None
class DistributedFurnitureManagerAI(DistributedObjectAI): notify = directNotify.newCategory("DistributedFurnitureManagerAI") def __init__(self, air, house, interior): DistributedObjectAI.__init__(self, air) self.house = house self.interior = interior self.director = None self.ownerId = house.avatarId self.ownerName = house.name self.atticItems = None self.atticWallpaper = None self.wallpaper = None self.atticWindows = None self.windows = None self.deletedItems = None self.items = [] # Initialize the above variables: self.loadFromHouse() def announceGenerate(self): DistributedObjectAI.announceGenerate(self) for item in self.items: item.generateWithRequired(self.zoneId) def delete(self): for item in self.items: item.destroy() DistributedObjectAI.delete(self) def loadFromHouse(self): self.b_setAtticItems(self.house.getAtticItems()) self.b_setAtticWallpaper(self.house.getAtticWallpaper()) self.b_setAtticWindows(self.house.getAtticWindows()) self.b_setDeletedItems(self.house.getDeletedItems()) self.wallpaper = CatalogItemList(self.house.getInteriorWallpaper(), store=CatalogItem.Customization) self.applyWallpaper() self.windows = CatalogItemList(self.house.getInteriorWindows(), store=CatalogItem.Customization | CatalogItem.WindowPlacement) self.applyWindows() self.setItems(self.house.getInteriorItems()) def saveToHouse(self): self.house.b_setAtticItems(self.getAtticItems()) self.house.b_setAtticWallpaper(self.getAtticWallpaper()) self.house.b_setAtticWindows(self.getAtticWindows()) self.house.b_setDeletedItems(self.getDeletedItems()) self.house.b_setInteriorWallpaper(self.wallpaper.getBlob()) self.house.b_setInteriorWindows(self.windows.getBlob()) self.house.b_setInteriorItems(self.getItems()) def applyWallpaper(self): self.interior.b_setWallpaper(self.wallpaper.getBlob()) def applyWindows(self): self.interior.b_setWindows(self.windows.getBlob()) def setItems(self, items): # Decode the blob: items = CatalogItemList(items, store=CatalogItem.Customization|CatalogItem.Location) # Throw out our old items: for item in self.items: item.destroy() self.items = [] items.removeDuplicates(FLCloset) # Due to a bug, some people are missing their closets... hasCloset = False for item in items: if item.getFlags() & FLCloset: hasCloset = True break if not hasCloset and self.ownerId != 0: item = CatalogFurnitureItem(500) # the basic closet... item.posHpr = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0) items.append(item) # Since we have modified the items list, should we save it back to the house? for item in items: if item.getFlags() & FLTrunk: if self.house.gender is 0: if item.furnitureType - 4000 < 10: item.furnitureType += 10 elif item.furnitureType - 4000 > 10: item.furnitureType -= 10 do = DistributedTrunkAI(self.air, self, item) elif item.getFlags() & FLCloset: if self.house.gender is 0: if item.furnitureType - 500 < 10: item.furnitureType += 10 elif item.furnitureType - 500 > 10: item.furnitureType -= 10 do = DistributedClosetAI(self.air, self, item) elif item.getFlags() & FLBank: continue # We dont want banks in the estates. elif item.getFlags() & FLPhone: do = DistributedPhoneAI(self.air, self, item) else: do = DistributedFurnitureItemAI(self.air, self, item) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) def getItems(self): items = CatalogItemList(store=CatalogItem.Customization|CatalogItem.Location) for item in self.items: items.append(item.catalogItem) return items.getBlob() def setOwnerId(self, ownerId): self.ownerId = ownerId def d_setOwnerId(self, ownerId): self.sendUpdate('setOwnerId', [ownerId]) def b_setOwnerId(self, ownerId): self.setOwnerId(ownerId) self.d_setOwnerId(ownerId) def getOwnerId(self): return self.ownerId def setOwnerName(self, ownerName): self.ownerName = ownerName def d_setOwnerName(self, ownerName): self.sendUpdate('setOwnerName', [ownerName]) def b_setOwnerName(self, ownerName): self.setOwnerName(ownerName) self.d_setOwnerName(ownerName) def getOwnerName(self): return self.ownerName def getInteriorId(self): return self.interior.doId def setAtticItems(self, items): self.atticItems = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticItems(self, items): self.sendUpdate('setAtticItems', [items]) def b_setAtticItems(self, items): self.setAtticItems(items) if self.isGenerated(): self.d_setAtticItems(items) def getAtticItems(self): return self.atticItems.getBlob() def setAtticWallpaper(self, items): self.atticWallpaper = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticWallpaper(self, items): self.sendUpdate('setAtticWallpaper', [items]) def b_setAtticWallpaper(self, items): self.setAtticWallpaper(items) if self.isGenerated(): self.d_setAtticWallpaper(items) def getAtticWallpaper(self): return self.atticWallpaper.getBlob() def setAtticWindows(self, items): self.atticWindows = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticWindows(self, items): self.sendUpdate('setAtticWindows', [items]) def b_setAtticWindows(self, items): self.setAtticWindows(items) if self.isGenerated(): self.d_setAtticWindows(items) def getAtticWindows(self): return self.atticWindows.getBlob() def setDeletedItems(self, items): self.deletedItems = CatalogItemList(items, store=CatalogItem.Customization) def d_setDeletedItems(self, items): self.sendUpdate('setDeletedItems', [items]) def b_setDeletedItems(self, items): self.setDeletedItems(items) if self.isGenerated(): self.d_setDeletedItems(items) def getDeletedItems(self): return self.deletedItems.getBlob() def suggestDirector(self, directorId): senderId = self.air.getAvatarIdFromSender() if self.ownerId != senderId: self.air.writeServerEvent('suspicious', avId=senderId, issue='Tried to move furniture, but not the house owner!') return if senderId != directorId and directorId != 0: self.air.writeServerEvent('suspicious', avId=senderId, issue='Tried to make someone else (%d) move their furniture!' % directorId) return director = self.air.doId2do.get(directorId) if directorId and not director: self.air.writeServerEvent('suspicious', avId=directorId, issue='Tried to move furniture without being on the shard!') return if self.director: self.director.b_setGhostMode(0) if director: if director.zoneId != self.zoneId: self.air.writeServerEvent('suspicious', avId=directorId, issue='Tried to become director from another zone!') return director.b_setGhostMode(1) self.director = director self.sendUpdate('setDirector', [directorId]) # Let's also save the furniture to the house (and thus to the DB) while # we're at it... self.saveToHouse() def avatarEnter(self): pass def avatarExit(self): pass # Furniture-manipulation: def moveItemToAttic(self, doId): item = self.getItemObject(doId) self.atticItems.append(item.catalogItem) self.d_setAtticItems(self.getAtticItems()) item.destroy() self.items.remove(item) return ToontownGlobals.FM_MovedItem def moveItemFromAttic(self, index, x, y, z, h, p, r): item = self.getAtticFurniture(self.atticItems, index) self.atticItems.remove(item) self.d_setAtticItems(self.getAtticItems()) item.posHpr = (x, y, z, h, p, r) if item.getFlags() & FLTrunk: if self.house.gender is 0: if item.furnitureType - 4000 < 10: item.furnitureType += 10 elif item.furnitureType - 4000 > 10: item.furnitureType -= 10 do = DistributedTrunkAI(self.air, self, item) elif item.getFlags() & FLCloset: if self.house.gender is 0: if item.furnitureType - 500 < 10: item.furnitureType += 10 elif item.furnitureType - 500 > 10: item.furnitureType -= 10 do = DistributedClosetAI(self.air, self, item) elif item.getFlags() & FLBank: pass # We don't want banks in the estates elif item.getFlags() & FLPhone: do = DistributedPhoneAI(self.air, self, item) else: do = DistributedFurnitureItemAI(self.air, self, item) do.generateWithRequired(self.zoneId) self.items.append(do) return (ToontownGlobals.FM_MovedItem, do.doId) def deleteItemFromAttic(self, blob, index): item = self.getAtticFurniture(self.atticItems, index) if item is None: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to delete an invalid item at index %s' % index) return ToontownGlobals.FM_InvalidIndex self.atticItems.remove(item) self.d_setAtticItems(self.getAtticItems()) return ToontownGlobals.FM_DeletedItem def deleteItemFromRoom(self, blob, doId): pass def moveWallpaperFromAttic(self, index, room): retcode = ToontownGlobals.FM_SwappedItem wallpaper = self.getAtticFurniture(self.atticWallpaper, index) if wallpaper is None: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Invalid wallpaper at index %s' % index) return ToontownGlobals.FM_InvalidIndex if room > 1: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to apply a wallpaper in an invalid room %d!' % room) return ToontownGlobals.FM_InvalidItem interiorIndex = room*4 if isinstance(wallpaper, CatalogMouldingItem): interiorIndex += 1 elif isinstance(wallpaper, CatalogFlooringItem): interiorIndex += 2 elif isinstance(wallpaper, CatalogWainscotingItem): interiorIndex += 3 atticIndex = self.atticWallpaper.index(wallpaper) self.atticWallpaper[atticIndex] = self.wallpaper[interiorIndex] self.d_setAtticWallpaper(self.getAtticWallpaper()) self.wallpaper[interiorIndex] = wallpaper self.applyWallpaper() return retcode def deleteWallpaperFromAttic(self, blob, index): wallpaper = self.getAtticFurniture(self.atticWallpaper, index) if wallpaper in self.atticWallpaper: self.atticWallpaper.remove(wallpaper) self.b_setAtticWallpaper(self.getAtticWallpaper()) def moveWindowToAttic(self, slot): window = self.getWindow(slot) if window is None: return ToontownGlobals.FM_InvalidIndex self.windows.remove(window) self.applyWindows() self.atticWindows.append(window) self.d_setAtticWindows(self.getAtticWindows()) return ToontownGlobals.FM_MovedItem def moveWindowFromAttic(self, index, slot): retcode = ToontownGlobals.FM_MovedItem window = self.getAtticFurniture(self.atticWindows, index) if slot > 5: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to move window to invalid slot %d!' % slot) return ToontownGlobals.FM_HouseFull if self.getWindow(slot): self.moveWindowToAttic(slot) retcode = ToontownGlobals.FM_SwappedItem self.atticWindows.remove(window) self.d_setAtticWindows(self.getAtticWindows()) window.placement = slot self.windows.append(window) self.applyWindows() return retcode def moveWindow(self, fromSlot, toSlot): retcode = ToontownGlobals.FM_MovedItem window = self.getWindow(fromSlot) if window is None: return ToontownGlobals.FM_InvalidIndex if toSlot > 5: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='DistributedfTried to move window to invalid slot %d!' % toSlot) return ToontownGlobals.FM_HouseFull if self.getWindow(toSlot): self.moveWindowToAttic(toSlot) retcode = ToontownGlobals.FM_SwappedItem window.placement = toSlot self.applyWindows() return retcode def deleteWindowFromAttic(self, blob, index): window = self.getAtticFurniture(self.atticWindows, index) if window is None: self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to delete an invalid window at index %s' % index) return ToontownGlobals.FM_InvalidIndex self.atticWindows.remove(window) self.d_setAtticWindows(self.getAtticWindows()) return ToontownGlobals.FM_DeletedItem def recoverDeletedItem(self, blob, index): pass def handleMessage(self, func, response, *args): context = args[-1] args = args[:-1] senderId = self.air.getAvatarIdFromSender() if not self.director or senderId != self.director.doId: self.air.writeServerEvent('suspicious', avId=senderId, issue='Sent furniture management request without' ' being the director.') retval = ToontownGlobals.FM_NotDirector else: try: retval = func(*args) or 0 except FurnitureError as e: retval = e.code if response == 'moveItemFromAtticResponse': if type(retval) == tuple: retval, doId = retval else: doId = 0 taskMgr.doMethodLater(1, self.sendUpdateToAvatarId, self.uniqueName('send-attic-response'), extraArgs=[senderId, response, [retval, doId, context]]) else: self.sendUpdateToAvatarId(senderId, response, [retval, context]) def moveItemToAtticMessage(self, doId, context): self.handleMessage(self.moveItemToAttic, 'moveItemToAtticResponse', doId, context) def moveItemFromAtticMessage(self, index, x, y, z, h, p, r, context): self.handleMessage(self.moveItemFromAttic, 'moveItemFromAtticResponse', index, x, y, z, h, p, r, context) def deleteItemFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteItemFromAttic, 'deleteItemFromAtticResponse', blob, index, context) def deleteItemFromRoomMessage(self, blob, doId, context): self.handleMessage(self.deleteItemFromRoom, 'deleteItemFromRoomResponse', blob, doId, context) def moveWallpaperFromAtticMessage(self, index, room, context): self.handleMessage(self.moveWallpaperFromAttic, 'moveWallpaperFromAtticResponse', index, room, context) def deleteWallpaperFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteWallpaperFromAttic, 'deleteWallpaperFromAtticResponse', blob, index, context) def moveWindowToAtticMessage(self, slot, context): self.handleMessage(self.moveWindowToAttic, 'moveWindowToAtticResponse', slot, context) def moveWindowFromAtticMessage(self, index, slot, context): self.handleMessage(self.moveWindowFromAttic, 'moveWindowFromAtticResponse', index, slot, context) def moveWindowMessage(self, fromSlot, toSlot, context): self.handleMessage(self.moveWindow, 'moveWindowResponse', fromSlot, toSlot, context) def deleteWindowFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteWindowFromAttic, 'deleteWindowFromAtticResponse', blob, index, context) def recoverDeletedItemMessage(self, blob, index, context): self.handleMessage(self.recoverDeletedItem, 'recoverDeletedItemResponse', blob, index, context) def getItemObject(self, doId): item = self.air.doId2do.get(doId) if item is None: raise FurnitureError(ToontownGlobals.FM_InvalidItem) if item not in self.items: raise FurnitureError(ToontownGlobals.FM_InvalidItem) return item def getAtticFurniture(self, attic, index): if index >= len(attic): raise FurnitureError(ToontownGlobals.FM_InvalidIndex) return attic[index] def getWindow(self, slot): for window in self.windows: if window.placement == slot: return window return None
class DistributedFurnitureManagerAI(DistributedObjectAI): notify = DirectNotifyGlobal.directNotify.newCategory( "DistributedFurnitureManagerAI") def __init__(self, air, house, interior): DistributedObjectAI.__init__(self, air) self.house = house self.interior = interior self.director = None self.ownerId = house.avatarId self.ownerName = house.name self.atticItems = None self.atticWallpaper = None self.wallpaper = None self.atticWindows = None self.windows = None self.deletedItems = None self.items = [] # Initialize the above variables: self.loadFromHouse() def announceGenerate(self): DistributedObjectAI.announceGenerate(self) for item in self.items: item.generateWithRequired(self.zoneId) def loadFromHouse(self): self.b_setAtticItems(self.house.getAtticItems()) self.b_setAtticWallpaper(self.house.getAtticWallpaper()) self.b_setAtticWindows(self.house.getAtticWindows()) self.b_setDeletedItems(self.house.getDeletedItems()) self.wallpaper = CatalogItemList(self.house.getInteriorWallpaper(), store=CatalogItem.Customization) self.applyWallpaper() self.windows = CatalogItemList(self.house.getInteriorWindows(), store=CatalogItem.Customization | CatalogItem.WindowPlacement) self.applyWindows() self.setItems(self.house.getInteriorItems()) def saveToHouse(self): self.house.b_setAtticItems(self.getAtticItems()) self.house.b_setAtticWallpaper(self.getAtticWallpaper()) self.house.b_setAtticWindows(self.getAtticWindows()) self.house.b_setDeletedItems(self.getDeletedItems()) self.house.b_setInteriorWallpaper(self.wallpaper.getBlob()) self.house.b_setInteriorWindows(self.windows.getBlob()) self.house.b_setInteriorItems(self.getItems()) def applyWallpaper(self): self.interior.b_setWallpaper(self.wallpaper.getBlob()) def applyWindows(self): self.interior.b_setWindows(self.windows.getBlob()) def setItems(self, items): # Decode the blob: items = CatalogItemList(items, store=CatalogItem.Customization | CatalogItem.Location) # Throw out our old items: for item in self.items: item.destroy() self.items = [] for item in items: if item.furnitureType in furnitureId2Do: do = furnitureId2Do[item.furnitureType](self.air, self, item, self.ownerId) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) else: do = DistributedFurnitureItemAI(self.air, self, item) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) def getItems(self): items = CatalogItemList(store=CatalogItem.Customization | CatalogItem.Location) for item in self.items: items.append(item.catalogItem) return items.getBlob() def setOwnerId(self, ownerId): self.ownerId = ownerId def d_setOwnerId(self, ownerId): self.sendUpdate('setOwnerId', [ownerId]) def b_setOwnerId(self, ownerId): self.setOwnerId(ownerId) self.d_setOwnerId(ownerId) def getOwnerId(self): return self.ownerId def setOwnerName(self, ownerName): self.ownerName = ownerName def d_setOwnerName(self, ownerName): self.sendUpdate('setOwnerName', [ownerName]) def b_setOwnerName(self, ownerName): self.setOwnerName(ownerName) self.d_setOwnerName(ownerName) def getOwnerName(self): return self.ownerName def getInteriorId(self): return self.interior.doId def setAtticItems(self, items): self.atticItems = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticItems(self, items): self.sendUpdate('setAtticItems', [items]) def b_setAtticItems(self, items): self.setAtticItems(items) if self.isGenerated(): self.d_setAtticItems(items) def getAtticItems(self): return self.atticItems.getBlob() def setAtticWallpaper(self, items): self.atticWallpaper = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticWallpaper(self, items): self.sendUpdate('setAtticWallpaper', [items]) def b_setAtticWallpaper(self, items): self.setAtticWallpaper(items) if self.isGenerated(): self.d_setAtticWallpaper(items) def getAtticWallpaper(self): return self.atticWallpaper.getBlob() def setAtticWindows(self, items): self.atticWindows = CatalogItemList(items, store=CatalogItem.Customization) def d_setAtticWindows(self, items): self.sendUpdate('setAtticWindows', [items]) def b_setAtticWindows(self, items): self.setAtticWindows(items) if self.isGenerated(): self.d_setAtticWindows(items) def getAtticWindows(self): return self.atticWindows.getBlob() def setDeletedItems(self, items): self.deletedItems = CatalogItemList(items, store=CatalogItem.Customization) def d_setDeletedItems(self, items): self.sendUpdate('setDeletedItems', [items]) def b_setDeletedItems(self, items): self.setDeletedItems(items) if self.isGenerated(): self.d_setDeletedItems(items) def getDeletedItems(self): return self.deletedItems.getBlob() def suggestDirector(self, directorId): senderId = self.air.getAvatarIdFromSender() if self.ownerId != senderId: self.air.writeServerEvent( 'suspicious', senderId, 'Tried to move furniture, but not the house owner!') return if senderId != directorId and directorId != 0: self.air.writeServerEvent( 'suspicious', senderId, 'Tried to make someone else (%d) move their furniture!' % directorId) return director = self.air.doId2do.get(directorId) if directorId and not director: self.air.writeServerEvent( 'suspicious', directorId, 'Tried to move furniture without being on the shard!') return if self.director: self.director.b_setGhostMode(0) if director: director.b_setGhostMode(1) self.director = director self.sendUpdate('setDirector', [directorId]) # Let's also save the furniture to the house (and thus to the DB) while # we're at it... self.saveToHouse() def avatarEnter(self): pass def avatarExit(self): pass # Furniture-manipulation: def moveItemToAttic(self, doId): item = self.getItemObject(doId) self.atticItems.append(item.catalogItem) self.d_setAtticItems(self.getAtticItems()) item.destroy() self.items.remove(item) return ToontownGlobals.FM_MovedItem def moveItemFromAttic(self, index, x, y, z, h, p, r): item = self.getAtticFurniture(self.atticItems, index) self.atticItems.remove(item) self.d_setAtticItems(self.getAtticItems()) item.posHpr = (x, y, z, h, p, r) if item.furnitureType in furnitureId2Do: do = furnitureId2Do[item.furnitureType](self.air, self, item, self.ownerId) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) else: do = DistributedFurnitureItemAI(self.air, self, item) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) return (ToontownGlobals.FM_MovedItem, do.doId) def deleteItemFromAttic(self, blob, index): pass def deleteItemFromRoom(self, blob, doId): pass def moveWallpaperFromAttic(self, index, room): pass def deleteWallpaperFromAttic(self, blob, index): pass def moveWindowToAttic(self, slot): window = self.getWindow(slot) if window is None: return ToontownGlobals.FM_InvalidIndex self.windows.remove(window) self.applyWindows() self.atticWindows.append(window) self.d_setAtticWindows(self.getAtticWindows()) return ToontownGlobals.FM_MovedItem def moveWindowFromAttic(self, index, slot): retcode = ToontownGlobals.FM_MovedItem window = self.getAtticFurniture(self.atticWindows, index) if slot > 5: # This is not a valid slot! HACKER!!! self.air.writeServerEvent( 'suspicious', self.air.getAvatarIdFromSender(), 'Tried to move window to invalid slot %d!' % slot) return ToontownGlobals.FM_HouseFull if self.getWindow(slot): # Already a window there, swap 'er out. self.moveWindowToAttic(slot) retcode = ToontownGlobals.FM_SwappedItem self.atticWindows.remove(window) self.d_setAtticWindows(self.getAtticWindows()) window.placement = slot self.windows.append(window) self.applyWindows() return retcode def moveWindow(self, fromSlot, toSlot): retcode = ToontownGlobals.FM_MovedItem window = self.getWindow(fromSlot) if window is None: return ToontownGlobals.FM_InvalidIndex if toSlot > 5: # This is not a valid slot! HACKER!!! self.air.writeServerEvent( 'suspicious', self.air.getAvatarIdFromSender(), 'Tried to move window to invalid slot %d!' % toSlot) return ToontownGlobals.FM_HouseFull if self.getWindow(toSlot): # Already a window there, swap 'er out. self.moveWindowToAttic(toSlot) retcode = ToontownGlobals.FM_SwappedItem window.placement = toSlot self.applyWindows() return retcode def deleteWindowFromAttic(self, blob, index): pass def recoverDeletedItem(self, blob, index): pass # Network handlers for the above: def handleMessage(self, func, response, *args): context = args[-1] args = args[:-1] senderId = self.air.getAvatarIdFromSender() if not self.director or senderId != self.director.doId: self.air.writeServerEvent( 'suspicious', senderId, 'Sent furniture management request without' ' being the director.') retval = ToontownGlobals.FM_NotDirector else: try: retval = func(*args) or 0 except FurnitureError as e: retval = e.code if response == 'moveItemFromAtticResponse': # This message actually includes a doId; we split the retval apart # if it's a tuple, otherwise it falls back to 0. if type(retval) == tuple: retval, doId = retval else: doId = 0 # Brief delay; this is to give the State Server time to finish # processing the new furniture item appearing before we hit the # client with the doId: taskMgr.doMethodLater( 5, self.sendUpdateToAvatarId, self.uniqueName('send-attic-response'), extraArgs=[senderId, response, [retval, doId, context]]) else: self.sendUpdateToAvatarId(senderId, response, [retval, context]) def moveItemToAtticMessage(self, doId, context): self.handleMessage(self.moveItemToAttic, 'moveItemToAtticResponse', doId, context) def moveItemFromAtticMessage(self, index, x, y, z, h, p, r, context): self.handleMessage(self.moveItemFromAttic, 'moveItemFromAtticResponse', index, x, y, z, h, p, r, context) def deleteItemFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteItemFromAttic, 'deleteItemFromAtticResponse', blob, index, context) def deleteItemFromRoomMessage(self, blob, doId, context): self.handleMessage(self.deleteItemFromRoom, 'deleteItemFromRoomResponse', blob, doId, context) def moveWallpaperFromAtticMessage(self, index, room, context): self.handleMessage(self.moveWallpaperFromAttic, 'moveWallpaperFromAtticResponse', index, room, context) def deleteWallpaperFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteWallpaperFromAttic, 'deleteWallpaperFromAtticResponse', blob, index, context) def moveWindowToAtticMessage(self, slot, context): self.handleMessage(self.moveWindowToAttic, 'moveWindowToAtticResponse', slot, context) def moveWindowFromAtticMessage(self, index, slot, context): self.handleMessage(self.moveWindowFromAttic, 'moveWindowFromAtticResponse', index, slot, context) def moveWindowMessage(self, fromSlot, toSlot, context): self.handleMessage(self.moveWindow, 'moveWindowResponse', fromSlot, toSlot, context) def deleteWindowFromAtticMessage(self, blob, index, context): self.handleMessage(self.deleteWindowFromAttic, 'deleteWindowFromAtticResponse', blob, index, context) def recoverDeletedItemMessage(self, blob, index, context): self.handleMessage(self.recoverDeletedItem, 'recoverDeletedItemResponse', blob, index, context) # Functions to safely process data off the wire: def getItemObject(self, doId): item = self.air.doId2do.get(doId) if item is None: raise FurnitureError(ToontownGlobals.FM_InvalidItem) if item not in self.items: raise FurnitureError(ToontownGlobals.FM_InvalidItem) return item def getAtticFurniture(self, attic, index): if index >= len(attic): raise FurnitureError(ToontownGlobals.FM_InvalidIndex) return attic[index] def getWindow(self, slot): for window in self.windows: if window.placement == slot: return window return None
def setItems(self, items): # Decode the blob: items = CatalogItemList(items, store=CatalogItem.Customization | CatalogItem.Location) # Throw out our old items: for item in self.items: item.destroy() self.items = [] items.removeDuplicates(FLCloset) items.removeDuplicates(FLPhone) items.removeDuplicates(FLBank) # Due to a bug, some people are missing their closets... hasCloset = False for item in items: try: if item.getFlags() & FLCloset: hasCloset = True break except: pass # kys hasAGodDamnPhone = False for killme in items: try: if killme.getFlags() & FLPhone: hasAGodDamnPhone = True break except: pass if not hasAGodDamnPhone and self.ownerId != 0: phone = CatalogFurnitureItem(1399) phone.posHpr = (-5, 0, 0, 0, 0, 0) items.append(phone) print('spawned a phone for someone') # banks hasBank = False for bank in items: try: if bank.getFlags() & FLBank: hasBank = True break except: pass if not hasBank and self.ownerId != 0: bank = CatalogFurnitureItem(1300) bank.posHpr = (5, 0, 0, 0, 0, 0) items.append(bank) print('spawned a bank for someone') if not hasCloset and self.ownerId != 0: item = CatalogFurnitureItem(500) # the basic closet... item.posHpr = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0) items.append(item) print('spawned a closet for someone') # Since we have modified the items list, should we save it back to the house? for item in items: try: if item.getFlags() & FLTrunk: if self.house.gender is 0: if item.furnitureType - 4000 < 10: item.furnitureType += 10 elif item.furnitureType - 4000 > 10: item.furnitureType -= 10 do = DistributedTrunkAI(self.air, self, item) elif item.getFlags() & FLCloset: if self.house.gender is 0: if item.furnitureType - 500 < 10: item.furnitureType += 10 elif item.furnitureType - 500 > 10: item.furnitureType -= 10 do = DistributedClosetAI(self.air, self, item) elif item.getFlags() & FLBank: do = DistributedBankAI(self.air, self, item) elif item.getFlags() & FLPhone: do = DistributedPhoneAI(self.air, self, item) else: do = DistributedFurnitureItemAI(self.air, self, item) if self.isGenerated(): do.generateWithRequired(self.zoneId) self.items.append(do) except: print( "another user with a broken estate hurray!!!!!!!!!!!!!!!!!!" )