def anti_caps_cb(word, word_eol, userdata): """Detects caps abuse in protected channels, warns the user the first time and expels repeat offenders Arguments: word -- array of strings sent by HexChat/X-Chat to every hook word_eol -- array of strings sent by HexChat/X-Chat to every hook userdata -- optional variable that can be sent to a hook (ignored) """ if helper.conf_read("caps", "protections") == "1": for channel in helper.conf_read("channels", "protections").split(','): if channel.lower() == word[2].lower(): string = word_eol[3][1:] if _ACTION_RE.match(string): string = string[7:] if string.isupper() and len(string) > 10: host = word[0][1:].split("@")[1] nick = word[0][1:].split("!")[0] if host in _HOSTS_ABUSING_CAPS: _HOSTS_ABUSING_CAPS.remove(host) message = "".join([" Writing in all caps is against", " the rules and you were warned."]) helper.expel(message, "1", word) else: _HOSTS_ABUSING_CAPS.append(host) message = "".join(["msg ", word[2], " ", nick, ":", " do not write in all caps, it is", " against the rules. Next time you", " will be expelled."]) xchat.command(message) return xchat.EAT_NONE
def color(): if helper.conf_read("highlightoverride", "common") == "1": color = helper.conf_read("highlightcolor", "common") else: event = xchat.get_info('event_text Channel Msg Hilight') color = re.findall(r'%C[0-9]{1,2}', event)[-1][2:] return color
def anti_away_cb(word, word_eol, userdata): """Detects away messages in protected channels and expels the author Arguments: word -- array of strings sent by HexChat/X-Chat to every hook word_eol -- array of strings sent by HexChat/X-Chat to every hook (ignored) userdata -- optional variable that can be sent to a hook (ignored) """ if helper.conf_read("away", "protections") == "1": if word[2].lower() in helper.conf_read("channels", "protections").split(','): awaystr = helper.conf_read("awaystr", "protections").split(",") for i in range(len(awaystr)): if word_eol[3].find(awaystr[i]) > 0: ban = "1" message = "".join([" Disable automatic away messages,", " if you are out, just shut up"]) helper.expel(message, ban, word) return xchat.EAT_NONE
def url_highlight_cb(word, word_eol, userdata): """Looks for URLs and highlight them with the chosen color. Arguments: word -- array of strings sent by HexChat/X-Chat to every hook word_eol -- array of strings sent by HexChat/X-Chat to every hook userdata -- optional variable that can be sent to a hook (ignored) """ # If we are dealing with a CTCP, don't bother trying' if len(word[3]) > 1 and word[3][1] in ctcp_txt: return xchat.EAT_NONE if helper.conf_read("highlight", "common") == "1": urls = re.compile("".join([ "((ftp|https?)://.*)|((www|ftp)\..*\..*)", "|([a-z0-9_\.-\\\+]+)\@([a-z0-9_\.-]+)\.([a-z\.]{2,6})"]), re.IGNORECASE) # Set the apropriate start depending on whether it's an action message # or the network it's received from action = False if word[3] in action_txt: words = word_eol[4][:-1].split(" ") action = True elif "freenode" in xchat.get_info("server").lower(): words = word_eol[3][2:].split(" ") else: words = word_eol[3][1:].split(" ") address = [] # Find if there is any URL for i in words: if urls.match(i): address.append(i) # If there is any URL, colorize all of them new_msg_tmp = [] if address: for entry in words: if entry in address: new_msg_tmp.append("".join(["\003", color(), entry, "\003"])) else: new_msg_tmp.append(entry) new_msg = " ".join(new_msg_tmp) # Find the context: context = xchat.get_context() # Find what's the appropiate event and emit the corresponding text if action is False: context.emit_print("Channel Message", word[0].split("!")[0][1:], new_msg) else: if word[2][0] == "#": context.emit_print("Channel Action", word[0].split("!")[0][1:], new_msg) else: context.emit_print("Private Action", word[0].split("!")[0][1:], new_msg) return xchat.EAT_ALL else: return xchat.EAT_NONE
def anti_notice_cb(word, word_eol, userdata): """Detects NOTICEs sent to protected channels and kick/ban the author. Arguments: word -- array of strings sent by HexChat/X-Chat to every hook word_eol -- array of strings sent by HexChat/X-Chat to every hook (ignored) userdata -- optional variable that can be sent to a hook (ignored) """ # >> :[email protected] NOTICE #gatoscript :hello # >> :CHaN!-@- NOTICE #canal :nick añade en #canal a nick2 con nivel 499 if helper.conf_read("notices", "protections") == "1": channels = helper.conf_read("channels", "protections").split(',') for channel in channels: if (word[2].lower() == channel.lower()) and \ (word[0].lower() != ":chan!-@-"): # Exception for IRC-Hispano print(word[0]) print("This ban is for sending notices") xchat.command("".join(["kickban ", word[0][1:].split("!")[0], " Notices to channel are NOT allowed"])) return xchat.EAT_NONE
def anti_ctcp_cb(word, word_eol, userdata): """Detect CTCPs sent to protected channels and kick/ban the author. Arguments: word -- array of strings sent by HexChat/X-Chat to every hook word_eol -- array of strings sent by HexChat/X-Chat to every hook (ignored) userdata -- optional variable that can be sent to a hook (ignored) """ if helper.conf_read("ctcps", "protections") == "1": channels = helper.conf_read("channels", "protections").split(',') for channel in channels: if channel.lower() == word[2].lower(): if _CTCP_RE.search(word[3]): message = "".join(["Received a CTCP to channel ", word[2]]) helper.gprint(message) host = word[0][1:].split("@")[-1] xchat.command("".join(["ban *!*@", host])) nick = word[0][1:].split("!")[0] xchat.command("".join(["kick ", nick, "CTCPs to channel"])) return xchat.EAT_NONE
def antispam_reload(): """Reload the antispam filters list to apply changes""" # Use the global variables so this change applies to the wole module global ANTISPAM global SPAMBOTS global CHANNELS if helper.CONNECTED == 1: ANTISPAM = int(helper.conf_read("spam", "protections")) SPAMBOTS = int(helper.conf_read("spambots", "protections")) CHANNELS = helper.conf_read("channels", "protections") # Load the new filter list and compile the regexps filters = helper.gatodb_cursor_execute("SELECT filter FROM filters") COMP_FILTERS = [] for item in filters: COMP_FILTERS.append(re.compile("".join([".*", item[0], ".*"]), re.IGNORECASE)) else: helper.gprint("Failed to reload filters, AntiSpam disabled") ANTISPAM = 0 SPAMBOTS = 0 CHANNELS = []
def anti_colors_cb(word, word_eol, userdata): """Detects messages containing colors/bold/underline on protected channels, warns the author the first time and expels repeat ofenders. Arguments: word -- array of strings sent by HexChat/X-Chat to every hook word_eol -- array of strings sent by HexChat/X-Chat to every hook userdata -- optional variable that can be sent to a hook (ignored) """ # Only act on protected channels if word[2].lower() in helper.conf_read("channels", "protections").split(","): string = word_eol[3][1:] if _ACTION_RE.match(string): string = string[7:] if _COLORS_RE.search(string): # If we are banning colors, expel the author if helper.conf_read("ban_colors", "protections") == "1": host = word[0][1:].split("@")[1] if host in _HOSTS_ABUSING_COLORS: _HOSTS_ABUSING_COLORS.remove(host) message = "".join([" Using colors is against the", " rules and you were warned."]) helper.expel(message, "1", word) else: _HOSTS_ABUSING_COLORS.append(host) message = "".join(["msg ", word[2], " ", word[0][1:].split("!")[0], ": do NOT", " use colors/bold/underline in", " this channel, it is against the", " rules. Next time you will be", " expelled."]) xchat.command(message) # If we are ignoring messages containing colors if helper.conf_read("ignore_colors", "protections") == "1": helper.gprint("".join(["Message from ", word[0][1:].split("!")[0], " ignored because it contains", " colors."])) return xchat.EAT_ALL return xchat.EAT_NONE
def anti_hoygan_cb(word, word_eol, userdata): """Detects messages containing the word "hoygan" on protected channels and bans the author. Arguments: word -- array of strings sent by HexChat/X-Chat to every hook word_eol -- array of strings sent by HexChat/X-Chat to every hook (ignored) userdata -- optional variable that can be sent to a hook (ignored) """ # >> :nick!ident@host PRIVMSG #channel :message if helper.conf_read("hoygan", "protections") == "1": for channel in helper.conf_read("channels", "protections").split(','): if channel.lower() == word[2].lower(): hoygan_re = re.compile('hoyga|h 0 y g 4 n', re.IGNORECASE) if hoygan_re.search(word_eol[3]): host = word[0][1:].split("@")[-1] xchat.command("".join(["ban *!*@", host])) nick = word[0][1:].split("!")[0] xchat.command("".join(["kick ", nick, " Hoygan are the", " electronic version of the class", " clown, and they are NOT funny."])) del host, nick return xchat.EAT_NONE
def anti_drone_cb(word, word_eol, userdata): """Detects users joining the channel with nick/indent matching those used by Drone and expels them before they can spam us. Arguments: word -- array of strings sent by HexChat/X-Chat to every hook word_eol -- array of strings sent by HexChat/X-Chat to every hook (ignored) userdata -- optional variable that can be sent to a hook (ignored) """ # print word_eol[0] if helper.conf_read("drones", "protections") == "1": nick = word[0][1:].split("!")[0] ident = word[0][1:].split("!")[1].split("@")[0] if _DRONE_RE.search(nick) and _DRONE_RE.search(ident): context = xchat.get_context() host = word[0].split("@")[1] context.command("".join(["ban *!*@", host])) context.command("".join(["kick ", nick, " Bot"])) return xchat.EAT_NONE
# Load all needed libraries import xchat import re import helper ############################################################################# # Define some environment variables ############################################################################# ############################################################################# # Initialize the module ############################################################################# # Load the filter list and compile the regular expressions if helper.CONNECTED == 1: ANTISPAM = int(helper.conf_read("spam", "protections")) SPAMBOTS = int(helper.conf_read("spambots", "protections")) CHANNELS = helper.conf_read("channels", "protections").split(",") filters = helper.gatodb_cursor_execute("SELECT filter FROM filters") COMP_FILTERS = [] for item in filters: COMP_FILTERS.append(re.compile("".join([".*", item[0], ".*"]), re.IGNORECASE)) else: helper.gprint("AntiSpam is disabled or couldn't read the filters list") ANTISPAM = 0 SPAMBOTS = 0 CHANNELS = [] #############################################################################
# Hook all callbacks with their respective commands ############################################################################## HOOKANTINOTICE = xchat.hook_server('NOTICE', anti_notice_cb, userdata=None) HOOKANTIDRONE = xchat.hook_server('JOIN', anti_drone_cb, userdata=None) HOOKANTICTCP = xchat.hook_server('PRIVMSG', anti_ctcp_cb, userdata=None) HOOKANTIHOYGAN = xchat.hook_server('PRIVMSG', anti_hoygan_cb, userdata=None) HOOKANTICAPS = xchat.hook_server('PRIVMSG', anti_caps_cb, userdata=None) HOOKANTICOLORS = xchat.hook_server('PRIVMSG', anti_colors_cb, userdata=None) HOOKANTIAWAY = xchat.hook_server('PRIVMSG', anti_away_cb, userdata=None) ############################################################################# # Add menu options ############################################################################# xchat.command('menu ADD "GatoScript/Options/Protections"') xchat.command("".join(['menu -t', helper.conf_read("away", "protections"), ' ADD "GatoScript/Options/Protections/Away"', ' "options protections away 1"', ' "options protections away 0"'])) xchat.command("".join(['menu -t', helper.conf_read("ban", "protections"), ' ADD "GatoScript/Options/Protections/Ban"', ' "options protections ban 1"', ' "options protections ban 0"'])) xchat.command("".join(['menu -t', helper.conf_read("ignore_colors", "protections"), ' ADD "GatoScript/Options/Protections/Ignore colors"', ' "options protections colors 1"', ' "options protections colors 0"'])) xchat.command("".join(['menu -t', helper.conf_read("ban_colors", "protections"), ' ADD "GatoScript/Options/Protections/Ban colors"',