def repairCharacterList(self): """ Fix the cases where: * characters in the characterList are no longer on disk """ charObj = None changed = False if self.client.charObj: charObj = self.client.charObj else: charObj = Character(self.client, self.getId()) # temp for methods for cName in self.characterList: charObj.setName(cName) # set the charName self.setDataFilename() # set the filename if not self.dataFileExists(): logger.warning( __class__.__name__ + " - Character " + cName + " of player " + self.email + " does " + " not exist at " + self.getDataFilename() + ". Removing character from account" ) self.characterList.remove(cName) changed = True charObj = None return changed
def getItemObj(self, itemStr, id1, id2=""): """ given return an existing object, or None if it doesn't exist """ if isRoomFactoryType(itemStr.lower()): itemObj = RoomFactory(itemStr, id1) elif itemStr.lower() == "character": itemObj = Character(None, id2) itemObj.setName(id1) elif itemStr.lower() == "creature": itemObj = Creature(id1) elif isObjectFactoryType(itemStr.lower()): itemObj = ObjectFactory(itemStr, id1) elif itemStr.lower() == "account": itemObj = Account() itemObj.email = id1 else: print("Can not determine object type.") return None if not itemObj: msg = "Object doesn't exist. Aborting..." print(msg + "\n") logger.warning(msg) return None if not itemObj.load(): if itemObj.getId() == 0: msg = "Couldn't load object and ID is 0. Aborting..." print(msg + "\n") logger.warning(msg) return None else: itemObj._isNew = True return itemObj
def serverLoop(self): """ This is the main entry point into the app * intended to be overwritten in subClass """ logger.info(str(self) + " serverLoop started") try: while True: # Server loop self.welcome("Sog Server\n") self.acctObj = account.Account(self) if self.acctLogin(): self.mainLoop() else: logger.warning(str(self) + " Authentication failed") self.acctObj = None if not self.isRunning(): break # exit loop to terminate time.sleep(1) finally: logger.info(str(self) + "serverLoop complete") return None def setArea(self, area): self._area = area def getArea(self): if self._area: return str(self._area) return None def isArea(self, area=""): if self._area: if self._area == area: return True return False
def isValid(self): """ Returns true if the class instance was created properly """ if hasattr(self, "email"): if self.email != "": return True else: msg = "{} Account is missing email address".format(self.client) logger.warning(msg) return False
def load(self, requestedAttNames=[], logStr="", fileType="pickle"): """ load from persistant storage - load data into tmp object - iterate through the attributes assigning all, except the ones that we specificly exclude, to the current object - values of excluded objects are not overwritten """ if logStr != "": logStr += " " # append a space for easy logging self.setDataFilename() # We may muck with the object data. Before we do, store # the datafile info as a local variable so that there is no conflict. filename = self._datafile logPrefix = self.__class__.__name__ + " load: " if filename == "": logger.error(logPrefix + " Could not determine " + "filename for loading " + logStr) return False dLog(logPrefix + "Loading " + filename + "...", self._debugStorage) if self.dataFileExists(): # read the persisted content if re.search("\\.json$", filename): loadedDict = self.readJsonFile(filename, logStr) else: loadedDict = self.readPickleFile(filename, logStr) if not loadedDict: logger.error("storage.load - Could not get loaded instance") # Add attributes to current class object, based on revised list self.addAttributesToSelf(loadedDict, requestedAttNames, logStr) dLog( logPrefix + " loaded " + logStr + str(self.getId()) + " - " + self.describe(), self._debugStorage, ) self.initTmpAttributes() self.fixAttributes() self.postLoad() if self.isValid(): return True else: logger.error(logPrefix + logStr + str(self.getId()) + " is not valid") else: logger.warning(logPrefix + " " + logStr + "datafile doesn't exist at " + self._datafile) return False
def removeCharacterFromAccount(self, characterName): if characterName in self.characterList: self.characterList.remove(characterName) self.save(logStr=__class__.__name__) else: logger.warning( "Could not remove character " + characterName + " from account " + self.getId() )
def do_game(self, line): """ play the game """ self.client.charObj = Character(self.client, self.acctObj.getId()) if self.client.charObj.login(): self.client.gameObj.joinGame(self.client) else: self.client.charObj = None msg = "Could not login to game" logger.warning(msg) self.client.spoolOut("Error: " + msg + "\n") self.acctObj.save(logStr=__class__.__name__) return False
def acctLogin(self): """ Login - return true if successful """ loggedIn = False if self.acctObj.login(): loggedIn = True else: logger.warning("{} Authentication failed".format(self)) self.acctObj = None if loggedIn: return True return False
def inflictDamage(self): """ Execute actions for spells that cause damage """ logger.warning("magic.inflictDamage: " + str(self.targetObj) + " was hit by a " + str(self.damage) + " damage " + self.spellName + " spell from " + self.charObj.getName()) if self.charObj.client: self.charObj.client.gameObj.attackCreature( self.charObj, self.targetObj, attackCmd=self.spellName, spellObj=self) else: logger.warning("magic.inflictDamage could not deal damage - " + "charObj.client == None")
def server(email=""): asyncThread = None logger.info("-------------------------------------------------------") logger.info("SVR Server Start {} (pid:{})".format(sys.argv[0], os.getpid())) logger.info("SVR Listening on {}:{}".format(common.globals.HOST, common.globals.PORT)) try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as serverHandle: serverHandle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) serverHandle.bind((common.globals.HOST, common.globals.PORT)) while True: if not threadIsRunning(asyncThread): asyncThread = createAndStartAsyncThread() serverHandle.listen(1) serverHandle.settimeout(60) try: clientsock, clientAddress = serverHandle.accept() newthread = ClientThread(clientsock, clientAddress, common.globals.totalConnections) common.globals.connections.append(newthread) common.globals.totalConnections += 1 common.globals.connections[newthread.getId()].start() except OSError: # This occurs when the socket accept times out, which, since # we are listening for new connections, is about # every second or so. Will leave this here for debugging if False: logger.warning("SVR socket accept() failed - timeout?") time.sleep(1) exitProg() except Terminator: haltAsyncThread(game.Game(), asyncThread) haltClientThreads() exitProg()
def charMsg(self, charObj, msg, allowDupMsgs=True): """ show only to yourself """ if not charObj: logger.warning("ipc.charMsg: charObj doesn't exist for " + charObj.describe() + ". Skipping charMsg: " + msg) return False if not charObj.client: logger.warning("ipc.charMsg: charObj.client doesn't exist for " + charObj.describe() + ". Skipping charMsg: " + msg) return False if not allowDupMsgs and charObj.client.outputSpoolContains(msg): # skip duplicate messages return True charObj.client.spoolOut(msg) if self._instanceDebug: debugMsg = re.sub("\n$", "", msg) logger.info("charMsg to " + charObj.getName() + ": " + debugMsg) return True
def directMsg(self, character, msg): """ show only to specified user """ received = False if not character: return False if isinstance(character, str): for oneChar in self.getCharacterList(): # get chars in game if re.match(character.lower(), oneChar.getName().lower()): recipientObj = oneChar break else: recipientObj = character if recipientObj.client: recipientObj.client.spoolOut(msg) # notify received = True logger.info("directMsg to " + recipientObj.getName() + ": " + msg) else: logger.warning( "ipc.directMsg: recipientObj.client doesn't exist for " + recipientObj.describe() + ". Skipping directMsg: " + msg) return received
def verifyAcctPassword(self, promptStr="Enter Account Password: "******""" Prompt user to verify password, returns True if successful """ if not self.email or self.email == "": msg = "{} verifyAcctPassword failed. email not defined".format(self.client) logger.debug(msg) return False if self.load(["password"], logStr=__class__.__name__): for x in range(1, 4): if self.validatePassword(self.password, promptStr): return True else: self.client.spoolOut( "Password invalid for account " + self.email + " (attempt " + str(x) + " of 3).\n" ) if x == 3: msg = "{} Failed password verification for account {}" logger.warning(msg.format(self.client, self.email)) return False
def fixAttributes(self): # noqa C901 """ Sometimes we change attributes, and need to fix them in rooms that are saved. This method lets us do that. This is the generic case, but subClasses may choose to do more class specific fixes """ logPrefix = "fixAttributes: " changed = False for attName in self.intAttributes: try: if not isinstance(getattr(self, attName), int): newVal = int(getattr(self, attName, 0)) setattr(self, attName, newVal) changed = True logger.warning(logPrefix + "Changed " + attName + " to int for " + self.describe()) except ValueError: setattr(self, attName, 0) logger.warning(logPrefix + "Set " + attName + "= 0") for attName in self.boolAttributes: try: if not isinstance(getattr(self, attName), bool): newVal = bool(getattr(self, attName, False)) setattr(self, attName, newVal) changed = True logger.warning(logPrefix + "Changed " + attName + " to bool for " + self.describe()) except ValueError: setattr(self, attName, False) logger.warning(logPrefix + "Set " + attName + "= False") for attName in self.strAttributes: try: if not isinstance(getattr(self, attName), str): newVal = str(getattr(self, attName, False)) setattr(self, attName, newVal) changed = True logger.warning(logPrefix + "Changed " + attName + " to str for " + self.describe()) except ValueError: setattr(self, attName, "") logger.warning(logPrefix + "Set " + attName + "= ''") for attName in self.obsoleteAttributes: try: if hasattr(self, attName): delattr(self, attName) changed = True logger.warning(logPrefix + "Removed '" + attName + "' from " + self.describe()) except AttributeError: pass return changed
def testDoorsInActiveRooms(self): ''' Set up a pair of doors and verify that door actions work ''' gameObj = self.getGameObj() gameCmdObj = self.getGameCmdObj() charObj = self.getCharObj() charObj.setName('doorOpener') charObj.setHitPoints(10) (roomObj1, roomObj2, doorObj1, doorObj2) = self.doorTestSetUp() self.joinRoom(room=roomObj1) # Add room with 2nd door to active rooms list gameObj.addToActiveRooms(roomObj2) # test that doors are set up correctly assert doorObj1.getToWhere() == roomObj2.getId() assert doorObj2.getToWhere() == roomObj1.getId() assert doorObj1.getCorresspondingDoorId() == doorObj2.getId() assert doorObj2.getCorresspondingDoorId() == doorObj1.getId() logger.info("Test: Original State") self.showItems([doorObj1, doorObj2], self.doorOpenAttributes) # Open door1 self.logRoomInventory(charObj) msg = "Opening door should succeed" logger.info("Test: " + msg) logger.warning("Opening Door") assert not gameCmdObj.do_open("door1") # cmds always return False assert doorObj1.isOpen(), msg self.showItems([doorObj1, doorObj2], self.doorOpenAttributes) # close door1 - check that its closed, and corresponding door is closed msg = "Closing door - both doors should be closed" logger.info("Test: " + msg) logger.warning("Closing Door") assert not gameCmdObj.do_close("door1") # cmds always return False self.showItems([doorObj1, doorObj2], self.doorOpenAttributes) assert doorObj1.isClosed(), msg # Door should be closed assert doorObj2.isClosed(), msg # Corresponding Door should be closed self.logRoomInventory(charObj) # Re-open door1 after being closed msg = "Opening door after it was closed - both doors should be open" logger.info("Test: " + msg) logger.warning("Opening Door") assert not gameCmdObj.do_open("door1") # cmds always return False self.showItems([doorObj1, doorObj2], self.doorOpenAttributes) assert doorObj1.isOpen() # Door should be open assert doorObj2.isOpen() # Corresponding Door should be open # # self._spring = True # automatically close if nobody is in the room # keyObj1 = self.createObject(num=99996, type='Key', name='goodkey') keyObj1._lockId = 99999 keyObj2 = self.createObject(num=99995, type='Key', name='badkey') keyObj2._lockId = 99990 charObj.addToInventory(keyObj1) charObj.addToInventory(keyObj2) msg = "Locking any door without key should fail" logger.info("Test: " + msg) assert not gameCmdObj.do_lock("door1") # cmds always return False assert not doorObj1.isLocked(), msg msg = "Locking an open door with key should fail" logger.info("Test: " + msg) assert not gameCmdObj.do_lock("door1 goodkey") # cmds always return False assert not doorObj1.isLocked(), msg logger.warning("Closing Door") assert not gameCmdObj.do_close("door1") # cmds always return False self.showItems([doorObj1], self.doorLockAttributes) msg = "Locking closed door with no lock should fail" logger.info("Test: " + msg) assert not gameCmdObj.do_lock("door1 goodkey") # cmds always return False assert not doorObj1.isLocked(), msg logger.warning("Adding lock level and lock id") doorObj1._locklevel = 1 doorObj1._lockId = 99999 self.showItems([doorObj1], self.doorLockAttributes) msg = "Locking door with bad key should fail" logger.info("Test: " + msg) assert not gameCmdObj.do_lock("door1 badkey") # cmds always return False assert not doorObj1.isLocked(), msg msg = "Locking door with good key should succeed - both should be locked" logger.info("Test: " + msg) assert not gameCmdObj.do_lock("door1 goodkey") # cmds always return False self.showItems([doorObj1, doorObj2], self.doorLockAttributes) assert doorObj1.isLocked(), msg assert doorObj2.isLocked(), msg msg = "Opening a locked door should fail - door should remain closed" logger.info("Test: " + msg) assert not gameCmdObj.do_open("door1") # cmds always return False assert doorObj1.isClosed(), msg assert doorObj1.isLocked(), msg msg = "Unlocking a locked door with key should succeed, both should be unlocked" logger.info("Test: " + msg) logger.warning("Unlocking Door") assert not gameCmdObj.do_unlock("door1 goodkey") # cmds always return False self.showItems([doorObj1], self.doorLockAttributes) assert doorObj1.isUnlocked(), msg assert doorObj2.isUnlocked(), msg msg = "Opening a previously locked door should succeed - both should be open" logger.info("Test: " + msg) logger.warning("Opening Door") assert not gameCmdObj.do_open("door1") # cmds always return False self.showItems([doorObj1], self.doorLockAttributes) assert doorObj1.isOpen(), msg assert doorObj2.isOpen(), msg msg = "Opening door with trap - char should be damaged" logger.info("Test: " + msg) charObj.client.popOutSpool() # Clear the output spool charObj._instanceDebug = True charObj.dexterity = -1000 # make sure random odds don't break tests charObj._level = -1000 # make sure random odds don't break tests logger.warning("Adding trap level") doorObj1._traplevel = 1 doorObj1.close(charObj) self.showItems([doorObj1], self.doorTrapAttributes) charObj.setMaxHP(100) charObj.setHitPoints(100) assert not gameCmdObj.do_open("door1") # cmds always return False charObj._instanceDebug = False logger.info("OutSpool: " + charObj.client.popOutSpool()) assert charObj.getHitPoints() < 100, msg msg = "Opening door with trap and poison - char should be poisoned" logger.info("Test: " + msg) charObj._instanceDebug = True logger.warning("Adding poison to trap") doorObj1._poison = True doorObj1.close(charObj) self.showItems([doorObj1], self.doorTrapAttributes) charObj.setMaxHP(100) charObj.setHitPoints(100) assert not gameCmdObj.do_open("door1") # cmds always return False charObj._instanceDebug = False logger.info("OutSpool: " + charObj.client.popOutSpool()) assert charObj.getHitPoints() < 100 assert charObj.isPoisoned(), msg msg = "Try to go through a toll door without funds. Should fail" logger.info("Test: " + msg) doorObj1._toll = 2000 charObj._level = 1 charObj.setCoins(1000) origId = roomObj1.getItemId() self.showItems([doorObj1], self.doorTrapAttributes) assert not gameCmdObj.do_look("door1") # cmds always return False assert not gameCmdObj.do_go("door1") # cmds always return False logger.info("OutSpool: " + charObj.client.popOutSpool()) assert roomObj1.getItemId() == origId, msg msg = "Go through a door with a toll - Char should have fewer coins" logger.info("Test: " + msg) doorObj1._toll = 250 charObj.setCoins(1000) doorLoc = doorObj1.getToWhere() assert not gameCmdObj.do_go("door1") # cmds always return False assert charObj.getCoins() == 750, msg assert charObj.getRoom().getId() == doorLoc, msg self.purgeTestRoomData(roomNums=[99992, 99993])
def _postCastTasks(self): # record the last attack command self.charObj.setLastAttack(cmd=self.spellName) if not self.targetObj: logger.warning("logPrefix" + "targetObj is not defined")