def botProcessChat(context, **kwargs): returnCode = FilterManager.CONTINUE chat = kwargs["chat"] if chat["type"] == "private": if BotUtils.canUserPerformAction(chat["userId"], "execute", kwargs["bot"]): doAction = False executeAll = False wordList = chat["text"].split() if len(wordList) > 0: if wordList[0].lower() == "execute": doAction = True elif wordList[0].lower() == "executeall": doAction = True executeAll = True if doAction: returnCode = FilterManager.FINISHED del wordList[0] command = " ".join(wordList) if executeAll: for bot in BotManager._bots: if bot.session != None and bot.session.isConnected and hasattr(bot.session, "chatManager"): try: bot.sendChatMessage(command) except AttributeError, inst: Report.error("chat", "Could not execute command: %s" % command, inst) else: kwargs["bot"].sendChatMessage(command)
def parseResponse(self): # Check for errors. effectRemovedPattern = PatternManager.getOrCompilePattern( 'effectRemoved') if effectRemovedPattern.search(self.responseText): return youDontHaveThatEffectPattern = PatternManager.getOrCompilePattern( 'youDontHaveThatEffect') if youDontHaveThatEffectPattern.search(self.responseText): raise DontHaveEffectError( "Unable to remove effect. The user does not have that effect.") youDontHaveSGEEAPattern = PatternManager.getOrCompilePattern( 'youDontHaveSGEEA') if youDontHaveSGEEAPattern.search(self.responseText): raise NotEnoughItemsError( "Unable to remove effect. You do not have a soft green echo eyedrop antidote." ) Report.error("request", "Unknown error occurred when trying to remove an effect") Report.error("request", self.responseText) raise RequestError( "Unknown error occurred when trying to remove an effect.")
def botEndCycle(context, **kwargs): returnCode = FilterManager.CONTINUE bot = kwargs['bot'] # Check for new kmails? aleabot.kmail_check_timer += aleabot.config.get('time_to_sleep') if aleabot.kmail_check_timer >= aleabot.config.get('time_to_sleep_kmail'): Report.trace('bot', 'Enabling doWork:kmail') bot.params['doWork:kmail'] = True aleabot.kmail_check_timer = 0 else: Report.trace('bot', 'Disabling doWork:kmail') bot.params.pop('doWork:kmail', None) # Update clan state in regular intervals (as configured) try: aleabot.clanstate.set_session(bot.session) if aleabot.clanstate.update(aleabot.config.get('clan_state_refresh_time')): Report.info('bot', 'Clan state update successful.') Report.trace('bot', 'I am in clan: ' + repr(aleabot.clanstate.my_clan())) Report.trace('bot', 'I have ' + str(len(aleabot.clanstate.my_whitelists())) + ' whitelists') # Set timer to switch back to home clan if aleabot.home_clan_timer < 0: aleabot.home_clan_timer = 0 except alea.clan.ClanRequestError as err: Report.error('bot', 'Unable to update clan state! Error: ' + str(err)) # Switch to home clan after some delay if aleabot.home_clan_timer >= 0: aleabot.home_clan_timer += aleabot.config.get('time_to_sleep') if aleabot.home_clan_timer >= aleabot.config.get('home_clan_delay'): aleabot.home_clan_timer = -1 # Breakfast now if not yet breakfasted today if 'breakfast' not in bot.states['rollover']: alea.breakfast.breakfast(bot.session) bot.states['rollover']['breakfast'] = True bot.writeState('rollover') # Switch to home clan now home_clan_id = aleabot.config.get('home_clan_id') if home_clan_id > 0 and aleabot.clanstate.my_clan().id() != home_clan_id: Report.info('bot', 'Switching back to home clan.') try: aleabot.clanstate.switch(alea.clan.Clan(home_clan_id, '')) except alea.clan.ClanRequestError as err: Report.error('bot', 'Unable to switch clan! Error: ' + str(err)) return returnCode
def parseResponse(self): # Check for errors. effectRemovedPattern = PatternManager.getOrCompilePattern("effectRemoved") if effectRemovedPattern.search(self.responseText): return youDontHaveThatEffectPattern = PatternManager.getOrCompilePattern("youDontHaveThatEffect") if youDontHaveThatEffectPattern.search(self.responseText): raise DontHaveEffectError("Unable to remove effect. The user does not have that effect.") youDontHaveSGEEAPattern = PatternManager.getOrCompilePattern("youDontHaveSGEEA") if youDontHaveSGEEAPattern.search(self.responseText): raise NotEnoughItemsError("Unable to remove effect. You do not have a soft green echo eyedrop antidote.") Report.error("request", "Unknown error occurred when trying to remove an effect") Report.error("request", self.responseText) raise RequestError("Unknown error occurred when trying to remove an effect.")
def handleClanChat(context, **kwargs): chat = kwargs["chat"] bot = kwargs["bot"] globalState = bot.states["global"] # Do nothing if the bot is squelched. if DataUtils.getBoolean(globalState, "isSquelched", False): return FilterManager.CONTINUE # Do nothing if the text is prefixed by PRIVATE: lowerText = chat["text"].lower() if lowerText.find("private:") == 0: return FilterManager.CONTINUE # Do nothing for broadcasted messages. if chat["userName"] == "System Message": return FilterManager.CONTINUE # Construct the message to send to the other bots. msg = None if "chatBroadcastDelimiters" in bot.params: chars = bot.params["chatBroadcastDelimiters"] if chat["type"] == "normal": msg = "%s%s%s %s" % (chars[0], chat["userName"], chars[1], chat["text"]) elif chat["type"] == "emote": msg = "/me %s%s%s %s" % (chars[0], chat["userName"], chars[1], chat["text"]) else: if chat["type"] == "normal": msg = "[%s] %s" % (chat["userName"], chat["text"]) elif chat["type"] == "emote": msg = "/me [%s] %s" % (chat["userName"], chat["text"]) # Send the message to the other bots. if msg != None: thisBot = kwargs["bot"] for bot in BotManager._bots: if bot.id != thisBot.id: if bot.session != None and bot.session.isConnected and hasattr( bot.session, "chatManager"): try: bot.sendChatMessage(msg) except AttributeError, inst: Report.error("chat", "Could not broadcast message.", inst)
def parseResponse(self): # Check for errors. effectRemovedPattern = PatternManager.getOrCompilePattern('effectRemoved') if effectRemovedPattern.search(self.responseText): return youDontHaveThatEffectPattern = PatternManager.getOrCompilePattern('youDontHaveThatEffect') if youDontHaveThatEffectPattern.search(self.responseText): raise Error.Error("Unable to remove effect. The user does not have that effect.", Error.EFFECT_NOT_FOUND) youDontHaveSGEEAPattern = PatternManager.getOrCompilePattern('youDontHaveSGEEA') if youDontHaveSGEEAPattern.search(self.responseText): raise Error.Error("Unable to remove effect. You do not have a soft green echo eyedrop antidote.", Error.ITEM_NOT_FOUND) Report.error("request", "Unknown error occurred when trying to remove an effect") Report.error("request", self.responseText) raise Error.Error("Unknown error occurred when trying to remove an effect.", Error.REQUEST_FATAL)
def handleClanChat(context, **kwargs): chat = kwargs["chat"] bot = kwargs["bot"] globalState = bot.states["global"] # Do nothing if the text is prefixed by PRIVATE: lowerText = chat["text"].lower() if lowerText.find("private:") == 0 or lowerText[0:2] == "p:": return FilterManager.CONTINUE if DataUtils.getBoolean(kwargs["bot"].params, "doWork:doLogChat", False): HogDatabase.logChat(chat["userId"], chat["userName"], bot.params["userClan"], chat["text"]) # Do nothing if the bot is squelched. if DataUtils.getBoolean(globalState, "isSquelched", False): return FilterManager.CONTINUE # Do nothing for broadcasted messages. if chat["userName"] == "System Message": return FilterManager.CONTINUE # Construct the message to send to the other bots. msg = None if "chatBroadcastDelimiters" in bot.params: chars = bot.params["chatBroadcastDelimiters"] if chat["type"] == "normal": msg = "%s%s%s %s" % (chars[0], chat["userName"], chars[1], chat["text"]) elif chat["type"] == "emote": msg = "/me %s%s%s %s" % (chars[0], chat["userName"], chars[1], chat["text"]) else: if chat["type"] == "normal": msg = "[%s] %s" % (chat["userName"], chat["text"]) elif chat["type"] == "emote": msg = "/me [%s] %s" % (chat["userName"], chat["text"]) # Send the message to the other bots. if msg != None: thisBot = kwargs["bot"] for bot in BotManager._bots: if bot.id != thisBot.id: if bot.session != None and bot.session.isConnected and hasattr(bot.session, "chatManager"): try: bot.sendChatMessage(msg) except AttributeError, inst: Report.error("chat", "Could not broadcast message.", inst)
def parseResponse(self): weakSkillPattern = PatternManager.getOrCompilePattern('skillTooWeak') badSkillPattern = PatternManager.getOrCompilePattern('skillNotTrainable') poorSkillPattern = PatternManager.getOrCompilePattern('skillTooPoor') haveSkillPattern = PatternManager.getOrCompilePattern('skillHaveAlready') if weakSkillPattern.search(self.responseText): raise InvalidActionError("You aren't a high enough level to train that skill") if badSkillPattern.search(self.responseText): raise SkillMissingError("You cannot train that skill at the Guild Hall") if poorSkillPattern.search(self.responseText): raise NotEnoughMeatError("You cannot afford to train that skill") if haveSkillPattern.search(self.responseText): raise RequestError("You already know that skill") skillLearnedPattern = PatternManager.getOrCompilePattern('skillLearned') match = skillLearnedPattern.search(self.responseText) if match: try: skill = SkillDatabase.getSkillFromName(match.group(1)) self.responseData["skill"] = skill except SkillNotFoundError, inst: Report.error("bot", inst.message, inst)
def breakfast(session): Report.info('bot', 'Start of breakfast.') meatGained = 0 Report.info('bot', 'Visiting hippy produce stand.') try: req = HippyProduceStandRequest(session) response = req.doRequest() meatGained += response['meat'] except Error.Error as err: Report.error('bot', 'Error while visiting hippy produce stand: ' + str(err)) Report.info('bot', 'Visiting potted meat bush.') try: req = MeatBushRequest(session) response = req.doRequest() meatGained += response['meat'] except Error.Error as err: Report.error('bot', 'Error while visiting potted meat bush: ' + str(err)) Report.info('bot', 'Visiting exotic hanging meat orchid.') try: req = MeatOrchidRequest(session) response = req.doRequest() meatGained += response['meat'] except Error.Error as err: Report.error('bot', 'Error while visiting exotic hanging meat orchid: ' + str(err)) Report.info('bot', 'Visiting potted meat tree.') try: req = MeatTreeRequest(session) response = req.doRequest() meatGained += response['meat'] except Error.Error as err: Report.error('bot', 'Error while visiting potted meat tree: ' + str(err)) Report.info('bot', 'End of breakfast. Meat gained: ' + str(meatGained))
def parseResponse(self): entries = [] entryPattern = PatternManager.getOrCompilePattern('clanLogEntry') for entryMatch in entryPattern.finditer(self.responseText): entry = {} date = entryMatch.group('date') entry['date'] = datetime.strptime(date, "%m/%d/%y, %I:%M%p") entry['userId'] = int(entryMatch.group('userId')) entry['userName'] = entryMatch.group('userName') action = entryMatch.group('action') foundAction = False if foundAction == False: pattern = PatternManager.getOrCompilePattern('clanLogFax') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_FAX entry['monster'] = match.group('monsterName') if foundAction == False: pattern = PatternManager.getOrCompilePattern('clanLogAttack') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_ATTACK entry['clanName'] = match.group('clanName') if foundAction == False: pattern = PatternManager.getOrCompilePattern( 'clanLogWhitelistAdd') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_WHITELISTED_PLAYER entry['targetUserName'] = match.group('userName') entry['targetUserId'] = int(match.group('userId')) if foundAction == False: pattern = PatternManager.getOrCompilePattern( 'clanLogPlayerJoinedAnotherClan') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_JOINED_ANOTHER_CLAN if foundAction == False: pattern = PatternManager.getOrCompilePattern( 'clanLogPlayerJoinedClanWhitelist') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_WHITELISTED_IN if foundAction == False: pattern = PatternManager.getOrCompilePattern( 'clanLogStashItemAdd') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_STASH_ADD entry['itemName'] = match.group('itemName') entry['quantity'] = int( match.group('quantity').replace(',', '')) if foundAction == False: pattern = PatternManager.getOrCompilePattern( 'clanLogStashItemRemove') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_STASH_REMOVE entry['itemName'] = match.group('itemName') entry['quantity'] = int( match.group('quantity').replace(',', '')) if foundAction == False: pattern = PatternManager.getOrCompilePattern( 'clanLogMeatSpentArmy') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_MEAT_SPENT_ARMY entry['meat'] = int(match.group('meat').replace(',', '')) if foundAction == False: pattern = PatternManager.getOrCompilePattern( 'clanLogChangedRank') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_CHANGED_RANK entry['targetUserName'] = match.group('userName') entry['targetUserId'] = int(match.group('userId')) if foundAction == False: pattern = PatternManager.getOrCompilePattern( 'clanLogChangedTitle') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_CHANGED_RANK entry['targetUserName'] = match.group('userName') entry['targetUserId'] = int(match.group('userId')) entry['clanTitle'] = match.group('clanTitle') if foundAction == False: Report.error("request", "Unknown clan log action: %s" % action) entry['type'] = CLAN_LOG_UNKNOWN entry['action'] = action entries.append(entry) self.responseData["entries"] = entries
def parseChatMessages(text, isIncoming): """ This function parses chats passed to it. The chats are assumed to come from a GetChatMessagesRequest. Returns a list of chats, each of which is a dictionary possibly containing the following keys: "type" : What kind of chat this is. Current possible values are "channel" "listen" "listen:start" "listen:stop" "normal" "emote" "private" "system message" "mod warning" "mod announcement" "notification:kmail" "notification:carnival" "unknown" "currentChannel" : The current channel as indicated when sending a /c, /s, or /l request "otherChannels" : The other channels being listened to as indicated by a /l request "description" : The description of the current channel as indicated when sending a /c or /s request "channel" : The channel this chat message was posted from "userId" : The user id number of the user sending this chat message "userName" : The user name of the user sending this chat message "text" : The text of the current chat message "isMultiline" : A flag indicating whether this is a multiline message such as a haiku or a message from the Gothy Effect """ # Prepare the patterns. htmlCommentPattern = PatternManager.getOrCompilePattern("htmlComment") htmlTagPattern = PatternManager.getOrCompilePattern("htmlTag") channelPattern = PatternManager.getOrCompilePattern("chatChannel") chatPattern = PatternManager.getOrCompilePattern("chatMessage") emotePattern = PatternManager.getOrCompilePattern("chatEmote") privateChatPattern = PatternManager.getOrCompilePattern("privateChat") newKmailPattern = PatternManager.getOrCompilePattern( "chatNewKmailNotification") linkPattern = PatternManager.getOrCompilePattern("chatLink") chatWhoPattern = PatternManager.getOrCompilePattern("chatWhoResponse") linkedPlayerPattern = PatternManager.getOrCompilePattern( "chatLinkedPlayer") multiLinePattern = PatternManager.getOrCompilePattern("chatMultiLineStart") multiEmotePattern = PatternManager.getOrCompilePattern( "chatMultiLineEmote") playerLoggedOnPattern = PatternManager.getOrCompilePattern( "chatPlayerLoggedOn") playerLoggedOffPattern = PatternManager.getOrCompilePattern( "chatPlayerLoggedOff") newCarnivalPattern = PatternManager.getOrCompilePattern("chatCarnival") # Get the chat messages. chats = [] # Check for responses to outgoing chat commands. if isIncoming == False: outPrivatePattern = PatternManager.getOrCompilePattern( "outgoingPrivate") chatNewChannelPattern = PatternManager.getOrCompilePattern( "newChatChannel") chatListenPattern = PatternManager.getOrCompilePattern( "chatListenResponse") chatListenStartPattern = PatternManager.getOrCompilePattern( "chatStartListen") chatListenStopPattern = PatternManager.getOrCompilePattern( "chatStopListen") # See if it is an outgoing private message match = outPrivatePattern.search(text) if match: chat = {} chat["type"] = "private" chat["userName"] = match.group(2) chat["userId"] = int(match.group(1)) chat["text"] = match.group(3).strip() text = text[:match.start()] + text[match.end():] chats.append(chat) # See if the user changed chat channels through /c or /s match = chatNewChannelPattern.search(text) if match: chat = {} chat["type"] = "channel" chat["currentChannel"] = match.group(1) chat["description"] = match.group(2).replace('<br>', '') text = text[:match.start()] + text[match.end():] chats.append(chat) # See if it is a /l response match = chatListenPattern.search(text) if match: chat = {} listen = match.group() currentPattern = PatternManager.getOrCompilePattern( "chatListenCurrent") otherPattern = PatternManager.getOrCompilePattern( "chatListenOthers") chat["type"] = "listen" chat["currentChannel"] = currentPattern.search(listen).group(1) other = [] for channel in otherPattern.finditer(listen): other.append(channel.group(1)) chat["otherChannels"] = other text = text[:match.start()] + text[match.end():] chats.append(chat) # See if it is a /l <channel> response to start listening to a channel match = chatListenStartPattern.search(text) if match: chat = {} chat["type"] = "listen:start" chat["channel"] = match.group(1) text = text[:match.start()] + text[match.end():] chats.append(chat) # See if it is a /l <channel> response to stop listening to a channel match = chatListenStopPattern.search(text) if match: chat = {} chat["type"] = "listen:stop" chat["channel"] = match.group(1) text = text[:match.start()] + text[match.end():] chats.append(chat) lines = text.split("<br>") for line in lines: line = htmlCommentPattern.sub('', line) line = line.strip() if len(line) == 0: continue # Mod Announcements and Mod Warnings leave leading </font> tags at the beginning of the next message # This method will remove them and also skip the line if that is all there is if line[:7] == "</font>": if len(line) == 7: continue else: line = line[7:].strip() # System Announcements leave leading </b></font> tags at the beginning of the next message # This method will remove them and also skip the line if that is all there is if line[:11] == "</b></font>": if len(line) == 11: continue else: line = line[11:].strip() chat = {} parsedChat = False # See if this message was posted to a different channel. match = channelPattern.search(line) if match: chat["channel"] = match.group(1) line = line[len(match.group(0)):] # See if this was a normal chat message. if parsedChat == False: match = chatPattern.search(line) if match: chat["type"] = "normal" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) # Check for special announcements if chat["userId"] == -1 or chat["userName"] == "System Message": chat["type"] = "system message" elif chat["userName"] == "Mod Warning": chat["type"] = "mod warning" elif chat["userName"] == "Mod Announcement": chat["type"] = "mod announcement" chat["text"] = match.group(3).strip() parsedChat = True # See if this was an emote. if parsedChat == False: match = emotePattern.search(line) if match: chat["type"] = "emote" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) chat["text"] = match.group(3).strip() parsedChat = True if isIncoming == True: # See if a user logged in. if parsedChat == False: match = playerLoggedOnPattern.search(line) if match: chat["type"] = "logonNotification" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) parsedChat = True # See if a user logged out. if parsedChat == False: match = playerLoggedOffPattern.search(line) if match: chat["type"] = "logoffNotification" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) parsedChat = True # See if this was a private message. if parsedChat == False: match = privateChatPattern.search(line) if match: chat["type"] = "private" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) chat["text"] = match.group(3).strip() parsedChat = True # See if this is a new kmail notification. if parsedChat == False: match = newKmailPattern.search(line) if match: chat["type"] = "notification:kmail" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) parsedChat = True # See if this is the start of a multi-line message (Gothy or Haiku) if parsedChat == False: match = multiLinePattern.search(line) if match: chat["type"] = "normal" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) chat["isMultiline"] = True chat["text"] = "" parsedChat = True if parsedChat == False: match = newCarnivalPattern.search(line) if match: chat["type"] = "notification:carnival" chat["userName"] = match.group(2) chat["userId"] = int(match.group(1)) parsedChat = True # See if this is the start of a multi-line emote (Gothy or Haiku) # I've seen a Haiku emote, don't know if Gothy will trigger for it if parsedChat == False: match = multiEmotePattern.search(line) if match: chat["type"] = "emote" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) chat["isMultiline"] = True chat["text"] = "" parsedChat = True else: # See if this is a /who response. if parsedChat == False: if chatWhoPattern.search(line): chat["type"] = "who" chat["users"] = [] chatWhoPersonPattern = PatternManager.getOrCompilePattern( "chatWhoPerson") for match in chatWhoPersonPattern.finditer(line): userClass = match.group(1) userId = match.group(2) userName = match.group(3) userInfo = {"userId": userId, "userName": userName} if userClass == "afk": userInfo["isAway"] = True chat["users"].append(userInfo) parsedChat = True if parsedChat and "text" in chat: chat["text"] = cleanChatText(chat["text"]) # Handle unrecognized chat messages. if parsedChat == False: # If the last chat was flagged as starting a multiline if len(chats) > 0 and "isMultiline" in chats[-1]: if chats[-1]["isMultiline"] == True: if len(chats[-1]["text"]) > 0: chats[-1]["text"] += "\n" line = line.replace('<Br>', '\n') cleanLine = cleanChatText(line) cleanLine = cleanLine.replace(' ', '').strip() chats[-1]["text"] += cleanLine continue # If the last chat was flagged as a System or Mod Announcement, skip past the trailing tags elif len(chats) > 0: if "type" in chats[-1] and chats[-1]["type"] in [ "system message", "mod warning", "mod announcement" ]: if line == "</b></font>": continue # Any other case we aren't prepared to handle Report.error("bot", "Unknown message. ResponseText = %s" % text) chat["type"] = "unknown" chat["text"] = StringUtils.htmlEntityDecode(line) chats.append(chat) return chats
def parseChatMessages(text, isIncoming): """ This function parses chats passed to it. The chats are assumed to come from a GetChatMessagesRequest. Returns a list of chats, each of which is a dictionary possibly containing the following keys: "type" : What kind of chat this is. Current possible values are "channel" "listen" "listen:start" "listen:stop" "normal" "emote" "private" "system message" "mod warning" "mod announcement" "notification:kmail" "unknown" "currentChannel" : The current channel as indicated when sending a /c, /s, or /l request "otherChannels" : The other channels being listened to as indicated by a /l request "description" : The description of the current channel as indicated when sending a /c or /s request "channel" : The channel this chat message was posted from "userId" : The user id number of the user sending this chat message "userName" : The user name of the user sending this chat message "text" : The text of the current chat message "isMultiline" : A flag indicating whether this is a multiline message such as a haiku or a message from the Gothy Effect """ # Prepare the patterns. htmlCommentPattern = PatternManager.getOrCompilePattern("htmlComment") htmlTagPattern = PatternManager.getOrCompilePattern("htmlTag") channelPattern = PatternManager.getOrCompilePattern("chatChannel") chatPattern = PatternManager.getOrCompilePattern("chatMessage") emotePattern = PatternManager.getOrCompilePattern("chatEmote") privateChatPattern = PatternManager.getOrCompilePattern("privateChat") newKmailPattern = PatternManager.getOrCompilePattern("chatNewKmailNotification") linkPattern = PatternManager.getOrCompilePattern("chatLink") chatWhoPattern = PatternManager.getOrCompilePattern("chatWhoResponse") linkedPlayerPattern = PatternManager.getOrCompilePattern("chatLinkedPlayer") multiLinePattern = PatternManager.getOrCompilePattern("chatMultiLineStart") multiEmotePattern = PatternManager.getOrCompilePattern("chatMultiLineEmote") playerLoggedOnPattern = PatternManager.getOrCompilePattern("chatPlayerLoggedOn") playerLoggedOffPattern = PatternManager.getOrCompilePattern("chatPlayerLoggedOff") # Get the chat messages. chats = [] # Check for responses to outgoing chat commands. if isIncoming == False: outPrivatePattern = PatternManager.getOrCompilePattern("outgoingPrivate") chatNewChannelPattern = PatternManager.getOrCompilePattern("newChatChannel") chatListenPattern = PatternManager.getOrCompilePattern("chatListenResponse") chatListenStartPattern = PatternManager.getOrCompilePattern("chatStartListen") chatListenStopPattern = PatternManager.getOrCompilePattern("chatStopListen") # See if it is an outgoing private message match = outPrivatePattern.search(text) if match: chat = {} chat["type"] = "private" chat["userName"] = match.group(2) chat["userId"] = int(match.group(1)) chat["text"] = match.group(3).strip() text = text[:match.start()] + text[match.end():] chats.append(chat) # See if the user changed chat channels through /c or /s match = chatNewChannelPattern.search(text) if match: chat = {} chat["type"] = "channel" chat["currentChannel"] = match.group(1) chat["description"] = match.group(2).replace('<br>','') text = text[:match.start()] + text[match.end():] chats.append(chat) # See if it is a /l response match = chatListenPattern.search(text) if match: chat = {} listen = match.group() currentPattern = PatternManager.getOrCompilePattern("chatListenCurrent") otherPattern = PatternManager.getOrCompilePattern("chatListenOthers") chat["type"] = "listen" chat["currentChannel"] = currentPattern.search(listen).group(1) other = [] for channel in otherPattern.finditer(listen): other.append(channel.group(1)) chat["otherChannels"] = other text = text[:match.start()] + text[match.end():] chats.append(chat) # See if it is a /l <channel> response to start listening to a channel match = chatListenStartPattern.search(text) if match: chat = {} chat["type"] = "listen:start" chat["channel"] = match.group(1) text = text[:match.start()] + text[match.end():] chats.append(chat) # See if it is a /l <channel> response to stop listening to a channel match = chatListenStopPattern.search(text) if match: chat = {} chat["type"] = "listen:stop" chat["channel"] = match.group(1) text = text[:match.start()] + text[match.end():] chats.append(chat) lines = text.split("<br>") for line in lines: line = htmlCommentPattern.sub('', line) line = line.strip() if len(line) == 0: continue # Mod Announcements and Mod Warnings leave leading </font> tags at the beginning of the next message # This method will remove them and also skip the line if that is all there is if line[:7] == "</font>": if len(line) == 7: continue else: line = line[7:].strip() # System Announcements leave leading </b></font> tags at the beginning of the next message # This method will remove them and also skip the line if that is all there is if line[:11] == "</b></font>": if len(line) == 11: continue else: line = line[11:].strip() chat = {} parsedChat = False # See if this message was posted to a different channel. match = channelPattern.search(line) if match: chat["channel"] = match.group(1) line = line[len(match.group(0)):] # See if this was a normal chat message. if parsedChat == False: match = chatPattern.search(line) if match: chat["type"] = "normal" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) # Check for special announcements if chat["userId"] == -1 or chat["userName"] == "System Message": chat["type"] = "system message" elif chat["userName"] == "Mod Warning": chat["type"] = "mod warning" elif chat["userName"] == "Mod Announcement": chat["type"] = "mod announcement" chat["text"] = match.group(3).strip() parsedChat = True # See if this was an emote. if parsedChat == False: match = emotePattern.search(line) if match: chat["type"] = "emote" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) chat["text"] = match.group(3).strip() parsedChat = True if isIncoming == True: # See if a user logged in. if parsedChat == False: match = playerLoggedOnPattern.search(line) if match: chat["type"] = "logonNotification" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) parsedChat = True # See if a user logged out. if parsedChat == False: match = playerLoggedOffPattern.search(line) if match: chat["type"] = "logoffNotification" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) parsedChat = True # See if this was a private message. if parsedChat == False: match = privateChatPattern.search(line) if match: chat["type"] = "private" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) chat["text"] = match.group(3).strip() parsedChat = True # See if this is a new kmail notification. if parsedChat == False: match = newKmailPattern.search(line) if match: chat["type"] = "notification:kmail" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) parsedChat = True # See if this is the start of a multi-line message (Gothy or Haiku) if parsedChat == False: match = multiLinePattern.search(line) if match: chat["type"] = "normal" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) chat["isMultiline"] = True chat["text"] = "" parsedChat = True # See if this is the start of a multi-line emote (Gothy or Haiku) # I've seen a Haiku emote, don't know if Gothy will trigger for it if parsedChat == False: match = multiEmotePattern.search(line) if match: chat["type"] = "emote" chat["userId"] = int(match.group(1)) chat["userName"] = match.group(2) chat["isMultiline"] = True chat["text"] = "" parsedChat = True else: # See if this is a /who response. if parsedChat == False: if chatWhoPattern.search(line): chat["type"] = "who" chat["users"] = [] chatWhoPersonPattern = PatternManager.getOrCompilePattern("chatWhoPerson") for match in chatWhoPersonPattern.finditer(line): userClass = match.group(1) userId = match.group(2) userName = match.group(3) userInfo = {"userId" : userId, "userName" : userName} if userClass == "afk": userInfo["isAway"] = True chat["users"].append(userInfo) parsedChat = True if parsedChat and "text" in chat: chat["text"] = cleanChatText(chat["text"]) # Handle unrecognized chat messages. if parsedChat == False: # If the last chat was flagged as starting a multiline if len(chats) > 0 and "isMultiline" in chats[-1]: if chats[-1]["isMultiline"] == True: if len(chats[-1]["text"]) > 0: chats[-1]["text"] += "\n" line = line.replace('<Br>','\n') cleanLine = cleanChatText(line) cleanLine = cleanLine.replace(' ','').strip() chats[-1]["text"] += cleanLine continue # If the last chat was flagged as a System or Mod Announcement, skip past the trailing tags elif len(chats) > 0: if "type" in chats[-1] and chats[-1]["type"] in ["system message", "mod warning", "mod announcement"]: if line == "</b></font>": continue # Any other case we aren't prepared to handle Report.error("bot", "Unknown message. ResponseText = %s" % text) chat["type"] = "unknown" chat["text"] = StringUtils.htmlEntityDecode(line) chats.append(chat) return chats
def botProcessKmail(context, **kwargs): returnCode = FilterManager.CONTINUE message = kwargs['kmail'] bot = kwargs['bot'] user_name = str(message['userName']) user_id = str(message['userId']) current_time = time.time() cmd = BotUtils.getKmailCommand(message) meat = message['meat'] items = message['items'] # Our response response = '' # Should items and meat be sent back? return_goodies = True # Should a candy heart be sent? send_heart = False # if 1 arrow was sent and the kmail is empty, interpret it as "arrow" if cmd == "" and len(items) == 1 and items[0]['id'] == ITEM_ID_ARROW and items[0]['quantity'] == 1 and meat == 0: cmd = 'arrow' if cmd == 'arrow': # Handle arrow request if len(items) == 1 and items[0]['id'] == ITEM_ID_ARROW and items[0]['quantity'] == 1 and meat == 0: # Everything is okay try: Report.info('bot', 'Firing arrow at player: ' + user_name) arrowreq = CursePlayerRequest(bot.session, user_id, ITEM_ID_ARROW) arrowreq.doRequest() return_goodies = False except Error.Error as err: if err.code == Error.ITEM_NOT_FOUND: response = aleabot.config.get('error_arrow_no_arrows') elif err.code == Error.USER_NOT_FOUND: response = aleabot.config.get('error_arrow_player_not_found') elif err.code == Error.USER_IN_HARDCORE_RONIN: response = aleabot.config.get('error_arrow_ronin') elif err.code == Error.ALREADY_COMPLETED: response = aleabot.config.get('error_arrow_already_hit') else: response = aleabot.config.get('error_arrow_generic') elif len(items) == 0 and meat == 0: Report.warning('bot', 'Arrow request without arrow from ' + user_name) response = aleabot.config.get('kmailtext_arrow_notattached') else: Report.warning('bot', 'Arrow request with extra items or meat from ' + user_name) response = aleabot.config.get('kmailtext_arrow_extraattached') elif cmd == 'donate' or cmd == 'donation': # Handle donation if len(items) == 0 and meat == 0: # Empty donation kmail? Report.warning('bot', 'Empty donation received from ' + user_name) response = aleabot.config.get('kmailtext_donate_empty') else: Report.info('bot', 'Donation received from ' + user_name) response = aleabot.config.get('kmailtext_donate_thanks') return_goodies = False send_heart = True else: # Handle unknown command Report.warning('bot', 'Unknown kmail command: ' + cmd) response = aleabot.config.get('kmailtext_unknown') # Send our response if response != '' or (return_goodies and (len(items) != 0 or meat != 0)): Report.info('bot', 'Responding to kmail') response_kmail = {} response_kmail['userId'] = message['userId'] response_kmail['text'] = format_reply(response + '\n\n' + aleabot.config.get('kmailtext_quote'), user_name=user_name, user_id=user_id, current_time=current_time) + '\n' + quote_kmail(message) if return_goodies: response_kmail['items'] = items response_kmail['meat'] = meat try: bot.sendKmail(response_kmail) except Error.Error as err: if err.code == Error.USER_IN_HARDCORE_RONIN: Report.error('bot', 'Tried to send items and meat back, but user is in Hardcore or Ronin!') response_kmail2 = {} response_kmail2['userId'] = message['userId'] response_kmail2['text'] = format_reply(response + '\n\n' + aleabot.config.get('kmailtext_quote_ronin'), user_name=user_name, user_id=user_id, curent_time=current_time) + '\n' + quote_kmail(message) try: bot.sendKmail(response_kmail2) except Error.Error as err2: Report.error('bot', 'Unexpected error while sending response_kmail2: ' + str(err2)) else: Report.error('bot', 'Unexpected error while sending response_kmail: ' + str(err)) # Send a candy heart if send_heart: try: Report.info('bot', 'Sending candy heart to player: ' + user_name) heartreq = CursePlayerRequest(bot.session, user_id, ITEM_ID_CANDYHEART) heartreq.requestData['texta'] = 'THANK' heartreq.requestData['textb'] = 'YOU' heartreq.doRequest() except Error.Error as err: Report.error('bot', 'Couldn\'t send candy heart: ' + str(err)) returnCode = FilterManager.FINISHED return returnCode
def parseResponse(self): entries = [] entryPattern = PatternManager.getOrCompilePattern('clanLogEntry') for entryMatch in entryPattern.finditer(self.responseText): entry = {} date = entryMatch.group('date') entry['date'] = datetime.strptime(date, "%m/%d/%y, %I:%M%p") entry['userId'] = int(entryMatch.group('userId')) entry['userName'] = entryMatch.group('userName') action = entryMatch.group('action') foundAction = False if foundAction == False: pattern = PatternManager.getOrCompilePattern('clanLogFax') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_FAX entry['monster'] = match.group('monsterName') if foundAction == False: pattern = PatternManager.getOrCompilePattern('clanLogAttack') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_ATTACK entry['clanName'] = match.group('clanName') if foundAction == False: pattern = PatternManager.getOrCompilePattern('clanLogWhitelistAdd') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_WHITELISTED_PLAYER entry['targetUserName'] = match.group('userName') entry['targetUserId'] = int(match.group('userId')) if foundAction == False: pattern = PatternManager.getOrCompilePattern('clanLogPlayerJoinedAnotherClan') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_JOINED_ANOTHER_CLAN if foundAction == False: pattern = PatternManager.getOrCompilePattern('clanLogPlayerJoinedClanWhitelist') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_WHITELISTED_IN if foundAction == False: pattern = PatternManager.getOrCompilePattern('clanLogStashItemAdd') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_STASH_ADD entry['itemName'] = match.group('itemName') entry['quantity'] = int(match.group('quantity').replace(',', '')) if foundAction == False: pattern = PatternManager.getOrCompilePattern('clanLogStashItemRemove') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_STASH_REMOVE entry['itemName'] = match.group('itemName') entry['quantity'] = int(match.group('quantity').replace(',', '')) if foundAction == False: pattern = PatternManager.getOrCompilePattern('clanLogMeatSpentArmy') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_MEAT_SPENT_ARMY entry['meat'] = int(match.group('meat').replace(',', '')) if foundAction == False: pattern = PatternManager.getOrCompilePattern('clanLogChangedRank') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_CHANGED_RANK entry['targetUserName'] = match.group('userName') entry['targetUserId'] = int(match.group('userId')) if foundAction == False: pattern = PatternManager.getOrCompilePattern('clanLogChangedTitle') match = pattern.match(action) if match: foundAction = True entry['type'] = CLAN_LOG_CHANGED_RANK entry['targetUserName'] = match.group('userName') entry['targetUserId'] = int(match.group('userId')) entry['clanTitle'] = match.group('clanTitle') if foundAction == False: Report.error("request", "Unknown clan log action: %s" % action) entry['type'] = CLAN_LOG_UNKNOWN entry['action'] = action entries.append(entry) self.responseData["entries"] = entries