#!/usr/bin/env python3 # # Random commands that used to be in sopeltest.py but are to small to get a # file of their own. # # Copyright © 2019-2021 by luk3yx # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # import random, string, subprocess, time, unicodedata # A quick "reply" function def reply(irc, hostmask, channel, *msg): mention = hostmask[0] if not hostmask[0].endswith('>'): mention += ':' if isinstance(channel, list): channel = channel[0] irc.msg(channel, mention, *map(str, msg)) en_chars = string.ascii_uppercase + string.ascii_lowercase + \ '1234567890!@#$%^&*(),\'' alt_chars = 'ÅıÇδϩӈÔ˚Ò˜Ø∏Œ®Í†¨√∑≈ÁΩå∫ç∂´ƒ©˙ˆ∆˚¬µ˜øπœ®ß†¨√∑≈\Ω¡™£¢∞§¶•ªº' \ '⁄€‹›fifl‡°·‚≤æ' @register_command('altcode', requires_admin = True) def altcode_cmd(irc, hostmask, is_admin, args): """ Usage: .altcode [encode|decode] """ assert is_admin assert len(en_chars) == len(alt_chars), 'Internal error!' res = args[1] if res.startswith('encode '): res = res[7:] it = zip(en_chars, alt_chars) elif res.startswith('decode ') or any(i in res for i in alt_chars): it = zip(alt_chars, en_chars) else: it = zip(en_chars, alt_chars) for en, alt in it: res = res.replace(en, alt) reply(irc, hostmask, args, res) # Random capitalisation def randcaps(text): res = ''.join(random.choice((str.upper, str.lower))(i) for i in text) return res.replace('S', 'Z').replace('O', '0') # .silly @register_command('silly', 'sillycaps') def silly_cmd(irc, hostmask, is_admin, args): """ Makes the capitalisation in a string... strange. """ if args[1].strip(): reply(irc, hostmask, args, randcaps(args[1])) else: irc.msg(args[0], randcaps('{}nvalid syntax! Syntax:{}').format( 'I', ' .silly ')) # .c0mmandz @register_command('c0mmandz') def bonkerzhelp(irc, hostmask, is_admin, args): irc.msg(args[0], randcaps('Hello! You must be bonkers too!')) time.sleep(0.75) irc.msg(args[0], 'So snap out of it and do .commands.') # .upper and .lower @register_command('upper', 'uppercase') def upper_cmd(irc, hostmask, is_admin, args): """ Makes a string uppercase. """ reply(irc, hostmask, args, args[1].upper().replace('.', '!')) @register_command('lower', 'lowercase') def lower_cmd(irc, hostmask, is_admin, args): """ Makes a string lowercase. """ reply(irc, hostmask, args, args[1].lower().replace('!', '.')) @register_command('rev', 'reverse') def rev_cmd(irc, hostmask, is_admin, args): """ Reverses a string. """ if '\u202e' in args[1]: irc.msg(args[0], "I don't think so {}™.".format(hostmask[0])) else: reply(irc, hostmask, args, args[1][::-1]) @register_command('ping') def ping(irc, hostmask, is_admin, args): if not random.randint(0, 9): irc.me(args[0], 'slaps {} with a frying pan'.format(hostmask[0])) else: reply(irc, hostmask, args, 'pong') # .roulette roulette_objs = ('trout', '... feather?', 'water molecule', 'troutgun', 'anvil', 'sheet of paper') @register_command('roulette', 'r') def roulette_cmd(irc, hostmask, is_admin, args): """ A Russian roulette-style game. """ if random.randint(1, 6) == 1: obj = random.choice(roulette_objs) if not obj.startswith('.'): obj = ' ' + obj irc.me(args[0], 'slaps {} around a bit with a large{}'.format( hostmask[0], obj)) else: reply(irc, hostmask, args, '\x1dClick!\x1d') # .choice def choice_cmd(irc, hostmask, is_admin, args): choices = map(str.strip, args[-1].split(',' if ',' in args[-1] else ' ')) # Deduplication choices = {choice.casefold(): choice for choice in choices} choices = tuple(choices.values()) if len(choices) < 2: if not choices or not choices[0]: reply(irc, hostmask, args, 'Invalid syntax! Usage: .choice ' '') else: reply(irc, hostmask, args, 'I need more than one option to choose from!') return choice = random.choice(choices) reply(irc, hostmask, args, 'Your options: ' + ', '.join(choices) + '. My (random) choice: ' + choice) # Only register .choice on lurklite. if register_command.__module__.startswith('lurklite.'): register_command('choice', 'choose')(choice_cmd) def get_fortune(): n = subprocess.check_output('/usr/games/fortune').decode('utf-8') # Avoid bad and possibly offensive fortunes # This is only targeted at the fortunes provided by Ubuntu. i = 0 while ('ugly' in n or 'tall, dark' in n or 'pass away' in n or 'blond' in n or 'cigarette' in n or 'appeal' in n): n = subprocess.check_output('/usr/games/fortune').decode('utf-8') i += 1 assert i < 100 return n.strip().replace('\t', ' ') @register_command('f', 'fortune') def fortune_cmd(irc, hostmask, is_admin, args): reply(irc, hostmask, args, get_fortune()) @register_command('coin', 'coinflip') def coinflip_cmd(irc, hostmask, is_admin, args): if random.randint(0, 6000) == 0: msg = 'The coin landed on its side!' elif random.randint(0, 1): msg = 'Heads' else: msg = 'Tails' reply(irc, hostmask, args, msg) def get_char_name(char): # Hack to get the name of control characters. U+2400 is "SYMBOL FOR NULL" # and this function will remove the leading "SYMBOL FOR " prefix when a # null byte is passed to it. if char <= '\x1f': char = chr(ord(char) + 0x2400) return unicodedata.name(char)[11:] return unicodedata.name(char, 'Unknown') @register_command('chr', 'unicode', 'u') def unicode_cmd(irc, hostmask, is_admin, args): chars = args[1] if len(chars) > 10: msg = f'You must provide 1-10 characters, not {len(chars)}.' elif not chars: msg = 'Usage: .unicode ' else: msg = ', '.join(f'U+{ord(char):04X} - {get_char_name(char)}' for char in chars) reply(irc, hostmask, args, msg)