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 delete(self, logStr=""): logPrefix = self.__class__.__name__ + " delete: " self.setDataFilename() filename = self._datafile if filename == "": logger.error(logPrefix + " Could not determine filename " + " while deleting " + logStr + str(self.getId())) return False if not os.path.isfile(filename): logger.error(logPrefix + " Could not delete " + filename + " because it is not a file ") return False if self.dataFileExists(): logger.info(logPrefix + " Preparing to delete " + logStr + " " + filename) try: os.remove(filename) except OSError as e: logger.error(logPrefix + "Failed with:" + e.strerror) logger.error(logPrefix + "Error code:" + e.code) if os.path.isfile(filename): logger.error(logPrefix + " " + filename + " could not " + "be deleted") return False else: logger.info(logPrefix + " " + filename + " deleted") return True else: logger.error(logPrefix + " " + filename + " could not " + "be deleted because it doesn't exist") return False return False
def create(self, email): self.client.spoolOut("Creating new account\n") self.setDisplayName(self.promptForDisplayName()) if self.getDisplayName() == "": return False password = self.promptForPassword() if password == "": return False self.password = common.security.hash_password(password) if self.validatePassword(self.password): self.email = email self._maxcharacters = 5 self._creationDate = datetime.now() self.setLoginDate() self._lastLogoutDate = self.setLogoutDate() self.prompt = "full" self.save(logStr=__class__.__name__) acctmsg = "Account {} created for {}\n".format( self.getDisplayName(), self.getEmail()) self.client.spoolOut(acctmsg) logger.info("{} NEW ACCOUNT {}".format(self.client, acctmsg)) return True else: self.client.spoolOut("Password validation failed\n") return False return False
def train(self, charObj): if not self.isTrainingGroundForChar(charObj): charObj.client.spoolOut(self.getNotHereTxt()) if not charObj.hasExpToTrain(): charObj.client.spoolOut( self.getNotEnoughExpTxt() + "You need " + str(charObj.getExp()) + " more experience" ) return False if not self.payToTrain(charObj): return False charObj.levelUp() newLevel = charObj.getLevel() charObj.client.spoolOut( self.getSuccessTxt() + "You are now level " + str(newLevel) + "." ) logger.info( "room.train: " + charObj.getId() + "has trained to " + "become level " + str(newLevel) + "." ) self.recordTrainStats(charObj) return True
def exitProg(statusCode=0): """ Cleanup and Exit program """ logger.info("SVR Server Exit - " + sys.argv[0]) # exit server try: sys.exit(statusCode) except SystemExit: pass
def synthesizer(event: dict, context: dict) -> dict: text, voice_id, output_format = extract_parameters_from_request(event) logger.info("Extracted parameters: " + text + ", " + voice_id + ", " + output_format) logger.info("Calling AWS Polly API - synthezise text to speech") speech = synthesize_speech(text, voice_id, output_format) return Response(speech).create()
def testMagicDevice(self): charObj = self.getCharObj() obj = self.createObject(num=self.testObjNumber, type="Scroll", name="scroll1") assert obj.isMagicItem() obj._spell = "fireball" assert obj.getSpellName() == "fireball" obj.cast(charObj, charObj) msg = charObj.client.popOutSpool() logger.info("\n" + msg) assert "You cast fireball" in msg.split("\n")
def _asyncLoop(self): """ Call the _asyncTasks method of the single game instance. * Thread control and tasks are handled in the game instance. """ if self._debugAsync: logger.debug("{} AsyncThread._asyncMain".format(self)) logger.info("{} Thread started (pid: {})".format(self, os.getpid())) while not self._stopFlag: self.gameObj.asyncTasks() self._lastRunTime = datetime.now() time.sleep(1)
def testEquip(self): equipmentList = ["Armor/1", "Weapon/1"] gameCmdObj = self.getGameCmdObj() for itemId in equipmentList: objType, objId = itemId.split("/") obj = ObjectFactory(objType, objId) name = obj.getName() self.getCharObj().addToInventory(obj) logger.info("Command: use " + name) assert not gameCmdObj.runcmd("use " + name)
def showItems(self, itemList, attList=[]): gameCmdObj = self.getGameCmdObj() for item in itemList: gameCmdObj.do_look(item.getName()) if len(attList): tmplist = [] for att in attList: tmplist.append(att + " = " + str(getattr(item, att))) logger.info("\n" + self.txtBanner(item.getName()) + "\n" + "\n".join(tmplist)) else: logger.info( self.txtBanner(item.getName()) + "\n" + item.debug())
def __init__(self): ServerIo.__init__(self) self.lobbyObj = lobby.Lobby() # create/use single lobby instance self.gameObj = game.Game() # create/use the single game instance self.acctObj = None self.charObj = None self._area = "server" self._debugServer = False # Turn on/off debug logging self._startdate = datetime.now() if self._debugServer: logger.info(str(self) + " New ClientThread")
def purgeTestRoomData(self, roomNums=[]): if len(roomNums) == 0: roomNums = self._tmpTestRoomNumbers # Clean up any saved room data for testRoomNum in roomNums: testRoomFilename = os.path.abspath(DATADIR + "/Room/" + str(testRoomNum) + ".json") if os.path.isfile(testRoomFilename): try: os.remove(testRoomFilename) logger.info("Removing test datafile " + testRoomFilename) except OSError: pass
def start(self): """ Start the editor """ logger.info("Editor Started - " + sys.argv[0]) print("Logs: " + LOGDIR + "\\editor.log") colorama.init() while self.isRunning(): prompt = "(Editor)" inputStr = input(prompt) self.processCommand(inputStr) self._cmdHistory.append(inputStr) if len(self._cmdHistory) > 20: self._cmdHistory.pop(0) colorama.deinit()
def serverLoop(self): """ This is the main entry point into the app """ logger.info(str(self) + " Client connection established") try: while True: # Server loop self.welcome("Sog Server\n") self.acctObj = account.Account(self) if self.acctLogin(): self.mainLoop() else: if not self.isRunning(): break # exit loop to terminate time.sleep(1) self.terminateClientConnection() finally: self.terminateClientConnection() return None
def logRoomInventory(self, charObj): logger.info( "----- room ID: " + charObj.getRoom().getItemId() + " " + str(charObj.getRoom()) + " -----" ) logger.info(charObj.getRoom().display(charObj)) logger.info(str(charObj.getRoom().getInventory())) logger.info("")
def extract_parameters_from_request(event: dict) -> (str, str, str): logger.info(event) if 'queryStringParameters' not in event: logger.error("No query parameters passed") return {} text = event.get('queryStringParameters').get('text', None) voice_id = event.get('queryStringParameters').get('voiceId', None) output_format = event.get('queryStringParameters').get( 'outputFormat', None) if len(text) == 0 or len( voice_id) == 0 or output_format not in AUDIO_FORMATS: logger.error("Bad request: wrong parameters") sys.exit(1) return text, voice_id, output_format
def _sendAndReceive(self): """ Send data as output and recieve input This is the simple "terminal" case for send/receive, but it can be overwritten for client/server or for automated testing """ # Simulate output # pop output off the spool and storing it where we can retrieve it self._outputStr = self.popOutSpool() logger.info("testIo.sr output = " + self._outputStr) # Simulate input by using the next unused input command in _inputCmds if self._cmdCounter < len(self._inputCmds): cmd = self._inputCmds[self._cmdCounter] else: cmd = "exit" self._cmdCounter += 1 self.setInputStr(cmd) # store input logger.info("testIo.sr input = " + self.cmd) return True
def testPlayerDeath(self): tmpRoomNum = 99980 # clean up the test room before we start self.purgeTestRoomData(roomNums=[tmpRoomNum]) gameObj = self.getGameObj() charObj = self.getCharObj() charObj.setName("deadGuy") charObj.setHitPoints(10) roomObj = self.createRoom(num=tmpRoomNum) roomObj._inventory = [] roomObj.save() self.joinRoom(room=roomObj) creObj = self.createCreature() logger.info("Testing character death") self.addFiveItemsToCharacter(charObj) assert len(charObj.getInventory()) == 5 assert len(roomObj.getInventory()) == 0 gameObj.applyPlayerDamage(charObj, creObj, 11) self.logRoomInventory(charObj) assert ( len(charObj.getInventory()) == 0 ), "player's belongings should be removed as they are dumped to room" assert len(charObj.getRoom().getInventory()) == 0 self.joinRoom(room=tmpRoomNum) self.logRoomInventory(charObj) assert ( len(charObj.getRoom().getInventory()) == 5 ), "player's belongings should have persisted in room inventory" logger.info(str(charObj.getRoom().getInventory())) self.joinRoom(room=self._testRoomNum) self.logRoomInventory(charObj) self.joinRoom(room=tmpRoomNum) self.logRoomInventory(charObj) assert ( len(charObj.getRoom().getInventory()) == 0 ), "player's belongings in room inventory should only persist once" self.purgeTestRoomData(roomNums=[tmpRoomNum])
def testTravelSouthAndThroughPortal(self): """ Use known test area which has a room to the south that contains a portal back to the start room """ startRoom = 320 southRoom = 319 portalDestination = startRoom gameCmdObj = self.getGameCmdObj() if self.debug: logger.debug(self.getCharObj().debug()) # Remember that all game commands return False so that command loop # continues self.joinRoom(startRoom) assert self.getCharObj().getRoom().getId() == startRoom logger.info("Command: s") assert not gameCmdObj.runcmd("s") assert self.getCharObj().getRoom().getId() == southRoom logger.info("Command: go portal") assert not gameCmdObj.runcmd("go portal") assert self.getCharObj().getRoom().getId() == portalDestination
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 testLimitations(self): charObj = self.getCharObj() obj = self.createObject(num=self.testObjNumber, type="Door", name="door1") # Test class limitations obj._classesAllowed = ["mage", "paladin"] charObj._classname = "fighter" assert not obj.limitationsAreSatisfied(charObj), charObj.getClassName() charObj._classname = "paladin" assert obj.limitationsAreSatisfied(charObj), charObj.getClassName() # Test class limitations obj._alignmentsAllowed = ["lawful", "neutral"] charObj._alignment = "chaotic" assert not obj.limitationsAreSatisfied(charObj), charObj.getAlignment() charObj._alignment = "neutral" assert obj.limitationsAreSatisfied(charObj), charObj.getAlignment() # Test gender limitations obj._gendersAllowed = ["male", "pan"] charObj._gender = "female" assert not obj.limitationsAreSatisfied(charObj), charObj.getGender() charObj._gender = "male" assert obj.limitationsAreSatisfied(charObj), charObj.getGender() # Test level limitations obj._minLevelAllowed = 3 obj._maxLevelAllowed = 5 charObj.setLevel(2) assert not obj.limitationsAreSatisfied(charObj), charObj.getLevel() charObj.setLevel(6) assert not obj.limitationsAreSatisfied(charObj), charObj.getLevel() charObj.setLevel(3) assert obj.limitationsAreSatisfied(charObj), charObj.getLevel() charObj.setLevel(4) assert obj.limitationsAreSatisfied(charObj), charObj.getLevel() charObj.setLevel(5) assert obj.limitationsAreSatisfied(charObj), charObj.getLevel() logger.info(str(obj))
def testRoomGuild(self): tmpRoomNum = 99999 roomObj = RoomFactory("Guild", tmpRoomNum) # instanciate room object roomObj._lastTrainees = ["Bob", "Satish", "Goldilocks", "Dom", "Lashi"] roomObj._order = "fighter" roomObj._masterLevel = 5 roomObj._masters = ["Berger"] charObj = self.getCharObj() charObj.setClassName("fighter") charObj.setCoins(10) charObj.setName("Bingo") assert not roomObj.train(charObj) assert roomObj.display(charObj) != "" assert roomObj.getNotHereTxt() != "" assert roomObj.getNotEnoughExpTxt() != "" assert roomObj.guildGetInfo() != "" assert roomObj.getOrder() != "" assert isinstance(roomObj.getLastTrainees(), list) assert isinstance(roomObj.getMasters(), list) assert roomObj.getMasterLevel() == 5 assert roomObj.getLastTrainDate() == getNeverDate() assert roomObj.isTrainingGround() assert roomObj.isTrainingGroundForChar(charObj) charObj.setClassName("mage") assert not roomObj.isTrainingGroundForChar(charObj) assert not roomObj.train(charObj) assert roomObj.getCostToTrain(5) == 4096 assert not roomObj.payToTrain(charObj) charObj.setCoins(4096) assert roomObj.payToTrain(charObj) charObj._expToNextLevel = 10 assert not roomObj.train(charObj) charObj._expToNextLevel = 0 assert roomObj.train(charObj) assert charObj.getLevel() == 2 assert roomObj.calculateMasterCoinBonus(7) == 49000 assert "Bingo" in roomObj.getLastTrainees() logger.info(roomObj.getPlaqueMsg()) assert roomObj.getPlaqueMsg() != ""
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 logout(self): """ clean up when the user is done """ buf = "" if "" == self.getEmail(): return True self.setLogoutDate() buf += ( self.getEmail() + " is logged out\n" + "Login Date: " + dateStr(self.getLastLoginDate()) + "\n" + "Logout Date: " + dateStr(self.getLastLogoutDate()) + "\n" + self.client.txtLine("=") + "\n" ) self.client.spoolOut(buf) self.save(logStr=__class__.__name__) if self.client: logger.info("{} Logout {}".format(self.client, self.getEmail())) self.__init__(self.client) return True
def testGameCmdGetObj(self): gameCmdObj = self.getGameCmdObj() roomObj = self.getRoomObj() charObj = self.getCharObj() obj = self.createObject(type="Weapon", name="laser") obj._singledesc = "green laser" roomObj.addToInventory(obj) logger.info("\n" + roomObj.display(charObj)) logger.info("Before:\n" + charObj.inventoryInfo()) assert not gameCmdObj.do_get("laser") # cmds always return False logger.info("After:\n" + charObj.inventoryInfo()) assert obj not in roomObj.getInventory() assert obj in charObj.getInventory()
def testContainer(self): box = self.createObject(num=99999, type="Container", name="box") axe = self.createObject(num=99998, type="Weapon", name="Axe") pin = self.createObject(num=99997, type="Treasure", name="Pin") charObj = self.createCharacter(name="Smoochie") charObj.addToInventory(axe) box.addToInventory(pin) logger.info(box.examine()) assert re.search("Pin", box.examine()) assert not re.search("Axe", box.examine()) assert not box.deposit(charObj, pin, saveItem=False) assert box.deposit(charObj, axe, saveItem=False) logger.info(box.examine()) assert box.getWeight() > box.getContainerWeight() assert re.search("Axe", box.examine()) assert re.search("Pin", box.examine()) assert box.withdraw(charObj, pin, saveItem=False) logger.info(box.examine()) assert not box.withdraw(charObj, pin, saveItem=False) assert not box.withdraw(charObj, None, saveItem=False) assert not box.deposit(charObj, None, saveItem=False) box.close(charObj) logger.info(box.examine()) assert not box.deposit(charObj, axe, saveItem=False)
def testGameCmdGetCoins(self): gameCmdObj = self.getGameCmdObj() roomObj = self.getRoomObj() charObj = self.getCharObj() charObj.setCoins(0) assert charObj.getCoins() == 0 coinObj = self.createObject(type="Coins", name="coins") coinObj._value = 50 roomObj.addToInventory(coinObj) logger.info("\n" + roomObj.display(charObj)) logger.info("Before:\n" + charObj.financialInfo()) assert not gameCmdObj.do_get("coins") # cmds always return False logger.info("After:\n" + charObj.financialInfo()) assert coinObj not in roomObj.getInventory() assert coinObj not in charObj.getInventory() assert charObj.getCoins() == 50
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 editRaw(self, objName, obj, changedSinceLastSave=False): # noqa C901 ROW_FORMAT = "({0:3}) {1:25s}({2:4s}): {3}\n" logger.info("Editing " + objName.capitalize() + " -- id = " + obj.describe()) obj.fixAttributes() while True: objDesc = objName.capitalize() + " " + str(obj.getId()) buf = self.strHeader("Editing " + objDesc) instanceAttributes = vars(obj) varDict = {} attributeList = sorted(instanceAttributes, key=self.customSort) bufCount = 0 for num, attName in enumerate(attributeList): if attName in ( ["client", "gameObj", "acctObj", "_datafile", "py/object"] + obj.obsoleteAttributes + obj.getAttributesThatShouldntBeSaved() ): pass # don't want these else: attValue = getattr(obj, attName) attType = self.getAttributeType(attValue) varDict[num] = {} varDict[num]["name"] = attName varDict[num]["type"] = attType varDict[num]["value"] = attValue msg = ROW_FORMAT.format(num, attName, attType, attValue) if bufCount % 5 == 0: msg = self.strYellow(msg) if attName in obj.wizardAttributes: msg = self.strBright(msg) buf += msg bufCount += 1 print(buf) print("Commands: [s]ave, [q]uit, [wiz]ard, [cust]om") inStr = input("Enter command or attribute to edit: ") cmdargs = inStr.split(" ") if inStr == "s" or inStr == "sq" or inStr == "wq" or inStr == "save": # save edited item if str(obj.getId()) == "" or str(obj.getId()) == "0": self.printError( "ERROR " + objName + " could not be saved. Bad Id: " + obj.getId() ) elif obj.getType().lower() == "room" and hasattr(obj, "_isShop"): # special case to protect us from editing shops/guilds # as rooms, since room objects can load shops self.printError( "ERROR Could not save. It looks " + "like you are editing a Shop/Guild " + " as a " + obj.getType() ) elif obj.save(): print(objName.capitalize(), obj.getId(), "saved") logger.info(objName + " changes saved") changedSinceLastSave = False # reset flag after save else: print("ERROR", objName, "could not be saved") if inStr == "q" or inStr == "sq" or inStr == "wq" or inStr == "": # quit objDescription = objName + " " + str(obj.getId()) objDesc2 = obj.describe(article="") if objDesc2.lower() != objDescription.lower(): objDescription += " (" + objDesc2 + ")" if changedSinceLastSave: # warn if user is quitting with unsaved changes verifyStr = input( "You have made changes since your " + "last save.\nAre you sure that " + "you want to abandon these changes" + " and quit [y/N]: " ) if verifyStr == "y": print("Changes to " + objDescription + " abandoned") logger.info( objName + " changes to " + objDescription + " abandoned" ) break else: print("Done editing " + objDescription) break if inStr == "wizard" or inStr == "wiz": self.wizard(objName, obj) changedSinceLastSave = True elif re.match("^d [0-9]+$", inStr): # delete attribute cmd, inNum = inStr.split(" ") inNum = int(inNum) print("Attribute " + varDict[inNum]["name"] + "deleted") delattr(obj, varDict[inNum]["name"]) changedSinceLastSave = True elif re.match("^[0-9]+$", inStr): # number entry - edit the corresponding field inNum = int(inStr) try: attName = varDict[inNum]["name"] attType = varDict[inNum]["type"] attValue = varDict[inNum]["value"] if self.changeValue(obj, attName, attType, attValue): changedSinceLastSave = True except KeyError: print("Invalid number") elif re.match("^_[^ ]+$", inStr): # named entry try: attValue = getattr(obj, inStr) except AttributeError: print("Can't edit that by name") return False attName = inStr attType = self.getAttributeType(attValue) if self.changeValue(obj, attName, attType, attValue): changedSinceLastSave = True elif re.match("^custom apply", inStr): if len(cmdargs) == 3 and isIntStr(cmdargs[2]): num = cmdargs[2] for item, val in self._customCmdDict[num]: setattr(obj, item, val) elif re.match("^cust", inStr): self.editCustomFunctions(cmdargs) return True
def banner(self, status="start", testName=""): """ show test header banner """ if not hasattr(self, "_testName"): self.setTestName(testName) testStr = self._testName + " " + str(masterTestNum) + " " + status logger.info(self.txtBanner(testStr, bCount=12))