def end_of_names_callback(word, word_eol, userdata): server = hexchat.get_info('server') if not server == TWITCH_IRC_SERVER or len(hexchat.get_list('users')) > 1: return current_channel = hexchat.get_info('channel') url = CHATTERS_URL_TEMPLATE % current_channel[1:] channel_key = server + current_channel hexchat.hook_timer(RETRIEVE_USERLIST_TIMEOUT, retrieve_userlist_update_callback, (url, channel_key)) start_new_thread(retrieve_userlist_update_thread, url, channel_key) channel = None for channel in hexchat.get_list('channels'): if channel.server == server and channel.channel == current_channel: break # This should never happen... assert channel # Initial userlist update, approximately 3 seconds after starting retrieve_userlist_update_thread. hexchat.hook_timer(INITIAL_UPDATE_USERLIST_TIMEOUT, initial_update_userlist_callback, channel) hexchat.hook_timer(UPDATE_USERLIST_TIMEOUT, update_userlist_callback, channel) return hexchat.EAT_NONE
def set_topic(self): """ Set the channel topic (no formatting) and print the topic locally with formatting """ #statusLong = "\00320\002OFF\002\00399" statusShort = get_pref("bullet_offline") if self.status == 1: #statusLong = "\00319\002ON\002\00399" statusShort = get_pref("bullet_online") if get_pref("modify_topic") == 1: msg = "{1}\00318{0}\00399 | {3} | \00318{2}\00399"\ .format(self.display_name, statusShort, self.game, self.title) # HexChat doesn't support hiding characters in the topic bar (Windows), so strip the formatting until it's fixed if sys.platform == "win32": msg = hexchat.strip(msg, -1, 3) if hexchat.get_info("topic") != msg: hexchat.command("RECV :[email protected] TOPIC #{0} :{1}".format(self.channel, msg)) if get_pref("modify_tab") == 1: # Set the tab title to the properly capitalized form of the name settabCommand = "SETTAB {0}{1}"\ .format(statusShort, self.display_name) hashChannel = "#{0}".format(self.channel) cxt = hexchat.find_context(hexchat.get_info("server"), hashChannel) if not cxt == None: cxt.command(settabCommand)
def pref_check(): if hexchat.get_info("network") in network_lst: return True elif hexchat.get_info("channel") in channel_lst and hexchat.get_info("network") in chan_net_lst: return True else: return False
def greplog(channel, pattern): logmask = hexchat.get_prefs("irc_logmask") logfile = logmask.replace("%n", hexchat.get_info("network")).replace("%s",hexchat.get_info("server")).replace("%c",channel) logfile = os.path.join(hexchat.get_info("configdir"), "logs", logfile) if not os.path.isfile(logfile): error("log-file %s does not exist" % logfile) return hexchat.EAT_ALL if is_linux: # on linux hexchat.command("exec grep '" + pattern + "' " + logfile) else: with open(logfile, "r") as f: for line in f: try: if re.search(pattern, line): hexchat.prnt(line) except: if line.find(pattern) > -1: hexchat.prnt(line) return hexchat.EAT_ALL
def recv_notice_cb(word, word_eol, userdata): global last_context_name context_name = None nick = word[0][1:].split('!')[0] to = word[2] if to.startswith('#'): return hexchat.EAT_NONE if nick == 'ChanServ': if word[3].startswith(':[#') and word[3].endswith(']'): context_name = word[3][2:-1] elif word[3].startswith(':+[#') and word[3].endswith(']'): context_name = word[3][3:-1] elif word_eol[3].startswith(':Deopped you on channel ') and word_eol[3].endswith(' because it is registered with channel services'): context_name = hexchat.strip(word[7]) elif word_eol[3] == ':and you are not a CHANOP on its access list.': context_name = last_context_name if not context_name: context_name = nick if context_name: context = hexchat.find_context(server=hexchat.get_info('server'), channel=context_name) if not context: if context_name.startswith('#'): return hexchat.EAT_NONE else: hexchat.command('QUERY -nofocus %s' % context_name) context = hexchat.find_context(server=hexchat.get_info('server'), channel=context_name) if context: context.set() last_context_name = context_name else: last_context_name = None
def send_message(word, word_eol, userdata): message = word_eol[0] if message.startswith('>') and not (preferences.ignore_emoticons and len(message) > 1 and message[1] != ' ' and not message[1].isalpha()): message = hexstuff.color_text(message, hexstuff.COLOR_GREEN) hexchat.command('PRIVMSG %s :%s' % (hexchat.get_info('channel'), message)) hexchat.emit_print('Your Message', hexchat.get_info('nick'), message) return hexchat.EAT_HEXCHAT
def main(word, word_eol, userdata): channel = hexchat.get_info("channel")[1:] if hexchat.get_info("server") == "tmi.twitch.tv": server = "twitch.tv" else: server = defaultserver if len(word) == 1: connect(channel, quality, server) elif word[1] == "raw" and len(word) >= 3: hexchat.command("exec livestreamer {0}".format(word_eol[2])) elif word[1] == "help" and len(word) >= 2: xstreamHelp(word, word_eol) elif any(word[1] == stopcmd for stopcmd in stopcommands) and len(word) == 2: if platform.system() == "Windows": hexchat.command("exec taskkill /im livestreamer.exe /f") elif platform.system() == "Linux": hexchat.command("exec pkill livestreamer") else: print("Sorry, I don't recognize your operating system") elif len(word) == 2: if word[1] == "stop": hexchat.command("execkill") elif word[1] == "raw": print("syntax: /xstream raw <command>") else: connect(word[1], quality, server) elif len(word) == 3: connect(word[1], word[2], server) elif len(word) == 4: connect(word[1], word[2], word[3]) else: print("Usage: /xstream (<channel>) (<quality>) (<server>)") return hexchat.EAT_ALL
def toggle_bookmark(chan, net): # It's a toggle because /menu sucks if chan == None: chan = hexchat.get_info('channel') if chan == '': return if net == None: try: # If from a $TAB it may be a different network. net = hexchat.find_context(None, chan).get_info('network') except AttributeError: net = hexchat.get_info('network') for channel in hexchat.get_list('channels'): if channel.channel == chan: if channel.type != 2: # Only bookmark channels return networks = get_networks(chan) pref = 'bookmark_' + chan if net in networks: # Remove if len(networks) == 1: hexchat.del_pluginpref(pref) else: networks.remove(net) hexchat.set_pluginpref(pref, ','.join(networks)) hexchat.command('menu del "Bookmarks/{}/{}"'.format(net, chan)) else: # Add networks.append(net) hexchat.set_pluginpref(pref, ','.join(networks)) hexchat.command('menu -p-2 add "Bookmarks/{}'.format(net)) hexchat.command('menu add "Bookmarks/{0}/{1}" "netjoin {1} {0}"'.format(net, chan))
def converter(key, data, userdata): global enabled if not enabled: return hexchat.EAT_NONE if key[0] == "65293": if (hexchat.get_info("inputbox").startswith("/")): return hexchat.EAT_NONE output = "" lower = random.choice([False, True]) for word in hexchat.get_info("inputbox").strip(" ").split(" "): newWord = "" for letter in word: if not lower: letter = letter.upper() else: letter = letter.lower() newWord = newWord + letter lower = not lower output = output + " " + newWord if output else output + newWord hexchat.command("say " + output) hexchat.command("settext ") return hexchat.EAT_ALL return hexchat.EAT_NONE
def sendmsg(word, word_eol, userdata): "Function called by /gpg. Parses user input, encrypts, and sends." channel = hexchat.get_info("channel") context = hexchat.find_context(channel=channel) if not userdata and len(word) < 3: context.emit_print("Channel Message", __module_name__, help_gpg) return hexchat.EAT_ALL elif userdata and len(word) < 4: context.emit_print("Channel Message", __module_name__, help_gpgs) return hexchat.EAT_ALL # Waiting for gpg-agent.exe to start and encrypt causes HexChat to hang. # Requires further testing with large messages. if not userdata: data = encrypt_message(word[1], None, word_eol[2], None) elif userdata and "s" in userdata: data = encrypt_message(word[1], word[2], word_eol[3], userdata) data = data.split("\n") for line in range(len(data)): data[line] = data[line].replace("\r", "") if data[line]: # Don't send blank lines context.emit_print( "Channel Message", hexchat.get_info("nick"), data[line] ) context.command( "PRIVMSG {0} {1}".format(channel, data[line]) ) return hexchat.EAT_ALL
def chan_check_cb(word, word_eol, userdata): word = [(word[i] if len(word) > i else "") for i in range(4)] chan = hexchat.get_info("channel") if chan in watched_channels: nick = hexchat.strip(word[0], -1, 3) time = datetime.now().strftime("[%b %d %Y %H:%M]") network = hexchat.get_info("network") url_finder(word, nick, network, chan, time)
def notify(title, message): if hexchat.get_prefs('away_omit_alerts') and hexchat.get_info('away'): return if hexchat.get_prefs('gui_focus_omitalerts') and hexchat.get_info('win_status') == 'active': return Notifier.notify(hexchat.strip(message), title=hexchat.strip(title), sender='org.hexchat', sound='default')
def raw_modes_cb(word, word_eol, event): """Eat the target part of the message, if it's obvious from context.""" target, *mode_args = split_irc_message(word[1]) if target not in (hexchat.get_info('channel'), hexchat.get_info('nick')): return hexchat.EAT_NONE print_event('Raw Modes', word[0], " ".join(mode_args)) return hexchat.EAT_HEXCHAT
def kicked(words, word_eols, userdata): wait = '0.15' # Increase if your computer is extremely slow (Intel 8080 (kidding)) channel = hexchat.get_info('channel') network = hexchat.get_info('network') if channel in channels: if ((len(channels[channel]) > 0) & (channels[channel] == network)) | (len(channels[channel]) == 0): hexchat.command('timer {} join {}'.format(wait, channel)) return hexchat.EAT_NONE
def openLogFile(word, word_eol, userdata): if len(word)>1: hexchat.command('help openLogFile') else: path = hexchat.get_info('configdir') logFile = '%s%slogs%s%s%s%s.log' % (path, os.sep, os.sep, hexchat.get_info('host'),os.sep, hexchat.get_info('channel')) os.startfile(logFile) return hexchat.EAT_ALL
def url_logger(stripped_word, nick, network, chan, time): directory = os.path.join(hexchat.get_info("configdir"), "logs", network, chan) if not os.path.exists(directory): os.makedirs(directory) directory = os.path.join(hexchat.get_info("configdir"), "logs", network, chan, "urls.txt") f = open(directory, "a") f.write(time + " " + nick + "@" + chan + ":" + network + " - " + stripped_word + "\n") f.close()
def on_message(word, word_eol, userdata): """Strip out commands being sent to the VM """ if hexchat.get_info('channel').startswith(CHANNEL) and is_command(word[1]): return hexchat.EAT_ALL elif hexchat.get_info('channel').startswith(CHANNEL) and word[0] == BOTNAME: print('\002\00304%s' % word[1]) return hexchat.EAT_ALL return hexchat.EAT_NONE
def urc_broadcast_hexchat(word, word_eol, userdata): chnl = hexchat.get_info("channel") if chnl: nick = hexchat.get_info("nick") if nick is None or len(nick) == 0: nick = "anon" try: userdata.broadcast(':{}[email protected] PRIVMSG {} :{}\n'.format(nick, chnl, word_eol[0])) except Exception as e: prnt("error in urc: {}".format(e))
def send(key, data, userdata): if key[0] == "65293": user_input = hexchat.get_info("inputbox"); if hexchat.get_info("channel") in channels: if user_input.startswith("/") and not user_input.startswith("/me"): return hexchat.EAT_NONE hexchat.command("say {}".format(user_input.upper())) hexchat.command("settext ") return hexchat.EAT_ALL return hexchat.EAT_NONE
def ban_cb(word, word_eol, userdata): if len(word) > 1: mask = get_mask(word[1]) command = "" if mask: do_op() if word[0] == "ban": command = "mode +b {}".format(mask) elif word[0] == "kickban": nick = word[1] chan = hexchat.get_info("channel") message = "" if len(word_eol) > 2: message = word_eol[2] command = "mode +b {}\r\nKICK {} {} :{}".format(mask, chan, nick, message) elif word[0] == "kick": nick = word[1] chan = hexchat.get_info("channel") message = "" if len(word_eol) > 2: message = word_eol[2] command = "quote KICK {} {} :{}".format(chan, nick, message) elif word[0] == "remove": nick = word[1] chan = hexchat.get_info("channel") message = "" if len(word_eol) > 2: message = word_eol[2] command = "quote REMOVE {} {} :{}".format(chan, nick, message) elif word[0] == "quiet": command = "mode +q {}".format(mask) elif word[0] == "unban": command = "mode -b {}".format(mask) elif word[0] == "unquiet": command = "mode -q {}".format(mask) if command: hexchat.hook_timer(100, do_command, command) return hexchat.EAT_HEXCHAT else: return hexchat.EAT_NONE
def keypress(w, we, u): if re.search(affected_networks, hexchat.get_info("network")): key, state, key_str, str_len = w if int(key) == 65289: # <Tab> inputbox = hexchat.get_info("inputbox") pos = hexchat.get_prefs("state_cursor") text, suffix = inputbox[:pos], inputbox[pos:] prefix, space, word = text.rpartition(" ") if len(word): prefix += space if word[0] == '#': return hexchat.EAT_NONE # let the built-in completion handle channels if word[0] == '@': word = word[1:] users = [] for u in hexchat.get_list("users"): if not hexchat.nickcmp(u.nick[:len(word)], word): users.append((u.nick, u.lasttalk)) for c in hexchat.get_list("channels"): if c.context == hexchat.get_context(): if c.type == 3: if not hexchat.nickcmp(c.channel[:len(word)], word): users.append((c.channel, 0)) # if we're in a dialog, include the targer user if len(users): if len(users) == 1: completion = "@" + users[0][0] + " " else: if hexchat.get_prefs("completion_sort") == 1: users = sorted(users, key = lambda x: -x[1]) else: users = sorted(users, key = lambda x: x[0].lower()) nicks = [u[0] for u in users] print(" ".join(nicks)) common = None # longest common prefix for nick in nicks: if common == None: common = word + nick[len(word):] # copy the case of characters entered by the user else: while hexchat.nickcmp(nick[:len(common)], common): common = common[:-1] for nick in nicks: if not hexchat.nickcmp(nick, word): common = nick # if we have an exact match, ignore the case of user's characters completion = "@" + common hexchat.command("settext " + prefix + completion + suffix) hexchat.command("setcursor " + str(len(prefix) + len(completion))) return hexchat.EAT_ALL else: prevword = prefix.rpartition(" ")[2] if len(prevword) and prevword[0] == '@': return hexchat.EAT_ALL # don't let the built-in completion kick in if we just completed a nick else: return hexchat.EAT_NONE else: return hexchat.EAT_NONE
def hook_remove_channel(word, word_eol, userdata): if len(word) > 1: channel = hexchat.strip(word[1]) else: channel = hexchat.get_info('channel') if AUTOCHANNEL.pop(hexchat.get_info('network') + ' ' + channel.lower(), None) is not None: save_config('yandex_tr_auto_channel', str(AUTOCHANNEL)) hexchat.prnt('Channel ' + channel + ' has been removed from the watch list.') return hexchat.EAT_ALL
def away_cb(word, word_eol, userdata): global away_time away_time[hexchat.get_info('server')] = time.time() reason = hexchat.get_info('away') for channel in hexchat.get_list('channels'): if channel.server == hexchat.get_info('server'): if channel.channel in announce_list: if reason: channel.context.command('me is away (%s)' %reason) else: channel.context.command('me is away')
def back_cb(word, word_eol, userdata): gone_time = None if away_time: gone_time = time.strftime('%H:%M:%S' , time.gmtime(time.time() - away_time.get(hexchat.get_info('server')))) for channel in hexchat.get_list('channels'): if channel.server == hexchat.get_info('server'): if channel.channel in announce_list: if gone_time: channel.context.command('me is back (gone %s)' %gone_time) else: channel.context.command('me is back')
def sendFilter(word, word_eol, userdata): channel = hexchat.get_info("channel")#get channel to privmsg if word_eol[0][:3]!="+OK" and word_eol[0][:1]!="\\":#if it isn't your new encrypted one or an escaped one hexchat.emit_print("Channel Message", userNickColor + hexchat.get_info("nick"), encryptedTextColor + word_eol[0])#makes it look to you like you spoke in plain text hexchat.command("PRIVMSG "+channel+" :"+crypto(word_eol[0], "e"))#encrypt it if word_eol[0][:1]==escapeCharacter:#if it's escaped hexchat.emit_print("Channel Message", userNickColor + hexchat.get_info("nick"), word_eol[0][1:])#prints it with a stripped \ endCrypto()#makes the sendFilter hook not catch it hexchat.command("PRIVMSG "+channel+" :"+word_eol[0][1:])#dont encrypt it beginCrypto() return hexchat.EAT_HEXCHAT
def paste(key, data, userdata): if key[0] == "65293": if hexchat.get_info("inputbox").startswith(command): try: req = requests.post("https://qbin.io/", {"Q": hexchat.get_info("inputbox")[len(command)+1:]}) hexchat.command("say " + req.text.strip()) hexchat.command("settext ") except: hexchat.command("settext ") return hexchat.EAT_ALL return hexchat.EAT_NONE
def hook_remove_user(word, word_eol, userdata): if len(word) < 2: hexchat.prnt("You must specify a user.") return hexchat.EAT_ALL user = hexchat.strip(word[1]) if AUTOUSER.pop(hexchat.get_info('network') + ' ' + hexchat.get_info('channel') + ' ' + user.lower(), None) is not None: save_config('yandex_tr_auto_user', str(AUTOUSER)) hexchat.prnt('User ' + user + ' has been removed from the watch list.') return hexchat.EAT_ALL
def isstreaming_cb(word, word_eol, userdata): CHANNEL = hexchat.get_info("channel") if (hexchat.get_info("host") != "irc.twitch.tv"): print("/ISSTREAMING works only in irc.twitch.tv chats") return hexchat.EAT_ALL with urllib.urlopen('https://api.twitch.tv/kraken/streams/' + CHANNEL.strip('#')) as data: obj = json.loads(data.readall().decode('utf-8')) if (obj["stream"] == None): pprint(CHANNEL.title() + " is not live on twitch.tv.") else: pprint(CHANNEL.title() + " is streaming for " + str(obj["stream"]["viewers"]) + " viewers on " + obj["stream"]["channel"]["url"])
def keypress_cb(word, word_eol, userdata): global last_index global last_completes global last_text global last_pos if not word[0] == '65289': # Tab return if not hexchat.get_info('channel') == '>>python<<': return shift_key_is_down = bool(int(word[1]) & 1) # check if shift modifier is hold text = hexchat.get_info('inputbox') pos = hexchat.get_prefs('state_cursor') if not text: return base = text[:pos].split(' ')[-1] module, _, prefix = base.rpartition('.') if not module: # can not dir() the console's interpreter state sadly return if last_text != text or last_pos != pos: # new completion context try: exec('import {}'.format(module), exec_scope) # Has to be imported to dir() it completions = eval('dir({})'.format(module), exec_scope) except (NameError, SyntaxError, ImportError): return completions = [c for c in completions if c.startswith(prefix)] if not completions: return index = 0 else: # same context, insert next completion completions = last_completes direction = 1 if not shift_key_is_down else -1 index = (last_index + direction) % len(completions) complete_text = completions[index] new_text = text[:pos - len(prefix)] + complete_text + text[pos:] new_pos = pos - len(prefix) + len(complete_text) hexchat.command('settext {}'.format(new_text)) hexchat.command('setcursor {}'.format(new_pos)) last_index = index last_completes = completions last_text = new_text last_pos = new_pos
def join_cb(word, word_eol, userdata): """ Restart the threaded process if necessary, then immediately get the stream status """ global t global twitch_chans if is_twitch(): if not t: get_current_status() channel = hexchat.get_info("channel") # TODO: make safer and don't modify the same object that is modified by get_stream_status twitch_chans[channel] = "" channel = channel[1:] get_stream_info(channel)
def command(w, we, u): cmd = w[0] channel = hexchat.get_info("channel") ctx = hexchat.get_context() @Async def async_action(thread): actions = parseActions(channel, we[1] if len(we) > 1 else "") log( 0, "[" + str(netId(ctx)) + "] [" + channel + "] /" + cmd + " " + renderActions(actions)) if cmd in ["cd", "d"]: ModeAction.append( actions, ModeAction(channel=channel, modes=[("-o", hexchat.get_info("nick"))])) whoises = {} if fixModes and not re.match(ignoreVersions, ctx.get_info("network")): version = versions.get(netId(ctx), {}) newactions = [] for a in actions: if isinstance(a, ModeAction): newactions.extend(tryFixModes(version, a)) else: newactions.append(a) actions = newactions for a in actions: if isinstance(a, ModeAction): for mode, arg in a.modes: if isinstance(arg, WhoisArg): if arg.nick not in whoises: whoises[arg.nick] = WhoisPromise( thread, ctx, arg.nick) arg.promise = whoises[arg.nick] if cmd in ["cd", "co"]: c = ChanServPromise(thread, ctx, channel) for y in c.wait(): yield y if not c.value: log( 2, "[" + str(netId(ctx)) + "] ChanServ OP failed, aborting actions in " + channel) return log( 1, "[" + str(netId(ctx)) + "] Opped by ChanServ in " + channel + ", executing actions") for y in executeActions(ctx, actions): yield y return hexchat.EAT_ALL
def message(word, word_eol, userdata): channel = hexchat.get_info('channel') if len(channel) == 0 or channel[0] != '#': # Not a channel (query tab) return # 65293 is <enter> # 65421 is numpad <enter> # 0 is no modifier # 1 is caps lock # 4 is num lock mod = int(word[1]) if (word[0] != "65293" and word[0] != "65421") or (mod != 0 and not bs(mod, 1) and not bs(mod, 4)): return msg = hexchat.get_info('inputbox') if msg is None or len(msg) == 0: return if handle_message(channel, msg): hexchat.command('settext') return hexchat.EAT_HEXCHAT
def message(word, word_eol, userdata): """ Handles a message by replacing its content containing `.keyword.` with the appropriate replacement. """ if not enabled: return channel = hexchat.get_info('channel') if len(channel) == 0 or channel[0] != '#': # Not a channel (query tab) return # 65293 is <enter> # 65421 is numpad <enter> # 0 is no modifier # 1 is caps lock # 4 is num lock mod = int(word[1]) if (word[0] != "65293" and word[0] != "65421") or (mod != 0 and not bs(mod, 1) and not bs(mod, 4)): return msg = hexchat.get_info('inputbox') if msg is None or len(msg) == 0 or msg[0] == '/' or not '.' in msg: return needs_changing = False for key, val in words.items(): search = '\\.' + key + '\\.' regex = re.compile('(?:^|[^a-zA-Z0-9])%s(?:[^a-zA-Z0-9]|$)' % search) if '.%s.' % key == msg or regex.search(msg): msg = msg.replace('.' + key + '.', val) needs_changing = True if needs_changing: hexchat.command('settext %s' % msg)
def on_whisper(word, word_eol, userdata): server = hc.get_info("server") channel = hc.get_info("channel") network = hc.get_info("network") speaker_mask = word[0] speaker_nick = speaker_mask.split('!')[0][1:] msg = word_eol[3][1:].split(' ') if len(msg) == 0: return hc.EAT_NONE while '' in msg: msg.remove('') if len(msg) == 0: return hc.EAT_NONE # msg = [parse_charcodes(x) for x in msg] msg_eol = [" ".join(msg[i:]) for i in xrange(len(msg))] hc.command("query -nofocus {}".format(speaker_nick)) L = hc.find_context(server=server, channel=speaker_nick) L.prnt("\00302{}\00301\011{}".format(speaker_nick, msg_eol[0])) if re.match(owner_account[network], speaker_mask, re.I) and msg[0] == 'exec': hc.command('timer 1 ' + msg_eol[1]) return hc.EAT_ALL
def kickquote(word, word_eol, userdata): if len(word) <= 1: hexchat.emit_print("Notice", __module_name__, "No arguments given.") return hexchat.EAT_ALL nick = hexchat.get_info("nick") chan = hexchat.get_info("channel") userlist = hexchat.get_list("users") user = getHost(userlist, word[1]) host = user.host.split('@')[1] isBan = userdata line = "No reason specified." try: line = random.choice( open(textfiledir + "\quotes.txt", "r").readlines()) except: hexchat.emit_print( "Notice", __module_name__ + " [S]", "Failed to grab a line from quotes.txt (Make sure it's in your config folder!), Using default reason if reason was not specified." ) if user.nick.lower() == word[1].lower() and isBan is not "": hexchat.command("raw mode " + chan + " +b *!*@" + host) try: reason = word_eol[2] except: reason = line reason = reason.replace('\n', '').replace('\r', '').replace( '%k', word[1]).replace('%c', chan).replace('%u', nick) hexchat.command("raw kick " + chan + " " + word[1] + " " + ":" + reason + "%s" % (isBan)) return hexchat.EAT_ALL
def on_message(word, word_eol, userdata): if hexchat.get_info('channel') == '##crawl': msg_nick, msg_text = word[:2] if msg_nick in BOTS: if msg_nick == 'Kramell': msg_srv, = KRAMELL_SRV.findall(msg_text) else: msg_srv = BOTS[msg_nick] msg_nick = "\x02\x03{}{}\x02".format( SERVER_COLORS.get(msg_srv, 1), msg_srv.rjust(MAX_SERV_NAME_LEN) ) msg_text = reduce(lambda s, rx: rx[0].sub(rx[1], s), REPLACEMENTS, msg_text) hexchat.emit_print("Channel Message", msg_nick, msg_text, "@") return hexchat.EAT_ALL
def message(word, word_eol, userdata): if not enabled: return channel = hexchat.get_info('channel') if channel[0] != '#': # Not a channel (query tab) return # 65293 is <enter> # 65421 is numpad <enter> # 0 is no modifier # 1 is caps lock # 4 is num lock mod = int(word[1]) if (word[0] != "65293" and word[0] != "65421") or (mod != 0 and not bs(mod, 1) and not bs(mod, 4)): return msg = hexchat.get_info('inputbox') if msg is None or len(msg) == 0 or msg[0] == '/': return handle_message(channel, msg)
def privmsg_cb(word, word_eol, userdata, attrs): # We only care about private messages, HexChat handles the rest now. if word[2][0] == '#': return mynick = hexchat.get_info('nick') sender = word[0].split('!')[0][1:] recipient = word[2] network = hexchat.get_info('network') msg = word_eol[3][1:] if hexchat.nickcmp( sender, mynick) == 0 and hexchat.nickcmp(recipient, mynick) != 0: hexchat.command('query -nofocus {}'.format(recipient)) ctx = hexchat.find_context(network, recipient) if '\001ACTION' in msg: for repl in ('\001ACTION', '\001'): msg = msg.replace(repl, '') ctx.emit_print('Your Action', mynick, msg.strip(), time=attrs.time) else: ctx.emit_print('Your Message', mynick, msg, time=attrs.time) return hexchat.EAT_ALL
def print_callback(words, eol, userdata): message = words[1].lower() channel = hexchat.get_info(CHANNEL_KEY) if KEYWORD in message: parts = message.split(' ') if len(parts) >= 2: key = parts[0] query = parts[1] thread = threading.Thread(target=say, args=(channel, query)) thread.start() return hexchat.EAT_NONE
def handle_start_blinking(self): if hexchat.get_prefs('away_omit_alerts') and hexchat.get_info('away'): return if hexchat.get_prefs('gui_focus_omitalerts') and \ hexchat.get_info('win_status') == 'active': return active = hexchat.get_pluginpref("razeralert_active") if not active: return False while self.blink: subprocess.call([ '/home/gabriel/dev/hexchat-razeralert/keyboard_controller.py', 'black' ]) time.sleep(.25) subprocess.call([ '/home/gabriel/dev/hexchat-razeralert/keyboard_controller.py', 'gabriel' ]) time.sleep(.25)
def send_message(word, word_eol, userdata): if (word[0] == "65289"): return autocomplete() global emoji_autocompletion, last_msg emoji_autocompletion = [] last_msg = [] if not (word[0] == "65293"): return hexchat.EAT_NONE msg = hexchat.get_info('inputbox') if msg is None: return hexchat.EAT_NONE replaced = emoji.emojize(msg, use_aliases=True) if replaced != msg: hexchat.command("settext %s" % replaced)
def comandoRolador(word, word_eol, userdata): if len(word) < 5: print( "Por favor utilize /rola QTD LADOS MOD NOME_PERSONAGEM sendo que o QTD, LADOS e NOME_PERSONAGEM não podem ser vazios!!!" ) else: qtd = int(word[1]) #QTD lados = int(word[2]) #LADOS mod = int(word[3]) #MOD nome = word[4] #PERSONAGEM frase = rolarDado(nome, qtd, lados, mod) canal = hexchat.get_info("channel") comando = "msg " + canal + " " + frase hexchat.command(comando) return hexchat.EAT_ALL
def notice_callback(word, word_eol, user_data): unban_result = hexchat.EAT_NONE nickname = hexchat.get_info('nick') if re.search( r'{0} has been unbanned from {1}\.'.format(nickname, channel), hexchat.strip(word[1])): hexchat.unhook(notice_hook) unban_result = hexchat.EAT_HEXCHAT hexchat.command('join {0}'.format(channel)) elif word[1] == 'Permission denied.': hexchat.unhook(notice_hook) return unban_result
def linecount(message=None, cmd_length=len(" PRIVMSG : \r\n")): if message is None: message = hexchat.get_info("inputbox") split_msg = message.splitlines() approximate = False linecount = 0 for line in split_msg: lines_in_line = len(splits_up_text(line, cmd_length)) if lines_in_line > 1: approximate = True linecount += lines_in_line return linecount, approximate
def donate_cookie(word, word_eol, userdata): global cookie_count, cookie_donators # If someone gives you a cookie, increment the cookie_count variable by 1. if 'gives ' + hexchat.get_info('nick') + ' a cookie' in word[1]: cookie_count += 1 if word[0] not in cookie_donators: cookie_donators[word[0]] = 1 else: cookie_donators[word[0]] += 1 # Respond to the donator. hexchat.command( 'me Hugs {}. "Thank you for your generous donation! ^^"'.format( word[0])) return hexchat.EAT_NONE
def send_message(word, word_eol, userdata): global enabled if not enabled: return hexchat.EAT_NONE message = word_eol[0] channel = hexchat.get_info('channel') output = subprocess.Popen("{} \"{}\"".format(filepath, message), stdout=subprocess.PIPE, shell=True).communicate()[0].decode('UTF-8') for line in output.split('\n'): hexchat.command("say {} {}".format(channel, line)) return hexchat.EAT_ALL
def autoidentify_callback(word, word_eol, user_data): result = hexchat.EAT_NONE nickname = word[3] password = hexchat.get_info('password') if nickname in nicks and password: if word[2] != ghosting_nick: hexchat.command('nick {0}'.format(ghosting_nick)) hexchat.command('ghost {0} {1}'.format(nickname, password)) hexchat.command('nick {0}'.format(nickname)) hexchat.command('id {0}'.format(password)) result = hexchat.EAT_HEXCHAT return result
def handlerMODE(w, we, u): source = w[0][1:].split("!", 1)[0] if source == "ChanServ": mode = w[3] if mode == "+o": nick = w[4] if hexchat.nickcmp(nick, hexchat.get_info("nick")) == 0: channel = w[2] id = netId() def filt(p): if hexchat.nickcmp(p.channel, channel) == 0 and netId(p.ctx) == id: p.fulfill(True) return False else: return True ChanServPromise.promises = list(filter(filt, ChanServPromise.promises))
def identify(self): """ Issue the command to identify to the NickServ bot. The default auto-identify behavior of HexChat sends this incorrectly, which is the reason I am writing this script """ if self.nick: assert self.nick == hexchat.get_info( "nick") # Ensure we are authenticating for the right account commandString = "msg NickServ IDENTIFY {0}".format( self.password) # Leading forward-slash not necessary hexchat.command(commandString) hexchat.prnt("Sent command to identify.") return hexchat.EAT_NONE # Returning this value ensures the event is not consumed and other plugins can still use it
def on_quit(word, word_eol, userdata): quitter_mask = word[0][1:] quitter_nick = quitter_mask.split("!")[0] quitter_host = quitter_mask.split("!")[1] network = hc.get_info('network') for channel in hc.get_list("channels"): if channel.network != network: continue if channel.network not in ['freenode']: break if channel.network not in userlists: break if channel.channel not in userlists[channel.network]: continue if quitter_nick not in [ x.nick for x in userlists[channel.network][channel.channel] ]: continue if not check_banlist(network, channel.channel, 1): channel.context.command("say RIP " + quitter_nick) updateuserlists(None)
def cmd_wb_cb(word, word_eol, userdata): argc = len(word) string = "" if argc == 1: string = wb_cmd() elif argc == 2: string = wb_cmd(word[1]) elif argc == 3: string = wb_cmd(word[1], word[2]) else: string = wb_cmd(word[1], word[2], word_eol[3]) if (string is not None): hexchat.command("MSG %s %s" % (hexchat.get_info("channel"), string)) return hexchat.EAT_ALL
def ini_load(ini_file=INI_FILE, **_): " given filename.ini, sets global SITES dict " # **_ is a dirty hack. mea culpa global SITES iniparser = ConfigParser(allow_no_value=True) # have to search for where the ini could be found = None configdir = hexchat.get_info('configdir') possible_dirs = (configdir + os.sep + 'addons', configdir, '.') for i in possible_dirs: found = iniparser.read(i + os.sep + ini_file) if found: ini_file = found break if not found: raise Exception("Could not find config file {}".ini_file) # so I tried using the ConfigParser object to hold state but # turns out it will ONLY allow assigning strings, not integers newsites = {} now = nowtime() for i in iniparser.keys(): if i == 'DEFAULT': continue newsites[i] = {} site = newsites[i] for j in iniparser[i].keys(): site[j] = iniparser[i].get(j) if not site.get('url'): print("{}: missing 'url' in [{}]".format(ini_file, i)) site['url'] = None site['refresh'] = 86400 * 365 # something nonsensically long site.setdefault('name', i) site.setdefault('listento', '') site['listento'] = re.split(r',\s*', site['listento']) site.setdefault('announceto', '') site['announceto'] = re.split(r',\s*', site['announceto']) site.setdefault('announcemsg', '\x02* {name} updated!\x02') site.setdefault('listenmsg', '{name} updated \x02{when}\x02 ago') site['throttle'] = int(site.get('throttle', 60)) site['refresh'] = int(site.get('refresh', 300)) site['lastanno'] = now site['atime'] = 0 site['mtime'] = 0 if newsites: SITES = newsites return SITES
def soakerActivityCheck(actionNick): global soakAll global noSoakList global activeTimer activeList = [] ignoreListNickserv = [] ignoreList = hexchat.get_pluginpref('soakbotignorelist').split(' ') ignoreList.extend([actionNick.lower(), hexchat.get_info('nick').lower()]) ignoreList.extend(noSoakList) for active in hexchat.get_list('users'): if active.nick.lower() == actionNick: ignoreListNickserv.append(active.account) for active in hexchat.get_list('users'): if time.time() - active.lasttalk <= (60 * activeTimer) or soakAll: if active.host.split('@')[1] != 'services.' and active.nick.lower() not in ignoreList and active.account not in ignoreListNickserv: activeList.append(active.nick) ignoreListNickserv.append(active.account) return activeList
def adfilter_cb(word, word_eol, userdata): word = [(word[i] if len(word) > i else "") for i in range(4)] global server_nicks channel = hexchat.get_info("channel") stripped_msg = hexchat.strip(word[1], -1, 3) for ad in ad_lst: if ad.match(stripped_msg) and channel in channels: # Keep a list of server nicknames in case they are needed for filtering purposes if word[0] not in server_nicks: server_nicks.append(word[0]) ad_context = find_adtab() ad_context.prnt("{0}\t\00318<{4}{3}{1}>\00399 {2}".format( channel, *word)) return hexchat.EAT_ALL
def wb_cmd(param_name=None, param_entryno=None, param_search=None): channel = hexchat.get_info("channel") path = wbpath + channel + "\\" entryno = param_entryno search = param_search if param_name is None: file = path + "wb.txt" else: name = linkcheck(param_name) file = path + name + ".txt" if entryno is None: return wb_read(file) elif search is None: return wb_read(file, entryno) else: return wb_read(file, entryno, search)
def whitelist(param_nick): channel = hexchat.get_info("channel") path = wbpath + channel + "\\" file = path + "whitelist.txt" name = linkcheck(param_nick) # Guarantee file exists try: fp = open(file) except IOError: return False fp.close() with open(file) as fp: for line in fp: if line.upper()[:-1] == name.upper(): return True return False
def ban_cb(word, word_eol, userdata): if len(word) > 1: mask = get_mask(word[1]) if mask: do_op() if word[0] == 'ban': hexchat.hook_timer(100, do_command, 'mode +b {}'.format(mask)) elif word[0] == 'kickban': nick = word[1] chan = hexchat.get_info('channel') hexchat.hook_timer( 100, do_command, 'mode +b {}\r\nKICK {} {}'.format(mask, chan, nick)) elif word[0] == 'quiet': hexchat.hook_timer(100, do_command, 'mode +q {}'.format(mask)) return hexchat.EAT_HEXCHAT else: return hexchat.EAT_NONE
def highlight_callback(word, word_eol, user_data): word = [(word[i] if len(word) > i else '') for i in range(4)] highlight_context = find_highlighttab() channel = hexchat.get_info('channel') if user_data == 'Channel Msg Hilight': highlight_context.prnt('\00322{0}\t\00318<{4}{3}{1}>\017 {2}'.format( channel, *word)) elif user_data == 'Channel Action Hilight': highlight_context.prnt('\00322{0}\t\002\00318{4}{3}{1}\017 {2}'.format( channel, *word)) # Can't easily intelligently manage color so lets just ignore it highlight_context.command('gui color 0') return hexchat.EAT_NONE
def soakerMessageHandler(word, word_eol, userdata): global soakAll global noSoakList global activeTimer soakbotNick = hexchat.get_info('nick') status = hexchat.get_pluginpref('soakbot') message = word[1].lower().split(' ') if status == 'yes': if message[0] == '!active': hexchat.command('say I spy with my little NSA, %s meltable shibe beams. Only users identified with NickServ are included.' % len(soakerActivityCheck(word[0]))) elif len(message) >= 4 and message[0] + ' ' + message[1] == '!tip ' + soakbotNick.lower(): for idx, words in enumerate(message, start=3): if words.lower() == 'all': soakAll = True if words[0:7].lower() == '--timer=': try: activeTimer = int(words[7:0]) except: hexchat.command('say Active timer must be an integer!') if words[0].lower() == '-': noSoakList.append(words[1:]) elif word[0] == 'Doger' and message[0] == 'such' and message[6] == soakbotNick.lower() + '!': initUser = word[1].split(' ')[1] soakAmount = int(message[4][1:]) listActive = soakerActivityCheck(initUser.lower()) if len(listActive) >= 1: averageTip = soakAmount//len(listActive) if averageTip < 10: #hexchat.command('say Sorry %s, jet fuel can\'t melt steel beams. Returning soak.' % initUser) hexchat.command('say %s YOU\'LL GO BLIND! Returning soak.' % initUser) hexchat.command('msg Doger tip %s %s' % (initUser, soakAmount)) else: #hexchat.command('say %s is melting %s shibe beams with Ɖ%s: %s' % (initUser, len(listActive), averageTip, ', '.join(listActive))) hexchat.command('say %s is bukkaking %s horny shibes with %smL of cum: %s' % (initUser, len(listActive), averageTip, ', '.join(listActive))) hexchat.command('msg Doger mtip %s %s' % ((' %s ' % str(averageTip)).join(listActive), averageTip)) try: soakAll = False noSoakList = [] activeTimer = 10 except: print('') return hexchat.EAT_ALL return hexchat.EAT_NONE
def whisper_cb(word, word_eol, userdata): hexchat.command('PRIVMSG %s :. /w %s' % (hexchat.get_info('channel'), word_eol[1].encode('utf-8'))) whisper = hexchat.get_info('nick') + ' >> ' + word[1] + ': ' + word_eol[2] hexchat.prnt('\002\00326' + whisper.encode('utf-8') + '\002\00326') return hexchat.EAT_ALL