def handle_quit(event, message): client = Client.findByNick(message.source) if (client is None): return log.info("Client exiting at %s: %s!%s@%s[%s]: %s", client.server, client.nick, client.username, client.ip, client.hostname, " ".join(message.parameters)) Client.removeClient(client)
def handle_nickchg(event, message): if(message.source is None or message.source==""): #new nick usermodes=virtualhost=cloakedhost=nickipaddr=None nick,hopcount,timestamp,username,hostname,server,servicestamp=message.parameters[0:7] if(ffservices.protoctl["NICKv2"]): usermodes,virtualhost=message.parameters[7:9] if(ffservices.protoctl["CLK"]): cloakedhost=message.parameters[9] if(ffservices.protoctl["NICKIP"]): nickipaddr=message.parameters[10] else: if(ffservices.protoctl["NICKIP"]): nickipaddr=message.parameters[9] realname=message.parameters[-1] c=Client(nick, hopcount, timestamp, username, hostname, server, servicestamp, usermodes, virtualhost, cloakedhost, nickipaddr, realname) log.info("Client connecting at %s: %s (%s@%s[%s])", c.server, c.nick, c.username, c.ip, c.hostname) if(not Client.addClient(c)): #if we can't add the client, that means that nick already exists. If the #nick already exists, it is a services pseudoclient -- so we kill the #non-services client c.kill("Nick Collision") else: #nick change who=message.source newnick, timestamp=message.parameters client=Client.findByNick(who) if(client is None): return if(client.changeNick(newnick, timestamp)): return #nick collision client.kill("Nick Collision")
def handle_modechg(event, message): target_is_channel=False source=message.source target=modelist=None params=[] if(event.eventName.split("/")[-1]=="UMODE2"): target=source modelist=message.parameters[0] else: target=message.parameters[0] modelist=message.parameters[1] if(target[0] in ("#", "&", "+")): target_is_channel=True params=message.parameters[2:] if(target_is_channel): if(not Server.findByName(source) is None and params[-1].isdigit()): timestamp=long(params[-1]) else: timestamp=time.time() channel=Channel.findByName(target) if(channel is None): return if(channel.timestamp==timestamp): channel.setModes(modelist, params, True) elif(channel.timestamp>timestamp): channel.clearModes() channel.setModes(modelist, params) else: client=Client.findByNick(target) if(client is None): return client.changeModes(modelist) log.debug("%s changed modes of %s to %s", source, client.nick, client.usermodes)
def run(plugin_list: bool, plugins: str): """ Version 3.0 work in progress """ config = Config() if plugin_list: pluginManager = PluginManager() pluginManager.print_plugins_list() exit(0) if plugins is not None: plugins = PluginManager(plugins) print("Loaded : {0} plugins".format(plugins.plugin_loaded())) # todo load data dataDriver file.json or mongo # check if app running in docker environment and run server or client code if config.docker_mode: if os.environ.get("IS_SERVER"): # run server mode server = Server() else: # run client mode client = Client() exit(0) print("No arg detected :/") print("Please run 'python3 Toudoum.py run --help'")
def handle_modechg(event, message): target_is_channel = False source = message.source target = modelist = None params = [] if (event.eventName.split("/")[-1] == "UMODE2"): target = source modelist = message.parameters[0] else: target = message.parameters[0] modelist = message.parameters[1] if (target[0] in ("#", "&", "+")): target_is_channel = True params = message.parameters[2:] if (target_is_channel): if (not Server.findByName(source) is None and params[-1].isdigit()): timestamp = long(params[-1]) else: timestamp = time.time() channel = Channel.findByName(target) if (channel is None): return if (channel.timestamp == timestamp): channel.setModes(modelist, params, True) elif (channel.timestamp > timestamp): channel.clearModes() channel.setModes(modelist, params) else: client = Client.findByNick(target) if (client is None): return client.changeModes(modelist) log.debug("%s changed modes of %s to %s", source, client.nick, client.usermodes)
def do_log_channel_msgs(event, message): global db_cursor, statserv, my_channels #this will end up being called on every incoming message (or at least quite a few of them) so we kind of have to do some extra sanity checks if(len(message.parameters)<1): return #definitely not something we're interested in #we have to know what channels to log - we'll join anything that we're invited to if(message.command=="INVITE"): if(message.parameters[0].lower()==statserv.nick.lower()): Network.sendMsg(IRCMessage(":", statserv.nick, "JOIN", message.parameters[1])) my_channels[message.parameters[1].lower()]=True #using a dict here because key lookup in a dict is probably faster than using in return #ignore invite messages, even if they're not for us #messages targeted at a channel should always have a "#" character as the first character of their first parameter (the message's target) if(not message.parameters[0][0]=="#"): return #finally, if we're not supposed to be in a particular channel, we don't log messages for it if(not my_channels.has_key(message.parameters[0].lower())): return client=Client.findByNick(message.source) #this will not work if the service stamp contains something other than nickserv's group id for that nick cl_groupid=client.servicestamp if (client is not None and client.hasMode("r")) else None try: db_cursor.execute("insert into `ff_statserv_channels`(`time`, `channel`, `nick`, `nickserv_groupid`, `message_type`, `message`) values (%s, %s, %s, %s, %s, %s)", ( time.time(), message.parameters[0], message.source, cl_groupid, message.command, " ".join(message.parameters[1:]) #hopefully this won't f**k up )) except Exception as e: log.warning("Can't update channel stats: %s", str(e))
def handle_kill(event, message): #when a services client is killed they will have to be reintroduced to the network #because unreal will see the KILL message and treat it as though the client is #killed, even if we don't want that Network.sendToUmode(None, "o", "Attempt by %s to kill %s - killing services pseudoclients is not permitted."%(message.source, message.parameters[0])) serv_client=Client.findByNick(message.parameters[0]) if(serv_client is None): return serv_client.introduce()
def handle_join(event, message): client=Client.findByNick(message.source) if(client is None): return chan=Channel.findByName(message.parameters[0]) if(chan is None): chan=Channel(message.parameters[0], time.time()) Channel.addChannel(chan) chan.addClient(client) log.debug("%s has joined %s", client.nick, chan.name)
def handle_join(event, message): client = Client.findByNick(message.source) if (client is None): return chan = Channel.findByName(message.parameters[0]) if (chan is None): chan = Channel(message.parameters[0], time.time()) Channel.addChannel(chan) chan.addClient(client) log.debug("%s has joined %s", client.nick, chan.name)
def handle_kill(event, message): #when a services client is killed they will have to be reintroduced to the network #because unreal will see the KILL message and treat it as though the client is #killed, even if we don't want that Network.sendToUmode( None, "o", "Attempt by %s to kill %s - killing services pseudoclients is not permitted." % (message.source, message.parameters[0])) serv_client = Client.findByNick(message.parameters[0]) if (serv_client is None): return serv_client.introduce()
def handle_leave(event, message): source = Client.findByNick(message.source) if (source is None): source = Server.findByName(message.source) if (source is None): return targetchan = Channel.findByName(message.parameters[0]) if (targetchan is None): return if (message.command == "PART"): targetuser = source reason = message.parameters[-1] if len( message.parameters) > 1 else "[none]" elif (message.command == "KICK"): targetuser = Client.findByNick(message.parameters[1]) if (targetuser is None): return reason = message.parameters[-1] log.debug( "%s has left %s: %s: %s", targetuser.nick, targetchan.name, "kicked by " + (source.nick if source.__class__.__name__ == "Client" else source.name) if message.command == "KICK" else "PART", reason) targetchan.removeClient(targetuser)
def handle_leave(event, message): source=Client.findByNick(message.source) if(source is None): source=Server.findByName(message.source) if(source is None): return targetchan=Channel.findByName(message.parameters[0]) if(targetchan is None): return if(message.command=="PART"): targetuser=source reason=message.parameters[-1] if len(message.parameters)>1 else "[none]" elif(message.command=="KICK"): targetuser=Client.findByNick(message.parameters[1]) if(targetuser is None): return reason=message.parameters[-1] log.debug("%s has left %s: %s: %s", targetuser.nick, targetchan.name, "kicked by "+(source.nick if source.__class__.__name__=="Client" else source.name) if message.command=="KICK" else "PART", reason ) targetchan.removeClient(targetuser)
def handle_cmd_group(source_s, command, c_text): global db_cursor, nickserv params = c_text.split() if (nick_is_registered(source_s)): nickserv.sendmsg(source_s, "Nick \x02%s\x02 is already registered.", source_s) elif (len(params) == 1): nickserv.sendMsg( source_s, "You must either supply both a registered nickname and a password, or nothing (if you are already identified)." ) elif (len(params) > 1): if (not nick_is_registered(params[0])): nickserv.sendMsg(source_s, "Nick \x02%s\x02 is not registered.", params[0]) return try: db_cursor.execute( "select `id`,`password`,`group` from `ff_nickserv_core` where `nick` like %s limit 1", (params[0])) u_id, password, group = db_cursor.fetchone() except Exception as e: log.error("%s", str(e)) nickserv.sendMsg(source_s, "Your nick cannot be grouped at this time.") return groupid = group if group is not None else u_id if (not authenticate(params[0], params[1], password)): nickserv.sendMsg(source_s, "Incorrect password.") return else: client = Client.findByNick(source_s) #TODO: check if client is none if (not client.hasMode("r")): nickserv.sendMsg(source_s, "You are not identified.") return groupid = client.servicestamp try: db_cursor.execute( """insert into `ff_nickserv_core` (`nick`,`password`,`email`,`time_registered`,`time_last_seen`,`email_confirmed`,`activated`,`disabled`,`group`,`confirmation_code`) select %s as `nick`,`password`,`email`,UNIX_TIMESTAMP() as `time_registered`, UNIX_TIMESTAMP() as `time_last_seen`, `email_confirmed`, `activated`, `disabled`, `id` as `group`, `confirmation_code` from `ff_nickserv_core` where `id`=%s limit 1""", (source_s, groupid)) db_cursor.execute( "select `nick` from `ff_nickserv_core` where `id`=%s limit 1", (groupid)) nickserv.sendMsg(source_s, "You are now in the group of \x02%s\x02.", db_cursor.fetchone()[0]) except Exception as e: nickserv.sendMsg(source_s, "Your nick cannot be grouped at this time.") log.error("Can't group %s in group #%d: %s", source_s, groupid, str(e))
def handle_nickchg(event, message): if (message.source is None or message.source == ""): #new nick usermodes = virtualhost = cloakedhost = nickipaddr = None nick, hopcount, timestamp, username, hostname, server, servicestamp = message.parameters[ 0:7] if (ffservices.protoctl["NICKv2"]): usermodes, virtualhost = message.parameters[7:9] if (ffservices.protoctl["CLK"]): cloakedhost = message.parameters[9] if (ffservices.protoctl["NICKIP"]): nickipaddr = message.parameters[10] else: if (ffservices.protoctl["NICKIP"]): nickipaddr = message.parameters[9] realname = message.parameters[-1] c = Client(nick, hopcount, timestamp, username, hostname, server, servicestamp, usermodes, virtualhost, cloakedhost, nickipaddr, realname) log.info("Client connecting at %s: %s (%s@%s[%s])", c.server, c.nick, c.username, c.ip, c.hostname) if (not Client.addClient(c)): #if we can't add the client, that means that nick already exists. If the #nick already exists, it is a services pseudoclient -- so we kill the #non-services client c.kill("Nick Collision") else: #nick change who = message.source newnick, timestamp = message.parameters client = Client.findByNick(who) if (client is None): return if (client.changeNick(newnick, timestamp)): return #nick collision client.kill("Nick Collision")
def handle_cmd_unidentify(source_s, command, c_text): global db_cursor, nickserv client=Client.findByNick(source_s) if(client is None): nickserv.sendMsg(source_s, "You do not seem to exist. This is a bug, please report it.") return if(not client.hasMode("r")): nickserv.sendMsg(source_s, "You are not identified.") else: client.changeModes("-r") Network.sendMsg(IRCMessage(":", nickserv.nick, "SVS2MODE", source_s, "-r")) nickserv.sendMsg(source_s, "You are no longer identified.")
def handle_cmd_glist(source_s, command, c_text): global db_cursor, nickserv client=Client.findByNick(source_s) if(not client.hasMode("r")): nickserv.sendMsg(source_s, "You are not registered.") return try: db_cursor.execute("select `nick`, `time_registered`, `time_last_seen` from `ff_nickserv_core` where `id`=%s or `group`=%s order by `id` asc", (client.servicestamp, client.servicestamp)) nickserv.sendMsg(source_s, "Nicknames in the group of \x02%s\x02:", source_s) for g_data in db_cursor.fetchall(): nickserv.sendMsg(source_s, "\x02%s\x02 (Registered %s ago, last seen %s ago)", g_data[0], ffservices.formatTimeDiff(g_data[1], time.time(), False), ffservices.formatTimeDiff(g_data[2], time.time(), False)) except Exception as e: log.error("%s", str(e))
def handle_user_info_chg(event, message): ev=event.eventName.split("/")[-1] action=ev[:3] prop=ev[3:] target=message.source if action=="SET" else message.parameters[0] client=Client.findByNick(target) if(client is None): return newvalue=message.parameters[0 if action=="SET" else 1] if(prop=="HOST"): client.changeModes("+xt") client.virtualhost=newvalue elif(prop=="IDENT"): client.username=newvalue elif(prop=="NAME"): client.realname=newvalue
def handle_user_info_chg(event, message): ev = event.eventName.split("/")[-1] action = ev[:3] prop = ev[3:] target = message.source if action == "SET" else message.parameters[0] client = Client.findByNick(target) if (client is None): return newvalue = message.parameters[0 if action == "SET" else 1] if (prop == "HOST"): client.changeModes("+xt") client.virtualhost = newvalue elif (prop == "IDENT"): client.username = newvalue elif (prop == "NAME"): client.realname = newvalue
def handle_cmd_unidentify(source_s, command, c_text): global db_cursor, nickserv client = Client.findByNick(source_s) if (client is None): nickserv.sendMsg( source_s, "You do not seem to exist. This is a bug, please report it.") return if (not client.hasMode("r")): nickserv.sendMsg(source_s, "You are not identified.") else: client.changeModes("-r") Network.sendMsg( IRCMessage(":", nickserv.nick, "SVS2MODE", source_s, "-r")) nickserv.sendMsg(source_s, "You are no longer identified.")
def handle_cmd_identify(source_s, command, c_text): global db_cursor, nickserv client=Client.findByNick(source_s) if(client is None): nickserv.sendMsg(source_s, "You do not seem to exist. This is a bug, please report it.") return if(client.hasMode("r")): nickserv.sendMsg(source_s, "You have already identified.") return try: db_cursor.execute("select * from `ff_nickserv_core` where `nick` like %s limit 1", (source_s)) if(db_cursor.rowcount==0): nickserv.sendMsg(source_s, "Nick \x02%s\x02 is not registered.", source_s) return u_id, nick, password, email, time_registered, time_last_seen, email_confirmed, activated, disabled, group, confirmation_code=db_cursor.fetchone() if(len(c_text)==0): nickserv.sendMsg(source_s, "You must supply a password.") return #elif(password==hash_password(source_s, c_text)): elif(authenticate(source_s, c_text, password)): if(not email_confirmed): nickserv.sendMsg(source_s, "You have not confirmed your email address.") return elif(not activated): nickserv.sendMsg(source_s, "Your account has not yet been activated.") return elif(disabled): nickserv.sendMsg(source_s, "Your account has been disabled.") return client.changeModes("+r") groupid=group if group is not None else u_id Network.sendMsg(IRCMessage(":", nickserv.nick, "SVS2MODE", source_s, "+rd", groupid)) client.servicestamp=groupid #using mode +d with svsmode or svs2mode changes the services stamp #in this case we set it to the user's group ID db_cursor.execute("update `ff_nickserv_core` set `time_last_seen`=%s where id=%s limit 1", (time.time(), u_id)) nickserv.sendMsg(source_s, "You are now identified for nick \x02%s\x02.", nick) else: nickserv.sendMsg(source_s, "Invalid password.") return except Exception as e: log.error("Can't identify user %s: %s", source_s, str(e)) nickserv.sendMsg(source_s, "A problem was encountered -- this is likely a bug, please report it.")
def handle_sjoin(event, message): chan_name = message.parameters[1] timestamp = message.parameters[0] chan = Channel.findByName(chan_name) if (chan is None): chan = Channel(chan_name, timestamp) Channel.addChannel(chan) p_idx = 2 if (message.parameters[p_idx][0] == "+"): #we have modes if (chan.timestamp == timestamp): #merge modes chan.setModes(message.parameters[p_idx], message.parameters[p_idx + 1:-1], True) elif (chan.timestamp > timestamp): #clear existing modes and use sjoin modes chan.clearModes() chan.setModes(message.parameters[p_idx], message.parameters[p_idx + 1:-1]) #else ignore sjoin modes new_modes = [] new_params = [] for item in message.parameters[-1].split(): #this could be a channel member, ban, exemption, or invex -- very confusing! # *~@%+ are user statuses qaohv, respectively # & is a ban, " is an exemption, ' is an invex item_type = item[0] if (sjoin_prefix_to_mode.has_key(item_type)): item = item[1:] new_modes.append(sjoin_prefix_to_mode[item_type]) new_params.append(item) if (not sjoin_prefix_to_mode.has_key(item_type) or item_type in ("*", "~", "@", "%", "+")): member = Client.findByNick(item) if (not member is None): log.debug("SJOIN: %s to %s", member.nick, chan.name) chan.addClient(member) if (len(new_modes) > 0): chan.setModes("+" + "".join(new_modes), new_params)
def handle_cmd_group(source_s, command, c_text): global db_cursor, nickserv params=c_text.split() if(nick_is_registered(source_s)): nickserv.sendmsg(source_s, "Nick \x02%s\x02 is already registered.", source_s) elif(len(params)==1): nickserv.sendMsg(source_s, "You must either supply both a registered nickname and a password, or nothing (if you are already identified).") elif(len(params)>1): if(not nick_is_registered(params[0])): nickserv.sendMsg(source_s, "Nick \x02%s\x02 is not registered.", params[0]) return try: db_cursor.execute("select `id`,`password`,`group` from `ff_nickserv_core` where `nick` like %s limit 1", (params[0])) u_id, password, group=db_cursor.fetchone() except Exception as e: log.error("%s", str(e)) nickserv.sendMsg(source_s, "Your nick cannot be grouped at this time.") return groupid=group if group is not None else u_id if(not authenticate(params[0], params[1], password)): nickserv.sendMsg(source_s, "Incorrect password.") return else: client=Client.findByNick(source_s) #TODO: check if client is none if(not client.hasMode("r")): nickserv.sendMsg(source_s, "You are not identified.") return groupid=client.servicestamp try: db_cursor.execute("""insert into `ff_nickserv_core` (`nick`,`password`,`email`,`time_registered`,`time_last_seen`,`email_confirmed`,`activated`,`disabled`,`group`,`confirmation_code`) select %s as `nick`,`password`,`email`,UNIX_TIMESTAMP() as `time_registered`, UNIX_TIMESTAMP() as `time_last_seen`, `email_confirmed`, `activated`, `disabled`, `id` as `group`, `confirmation_code` from `ff_nickserv_core` where `id`=%s limit 1""", (source_s, groupid)) db_cursor.execute("select `nick` from `ff_nickserv_core` where `id`=%s limit 1", (groupid)) nickserv.sendMsg(source_s, "You are now in the group of \x02%s\x02.", db_cursor.fetchone()[0]) except Exception as e: nickserv.sendMsg(source_s, "Your nick cannot be grouped at this time.") log.error("Can't group %s in group #%d: %s", source_s, groupid, str(e))
def handle_cmd_glist(source_s, command, c_text): global db_cursor, nickserv client = Client.findByNick(source_s) if (not client.hasMode("r")): nickserv.sendMsg(source_s, "You are not registered.") return try: db_cursor.execute( "select `nick`, `time_registered`, `time_last_seen` from `ff_nickserv_core` where `id`=%s or `group`=%s order by `id` asc", (client.servicestamp, client.servicestamp)) nickserv.sendMsg(source_s, "Nicknames in the group of \x02%s\x02:", source_s) for g_data in db_cursor.fetchall(): nickserv.sendMsg( source_s, "\x02%s\x02 (Registered %s ago, last seen %s ago)", g_data[0], ffservices.formatTimeDiff(g_data[1], time.time(), False), ffservices.formatTimeDiff(g_data[2], time.time(), False)) except Exception as e: log.error("%s", str(e))
def handle_sjoin(event, message): chan_name=message.parameters[1] timestamp=message.parameters[0] chan=Channel.findByName(chan_name) if(chan is None): chan=Channel(chan_name, timestamp) Channel.addChannel(chan) p_idx=2 if(message.parameters[p_idx][0]=="+"): #we have modes if(chan.timestamp==timestamp): #merge modes chan.setModes(message.parameters[p_idx], message.parameters[p_idx+1:-1], True) elif(chan.timestamp>timestamp): #clear existing modes and use sjoin modes chan.clearModes() chan.setModes(message.parameters[p_idx], message.parameters[p_idx+1:-1]) #else ignore sjoin modes new_modes=[] new_params=[] for item in message.parameters[-1].split(): #this could be a channel member, ban, exemption, or invex -- very confusing! # *~@%+ are user statuses qaohv, respectively # & is a ban, " is an exemption, ' is an invex item_type=item[0] if(sjoin_prefix_to_mode.has_key(item_type)): item=item[1:] new_modes.append(sjoin_prefix_to_mode[item_type]) new_params.append(item) if(not sjoin_prefix_to_mode.has_key(item_type) or item_type in ("*", "~", "@", "%", "+")): member=Client.findByNick(item) if(not member is None): log.debug("SJOIN: %s to %s", member.nick, chan.name) chan.addClient(member) if(len(new_modes)>0): chan.setModes("+"+"".join(new_modes), new_params)
def do_log_channel_msgs(event, message): global db_cursor, statserv, my_channels #this will end up being called on every incoming message (or at least quite a few of them) so we kind of have to do some extra sanity checks if (len(message.parameters) < 1): return #definitely not something we're interested in #we have to know what channels to log - we'll join anything that we're invited to if (message.command == "INVITE"): if (message.parameters[0].lower() == statserv.nick.lower()): Network.sendMsg( IRCMessage(":", statserv.nick, "JOIN", message.parameters[1])) my_channels[message.parameters[1].lower( )] = True #using a dict here because key lookup in a dict is probably faster than using in return #ignore invite messages, even if they're not for us #messages targeted at a channel should always have a "#" character as the first character of their first parameter (the message's target) if (not message.parameters[0][0] == "#"): return #finally, if we're not supposed to be in a particular channel, we don't log messages for it if (not my_channels.has_key(message.parameters[0].lower())): return client = Client.findByNick(message.source) #this will not work if the service stamp contains something other than nickserv's group id for that nick cl_groupid = client.servicestamp if (client is not None and client.hasMode("r")) else None try: db_cursor.execute( "insert into `ff_statserv_channels`(`time`, `channel`, `nick`, `nickserv_groupid`, `message_type`, `message`) values (%s, %s, %s, %s, %s, %s)", ( time.time(), message.parameters[0], message.source, cl_groupid, message.command, " ".join(message.parameters[1:]) #hopefully this won't f**k up )) except Exception as e: log.warning("Can't update channel stats: %s", str(e))
def client(): return Client()
def handle_cmd_identify(source_s, command, c_text): global db_cursor, nickserv client = Client.findByNick(source_s) if (client is None): nickserv.sendMsg( source_s, "You do not seem to exist. This is a bug, please report it.") return if (client.hasMode("r")): nickserv.sendMsg(source_s, "You have already identified.") return try: db_cursor.execute( "select * from `ff_nickserv_core` where `nick` like %s limit 1", (source_s)) if (db_cursor.rowcount == 0): nickserv.sendMsg(source_s, "Nick \x02%s\x02 is not registered.", source_s) return u_id, nick, password, email, time_registered, time_last_seen, email_confirmed, activated, disabled, group, confirmation_code = db_cursor.fetchone( ) if (len(c_text) == 0): nickserv.sendMsg(source_s, "You must supply a password.") return #elif(password==hash_password(source_s, c_text)): elif (authenticate(source_s, c_text, password)): if (not email_confirmed): nickserv.sendMsg(source_s, "You have not confirmed your email address.") return elif (not activated): nickserv.sendMsg(source_s, "Your account has not yet been activated.") return elif (disabled): nickserv.sendMsg(source_s, "Your account has been disabled.") return client.changeModes("+r") groupid = group if group is not None else u_id Network.sendMsg( IRCMessage(":", nickserv.nick, "SVS2MODE", source_s, "+rd", groupid)) client.servicestamp = groupid #using mode +d with svsmode or svs2mode changes the services stamp #in this case we set it to the user's group ID db_cursor.execute( "update `ff_nickserv_core` set `time_last_seen`=%s where id=%s limit 1", (time.time(), u_id)) nickserv.sendMsg(source_s, "You are now identified for nick \x02%s\x02.", nick) else: nickserv.sendMsg(source_s, "Invalid password.") return except Exception as e: log.error("Can't identify user %s: %s", source_s, str(e)) nickserv.sendMsg( source_s, "A problem was encountered -- this is likely a bug, please report it." )
def handle_quit(event, message): client=Client.findByNick(message.source) if(client is None): return log.info("Client exiting at %s: %s!%s@%s[%s]: %s", client.server, client.nick, client.username, client.ip, client.hostname, " ".join(message.parameters)) Client.removeClient(client)