From 579f7df5a512e25f0d22021eca79610b6c53b287 Mon Sep 17 00:00:00 2001 From: aewens Date: Wed, 10 Apr 2019 14:12:14 -0400 Subject: [PATCH] Fixed passive action bug --- .gitignore | 1 + actions/__init__.py | 6 +++--- actions/access.py | 8 +++++--- actions/stupid.py | 2 +- app.py | 10 +++++----- bot/core.py | 41 ++++++++++++++++++++++++++++++++--------- bot/responses.py | 36 ++++++++++++++++++++++++------------ 7 files changed, 71 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 2584d24..255b2be 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ settings.json settings.demo.json settings.test.json +*.local data/*.json logs/*.log* logs/*.log.* diff --git a/actions/__init__.py b/actions/__init__.py index 85ca192..73d5a87 100644 --- a/actions/__init__.py +++ b/actions/__init__.py @@ -51,7 +51,7 @@ actions = [ "callback": nomad }, { - "type": "response", + "type": "passive", "pattern": "/^[^!]*hm+/", "callback": score_word("hmm", "hm+") }, @@ -66,9 +66,9 @@ actions = [ "callback": wordscoreboard("hmm") }, { - "type": "response", + "type": "passive", "pattern": "/^[^!]*oo+f/", - "callback": score_word("oof", "o+f") + "callback": score_word("oof", "oo+f") }, { "type": "response", diff --git a/actions/access.py b/actions/access.py index 0de9c1f..57bfcf2 100644 --- a/actions/access.py +++ b/actions/access.py @@ -28,10 +28,12 @@ def pardon(self, name, source, response): if name != author: return - - del self.bot.memories["users"][user]["blacklist"] + + user_memories = self.bot.memories["users"].get(user, dict()) + if user_memories.get("blacklist", None) is not None: + del user_memories["blacklist"] self.bot.thread(self.bot.save_memories) confirmation = "{} has been pardoned".format(user) - self.bot.send_message(source, confirmation) \ No newline at end of file + self.bot.send_message(source, confirmation) diff --git a/actions/stupid.py b/actions/stupid.py index 0bc3484..5c7c08a 100644 --- a/actions/stupid.py +++ b/actions/stupid.py @@ -78,4 +78,4 @@ def wordscoreboard(word): response = "{} Score Leaderboard: {}".format(capitalize(word), leaders) self.bot.send_message(source, response) - return scoreboard \ No newline at end of file + return scoreboard diff --git a/app.py b/app.py index b16c1d5..2cafb90 100755 --- a/app.py +++ b/app.py @@ -17,7 +17,7 @@ parser.add_argument( ) arguments = parser.parse_args() -bot = Bot("127.0.0.1", 6667) +bot = Bot("localhost", 6667) responses = Responses(bot) tasks = Tasks(bot) tasks.coroutines = coroutines @@ -62,8 +62,8 @@ def handle_invite(channel, name): bot.memories["users"][name]["invites"].append(channel) changed = True - if changed: - bot.thread(bot.save_memories) + #if changed: + # bot.thread(bot.save_memories) def handle_kick(name, source): if source in bot.settings.get("extras", dict()).get("rejoin", list()): @@ -73,7 +73,7 @@ def handle_kick(name, source): bot.memories["users"][name] = dict() bot.memories["users"][name]["kicker"] = True - bot.thread(bot.save_memories) + #bot.thread(bot.save_memories) def handle_message(name, source, response): responses.parse(name, source, response) @@ -81,7 +81,7 @@ def handle_message(name, source, response): bot.logger.debug(":: {}".format(bot.memories)) def handle_raw(message): - if "KICK #chaos {}".format(bot.author) in message: + if "KICK #chaos {} :".format(bot.author) in message: bot.send("INVITE {} :#chaos".format(bot.author)) def handle_crashed(): diff --git a/bot/core.py b/bot/core.py index 654b6cc..63ceab4 100644 --- a/bot/core.py +++ b/bot/core.py @@ -60,7 +60,10 @@ class Bot: self.logger.info(response) print("DEBUG: ", response) - self.ircsock.send(response.encode()) + try: + self.ircsock.send(response.encode()) + except BrokenPipeError: + self.stop() def send_action(self, target, message, *args): self.send_message(target, "\001ACTION {}\001".format(message), *args) @@ -72,14 +75,18 @@ class Bot: message = "" magic_string = "End of /NAMES list." banned = "Cannot join channel (You're banned)" + start = time.time() while magic_string not in message: + # Taking too long, escaping JOIN request + if time.time() - start == 2000: + return try: message = self.ircsock.recv(self.recv_size).decode() if banned in message: self.places.remove(chan) return # message = message.strip(self.splitter) - self.logger.debug(message) + #self.logger.debug(message) except UnicodeDecodeError: continue @@ -113,7 +120,7 @@ class Bot: return text.split("!", 1)[0][1:] def parse_name(self, name): - if name[0] == "~" or name[0] == "@" or name[0] == "+": + if name[0] in ["~", "@", "+", "%"]: return name[1:] else: return name @@ -138,8 +145,8 @@ class Bot: name = self.parse_name(name) user = self.memories["users"][name] - del self.memories["users"][name] self.memories["users"][new_name] = user + del self.memories["users"][name] return user, new_name def handle_invite(self, message): @@ -240,19 +247,23 @@ class Bot: magic_phrase = { "has_registered": "Password", "needs_to_register": "choose a different nick", - "needs_to_confirm": "Your account will expire" + "needs_to_confirm": "Your account will expire", + "not_registered": "Your nickname is not registered" + #"ready_to_id": "is now your displayed host", + #"nickserv_missing": "No such nick/channel" } - + authenticate = len(password) > 0 and len(confirm) > 0 magic_string = "MODE {} +r".format(self.botnick) while magic_string not in message and authenticate: try: message = self.ircsock.recv(self.recv_size).decode() + print(message) except UnicodeDecodeError: continue message = message.strip(self.splitter) - self.logger.debug(message) + #self.logger.debug(message) if not registered and magic_phrase["has_registered"] in message: registered = True if not registered and magic_phrase["needs_to_register"] in message: @@ -260,6 +271,12 @@ class Bot: if not confirmed and magic_phrase["needs_to_confirm"] in message: self.send_message("NickServ", "CONFIRM {}", self.confirm) confirmed = True + if not registered and magic_phrase["not_registered"] in message: + break + #if not registered and magic_phrase["ready_to_id"] in message: + # self.send_message("NickServ", "IDENTIFY {}", password) + #if not registered and magic_phrase["nickserv_missing"] in message: + # break if not authenticate: time.sleep(3) @@ -291,40 +308,45 @@ class Bot: messages = [msg for msg in _message.split(self.splitter) if msg] for message in messages: - self.logger.debug("{}".format(message)) - if message[:4] == "PING": self.ping(message) if "ping" in callback: callback["ping"]() elif "PRIVMSG " in message: name, source, response = self.parse(message) + self.logger.debug(message) if source == self.botnick and "pm" in callback: callback["pm"](name, response) elif "message" in callback: callback["message"](name, source, response) elif "MODE " in message: channel, mode = self.handle_mode(message) + self.logger.debug(message) if "mode" in callback: callback["mode"](channel, mode) elif "NICK " in message: old_name, new_name = self.handle_rename(message) + self.logger.debug(message) if "nick" in callback: callback["nick"](old_name, new_name) elif "KICK " in message: kicker, source = self.handle_kick(message) + self.logger.debug(message) if "kick" in callback: callback["kick"](kicker, source) elif "JOIN " in message: user = self.handle_join(message) + self.logger.debug(message) if "join" in callback: callback["join"](user) elif "PART " in message: user = self.handle_part(message) + self.logger.debug(message) if "part" in callback: callback["part"](user) elif "INVITE " in message: channel, name = self.handle_invite(message) + self.logger.debug(message) if "invite" in callback: callback["invite"](channel, name) elif "unhandled" in callback: @@ -332,6 +354,7 @@ class Bot: callback["unhandled"](message) elif ":Closing link:" in message: self.logger.warning(message) + self.logger.error("Activing crash mode") if "crashed" in callback: callback["crashed"]() break diff --git a/bot/responses.py b/bot/responses.py index b014ae9..d2be45b 100644 --- a/bot/responses.py +++ b/bot/responses.py @@ -7,7 +7,8 @@ class Responses: self.triggers = { "name": dict(), "source": dict(), - "response": dict() + "response": dict(), + "passive": dict() } def add_trigger(self, trigger_type, pattern, callback): @@ -40,6 +41,12 @@ class Responses: return True + def log(self, name, trigger): + if trigger != "response": + return + now = datetime.now().timestamp() + self.bot.memories["users"][name]["last_response"] = now + def parse(self, name, source, response): users = self.bot.memories["users"] if name not in users: @@ -49,7 +56,8 @@ class Responses: trig = { "name": name, "source": source, - "response": response.lower().strip() + "response": response.lower().strip(), + "passive": response.lower().strip() } for trigger in list(self.triggers.keys()): @@ -57,6 +65,19 @@ class Responses: if pattern[0] != "/" and pattern[-1] != "/": if pattern == check: if self.allowed(name, source): + self.log(name, trigger) + callback(self, name, source, response) + elif "blacklist" in users[name]: + reason = users[name]["blacklist"]["reason"] + message = "You were banished for reason '{}'" + message = message.format(reason) + #self.bot.send_message(name, message) + return False + elif trigger != "passive": + regex = re.compile(pattern[1:-1]) + if regex.match(trig[trigger]) is not None: + if self.allowed(name, source): + self.log(name, trigger) callback(self, name, source, response) elif "blacklist" in users[name]: reason = users[name]["blacklist"]["reason"] @@ -67,14 +88,5 @@ class Responses: else: regex = re.compile(pattern[1:-1]) if regex.match(trig[trigger]) is not None: - if self.allowed(name, source): - callback(self, name, source, response) - elif "blacklist" in users[name]: - reason = users[name]["blacklist"]["reason"] - message = "You were banished for reason '{}'" - message = message.format(reason) - #self.bot.send_message(name, message) - return False + callback(self, name, source, response) - now = datetime.now().timestamp() - self.bot.memories["users"][name]["last_response"] = now