def enterPlayGame(self): self._zoneDataStore = AIZoneDataStore() AIRepository.enterPlayGame(self) if ConfigVariableBool('game-server-tests', 0).getValue(): from otp.distributed import DistributedTestObjectAI self.testObject = DistributedTestObjectAI.DistributedTestObjectAI(self) self.testObject.generateOtpObject(self.getGameDoId(), 3) taskMgr.doMethodLater(300, self.printPopulationToLog, self.uniqueName("printPopulationTask"))
def __init__(self, baseChannel, stateServerChannel, districtName): ToontownInternalRepository.__init__( self, baseChannel, stateServerChannel, dcSuffix='AI') self.districtName = districtName self.notify.setInfo(True) # Our AI repository should always log info. self.hoods = [] self.cogHeadquarters = [] self.dnaStoreMap = {} self.dnaDataMap = {} self.suitPlanners = {} self.buildingManagers = {} self.factoryMgr = None self.mintMgr = None self.lawOfficeMgr = None self.countryClubMgr = None self.zoneAllocator = UniqueIdAllocator(ToontownGlobals.DynamicZonesBegin, ToontownGlobals.DynamicZonesEnd) self.zoneDataStore = AIZoneDataStore() self.wantFishing = self.config.GetBool('want-fishing', True) self.wantHousing = self.config.GetBool('want-housing', True) self.wantPets = self.config.GetBool('want-pets', True) self.wantParties = self.config.GetBool('want-parties', True) self.wantCogbuildings = self.config.GetBool('want-cogbuildings', True) self.wantCogdominiums = self.config.GetBool('want-cogdominiums', True) self.doLiveUpdates = self.config.GetBool('want-live-updates', False) self.wantTrackClsends = self.config.GetBool('want-track-clsends', False) self.baseXpMultiplier = self.config.GetFloat('base-xp-multiplier', 1.0) self.wantHalloween = self.config.GetBool('want-halloween', False) self.wantChristmas = self.config.GetBool('want-christmas', False) self.cogSuitMessageSent = False
def createLocals(self): """ Creates "local" (non-distributed) objects. """ # Create our holiday manager... self.holidayManager = HolidayManagerAI(self) # Create our zone data store... self.zoneDataStore = AIZoneDataStore() # Create our pet manager... self.petMgr = PetManagerAI(self) # Create our suit invasion manager... self.suitInvasionManager = SuitInvasionManagerAI(self) # Create our quest manager... self.questManager = QuestManagerAI(self) # Create our promotion manager... self.promotionMgr = PromotionManagerAI(self) # Create our Cog page manager... self.cogPageManager = CogPageManagerAI(self) # Create our race manager... self.raceMgr = RaceManagerAI(self)
def createLocals(self): """ Creates "local" objects. """ # Create our holiday manager... self.holidayManager = HolidayManagerAI(self) # Create our zone data store... self.zoneDataStore = AIZoneDataStore() # Create our pet manager... self.petMgr = PetManagerAI(self) # Create our suit invasion manager... self.suitInvasionManager = SuitInvasionManagerAI(self) # Create our zone allocator... self.zoneAllocator = UniqueIdAllocator( ToontownGlobals.Zones.DynamicZonesBegin, ToontownGlobals.Zones.DynamicZonesEnd) # Create our quest manager... self.questManager = QuestManagerAI(self) # Create our Cog page manager... self.cogPageManager = CogPageManagerAI(self) # Create our fish manager... self.fishManager = FishManagerAI(self) # Create our factory manager... self.factoryMgr = FactoryManagerAI(self) # Create our mint manager... self.mintMgr = MintManagerAI(self) # Create our law office manager... self.lawMgr = LawOfficeManagerAI(self) # Create our country club manager... self.countryClubMgr = CountryClubManagerAI(self) # Create our promotion manager... self.promotionMgr = PromotionManagerAI(self) # Create our Cog suit manager... self.cogSuitMgr = CogSuitManagerAI(self) # Create our race manager... self.raceMgr = RaceManagerAI(self) # Create our Toontown time manager... self.toontownTimeManager = ToontownTimeManager( serverTimeUponLogin=int(time.time()), globalClockRealTimeUponLogin=globalClock.getRealTime())
def __init__(self, baseChannel, stateServerChannel, districtName, startTime=6): ToontownInternalRepository.__init__(self, baseChannel, stateServerChannel, dcSuffix='AI') self.districtName = districtName self.notify.setInfo(True) self.hoods = [] self.hoodId2Hood = {} self.cogHeadquarters = [] self.dnaStoreMap = {} self.dnaDataMap = {} self.suitPlanners = {} self.buildingManagers = {} self.sillyMeterMgr = None self.factoryMgr = None self.mintMgr = None self.lawOfficeMgr = None self.countryClubMgr = None self.boardofficeMgr = None self.startTime = startTime import pymongo self.isRaining = False self.betaEventTTC = None self.betaEventBDHQ = None self.invLastPop = None self.invLastStatus = None import pymongo # Mongo stuff to store seperate database things self.dbConn = pymongo.MongoClient(config.GetString('mongodb-url', 'localhost')) self.dbGlobalCursor = self.dbConn.altis self.dbCursor = self.dbGlobalCursor['air-%d' % self.ourChannel] self.zoneAllocator = UniqueIdAllocator(ToontownGlobals.DynamicZonesBegin, ToontownGlobals.DynamicZonesEnd) self.zoneDataStore = AIZoneDataStore() self.wantFishing = self.config.GetBool('want-fishing', True) self.wantHousing = self.config.GetBool('want-housing', True) self.wantPets = self.config.GetBool('want-pets', True) self.wantParties = self.config.GetBool('want-parties', True) self.wantCogbuildings = self.config.GetBool('want-cogbuildings', True) self.wantCogdominiums = self.config.GetBool('want-cogdominiums', True) self.doLiveUpdates = self.config.GetBool('want-live-updates', False) self.wantTrackClsends = self.config.GetBool('want-track-clsends', False) self.wantAchievements = self.config.GetBool('want-achievements', True) self.wantCharityScreen = self.config.GetBool('want-charity-screen', False) self.baseXpMultiplier = self.config.GetFloat('base-xp-multiplier', 1.0) self.wantHalloween = self.config.GetBool('want-halloween', False) self.wantChristmas = self.config.GetBool('want-christmas', False) self.wantGardening = self.config.GetBool('want-gardening', False) self.cogSuitMessageSent = False self.weatherCycleDuration = self.config.GetInt('weather-cycle-duration', 100)
def createLocals(self): """ Creates "local" (non-distributed) objects. """ # Create our holiday manager... self.holidayManager = HolidayManagerAI(self) # Create our zone data store... self.zoneDataStore = AIZoneDataStore() # Create our pet manager... self.petMgr = PetManagerAI(self) # Create our suit invasion manager... self.suitInvasionManager = SuitInvasionManagerAI(self) # Create our zone allocator... self.zoneAllocator = UniqueIdAllocator( ToontownGlobals.DynamicZonesBegin, ToontownGlobals.DynamicZonesEnd) # Create our quest manager... self.questManager = QuestManagerAI(self) # Create our promotion manager... self.promotionMgr = PromotionManagerAI(self) # Create our Cog page manager... self.cogPageManager = CogPageManagerAI(self) # Create our race manager... self.raceMgr = RaceManagerAI(self) # Create our country club manager... self.countryClubMgr = CountryClubManagerAI(self) # Create our factory manager... self.factoryMgr = FactoryManagerAI(self) # Create our mint manager... self.mintMgr = MintManagerAI(self) # Create our law office manager... self.lawMgr = LawOfficeManagerAI(self) # Create our Cog suit manager... self.cogSuitMgr = CogSuitManagerAI(self)
def createLocals(self): self.holidayManager = HolidayManagerAI(self) self.zoneDataStore = AIZoneDataStore() self.petMgr = PetManagerAI(self) self.suitInvasionManager = SuitInvasionManagerAI(self) self.zoneAllocator = UniqueIdAllocator( ToontownGlobals.DynamicZonesBegin, ToontownGlobals.DynamicZonesEnd) self.questManager = QuestManagerAI(self) self.cogPageManager = CogPageManagerAI(self) self.fishManager = FishManagerAI(self) self.factoryMgr = FactoryManagerAI(self) self.mintMgr = MintManagerAI(self) self.lawMgr = LawOfficeManagerAI(self) self.countryClubMgr = CountryClubManagerAI(self) self.promotionMgr = PromotionManagerAI(self) self.cogSuitMgr = CogSuitManagerAI(self) self.raceMgr = RaceManagerAI(self) self.toontownTimeManager = ToontownTimeManager( serverTimeUponLogin=int(time.time()), globalClockRealTimeUponLogin=globalClock.getRealTime())
class AIDistrict(AIRepository): notify = DirectNotifyGlobal.directNotify.newCategory("AIDistrict") def __init__( self, mdip, mdport, esip, esport, dcFileNames, districtId, districtName, districtType, serverId, minChannel, maxChannel, dcSuffix = 'AI'): assert self.notify.debugStateCall(self) # Save the district Id (needed for calculations in AIRepository code) self.districtId = districtId self.districtName = districtName self.districtType = districtType AIRepository.__init__( self, mdip, mdport, esip, esport, dcFileNames, serverId, minChannel, maxChannel, dcSuffix) self.setClientDatagram(0) assert minChannel > districtId if hasattr(self, 'setVerbose'): if ConfigVariableBool('verbose-airepository', 0).getValue(): self.setVerbose(1) # Save the state server id self.serverId = serverId # Record the reason each client leaves the shard, according to # the client. self._avatarDisconnectReasons = {} # A list of avIds to pretend to disconnect at the next poll # cycle, for debugging purposes only. self._debugDisconnectIds = [] # player avatars will increment and decrement this count self._population = 0 # The AI State machine self.fsm = ClassicFSM.ClassicFSM('AIDistrict', [State.State('off', self.enterOff, self.exitOff, ['connect']), State.State('connect', self.enterConnect, self.exitConnect, ['districtReset', 'noConnection', # I added this because Skyler removed the transition to # districtReset -- Joe 'playGame', ]), State.State('districtReset', self.enterDistrictReset, self.exitDistrictReset, ['playGame','noConnection']), State.State('playGame', self.enterPlayGame, self.exitPlayGame, ['noConnection']), State.State('noConnection', self.enterNoConnection, self.exitNoConnection, ['connect'])], # initial state 'off', # final state 'off', ) self.fsm.enterInitialState() self.fsm.request("connect") def uniqueName(self, desc): return desc+"-"+str(self.districtId) def getGameDoId(self): self.notify.error('derived must override') def incrementPopulation(self): self._population += 1 def decrementPopulation(self): if __dev__: assert self._population > 0 self._population = max(0, self._population - 1) def getPopulation(self): if simbase.fakeDistrictPopulations: if not hasattr(self, '_fakePopulation'): import random self._fakePopulation = random.randrange(1000) return self._fakePopulation return self._population def printPopulationToLog(self, task): self.notify.info("district-name %s | district-id %s | population %s" % (self.districtName, self.districtId, self._population)) return Task.again # check if this is a player avatar in a location where they should not be def _isValidPlayerLocation(self, parentId, zoneId): return True #### Init #### def writeServerEvent(self, eventType, who, description): AIRepository.writeServerEvent(self, eventType, who, description, serverId=self.districtId) #### DistrictReset #### def enterDistrictReset(self): self.handler = self.handleDistrictReset self.deleteDistrict(self.districtId) def exitDistrictReset(self): self.handler = None def handleDistrictReset(self, msgType, di): if msgType == STATESERVER_OBJECT_DELETE_RAM: doId = di.getUint32() self.notify.info("Got request to delete doId: " + str(doId)) if (doId == self.districtId): self.fsm.request("playGame") elif msgType == STATESERVER_OBJECT_NOTFOUND: doId = di.getUint32() self.notify.info("Got Not Found For doId: " + str(doId)) if (doId == self.districtId): self.fsm.request("playGame") else: self.handleMessageType(msgType, di) #### DistrictReset #### def enterPlayGame(self): self._zoneDataStore = AIZoneDataStore() AIRepository.enterPlayGame(self) if ConfigVariableBool('game-server-tests', 0).getValue(): from otp.distributed import DistributedTestObjectAI self.testObject = DistributedTestObjectAI.DistributedTestObjectAI(self) self.testObject.generateOtpObject(self.getGameDoId(), 3) taskMgr.doMethodLater(300, self.printPopulationToLog, self.uniqueName("printPopulationTask")) def getZoneDataStore(self): """This will crash (as designed) if called outside of the PlayGame state.""" return self._zoneDataStore def getRender(self, parentId, zoneId): # distributed objects should call getRender on themselves rather than # call this function. Only call this for zones that are actively being # used, otherwise the zone data will be destroyed before this function # returns zd = AIZoneData(self, parentId, zoneId) render = zd.getRender() zd.destroy() return render def getNonCollidableParent(self, parentId, zoneId): # distributed objects should call getNonCollidableParent on themselves rather than # call this function. Only call this for zones that are actively being # used, otherwise the zone data will be destroyed before this function # returns zd = AIZoneData(self, parentId, zoneId) ncParent = zd.getNonCollidableParent() zd.destroy() return ncParent def getCollTrav(self, parentId, zoneId, *args, **kArgs): # see comment in getRender zd = AIZoneData(self, parentId, zoneId) collTrav = zd.getCollTrav(*args, **kArgs) zd.destroy() return collTrav def getParentMgr(self, parentId, zoneId): # see comment in getRender zd = AIZoneData(self, parentId, zoneId) parentMgr = zd.getParentMgr() zd.destroy() return parentMgr def exitPlayGame(self): if ConfigVariableBool('game-server-tests', 0).getValue(): self.testObject.requestDelete() del self.testObject self._zoneDataStore.destroy() del self._zoneDataStore taskMgr.remove(self.uniqueName("printPopulationTask")) AIRepository.exitPlayGame(self) #### connect ##### def enterConnect(self): self.handler = self.handleConnect self.lastMessageTime = 0 self.connect([self.mdurl], successCallback = self._connected, failureCallback = self._failedToConnect) def _failedToConnect(self, statusCode, statusString): self.fsm.request("noConnection") def _connected(self): # Register our channel self.setConnectionName(self.districtName) AIRepository._connected(self) self.registerShardDownMessage(self.serverId) if self.districtType is not None: self.fsm.request("districtReset") def _handleValidDistrictDown(self, msgType, di): downDistrictId = di.getUint32() if (downDistrictId != self.districtId): self.notify.error("Tried to bring down " + str(self.districtId) + " but " + str(downDistrictId) + " came down instead!") else: # We don't really need to do anything here. pass def _handleIgnorableObjectDelete(self, msgType, di): doId = di.getUint32() self.notify.debug("Ignoring request to delete doId: " + str(doId)) def _handleValidDistrictUp(self, msgType, di): if msgType == STATESERVER_DISTRICT_UP: upDistrictId = di.getUint32() if (upDistrictId != self.districtId): self.notify.error("Tried to bring up " + str(self.districtId) + " but " + str(downDistrictId) + " came up instead!") else: self.notify.info("District %s %s is up. Creating objects..." % (self.districtId, self.districtName)) self.fsm.request("playGame") def exitConnect(self): self.handler = None # Clean up the create district tasks taskMgr.remove(self.uniqueName("newDistrictWait")) del self.lastMessageTime def readerPollUntilEmpty(self, task): # This overrides AIRepository.readerPollUntilEmpty() # to provide an additional debugging hook. while self._debugDisconnectIds: avId = self._debugDisconnectIds.pop() self._doDebugDisconnectAvatar(avId) try: return AIRepository.readerPollUntilEmpty(self, task) except Exception as e: appendStr(e, '\nSENDER ID: %s' % self.getAvatarIdFromSender()) raise def handleReaderOverflow(self): assert self.notify.debugStateCall(self) # may as well delete the shard at this point self.deleteDistrict(self.districtId) raise Exception("incoming-datagram buffer overflowed, aborting AI process") ##### General Purpose functions ##### def getAvatarExitEvent(self, avId): return ("districtExit-" + str(avId)) def debugDisconnectAvatar(self, avId): # This function will pretend to disconnect the indicated # avatar at the next poll cycle, as if the avatar suddenly # disconnected. This is for the purposes of debugging only. # It makes the AI totally forget who this avatar is, but the # avatar is still connected to the server. self._debugDisconnectIds.append(avId) def _doDebugDisconnectAvatar(self, avId): obj = self.doId2do.get(avId) if obj: self.deleteDistObject(obj) self._announceDistObjExit(avId) def _announceDistObjExit(self, avId): # This announces the exiting of this particular avatar messenger.send(self.getAvatarExitEvent(avId)) # This announces generally that an avatar has left. #messenger.send("avatarExited") # Now we don't need to store the disconnect reason any more. try: del self._avatarDisconnectReasons[avId] except: pass def setAvatarDisconnectReason(self, avId, disconnectReason): # This is told us by the client just before he disconnects. self._avatarDisconnectReasons[avId] = disconnectReason def getAvatarDisconnectReason(self, avId): # Returns the reason (as reported by the client) for an # avatar's unexpected exit, or 0 if the reason is unknown. It # is only valid to query this during the handler for the # avatar's unexpected-exit event. return self._avatarDisconnectReasons.get(avId, 0) def _handleUnexpectedDistrictDown(self, di): # Get the district Id downDistrict = di.getUint32() if downDistrict == self.districtId: self.notify.warning("Somebody brought my district(" + str(self.districtId) + ") down! I'm shutting down!") sys.exit() else: self.notify.warning("Weird... My district is " + str(self.districtId) + " and I just got a message that district " + str(downDistrict) + " is going down. I'm ignoring it.") def _handleUnexpectedDistrictUp(self, di): # Get the district Id upDistrict = di.getUint32() if upDistrict == self.districtId: self.notify.warning("Somebody brought my district(" + str(self.districtId) + ") up! I'm shutting down!") sys.exit() else: self.notify.warning("Weird... My district is " + str(self.districtId) + " and I just got a message that district " + str(upDistrict) + " is coming up. I'm ignoring it.") def _handleMakeFriendsReply(self, di): result = di.getUint8() context = di.getUint32() messenger.send("makeFriendsReply", [result, context]) def _handleRequestSecretReply(self, di): result = di.getUint8() secret = di.getString() requesterId = di.getUint32() messenger.send("requestSecretReply", [result, secret, requesterId]) def _handleSubmitSecretReply(self, di): result = di.getUint8() secret = di.getString() requesterId = di.getUint32() avId = di.getUint32() self.writeServerEvent('entered-secret', requesterId, '%s|%s|%s' % (result, secret, avId)) messenger.send("submitSecretReply", [result, secret, requesterId, avId]) def registerShardDownMessage(self, stateserverid): assert self.notify.debugStateCall(self) datagram = PyDatagram() datagram.addServerHeader(stateserverid, self.ourChannel, STATESERVER_SHARD_REST) datagram.addChannel(self.ourChannel) # schedule for execution on socket close self.addPostSocketClose(datagram) def sendSetZone(self, distobj, zoneId): datagram = PyDatagram() datagram.addServerHeader(distobj.doId, self.ourChannel, STATESERVER_OBJECT_SET_ZONE) # Add the zone parent id # HACK: parentId = oldParentId = self.districtId datagram.addUint32(parentId) # Put in the zone id datagram.addUint32(zoneId) # Send it self.send(datagram) # The servers don't inform us of this zone change, because we're the # one that requested it. Update immediately. # TODO: pass in the old parent and old zone distobj.setLocation(parentId, zoneId) #, oldParentId, distobj.zoneId) def deleteDistrict(self, districtId): assert self.notify.debugStateCall(self) # Create a message datagram = PyDatagram() datagram.addServerHeader(self.serverId, self.ourChannel, STATESERVER_OBJECT_DELETE_RAM) # The Id of the object in question datagram.addUint32(districtId) # Send the message self.send(datagram) # Make sure the message gets there. self.flush() def makeFriends(self, avatarAId, avatarBId, flags, context): """ Requests to make a friendship between avatarA and avatarB with the indicated flags (or upgrade an existing friendship with the indicated flags). The context is any arbitrary 32-bit integer. When the friendship is made, or the operation fails, the "makeFriendsReply" event is generated, with two parameters: an integer result code, and the supplied context. """ datagram = PyDatagram() datagram.addServerHeader(DBSERVER_ID, self.ourChannel, DBSERVER_MAKE_FRIENDS) # Indicate the two avatars who are making friends datagram.addUint32(avatarAId) datagram.addUint32(avatarBId) datagram.addUint8(flags) datagram.addUint32(context) self.send(datagram) def requestSecret(self, requesterId): """ Requests a "secret" from the database server. This is a unique string that will be associated with the indicated requesterId, for the purposes of authenticating true-life friends. When the secret is ready, a "requestSecretReply" message will be thrown with three parameters: the result code (0 or 1, indicating failure or success), the generated secret, and the requesterId again. """ datagram = PyDatagram() datagram.addServerHeader(DBSERVER_ID,self.ourChannel,DBSERVER_REQUEST_SECRET) # Indicate the number we want to associate with the new secret. datagram.addUint32(requesterId) # Send it off! self.send(datagram) def submitSecret(self, requesterId, secret): """ Submits a "secret" back to the database server for validation. This attempts to match the indicated string, entered by the user, to a string returned by a previous call to requestSecret(). When the response comes back from the server, a "submitSecretReply" message will be thrown with four parameters: the result code (0 or 1, indicating failure or success), the secret again, the requesterId again, and the number associated with the original secret (that is, the original requesterId). """ datagram = PyDatagram() datagram.addServerHeader( DBSERVER_ID, self.ourChannel, DBSERVER_SUBMIT_SECRET) # Pass in our identifying number, and the string. datagram.addUint32(requesterId) datagram.addString(secret) self.send(datagram) def replaceMethod(self, oldMethod, newFunction): return 0
class AIDistrict(AIRepository): notify = DirectNotifyGlobal.directNotify.newCategory("AIDistrict") def __init__(self, mdip, mdport, esip, esport, dcFileNames, districtId, districtName, districtType, serverId, minChannel, maxChannel, dcSuffix='AI'): assert self.notify.debugStateCall(self) # Save the district Id (needed for calculations in AIRepository code) self.districtId = districtId self.districtName = districtName self.districtType = districtType AIRepository.__init__(self, mdip, mdport, esip, esport, dcFileNames, serverId, minChannel, maxChannel, dcSuffix) self.setClientDatagram(0) assert minChannel > districtId if hasattr(self, 'setVerbose'): if self.config.GetBool('verbose-airepository'): self.setVerbose(1) # Save the state server id self.serverId = serverId # Record the reason each client leaves the shard, according to # the client. self._avatarDisconnectReasons = {} # A list of avIds to pretend to disconnect at the next poll # cycle, for debugging purposes only. self._debugDisconnectIds = [] # player avatars will increment and decrement this count self._population = 0 # The AI State machine self.fsm = ClassicFSM.ClassicFSM( 'AIDistrict', [ State.State('off', self.enterOff, self.exitOff, ['connect']), State.State( 'connect', self.enterConnect, self.exitConnect, [ 'districtReset', 'noConnection', # I added this because Skyler removed the transition to # districtReset -- Joe 'playGame', ]), State.State('districtReset', self.enterDistrictReset, self.exitDistrictReset, ['playGame', 'noConnection']), State.State('playGame', self.enterPlayGame, self.exitPlayGame, ['noConnection']), State.State('noConnection', self.enterNoConnection, self.exitNoConnection, ['connect']) ], # initial state 'off', # final state 'off', ) self.fsm.enterInitialState() self.fsm.request("connect") def uniqueName(self, desc): return desc + "-" + str(self.districtId) def getGameDoId(self): self.notify.error('derived must override') def incrementPopulation(self): self._population += 1 def decrementPopulation(self): if __dev__: assert self._population > 0 self._population = max(0, self._population - 1) def getPopulation(self): if simbase.fakeDistrictPopulations: if not hasattr(self, '_fakePopulation'): import random self._fakePopulation = random.randrange(1000) return self._fakePopulation return self._population def printPopulationToLog(self, task): self.notify.info( "district-name %s | district-id %s | population %s" % (self.districtName, self.districtId, self._population)) return Task.again # check if this is a player avatar in a location where they should not be def _isValidPlayerLocation(self, parentId, zoneId): return True #### Init #### def writeServerEvent(self, eventType, who, description): AIRepository.writeServerEvent(self, eventType, who, description, serverId=self.districtId) #### DistrictReset #### def enterDistrictReset(self): self.handler = self.handleDistrictReset self.deleteDistrict(self.districtId) def exitDistrictReset(self): self.handler = None def handleDistrictReset(self, msgType, di): if msgType == STATESERVER_OBJECT_DELETE_RAM: doId = di.getUint32() self.notify.info("Got request to delete doId: " + str(doId)) if (doId == self.districtId): self.fsm.request("playGame") elif msgType == STATESERVER_OBJECT_NOTFOUND: doId = di.getUint32() self.notify.info("Got Not Found For doId: " + str(doId)) if (doId == self.districtId): self.fsm.request("playGame") else: self.handleMessageType(msgType, di) #### DistrictReset #### def enterPlayGame(self): self._zoneDataStore = AIZoneDataStore() AIRepository.enterPlayGame(self) if simbase.config.GetBool('game-server-tests', 0): from otp.distributed import DistributedTestObjectAI self.testObject = DistributedTestObjectAI.DistributedTestObjectAI( self) self.testObject.generateOtpObject(self.getGameDoId(), 3) taskMgr.doMethodLater(300, self.printPopulationToLog, self.uniqueName("printPopulationTask")) def getZoneDataStore(self): """This will crash (as designed) if called outside of the PlayGame state.""" return self._zoneDataStore def getRender(self, parentId, zoneId): # distributed objects should call getRender on themselves rather than # call this function. Only call this for zones that are actively being # used, otherwise the zone data will be destroyed before this function # returns zd = AIZoneData(self, parentId, zoneId) render = zd.getRender() zd.destroy() return render def getNonCollidableParent(self, parentId, zoneId): # distributed objects should call getNonCollidableParent on themselves rather than # call this function. Only call this for zones that are actively being # used, otherwise the zone data will be destroyed before this function # returns zd = AIZoneData(self, parentId, zoneId) ncParent = zd.getNonCollidableParent() zd.destroy() return ncParent def getCollTrav(self, parentId, zoneId, *args, **kArgs): # see comment in getRender zd = AIZoneData(self, parentId, zoneId) collTrav = zd.getCollTrav(*args, **kArgs) zd.destroy() return collTrav def getParentMgr(self, parentId, zoneId): # see comment in getRender zd = AIZoneData(self, parentId, zoneId) parentMgr = zd.getParentMgr() zd.destroy() return parentMgr def exitPlayGame(self): if simbase.config.GetBool('game-server-tests', 0): self.testObject.requestDelete() del self.testObject self._zoneDataStore.destroy() del self._zoneDataStore taskMgr.remove(self.uniqueName("printPopulationTask")) AIRepository.exitPlayGame(self) #### connect ##### def enterConnect(self): self.handler = self.handleConnect self.lastMessageTime = 0 self.connect([self.mdurl], successCallback=self._connected, failureCallback=self._failedToConnect) def _failedToConnect(self, statusCode, statusString): self.fsm.request("noConnection") def _connected(self): # Register our channel self.setConnectionName(self.districtName) AIRepository._connected(self) self.registerShardDownMessage(self.serverId) if self.districtType is not None: self.fsm.request("districtReset") def _handleValidDistrictDown(self, msgType, di): downDistrictId = di.getUint32() if (downDistrictId != self.districtId): self.notify.error("Tried to bring down " + str(self.districtId) + " but " + str(downDistrictId) + " came down instead!") else: # We don't really need to do anything here. pass def _handleIgnorableObjectDelete(self, msgType, di): doId = di.getUint32() self.notify.debug("Ignoring request to delete doId: " + str(doId)) def _handleValidDistrictUp(self, msgType, di): if msgType == STATESERVER_DISTRICT_UP: upDistrictId = di.getUint32() if (upDistrictId != self.districtId): self.notify.error("Tried to bring up " + str(self.districtId) + " but " + str(downDistrictId) + " came up instead!") else: self.notify.info("District %s %s is up. Creating objects..." % (self.districtId, self.districtName)) self.fsm.request("playGame") def exitConnect(self): self.handler = None # Clean up the create district tasks taskMgr.remove(self.uniqueName("newDistrictWait")) del self.lastMessageTime def readerPollUntilEmpty(self, task): # This overrides AIRepository.readerPollUntilEmpty() # to provide an additional debugging hook. while self._debugDisconnectIds: avId = self._debugDisconnectIds.pop() self._doDebugDisconnectAvatar(avId) try: return AIRepository.readerPollUntilEmpty(self, task) except Exception, e: appendStr(e, '\nSENDER ID: %s' % self.getAvatarIdFromSender()) raise