diff --git a/bot.py b/bot.py index adab7bf..5f3f88f 100755 --- a/bot.py +++ b/bot.py @@ -106,6 +106,9 @@ class Fulvia(irc.IRCClient): the URL module. """ + self._user_joined = [] + """These get called when a user joins a channel.""" + self._disabled_modules = self.config.core.disabled_modules.split(",") """These modules will NOT be loaded when load_modules() is called.""" @@ -171,6 +174,9 @@ class Fulvia(irc.IRCClient): for url in func.url_callback: self.url_callbacks[url] = func + if func.user_joined: + self._user_joined.append(func) + def unregister_callable(self, func): """ @@ -196,6 +202,9 @@ class Fulvia(irc.IRCClient): for url in func.url_callback: self.url_callbacks.pop(url) + if func.user_joined: + self._user_joined.remove(func) + def stillConnected(self): """Returns true if the bot is still connected to the server.""" @@ -364,6 +373,8 @@ class Fulvia(irc.IRCClient): def signedOn(self): """Called when the bot successfully connects to the server.""" + if self.config.core.oper_password: + self.sendLine("OPER " + self.config.core.nickname + ' ' + self.config.core.oper_password) print(f"Signed on as {self.nickname}") self.whois(self.nickname) @@ -412,6 +423,12 @@ class Fulvia(irc.IRCClient): self.users[nick] = tools.User(nick) self.channels[channel].add_user(self.users[nick]) + for func in self._user_joined: + trigger = Trigger(user, channel, f"{user} has joined", "PRIVMSG", self.config) + bot = FulviaWrapper(self, trigger) + t = threading.Thread(target=self.call,args=(func, bot, trigger)) + t.start() + def userLeft(self, user, channel, reason=""): """Called when the bot sees another user leave a channel.""" diff --git a/loader.py b/loader.py index c57f52c..80ca9b9 100755 --- a/loader.py +++ b/loader.py @@ -67,7 +67,7 @@ def is_triggerable(obj): Checks if the given function object is triggerable by Fulvia, eg. has any of a few particular attributes or declarators defined. """ - triggerable_attributes = ("commands", "hook", "url_callback") + triggerable_attributes = ("commands", "hook", "url_callback", "user_joined") return any(hasattr(obj, attr) for attr in triggerable_attributes) @@ -92,6 +92,7 @@ def process_callable(func, config): func.channel_rate = getattr(func, "channel_rate", 0) func.global_rate = getattr(func, "global_rate", 0) func.priv = getattr(func, "priv", 0) + func.user_joined = getattr(func, "user_joined", False) if hasattr(func, 'commands'): if len(func.commands) > 1: diff --git a/module.py b/module.py index fa2bbbc..94246a5 100755 --- a/module.py +++ b/module.py @@ -249,4 +249,19 @@ def url_callback(url): function.url_callback.append(url) return function return add_attribute - \ No newline at end of file + + +def user_joined(value=False): + """ + Decorate a function to be called every time the bot sees a user join. + + Args: + value: Either True or False. If True the function is called every + time a PRIVMSG is received. If False it is not. Default is False. + + Note: Do not use this with the commands decorator. + """ + def add_attribute(function): + function.user_joined = value + return function + return add_attribute diff --git a/modules/adalwulf__.py b/modules/adalwulf__.py new file mode 100644 index 0000000..5311a08 --- /dev/null +++ b/modules/adalwulf__.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +""" +Renames defaultnick's to Adalwulf__. +""" +from module import user_joined, commands, require_owner + +MAX_NICKLEN = 100 +NICK_ZERO = 'Adalwulf_' + +def new_bot_name(number): + """ + Accepts the number of the new bot. Returns the nickname. + """ + max_underscore = MAX_NICKLEN - len(NICK_ZERO) + pluses = 0 + while number > max_underscore * 2: + pluses += 1 + number -= max_underscore * 2 + 1 + max_underscore -= 1 + equals = max(number - max_underscore, 0) + under = min(number, max_underscore) - equals + nick = NICK_ZERO + '+' * pluses + '|' * equals + '_' * under + return nick + + +@user_joined(True) +def adalwulf_(bot, trigger): + """Renames adalwulf__.""" + print(True) + print(trigger.nick) + if not trigger.nick.startswith('defaultnick'): + return + names = bot.channels[trigger.channel].users + adals = [nick for nick in names if nick.startswith('Adalwulf__')] + adals += [nick for nick in names if nick.startswith('Adalwulf_|')] + old_nick = trigger.nick + new_nick = new_bot_name(len(adals) + 1) + bot.sendLine(f"SANICK {old_nick} {new_nick}") + + +@require_owner +@commands('rename_hydra') +def rename_hydra(bot, trigger): + """Renames defaultnick's appropriately.""" + for nick in list(bot.channels[trigger.channel].users.keys()): + if not nick.startswith('defaultnick'): + continue + names = bot.channels[trigger.channel].users + adals = [nick for nick in names if nick.startswith('Adalwulf__')] + adals += [nick for nick in names if nick.startswith('Adalwulf_|')] + old_nick = nick + new_nick = new_bot_name(len(adals) + 1) + print(f"SANICK {old_nick} {new_nick}") + bot.sendLine(f"SANICK {old_nick} {new_nick}")