diff --git a/etc/toon.dc b/etc/toon.dc index 6c9936d..4f09c30 100755 --- a/etc/toon.dc +++ b/etc/toon.dc @@ -1603,9 +1603,15 @@ dclass DistributedBuilding : DistributedObject { dclass DistributedAnimBuilding : DistributedBuilding { }; +struct savedBy { + uint32 avId; + string name; + blob dna; +} + dclass DistributedToonInterior : DistributedObject { setZoneIdAndBlock(uint32, uint16) required broadcast ram; - setToonData(blob) required broadcast ram; + setSavedBy(savedBy[]) required broadcast ram; setState(string, int16) required broadcast ram; }; diff --git a/toontown/building/DistributedBuildingAI.py b/toontown/building/DistributedBuildingAI.py index 39c262e..2f675c6 100644 --- a/toontown/building/DistributedBuildingAI.py +++ b/toontown/building/DistributedBuildingAI.py @@ -56,7 +56,7 @@ class DistributedBuildingAI(DistributedObjectAI.DistributedObjectAI): self.track = 'c' self.difficulty = 1 self.numFloors = 0 - self.savedBy = None + self.savedBy = [] self.becameSuitTime = 0 self.frontDoorPoint = None self.suitPlannerExt = None @@ -89,9 +89,17 @@ class DistributedBuildingAI(DistributedObjectAI.DistributedObjectAI): DistributedObjectAI.DistributedObjectAI.delete(self) del self.fsm - def getPickleData(self): - pickleData = {'state': str(self.fsm.getCurrentState().getName()), 'block': str(self.block), 'track': str(self.track), 'difficulty': str(self.difficulty), 'numFloors': str(self.numFloors), 'savedBy': self.savedBy, 'becameSuitTime': self.becameSuitTime} - return pickleData + def getBuildingData(self): + buildingData = { + 'state': str(self.fsm.getCurrentState().getName()), + 'block': str(self.block), + 'track': str(self.track), + 'difficulty': str(self.difficulty), + 'numFloors': str(self.numFloors), + 'savedBy': self.savedBy, + 'becameSuitTime': self.becameSuitTime + } + return buildingData def _getMinMaxFloors(self, difficulty): return SuitBuildingGlobals.SuitBuildingInfo[difficulty][0] @@ -99,7 +107,7 @@ class DistributedBuildingAI(DistributedObjectAI.DistributedObjectAI): def suitTakeOver(self, suitTrack, difficulty, buildingHeight): if not self.isToonBlock(): return - self.updateSavedBy(None) + self.updateSavedBy([]) difficulty = min(difficulty, len(SuitBuildingGlobals.SuitBuildingInfo) - 1) minFloors, maxFloors = self._getMinMaxFloors(difficulty) if buildingHeight == None: @@ -118,7 +126,7 @@ class DistributedBuildingAI(DistributedObjectAI.DistributedObjectAI): def cogdoTakeOver(self, suitTrack, difficulty, buildingHeight): if not self.isToonBlock(): return - self.updateSavedBy(None) + self.updateSavedBy([]) numFloors = self.FieldOfficeNumFloors self.track = suitTrack self.difficulty = difficulty diff --git a/toontown/building/DistributedBuildingMgrAI.py b/toontown/building/DistributedBuildingMgrAI.py index 7e0fc82..9833900 100644 --- a/toontown/building/DistributedBuildingMgrAI.py +++ b/toontown/building/DistributedBuildingMgrAI.py @@ -1,6 +1,6 @@ import os from direct.task.Task import Task -import pickle +import json from otp.ai.AIBaseGlobal import * from . import DistributedBuildingAI, HQBuildingAI, GagshopBuildingAI, PetshopBuildingAI from toontown.building.KartShopBuildingAI import KartShopBuildingAI @@ -231,35 +231,18 @@ class DistributedBuildingMgrAI: return building def getFileName(self): - f = '%s%s_%d.buildings' % (self.serverDatafolder, self.shard, self.branchID) + f = '%s%s_%d_buildings.json' % (self.serverDatafolder, self.shard, self.branchID) return f - def saveTo(self, file, block=None): - if block: - pickleData = block.getPickleData() - pickle.dump(pickleData, file) - else: - for i in list(self.__buildings.values()): - if isinstance(i, HQBuildingAI.HQBuildingAI): - continue - pickleData = i.getPickleData() - pickle.dump(pickleData, file) + def saveTo(self, file): + buildings = {} + for i in list(self.__buildings.values()): + if isinstance(i, HQBuildingAI.HQBuildingAI): + continue + buildingData = i.getBuildingData() + buildings[buildingData['block']] = buildingData - def fastSave(self, block): - return - try: - fileName = self.getFileName() + '.delta' - working = fileName + '.temp' - if os.path.exists(working): - os.remove(working) - os.rename(fileName, working) - file = open(working, 'wb') - file.seek(0, 2) - self.saveTo(file, block) - file.close() - os.rename(working, fileName) - except IOError: - self.notify.error(str(sys.exc_info()[1])) + json.dump(buildings, file, indent=2) def save(self): try: @@ -267,7 +250,7 @@ class DistributedBuildingMgrAI: backup = fileName + self.backupExtension if os.path.exists(fileName): os.rename(fileName, backup) - file = open(fileName, 'wb') + file = open(fileName, 'w') file.seek(0) self.saveTo(file) file.close() @@ -278,25 +261,21 @@ class DistributedBuildingMgrAI: def loadFrom(self, file): blocks = {} - try: - while 1: - pickleData = pickle.load(file) - blocks[int(pickleData['block'])] = pickleData - - except EOFError: - pass + buildingData = json.load(file) + for block in buildingData: + blocks[int(block)] = buildingData[block] return blocks def load(self): fileName = self.getFileName() try: - file = open(fileName + self.backupExtension, 'rb') + file = open(fileName + self.backupExtension, 'r') if os.path.exists(fileName): os.remove(fileName) except IOError: try: - file = open(fileName, 'rb') + file = open(fileName, 'r') except IOError: return {} diff --git a/toontown/building/DistributedToonInterior.py b/toontown/building/DistributedToonInterior.py index 1efcdfd..6ebd00b 100644 --- a/toontown/building/DistributedToonInterior.py +++ b/toontown/building/DistributedToonInterior.py @@ -137,28 +137,26 @@ class DistributedToonInterior(DistributedObject.DistributedObject): self.zoneId = zoneId self.block = block - def setToonData(self, toonData): - savedBy = pickle.loads(toonData) + def setSavedBy(self, savedBy): self.savedBy = savedBy def buildTrophy(self): - if self.savedBy == None: + if not self.savedBy: return numToons = len(self.savedBy) pos = 1.25 - 1.25 * numToons trophy = hidden.attachNewNode('trophy') - for avId, name, dnaTuple, isGM in self.savedBy: - frame = self.buildFrame(name, dnaTuple) + for avId, name, dnaString in self.savedBy: + frame = self.buildFrame(name, dnaString) frame.reparentTo(trophy) frame.setPos(pos, 0, 0) pos += 2.5 return trophy - def buildFrame(self, name, dnaTuple): + def buildFrame(self, name, dnaString): frame = loader.loadModel('phase_3.5/models/modules/trophy_frame') - dna = ToonDNA.ToonDNA() - dna.newToonFromProperties(*dnaTuple) + dna = ToonDNA.ToonDNA(dnaString) head = ToonHead.ToonHead() head.setupHead(dna) head.setPosHprScale(0, -0.05, -0.05, 180, 0, 0, 0.55, 0.02, 0.55) diff --git a/toontown/building/DistributedToonInteriorAI.py b/toontown/building/DistributedToonInteriorAI.py index f1af11f..89b39b3 100644 --- a/toontown/building/DistributedToonInteriorAI.py +++ b/toontown/building/DistributedToonInteriorAI.py @@ -7,6 +7,7 @@ from direct.fsm import ClassicFSM, State from direct.distributed import DistributedObjectAI from direct.fsm import State from toontown.toon import NPCToons +from toontown.toon.ToonDNA import ToonDNA class DistributedToonInteriorAI(DistributedObjectAI.DistributedObjectAI): @@ -38,8 +39,13 @@ class DistributedToonInteriorAI(DistributedObjectAI.DistributedObjectAI): self.zoneId, self.block] return r - def getToonData(self): - return pickle.dumps(self.building.savedBy, 1) + def getSavedBy(self): + savedBy = [] + for avId, name, dnaTuple in self.building.savedBy: + dna = ToonDNA() + dna.newToonFromProperties(*dnaTuple) + savedBy.append([avId, name, dna.makeNetString()]) + return savedBy def getState(self): r = [