def check_channel_whitelist(client, message): deny_all = [] allow_all = ["politbiuro", "linki", "retro", "luzna_jazda"] unlimited = ["japabocie", "japa_bocie"] # default: disallow fulltext, enable flood control, enable bot permissions = {"fulltext" : False, "flood" : True, "disallow" : False} if str(message.channel).startswith("Direct Message"): sh.debug("Private message", message) permissions["flood"] = False permissions["fulltext"] = True elif str(message.channel) in deny_all: sh.debug("Blacklisted channel", message) permissions["disallow"] = True elif str(message.channel) in allow_all: sh.debug("Whitelisted channel", message) permissions["fulltext"] = True elif str(message.channel) in unlimited: sh.debug("Flood control inactive", message) permissions["flood"] = False permissions["fulltext"] = True else: sh.debug("Default options", message) return permissions
def update_msg_deletion(msg, db=stats, cursor=stats_c): data = (msg.id, ) cursor.execute("UPDATE messages SET deleted = 1 WHERE message = ? LIMIT 1", data) remove_emojis(msg, True) sh.debug("Deleted message {} from the stat database".format(msg.id))
def update_msg_function(msg, funct, db=stats, cursor=stats_c, tmp=False): data = (funct, msg.id) cursor.execute("UPDATE messages SET function = ? WHERE message = ?", data) if not tmp: db.commit() sh.debug("Updated message function: {}".format(funct))
def insert_msg(msg, db=stats, cursor=stats_c, tmp=False): data = (msg.id, msg.server.id if msg.server is not None else 0, msg.channel.id if msg.channel is not None else None, msg.author.id, msg.timestamp, msg.mention_everyone, 0, 1 if msg.author.bot else 0, None) cursor.execute("INSERT INTO messages VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", data) if not tmp: db.commit() sh.debug("Inserted message {} into the stat database".format(msg.id))
def check_flood(client, message): sh.debug("Checking for flood...") msg_limit = 5 # messages per channel time_limit = 5 # minutes if message.channel not in check: # channel not tracked yet check[message.channel] = {} if message.author not in check[message.channel]: # author on channel not tracked yet: check[message.channel][message.author] = {} check[message.channel][message.author]["timestamps"] = [] check[message.channel][message.author]["warning_issued"] = False if len(check[message.channel][message.author]["timestamps"]) < msg_limit: # less than limit messages sent sh.debug( "Message number " + str(len(check[message.channel][message.author]["timestamps"]) + 1)) check[message.channel][message.author]["timestamps"].append( time.time()) return False else: time_diff = time.time() - check[message.channel][ message.author]["timestamps"][0] if time_diff > (time_limit * 60): # message older than time limit sh.debug( "Message number " + str(msg_limit) + "; deleted timestamp " + str(check[message.channel][message.author]["timestamps"][0]), message) check[message.channel][message.author]["timestamps"].pop(0) check[message.channel][message.author]["timestamps"].append( time.time()) check[message.channel][message.author]["warning_issued"] = False return False else: if check[message.channel][ message.author]["warning_issued"] == False: # scold user for spamming sh.debug("This user is spamming!") yield from client.send_message( message.channel, sh.mention(message) + "zamknij pizdę przez " + datetime.datetime.utcfromtimestamp( (time_limit * 60) - time_diff).strftime("%Mmin %Ss") + ". Spamuj w <#386148571529084929>") check[message.channel][message.author]["warning_issued"] = True return True else: # ...but just once sh.debug("Shut him up pls") return False
def check_flood_channel(client, message): sh.debug("Checking for channel flood...") msg_limit = 5 # messages per channel time_limit = 1 # minutes if message.channel not in check: # channel not tracked yet check[message.channel] = {} check[message.channel]["timestamps"] = [] check[message.channel]["warning_issued"] = False if len(check[message.channel]["timestamps"]) < msg_limit: # less than limit messages sent sh.debug("Channel message number " + str(len(check[message.channel]["timestamps"]) + 1)) check[message.channel]["timestamps"].append(time.time()) return False else: time_diff = time.time() - check[message.channel]["timestamps"][0] if time_diff > (time_limit * 60): # message older than time limit sh.debug( "Channel message number " + str(msg_limit) + "; deleted timestamp " + str(check[message.channel]["timestamps"][0]), message) check[message.channel]["timestamps"].pop(0) check[message.channel]["timestamps"].append(time.time()) check[message.channel]["warning_issued"] = False return False else: if check[message.channel]["warning_issued"] == False: # scold these idiots for spamming sh.debug("This channel is being flooded!") client.send_message( message.channel, "Weźcie wszyscy sklejcie pizdy przez " + datetime.datetime.utcfromtimestamp( (time_limit * 60) - time_diff).strftime("%Mmin %Ss") + ". Od spamowania jest <#386148571529084929>") check[message.channel]["warning_issued"] = True return True else: # ...but just once sh.debug("I CAN STILL HEAR VOICES") return False
def on_message_delete(message): billy_c_stats.update_msg_deletion(message) content = sh.rm_leading_quotes(message) if message.author == client.user or not message.server or not re.match( client.command_prefix, content): return sh.debug("User message deleted: " + message.content, message) for log in reversed( list((yield from client.logs_from(message.channel, limit=50, after=message)))): if log.author != client.user or not log.content.startswith( "<@!" + message.author.id + ">:"): continue sh.debug("Found a message to delete: " + log.content, message) yield from client.delete_message(log) return sh.debug("No matching bot response found")
def check_channel_whitelist(client, message): deny_all = [] # pecetgej, politbiuro, luzna_jazda, japabocie, japa_bocie allow_fulltext = [ "318733700160290826", "174449535811190785", "316323075622961152", "319056762814595076", "386148571529084929" ] # japabocie, japa_bocie, sesje_rpg, sun_world, kanau_fela unlimited = [ "316323075622961152", "319056762814595076", "386148571529084929", "174541542923436032", "539154754631106584", "232881423604776960" ] # default: disallow fulltext, enable flood control, enable bot permissions = {"fulltext": False, "flood": True, "disallow": False} if str(message.channel).startswith("Direct Message"): sh.debug("Private message", message) permissions["flood"] = False permissions["fulltext"] = True else: if message.channel.id in deny_all: #sh.debug("Blacklisted channel", message) permissions["disallow"] = True if message.channel.id in allow_fulltext: #sh.debug("Whitelisted channel", message) permissions["fulltext"] = True if message.channel.id in unlimited: #sh.debug("Flood control inactive", message) permissions["flood"] = False sh.debug("Received message", message) return permissions
def parse_message(message, edited=False): if not edited: billy_c_stats.insert_msg(message) # Track used emojis emoji_list = list( c for c in message.clean_content if c in emoji.UNICODE_EMOJI) or [] custom_emoji_list = re.findall(r"<:\S+?:\d+>", message.clean_content, re.IGNORECASE) or [] billy_c_stats.insert_emojis_post(message, emoji_list, custom_emoji_list, edited) # ignore bot messages if message.author == client.user: return perm = af.check_channel_whitelist(client, message) # channel blacklisted if perm["disallow"]: return # strip quotes content = sh.rm_leading_quotes(message) if not edited: # fulltext search for f in f_functions: c = getattr(f, "command", False) p = getattr(f, "prob", False) if c and p and re.search(c, content, re.IGNORECASE) and ( p >= 1.0 or (perm["fulltext"] and random.random() < p)): sh.debug("Triggered " + f.__name__ + "...") try: yield from f(client, message) except Exception: print_warning("An error occured in " + f.__name__ + "!!! (" + content + ")") raise # commands if re.match(client.command_prefix, content): sh.debug("This seems to be a command: " + sh.get_command(message)) # check antiflood #if perm["flood"] and ((yield from af.check_flood_channel(client, message)) or (yield from af.check_flood(client, message))): # sh.debug("Anti-flood kicked in yo") # return # help # not needed here #else: # iterate over functions for f in c_functions: c = getattr(f, "command", False) r = re.match(compile_command(c), content, re.IGNORECASE) if c and r: sh.debug("Executing " + f.__name__ + "...") yield from client.send_typing(message.channel) try: yield from f(client, message) billy_c_stats.update_msg_function(message, f.__name__) except Exception: yield from client.send_message( message.channel, "Oho, chyba jakiś błąd w kodzie. <@307949259658100736> to kiedyś naprawi, jak się skończy bawić pociągami." ) print_warning("An error occured in " + f.__name__ + "!!! (" + content + ")") #CZEMU TY CHUJU NIE DZIALASZ #logging.exception("An error occured in " + f.__name__ + "!!! (" + content + ")") raise continue break
module = sys.modules[module_name] for name, val in module.__dict__.items(): if callable(val) and name.startswith(("c_", "f_", "t_")): if name.startswith("t_"): if hasattr(val, "time") and not re.match( r"([0-9]|[0-1][0-9]|2[0-3])\:[0-5][0-9]", getattr(val, "time")): print("Invalid specified time: " + name) continue elif not hasattr(val, "channels"): print("No channels specified: " + name) continue else: # Timer functions functions sh.debug("Imported timer: " + name) t_functions.append(val) i += 1 elif not hasattr(val, "command"): # Omit functions without specified .command print("Missing command regex: " + name) continue elif name.startswith("f_") and not hasattr(val, "prob"): # Omit fulltext without specified .prob print("Missing fulltext probability: " + name) continue elif name.startswith("c_"): # Called functions
def parse_message(message, edited=False): #if not edited: # billy_c_stats.insert_msg(message) # Track used emojis #emoji_list = list(c for c in message.clean_content if c in emoji.UNICODE_EMOJI) or [] #custom_emoji_list = re.findall(r"<:\S+?:\d+>", message.clean_content, re.IGNORECASE) or [] #billy_c_stats.insert_emojis_post(message, emoji_list, custom_emoji_list, edited) # ignore bot messages if message.author == client.user: return perm = af.check_channel_whitelist(client, message) # channel blacklisted if perm["disallow"]: return # strip quotes content = unidecode.unidecode(sh.rm_leading_quotes(message)) if not edited: # fulltext search for f in f_functions: c = getattr(f, "command", False) p = getattr(f, "prob", False) if c and p and re.search(c, content, re.IGNORECASE) and ( p >= 1.0 or (perm["fulltext"] and random.random() < p)): sh.debug("Triggered " + f.__name__ + "...") try: yield from f(client, message) except Exception: print_warning("An error occured in " + f.__name__ + "!!! (" + content + ")") raise # commands if re.match(client.command_prefix, content): sh.debug("This seems to be a command: " + sh.get_command(message)) # check antiflood if perm["flood"] and ( (yield from af.check_flood_channel(client, message)) or (yield from af.check_flood(client, message))): sh.debug("Anti-flood kicked in yo") return # help if re.match(compile_command(r"(help|pomoc)"), content, re.IGNORECASE): sh.debug("What a noob") ret = "Witam witam, z tej strony Billy Mays z kolejnym fantastycznym produktem!\nDozwolone przedrostki funkcji: . , \ / ! ;\n\n" for f in c_functions: desc = getattr(f, "desc", False) if hasattr(f, "rhyme") or desc == "hidden": continue command = getattr(f, "command", False) ret += "." + getattr(f, "command") params = getattr(f, "params", False) if params: for p in params: ret += " [" + p + "]" if desc: ret += " - " + desc ret += "\n" ret += "\nRymy i inne bzdety: .rymy" ret += "\nZadzwoń teraz, a podwoimy ofertę!" if len(ret) > 2000: n = 40 groups = ret.split("\n") help = ["\n".join(groups[:n]), "\n".join(groups[n:])] else: help = [ret] for m in help: yield from client.send_message(message.channel, m) elif re.match(compile_command(r"(rymy|rhymes)"), content, re.IGNORECASE): sh.debug("What an utter pillock") ret = "Rymy i inne bzdety:\n" for f in c_functions: if not hasattr(f, "rhyme"): continue command = getattr(f, "command", False) ret += "." + getattr(f, "command") + "\n" yield from client.send_message(message.channel, ret[:-1]) else: # iterate over functions for f in c_functions: c = getattr(f, "command", False) r = re.match(compile_command(c), content, re.IGNORECASE) if c and r: sh.debug("Executing " + f.__name__ + "...") yield from client.send_typing(message.channel) try: yield from f(client, message) #billy_c_stats.update_msg_function(message, f.__name__) except Exception: yield from client.send_message( message.channel, "Oho, chyba jakiś błąd w kodzie. <@307949259658100736> to kiedyś naprawi, jak się skończy bawić pociągami." ) print_warning("An error occured in " + f.__name__ + "!!! (" + content + ")") #CZEMU TY CHUJU NIE DZIALASZ #logging.exception("An error occured in " + f.__name__ + "!!! (" + content + ")") raise continue break
def on_message(message): #ignore bot messages if message.author == client.user: return perm = af.check_channel_whitelist(client, message) # channel blacklisted if perm["disallow"]: return # strip quotes content = sh.rm_leading_quotes(message) if perm["fulltext"]: # fulltext search for f in f_functions: c = getattr(f, "command", False) p = getattr(f, "prob", False) if c and p and re.search(c, content, re.IGNORECASE) and random.random() < p: sh.debug("Triggered " + f.__name__ + "...") try: yield from f(client, message) except Exception: print("An error occured in " + f.__name__ + "!!! (" + content + ")") raise continue # commands if re.match(client.command_prefix, content): sh.debug("This seems to be a command: " + sh.get_command(message)) # check antiflood if perm["flood"] and ( (yield from af.check_flood_channel(client, message)) or (yield from af.check_flood(client, message))): sh.debug("Anti-flood kicked in yo") return # help if re.match(compile_command(r"(help|pomoc)"), content, re.IGNORECASE): sh.debug("What a noob") ret = "Witam witam, z tej strony Billy Mays z kolejnym fantastycznym produktem!\nDozwolone przedrostki funkcji: . , \ / !\n\n" for f in c_functions: desc = getattr(f, "desc", False) if hasattr(f, "rhyme") or desc == "hidden": continue command = getattr(f, "command", False) ret += "." + getattr(f, "command") params = getattr(f, "params", False) if params: for p in params: ret += " [" + p + "]" if desc: ret += " - " + desc ret += "\n" ret += "\nRymy i inne bzdety: .rymy" ret += "\nZadzwoń teraz, a podwoimy ofertę!" yield from client.send_message(message.channel, ret) elif re.match(compile_command(r"(rymy|rhymes)"), content, re.IGNORECASE): sh.debug("What an utter pillock") ret = "Rymy i inne bzdety:\n" for f in c_functions: if not hasattr(f, "rhyme"): continue command = getattr(f, "command", False) ret += "." + getattr(f, "command") + "\n" yield from client.send_message(message.channel, ret[:-1]) else: # iterate over functions for f in c_functions: c = getattr(f, "command", False) r = re.match(compile_command(c), content, re.IGNORECASE) if c and r: sh.debug("Executing " + f.__name__ + "...") yield from client.send_typing(message.channel) try: yield from f(client, message) except Exception: yield from client.send_message( message.channel, "Oho, chyba jakiś błąd w kodzie. <@307949259658100736> to kiedyś naprawi, jak się skończy bawić pociągami." ) print("An error occured in " + f.__name__ + "!!! (" + content + ")") #CZEMU TY CHUJU NIE DZIALASZ #logging.exception("An error occured in " + f.__name__ + "!!! (" + content + ")") raise continue break return