Esempio n. 1
0
async def getCards(ch):
    C[ch]["black"] = []
    C[ch]["white"] = []

    async with aiosqlite.connect('packs.db') as db:

        async def getPack(pack):
            async with db.execute(
                    'select card from cards where pack=? and black=1',
                (pack, )) as cursor:
                b = await cursor.fetchall()
            async with db.execute(
                    'select card from cards where pack=? and black=0',
                (pack, )) as cursor:
                w = await cursor.fetchall()
            return b, w

        for p in C[ch]["packs"]:
            if p == "base":
                cards = await getPack(
                    'base') if C[ch]['lang'] == 'English' else await getPack(
                        languages[C[ch]['lang']])
                C[ch]["black"] += [x[0] for x in cards[0]]
                C[ch]["white"] += [x[0] for x in cards[1]]
            elif p in packs or p in thirdparty:
                cards = await getPack(p)
                C[ch]["black"] += [x[0] for x in cards[0]]
                C[ch]["white"] += [x[0] for x in cards[1]]
            else:
                b, w = api.get_deck_blacks_json(p), api.get_deck_whites_json(p)
                C[ch]["black"] += ['_'.join(c["text"]) for c in b]
                C[ch]["white"] += [''.join(c["text"]) for c in w]
Esempio n. 2
0
 async def removePack(self, ch, s):
     """Given a pack name, try to remove that pack."""
     
     s = s.strip()
     
     # CardCast
     try:
         if s in config.C[ch]['packs']:
             b, w = api.get_deck_blacks_json(s), api.get_deck_whites_json(s)
             config.C[ch]['black'] = [x for x in config.C[ch]['black'] if x not in ['_'.join(c['text']) for c in b]]
             config.C[ch]['white'] = [x for x in config.C[ch]['white'] if x not in [''.join(c['text']) for c in w]]
             
             config.C[ch]['packs'].remove(s)
             await self.client.send_message(ch, s + ' removed!')
     except:
         pass
     
     s = s.lower()
     
     for p in config.packs:
         if p in s and p in config.C[ch]['packs']:
             config.C[ch]['black'] = [x for x in config.C[ch]['black'] if x not in eval('config.black_'+p)]
             config.C[ch]['white'] = [x for x in config.C[ch]['white'] if x not in eval('config.white_'+p)]
             
             config.C[ch]['packs'].remove(p)
             await self.client.send_message(ch, config.packs[p] + ' removed!')
     for p in config.thirdparty:
         if p in s and p in config.C[ch]['packs']:
             config.C[ch]['black'] = [x for x in config.C[ch]['black'] if x not in eval('config.black_'+p)]
             config.C[ch]['white'] = [x for x in config.C[ch]['white'] if x not in eval('config.white_'+p)]
             
             config.C[ch]['packs'].remove(p)
             await self.client.send_message(ch, config.thirdparty[p] + ' removed!')
     
     # remove red, green, and blue expansions
     if s == 'rgb':
         await self.removePack(ch, 'redgreenblue')
     
     # remove base pack
     if 'base' in s and 'base' in config.C[ch]['packs']:
         config.C[ch]['black'] = [x for x in config.C[ch]['black'] if x not in config.black]
         config.C[ch]['white'] = [x for x in config.C[ch]['white'] if x not in config.white]
         config.C[ch]['packs'].remove('base')
         await self.client.send_message(ch, 'Base Cards Against Humanity removed!')
     
     # remove all packs
     if len(config.C[ch]['black']) * len(config.C[ch]['white']) == 0 or s == 'all':
         if config.C[ch]['lang'] == 'English':
             config.C[ch]['black'] = list(config.black)
             config.C[ch]['white'] = list(config.white)
         else:
             config.C[ch]['black'] = list(eval('config.black_'+config.languages[config.C[ch]['lang']]))
             config.C[ch]['white'] = list(eval('config.white_'+config.languages[config.C[ch]['lang']]))
         
         config.C[ch]['packs'] = ['base']
         await self.client.send_message(ch, 'No cards left. Reverting to base pack')
     
     await self.edit_start_msg(ch)
Esempio n. 3
0
def main():
    parser = OptionParser(version='%prog ' + __version__,
                          usage="%prog [options]")
    parser.add_option('-t', '--task', default=None, help='[REQUIRED] Valid tasks are [deckslist, deckinfo, cards, blacks, whites]')
    parser.add_option('-d', '--deck', default=None, help='The deck ID. REQUIRED for deckinfo, cards, blacks, and whites tasks, ignored otherwise.')
    parser.add_option('-a', '--author', default=None, help='A user name to search for. Used with the deckslist task, otherwise ignored.')
    parser.add_option('-c', '--category', default=None, help='A category to search for. Used with the deckslist task, otherwise ignored.')
    parser.add_option('-s', '--search', default=None, help='Keywords to search for. Used with the deckslist task, otherwise ignored.')
    parser.add_option('-n', '--num-results', default=constants.DECK_LIST_REQ_MAX_RESULTS, help='The number of results to return with the deckslist task. [default: %default]')
    parser.add_option('-o', '--offset', default=0, help='The number of decks to offset the result window returned by the deckslist task. [default: %default]')

    options, args = parser.parse_args()

    if not options.task:
        parser.print_help()
        exit(1)

    if not options.task in ['deckslist', 'deckinfo', 'cards', 'blacks', 'whites']:
        print('Invalid task specified: %s' % options.task)
        parser.print_help()
        exit(2)

    if options.task in ['deckinfo', 'cards', 'blacks', 'whites']:
        if not options.deck:
            print('Task %s requires a deck ID to be specified using the -d option.' % options.task)
            parser.print_help()
            exit(3)

        if options.task == 'deckinfo':
            print(api.get_deck_info_json(options.deck))
        elif options.task == 'cards':
            print(api.get_deck_cards_json(options.deck))
        elif options.task == 'blacks':
            print(api.get_deck_blacks_json(options.deck))
        elif options.task == 'whites':
            print(api.get_deck_whites_json(options.deck))
    else:
        print(api.get_deck_list_json(search=options.search, author=options.author, category=options.category, limit=options.num_results, offset=options.offset))
Esempio n. 4
0
    async def addPack(self, ch, s):
        """Given a pack name, try to add that pack."""

        s = s.strip()

        success = total = added = 0

        # CardCast
        try:
            if s not in config.C[ch]['packs']:
                b, w = api.get_deck_blacks_json(s), api.get_deck_whites_json(s)
                config.C[ch]['black'] += ['_'.join(c['text']) for c in b]
                config.C[ch]['white'] += [''.join(c['text']) for c in w]

                config.C[ch]['packs'].append(s)

                success += 1
                total += 1
            else:
                added += 1
                total += 1
        except:
            pass

        s = s.lower()

        # add all official packs
        if s == 'all':
            await self.addPack(ch, ''.join(x for x in config.packs))
            return

        # add all third party packs
        if s == '3rdparty' or s == 'thirdparty':
            await self.addPack(ch, ''.join(x for x in config.thirdparty))
            return

        # add the red, green, and blue expansions
        if s == 'rgb':
            await self.addPack(ch, 'redbluegreen')
            return

        for p in config.packs:
            if p == 'cats' and s.count('cats') == s.count('cats2'):
                continue

            if p in s:
                total += 1
                if p not in config.C[ch]['packs']:
                    config.C[ch]['black'] += list(eval('config.black_' + p))
                    config.C[ch]['white'] += list(eval('config.white_' + p))

                    config.C[ch]['packs'].append(p)

                    success += 1
                else:
                    added += 1
        for p in config.thirdparty:
            if p in s:
                total += 1
                if p not in config.C[ch]['packs']:
                    config.C[ch]['black'] += list(eval('config.black_' + p))
                    config.C[ch]['white'] += list(eval('config.white_' + p))

                    config.C[ch]['packs'].append(p)

                    success += 1
                else:
                    added += 1

        if total:
            msg = 'Successfully added ' + str(success) + ' out of ' + str(
                total) + (' packs' if total > 1 else ' pack')
            if added:
                msg += '\n' + str(added) + (' packs' if added > 1 else
                                            ' pack') + ' already added'
            await self.client.send_message(ch, msg)
            await self.edit_start_msg(ch)
Esempio n. 5
0
    async def on_message(self, message):
        #if (time.time() / 3600) - last_update > 1:
        #    await self.client.change_presence(game=discord.Game(name='on '+'_'*4+' servers. ' + str(len(client.servers))+'.'))
        #    config.last_update = time.time() / 3600

        msg = message.content.lower()
        ch = message.channel
        au = message.author

        c = config.pre[ch.id] if ch.id in config.pre else 'c'

        # ignore own messages
        if au.id == '429024440060215296':
            return

        # fill in blank cards
        if self.shard == 0:
            if ch.is_private:
                # check for c!p or c!play
                if len(msg) > 3 and msg[:3] == c + '!p':
                    await self.client.send_message(
                        au,
                        'Please play your card(s) in the corresponding channel and not as a private message.'
                    )
                    return

                found = False
                if au in config.P:  # check that user has a blank card
                    for c in config.P[
                            au]:  # check all channels that user is in
                        if config.C[c]['started'] and au in config.C[c][
                                'players']:  # check that user is currently playing
                            i = config.C[c]['players'].index(au)
                            if '' in config.C[c]['hands'][
                                    i]:  # check that player has a blank
                                found = True
                                j = config.C[c]['hands'][i].index('')
                                config.C[c][
                                    'hands'][i][j] = message.content.replace(
                                        '*', '\*').replace('_', '\_').replace(
                                            '~', '\~').replace('`', '\`')
                                await self.sendHand(c, i)
                                break
                if not found:
                    edited_msg = message.content.replace('*', '\*').replace(
                        '_', '\_').replace('~', '\~').replace('`', '\`')
                    for i in range(1, self.num_shards):
                        async with aiosqlite.connect(
                                'messages{0}.db'.format(i)) as conn:
                            C = await conn.cursor()
                            await C.execute(
                                """insert into Messages values (?, ?)""",
                                (au.id, edited_msg))
                            await conn.commit()

                return

        # ignore irrelevant messages
        if not (len(msg) > 2 and msg[:2] == c + '!'):
            return

        if ch not in config.C:
            config.C[ch] = {}
            await config.initChannel(ch)

        # warning
        if len(
                msg
        ) > 9 and msg[:9] == c + '!warning' and au.id == '252249185112293376':
            for x in config.C:
                if config.C[x]['started']:
                    await self.client.send_message(x, message.content[9:])
        # check number of ongoing games
        if msg == c + '!ongoing' and au.id == '252249185112293376':
            nC = 0
            for x in config.C:
                if config.C[x]['started']:
                    nC += 1
            await self.client.send_message(ch, str(nC))
        # save state
        if (msg == c + '!save'
                or msg == c + '!savestate') and au.id == '252249185112293376':
            self.save_state()

        # changelog
        if msg == c + '!whatsnew' or msg == c + '!update' or msg == c + '!updates':
            s = info.changelog
            await self.client.send_message(ch, s[:s.index('**9/27')])

        # commands list
        if msg == c + '!commands' or msg == c + '!command':
            await self.client.send_message(ch, info.commands)

        # support server
        if msg == c + '!support' or msg == c + '!server' or msg == c + '!supp':
            await self.client.send_message(ch, 'https://discord.gg/qGjRSYQ')

        # FAQ
        if msg == c + '!faq':
            await self.client.send_message(ch, 'https://goo.gl/p9j2ve')

        # invite link
        if msg == c + '!invite':
            await self.client.send_message(
                ch,
                'Use this link to invite the bot to your own server:\n<https://discordapp.com/api/oauth2/authorize?client_id=429024440060215296&permissions=134294592&scope=bot>'
            )

        # vote link
        if msg == c + '!vote':
            await self.client.send_message(
                ch,
                'Use this link to vote for the bot on discordbots.org:\n<https://discordbots.org/bot/429024440060215296/vote>'
            )

        # shard
        if msg == c + '!shard':
            await self.client.send_message(ch, str(self.shard))

        # custom prefix setting
        if len(msg
               ) == 10 and msg[:9] == c + '!prefix ' and 'a' <= msg[9] <= 'z':
            await self.client.send_message(
                ch, 'Command prefix set to `' + msg[9] + '`!')
            config.pre[ch.id] = msg[9]
            with open('prefix.txt', 'a') as f:
                f.write(ch.id + ' ' + msg[9] + '\n')

        if not config.C[ch]['started']:
            # language change
            for l in config.languages:
                if msg == c + '!language ' + l.lower():
                    if config.C[ch]['lang'] != l:
                        config.C[ch]['lang'] = l
                        config.C[ch]['black'] = list(
                            eval('config.black_' + config.languages[l]))
                        config.C[ch]['white'] = list(
                            eval('config.white_' + config.languages[l]))
                        await self.client.send_message(
                            ch, 'Language changed to ' + l + '.')
                        await self.edit_start_msg(ch)

            if msg == c + '!help':
                await self.client.send_message(ch, (
                    "Use `{0}!start` to start a game of Cards Against Humanity, or `{0}!cancel` to cancel an existing one.\n"
                    "Use `{0}!commands` to bring up a list of available commands.\n"
                    "For a list of frequently asked questions and general directions, use `{0}!faq`."
                ).format(c))
            elif msg == c + '!language english':
                if config.C[ch]['lang'] != 'English':
                    config.C[ch]['lang'] = 'English'
                    config.C[ch]['black'] = config.black
                    config.C[ch]['white'] = config.white
                    await self.client.send_message(
                        ch, 'Language changed to English.')
                    await self.edit_start_msg(ch)
            elif msg == c + '!start':
                if not config.C[ch]['playerMenu']:
                    config.C[ch]['playerMenu'] = True
                    config.C[ch]['players'].append(au)
                    s = await self.get_start_msg(ch)
                    config.C[ch]['msg'] = await self.client.send_message(ch, s)
                    output = str(len(
                        config.C[ch]['players'])) + '/20 Players: '
                    output += ', '.join(usr.display_name
                                        for usr in config.C[ch]['players'])
                    await self.client.send_message(ch, output)
                elif 2 <= len(config.C[ch]['players']) <= 20:
                    config.C[ch]['playerMenu'] = False
                    config.C[ch]['nPlayers'] = len(config.C[ch]['players'])
                    await self.start_(ch)

                    await self.client.send_message(
                        ch, 'Game is starting!\n' +
                        ' '.join(usr.mention
                                 for usr in config.C[ch]['players']))

                    config.C[ch]['msg'] = None
                    await self.displayMid(ch)
            elif len(msg) > 8 and msg[:8] == c + '!setwin':
                try:
                    n = int(msg[8:].strip())
                    if n > 0:
                        config.C[ch]['win'] = n
                        await self.client.send_message(
                            ch,
                            'Number of points needed to win has been set to ' +
                            str(n) + '.')
                        await self.edit_start_msg(ch)
                except:
                    pass
            elif len(msg) > 7 and msg[:7] == c + '!timer':
                try:
                    n = int(msg[7:].strip())
                    if n >= 15:
                        config.C[ch]['timer'] = n
                        await self.client.send_message(
                            ch, 'Idle timer set to ' + str(n) + ' seconds.')
                        await self.edit_start_msg(ch)
                    elif n == 0:
                        config.C[ch]['timer'] = n
                        await self.client.send_message(
                            ch, 'Idle timer is now disabled.')
                        await self.edit_start_msg(ch)
                    else:
                        await self.client.send_message(
                            ch, 'Please choose a minimum of 15 seconds.')
                except:
                    pass
            elif len(msg) > 10 and msg[:10] == c + '!settimer':
                try:
                    n = int(msg[10:].strip())
                    if n >= 15:
                        config.C[ch]['timer'] = n
                        await self.client.send_message(
                            ch, 'Idle timer set to " + str(n) + " seconds.')
                        await self.edit_start_msg(ch)
                    elif n == 0:
                        config.C[ch]['timer'] = n
                        await self.client.send_message(
                            ch, 'Idle timer is now disabled.')
                        await self.edit_start_msg(ch)
                    else:
                        await self.client.send_message(
                            ch, 'Please choose a minimum of 15 seconds.')
                except:
                    pass
            elif len(msg) > 10 and msg[:10] == c + '!setblank':
                try:
                    n = int(msg[10:].strip())
                    if 0 <= n <= 30:
                        config.C[ch]['blanks'] = n
                        await self.client.send_message(
                            ch,
                            'Number of blanks has been set to ' + str(n) + '.')
                        await self.edit_start_msg(ch)
                except:
                    pass
            elif msg == c + '!packs':
                output = (
                    "**List of available packs:**\n"
                    "(pack code followed by name of pack, then number of black and white cards)\n"
                    "----------\n")
                for p in config.packs:
                    output += '**'+p+'** - ' + config.packs[p] \
                        + ' (' + str(len(eval('config.black_'+p))) + '/' + str(len(eval('config.white_'+p))) + ')\n'
                await self.client.send_message(ch, output)
                output = '\nThird party packs:\n'
                for p in config.thirdparty:
                    output += '**'+p+'** - ' + config.thirdparty[p] \
                        + ' (' + str(len(eval('config.black_'+p))) + '/' + str(len(eval('config.white_'+p))) + ')\n'
                output += (
                    "\nUse `{0}!add <code>` to add a pack, or use `{0}!add all` to add all available packs.\n"
                    "(Note: this will only add official CAH packs; use `{0}!add thirdparty` to add all third party packs.)\n"
                    "Use `{0}!contents <code>` to see what cards are in a specific pack."
                ).format(c)
                await self.client.send_message(ch, output)
            elif len(msg) > 10 and msg[:10] == c + '!contents':
                pk = message.content[10:].strip()

                # check for CardCast packs
                try:
                    b, w = api.get_deck_blacks_json(
                        pk), api.get_deck_whites_json(pk)
                    deck_b = ['_'.join(c['text']) for c in b]
                    deck_w = [''.join(c['text']) for c in w]

                    output = '**Cards in ' + api.get_deck_info_json(
                        pk)['name'] + '** (code: ' + pk + ')**:**\n\n'
                    output += '**Black cards:** (' + str(len(deck_b)) + ')\n'
                    for c in deck_b:
                        output += '- ' + c + '\n'
                        if len(output) > 1500:
                            await self.client.send_message(
                                ch, output.replace('_', '\_' * 3))
                            output = ''
                    output += '\n**White cards:** (' + str(len(deck_w)) + ')\n'
                    for c in deck_w:
                        output += '- ' + c + '\n'
                        if len(output) > 1500:
                            await self.client.send_message(
                                ch, output.replace('_', '\_' * 3))
                            output = ''
                    await self.client.send_message(
                        ch, output.replace('_', '\_' * 3))

                    return
                except:
                    pass

                # check built-in packs
                pk = pk.lower()
                if pk in config.packs or pk in config.thirdparty:
                    output = ''
                    if pk in config.packs:
                        output = '**Cards in ' + config.packs[pk] + ':**\n\n'
                    elif pk in config.thirdparty:
                        output = '**Cards in ' + config.thirdparty[
                            pk] + ':**\n\n'

                    output += '**Black cards:** (' + str(
                        len(eval('config.black_' + pk))) + ')\n'
                    for c in eval('config.black_' + pk):
                        output += '- ' + c + '\n'
                        if len(output) > 1500:
                            await self.client.send_message(
                                ch, output.replace('_', '\_' * 3))
                            output = ''
                    output += '\n**White cards:** (' + str(
                        len(eval('config.white_' + pk))) + ')\n'
                    for c in eval('config.white_' + pk):
                        output += '- ' + c + '\n'
                        if len(output) > 1500:
                            await self.client.send_message(
                                ch, output.replace('_', '\_' * 3))
                            output = ''
                    await self.client.send_message(
                        ch, output.replace('_', '\_' * 3))
            elif msg == c + '!cancel':
                if config.C[ch]['playerMenu']:
                    config.C[ch]['playerMenu'] = False
                    config.C[ch]['players'] = []
                    await self.client.send_message(ch, 'Game cancelled!')

            if config.C[ch]['playerMenu']:
                curr = len(config.C[ch]['players'])
                if msg == c + '!join':
                    if au not in config.C[ch]['players']:
                        config.C[ch]['players'].append(au)
                elif msg == c + '!leave':
                    if au in config.C[ch]['players']:
                        config.C[ch]['players'].remove(au)
                if curr != len(config.C[ch]['players']):
                    output = str(len(
                        config.C[ch]['players'])) + '/20 Players: '
                    output += ', '.join(usr.display_name
                                        for usr in config.C[ch]['players'])
                    await self.client.send_message(ch, output)
                if len(msg) > 6 and msg[:6] == c + '!add ' and config.C[ch][
                        'lang'] == 'English':
                    await self.addPack(ch, message.content[6:])
                if len(msg) > 9 and msg[:9] == c + '!remove ' and config.C[ch][
                        'lang'] == 'English':
                    await self.removePack(ch, message.content[9:])
                elif len(msg) > 5 and msg[:5] == c + '!rm ' and config.C[ch][
                        'lang'] == 'English':
                    await self.removePack(ch, message.content[5:])
        else:
            if msg == c + '!help':
                await self.client.send_message(ch, (
                    "To play white cards, use `{0}!play` followed by the letters next to the cards you want to play. "
                    "For example, `{0}!play b` would play card B, and `{0}!play df` would play cards D and F.\n"
                    "If you're the czar, react with the letter of your choice once everyone has played their cards.\n"
                    "To reset an ongoing game, use `{0}!reset`.\n"
                    "To leave an ongoing game, use `{0}!leave` or `{0}!quit`.\n"
                    "To join an ongoing game, use `{0}!join`.\n"
                    "To kick an AFK player, use `{0}!kick <player>`."
                ).format(c))

            # player commands
            if au in config.C[ch]['players']:
                if msg == c + '!display':
                    config.C[ch]['msg'] = None
                    await self.displayMid(ch)
                    return
                elif msg == c + '!leave' or msg == c + '!quit':
                    if not config.done(ch):
                        await self.removePlayer(ch, au)
                    else:
                        await self.client.send_message(
                            ch,
                            'Please wait for the czar to pick a card before leaving.'
                        )
                elif len(msg) > 7 and msg[:7] == c + '!kick ':
                    mt = message.content[7:].strip()  # player to kick
                    if mt == au.mention:
                        await self.client.send_message(
                            ch,
                            'You cannot kick yourself. To leave the game, use `'
                            + c + '!leave`.')
                    else:
                        for i in range(len(config.C[ch]['players'])):
                            p = config.C[ch]['players'][i]
                            if mt == p.mention:
                                if not config.C[ch]['played'][i]:
                                    config.C[ch]['kick'][config.C[ch][
                                        'players'].index(au)] = p.mention
                                    cnt = config.C[ch]['kick'].count(p.mention)
                                    await self.client.send_message(ch, au.mention + ' has voted to kick ' + p.mention + '. ' \
                                        + str(cnt) + '/' + str(config.C[ch]['nPlayers']-1) + ' votes needed')
                                    if cnt == config.C[ch]['nPlayers'] - 1:
                                        await self.client.send_message(
                                            ch, p.mention +
                                            ' has been kicked from the game.')
                                        await self.removePlayer(ch,
                                                                p,
                                                                kick=True)
                                else:
                                    await self.client.send_message(
                                        ch,
                                        'This player has already played and cannot be kicked.'
                                    )

                                break
                elif msg == c + '!reset':
                    await config.reset(ch)
                    await self.client.send_message(ch, 'Game reset!')
                    return
            else:
                if msg == c + '!join':
                    if not config.done(ch):
                        await self.addPlayer(ch, au)
                    else:
                        await self.client.send_message(
                            ch,
                            'Please wait for the czar to pick an answer before joining.'
                        )

            # playing cards
            if len(msg) > 6 and msg[:6] == c + '!play':
                await self.play(ch, au, msg[6:])
                try:
                    await self.client.delete_message(message)
                except:
                    pass
            elif len(msg) > 4 and msg[:4] == c + '!p ':
                await self.play(ch, au, msg[4:])
                try:
                    await self.client.delete_message(message)
                except:
                    pass

            # admin override
            if au.id == '252249185112293376' or au.permissions_in(
                    ch).administrator:
                if msg == c + '!display':
                    config.C[ch]['msg'] = None
                    await self.displayMid(ch)
                elif msg == c + '!reset':
                    await config.reset(ch)
                    await self.client.send_message(ch, 'Game reset!')
Esempio n. 6
0
def main():
    parser = OptionParser(version='%prog ' + __version__,
                          usage="%prog [options]")
    parser.add_option(
        '-t',
        '--task',
        default=None,
        help=
        '[REQUIRED] Valid tasks are [deckslist, deckinfo, cards, blacks, whites]'
    )
    parser.add_option(
        '-d',
        '--deck',
        default=None,
        help=
        'The deck ID. REQUIRED for deckinfo, cards, blacks, and whites tasks, ignored otherwise.'
    )
    parser.add_option(
        '-a',
        '--author',
        default=None,
        help=
        'A user name to search for. Used with the deckslist task, otherwise ignored.'
    )
    parser.add_option(
        '-c',
        '--category',
        default=None,
        help=
        'A category to search for. Used with the deckslist task, otherwise ignored.'
    )
    parser.add_option(
        '-s',
        '--search',
        default=None,
        help=
        'Keywords to search for. Used with the deckslist task, otherwise ignored.'
    )
    parser.add_option(
        '-n',
        '--num-results',
        default=constants.DECK_LIST_REQ_MAX_RESULTS,
        help=
        'The number of results to return with the deckslist task. [default: %default]'
    )
    parser.add_option(
        '-o',
        '--offset',
        default=0,
        help=
        'The number of decks to offset the result window returned by the deckslist task. [default: %default]'
    )

    options, args = parser.parse_args()

    if not options.task:
        parser.print_help()
        exit(1)

    if not options.task in [
            'deckslist', 'deckinfo', 'cards', 'blacks', 'whites'
    ]:
        print('Invalid task specified: %s' % options.task)
        parser.print_help()
        exit(2)

    if options.task in ['deckinfo', 'cards', 'blacks', 'whites']:
        if not options.deck:
            print(
                'Task %s requires a deck ID to be specified using the -d option.'
                % options.task)
            parser.print_help()
            exit(3)

        if options.task == 'deckinfo':
            print(api.get_deck_info_json(options.deck))
        elif options.task == 'cards':
            print(api.get_deck_cards_json(options.deck))
        elif options.task == 'blacks':
            print(api.get_deck_blacks_json(options.deck))
        elif options.task == 'whites':
            print(api.get_deck_whites_json(options.deck))
    else:
        print(
            api.get_deck_list_json(search=options.search,
                                   author=options.author,
                                   category=options.category,
                                   limit=options.num_results,
                                   offset=options.offset))
Esempio n. 7
0
    async def on_message(self, message):
        #if (time.time() / 3600) - last_update > 1:
        #    await self.client.change_presence(game=discord.Game(name='on '+'_'*4+' servers. ' + str(len(client.guilds))+'.'))
        #    config.last_update = time.time() / 3600

        msg = message.content.lower()
        ch = message.channel
        au = message.author

        c = config.pre[ch.id] if ch.id in config.pre else 'c'

        # ignore own messages
        if au.id == 429024440060215296:
            return

        # fill in blank cards
        if isinstance(ch, discord.abc.PrivateChannel):
            # check for c!p or c!play
            if msg.startswith(c + '!p'):
                await au.send(
                    'Please play your card(s) in the corresponding channel and not as a private message.'
                )
                return

            # iterate through all users with blank cards
            for p in config.P:
                if p.id == au.id:
                    for c in config.P[p]:
                        if config.C[c]['started'] and au in config.C[c][
                                'players']:  # check that user is currently playing
                            i = config.C[c]['players'].index(au)
                            if '' in config.C[c]['hands'][
                                    i]:  # check that player has a blank
                                j = config.C[c]['hands'][i].index('')
                                config.C[c][
                                    'hands'][i][j] = message.content.replace(
                                        '*', '\*').replace('_', '\_').replace(
                                            '~', '\~').replace('`', '\`')
                                await self.sendHand(c, i)
                                break
            return

        # ignore irrelevant messages
        if not msg.startswith(c + '!'):
            return

        if ch not in config.C:
            config.C[ch] = {}
            await config.initChannel(ch)

        # warning
        if msg.startswith(c + '!warning') and au.id == 252249185112293376:
            for x in config.C:
                if config.C[x]['started']:
                    await x.send(message.content[9:])
        # check number of ongoing games
        if msg == c + '!ongoing' and (au.id == 252249185112293376
                                      or au.id == 413516816137322506):
            nC = 0
            for x in config.C:
                if config.C[x]['started']:
                    nC += 1
            await ch.send(str(nC))
        # save state
        if (msg == c + '!save'
                or msg == c + '!savestate') and au.id == 252249185112293376:
            self.save_state()
        # number of servers
        if msg == c + '!servers' and (au.id == 252249185112293376
                                      or au.id == 413516816137322506):
            await ch.send(str(len(self.client.guilds)))
#         # eval
#         if message.content.startswith(c+'!eval') and au.id == 252249185112293376:
#             try:
#                 print(eval(message.content[6:].strip()))
#                 await ch.send(str(eval(message.content[6:].strip())))
#             except:
#                 pass

# changelog
        if msg == c + '!whatsnew' or msg == c + '!update' or msg == c + '!updates':
            s = info.changelog
            await ch.send(s[:s.index('**9/27')])

        # commands list
        if msg == c + '!commands' or msg == c + '!command':
            await ch.send(info.commands)

        # support server
        if msg == c + '!support' or msg == c + '!server' or msg == c + '!supp':
            await ch.send('https://discord.gg/qGjRSYQ')

        # FAQ
        if msg == c + '!faq':
            await ch.send('https://goo.gl/p9j2ve')

        # invite link
        if msg == c + '!invite':
            await ch.send(
                'Use this link to invite the bot to your own server:\n<https://discordapp.com/api/oauth2/authorize?client_id=429024440060215296&permissions=134294592&scope=bot>'
            )

        # vote link
        if msg == c + '!vote':
            await ch.send(
                'Use this link to vote for the bot on discordbots.org:\n<https://discordbots.org/bot/429024440060215296/vote>'
            )

        # donation links
        if msg == c + '!donate':
            await ch.send(
                'Help support the bot:\n<http://buymeacoffee.com/sourmongoose>\n<https://paypal.me/sourmongoose>'
            )

        # custom prefix setting
        if len(msg
               ) == 10 and msg[:9] == c + '!prefix ' and 'a' <= msg[9] <= 'z':
            await ch.send('Command prefix set to `' + msg[9] + '`!')
            config.pre[ch.id] = msg[9]
            with open('prefix.txt', 'a') as f:
                f.write(str(ch.id) + ' ' + msg[9] + '\n')

        if not config.C[ch]['started']:
            # language change
            for l in config.languages:
                if msg == c + '!language ' + l.lower():
                    if config.C[ch]['lang'] != l:
                        config.C[ch]['lang'] = l
                        await ch.send('Language changed to ' + l + '.')
                        await self.edit_start_msg(ch)

            if msg == c + '!help':
                await ch.send((
                    "Use `{0}!start` to start a game of Cards Against Humanity, or `{0}!cancel` to cancel an existing one.\n"
                    "Use `{0}!commands` to bring up a list of available commands.\n"
                    "For a list of frequently asked questions and general directions, use `{0}!faq`."
                ).format(c))
            elif msg == c + '!language english':
                if config.C[ch]['lang'] != 'English':
                    config.C[ch]['lang'] = 'English'
                    await ch.send('Language changed to English.')
                    await self.edit_start_msg(ch)
            elif msg == c + '!start':
                if not config.C[ch]['playerMenu']:
                    config.C[ch]['playerMenu'] = True
                    config.C[ch]['players'].append(au)
                    s = await self.get_start_msg(ch)
                    config.C[ch]['msg'] = await ch.send(s)
                    output = str(len(
                        config.C[ch]['players'])) + '/20 Players: '
                    output += ', '.join(usr.display_name
                                        for usr in config.C[ch]['players'])
                    await ch.send(output)
                elif 2 <= len(config.C[ch]['players']) <= 20:
                    config.C[ch]['playerMenu'] = False
                    config.C[ch]['nPlayers'] = len(config.C[ch]['players'])
                    await self.start_(ch)

                    await ch.send('Game is starting!\n' +
                                  ' '.join(usr.mention
                                           for usr in config.C[ch]['players']))

                    config.C[ch]['msg'] = None
                    await self.displayMid(ch)
            elif msg.startswith(c + '!setwin'):
                try:
                    n = int(msg[8:].strip())
                    if n > 0:
                        config.C[ch]['win'] = n
                        await ch.send(
                            f'Number of points needed to win has been set to {n}.'
                        )
                        await self.edit_start_msg(ch)
                except:
                    pass
            elif msg.startswith(c + '!timer') or msg.startswith(c +
                                                                '!settimer'):
                #await ch.send('Idle timer is currently disabled.')
                try:
                    n = int(msg[msg.index('timer') + 5:].strip())
                    if n >= 15:
                        config.C[ch]['timer'] = n
                        await ch.send(f'Idle timer set to {n} seconds.')
                        await self.edit_start_msg(ch)
                    elif n == 0:
                        config.C[ch]['timer'] = n
                        await ch.send('Idle timer is now disabled.')
                        await self.edit_start_msg(ch)
                    else:
                        await ch.send('Please choose a minimum of 15 seconds.')
                except:
                    pass
            elif msg.startswith(c + '!blank') or msg.startswith(c +
                                                                '!setblank'):
                #await ch.send('Blank cards are currently disabled.')
                try:
                    n = int(msg[msg.index('blank') + 5:].strip())
                    if 0 <= n <= 30:
                        config.C[ch]['blanks'] = n
                        await ch.send(f'Number of blanks has been set to {n}.')
                        await self.edit_start_msg(ch)
                    elif n > 30:
                        await ch.send('Please choose a maximum of 30 cards.')
                except:
                    pass
            elif msg == c + '!packs':
                output = (
                    "**List of available packs:**\n"
                    "(pack code followed by name of pack, then number of black and white cards)\n"
                    "----------\n")
                for p in config.packs:
                    cnt = await config.getCount(p)
                    output += f'**{p}** - {config.packs[p]} ({cnt[0]}/{cnt[1]})\n'
                await ch.send(output)
                output = '\nThird party packs:\n'
                for p in config.thirdparty:
                    cnt = await config.getCount(p)
                    output += f'**{p}** - {config.thirdparty[p]} ({cnt[0]}/{cnt[1]})\n'
                output += (
                    "\nUse `{0}!add <code>` to add a pack, or use `{0}!add all` to add all available packs.\n"
                    "(Note: this will only add official CAH packs; use `{0}!add thirdparty` to add all third party packs.)\n"
                    "Use `{0}!contents <code>` to see what cards are in a specific pack."
                ).format(c)
                await ch.send(output)
            elif msg.startswith(c + '!contents'):
                pk = message.content[10:].strip()

                # check for CardCast packs
                try:
                    b, w = api.get_deck_blacks_json(
                        pk), api.get_deck_whites_json(pk)
                    deck_b = ['_'.join(c['text']) for c in b]
                    deck_w = [''.join(c['text']) for c in w]

                    output = '**Cards in ' + api.get_deck_info_json(
                        pk)['name'] + '** (code: ' + pk + ')**:**\n\n'
                    output += '**Black cards:** (' + str(len(deck_b)) + ')\n'
                    for c in deck_b:
                        output += '- ' + c + '\n'
                        if len(output) > 1500:
                            await ch.send(output.replace('_', '\_' * 3))
                            output = ''
                    output += '\n**White cards:** (' + str(len(deck_w)) + ')\n'
                    for c in deck_w:
                        output += '- ' + c + '\n'
                        if len(output) > 1500:
                            await ch.send(output.replace('_', '\_' * 3))
                            output = ''
                    await ch.send(output.replace('_', '\_' * 3))

                    return
                except:
                    pass

                # check built-in packs
                pk = pk.lower()
                if pk in config.packs or pk in config.thirdparty:
                    output = ''
                    if pk in config.packs:
                        output = '**Cards in ' + config.packs[pk] + ':**\n\n'
                    elif pk in config.thirdparty:
                        output = '**Cards in ' + config.thirdparty[
                            pk] + ':**\n\n'

                    cnt = await config.getCount(pk)
                    cards = await config.getPack(pk)
                    output += f'**Black cards:** ({cnt[0]})\n'
                    for card in cards[0]:
                        output += '- ' + card[0] + '\n'
                        if len(output) > 1500:
                            await ch.send(output.replace('_', '\_' * 3))
                            output = ''
                    output += f'\n**White cards:** ({cnt[1]})\n'
                    for card in cards[1]:
                        output += '- ' + card[0] + '\n'
                        if len(output) > 1500:
                            await ch.send(output.replace('_', '\_' * 3))
                            output = ''
                    await ch.send(output.replace('_', '\_' * 3))
            elif msg == c + '!cancel':
                if config.C[ch]['playerMenu']:
                    config.C[ch]['playerMenu'] = False
                    config.C[ch]['players'] = []
                    await ch.send('Game cancelled!')

            if config.C[ch]['playerMenu']:
                curr = len(config.C[ch]['players'])
                if msg == c + '!join':
                    if au not in config.C[ch]['players']:
                        config.C[ch]['players'].append(au)
                elif msg == c + '!leave':
                    if au in config.C[ch]['players']:
                        config.C[ch]['players'].remove(au)
                if curr != len(config.C[ch]['players']):
                    output = str(len(
                        config.C[ch]['players'])) + '/20 Players: '
                    output += ', '.join(usr.display_name
                                        for usr in config.C[ch]['players'])
                    await ch.send(output)
                if len(msg) > 6 and msg[:6] == c + '!add ' and config.C[ch][
                        'lang'] == 'English':
                    await self.addPack(ch, message.content[6:])
                if len(msg) > 9 and msg[:9] == c + '!remove ' and config.C[ch][
                        'lang'] == 'English':
                    await self.removePack(ch, message.content[9:])
                elif len(msg) > 5 and msg[:5] == c + '!rm ' and config.C[ch][
                        'lang'] == 'English':
                    await self.removePack(ch, message.content[5:])
            else:
                if msg == c + '!join' or (len(msg) > 6
                                          and msg[:6] == c + '!add '):
                    await ch.send(
                        'Use `c!start` to start a game before joining or adding packs.'
                    )
        else:
            if msg == c + '!help':
                await ch.send((
                    "To play white cards, use `{0}!play` followed by the letters next to the cards you want to play. "
                    "For example, `{0}!play b` would play card B, and `{0}!play df` would play cards D and F.\n"
                    "If you're the czar, react with the letter of your choice once everyone has played their cards.\n"
                    "To reset an ongoing game, use `{0}!reset`.\n"
                    "To leave an ongoing game, use `{0}!leave` or `{0}!quit`.\n"
                    "To join an ongoing game, use `{0}!join`.\n"
                    "To kick an AFK player, use `{0}!kick <player>`.\n"
                    "To re-display the scoreboard, use `{0}!display`."
                ).format(c))

            # player commands
            if au in config.C[ch]['players']:
                if msg == c + '!display':
                    config.C[ch]['msg'] = None
                    await self.displayMid(ch)
                    return
                elif msg == c + '!leave' or msg == c + '!quit':
                    if not config.done(ch):
                        await self.removePlayer(ch, au)
                    else:
                        await ch.send(
                            'Please wait for the czar to pick a card before leaving.'
                        )
                elif msg.startswith(c + '!kick'):
                    mt = message.content[6:].strip()  # player to kick
                    if mt == au.mention:
                        await ch.send(
                            'You cannot kick yourself. To leave the game, use `'
                            + c + '!leave`.')
                    else:
                        for i in range(len(config.C[ch]['players'])):
                            p = config.C[ch]['players'][i]
                            if mt == p.mention:
                                if not config.C[ch]['played'][i]:
                                    config.C[ch]['kick'][config.C[ch][
                                        'players'].index(au)] = p.mention
                                    cnt = config.C[ch]['kick'].count(p.mention)
                                    await ch.send(au.mention + ' has voted to kick ' + p.mention + '. ' \
                                        + str(cnt) + '/' + str(config.C[ch]['nPlayers']-1) + ' votes needed')
                                    if cnt == config.C[ch]['nPlayers'] - 1:
                                        await ch.send(
                                            p.mention +
                                            ' has been kicked from the game.')
                                        await self.removePlayer(ch,
                                                                p,
                                                                kick=True)
                                else:
                                    await ch.send(
                                        'This player has already played and cannot be kicked.'
                                    )

                                break
                elif msg == c + '!reset':
                    await config.reset(ch)
                    await ch.send('Game reset!')
                    return
            else:
                if msg == c + '!join':
                    if not config.done(ch):
                        await self.addPlayer(ch, au)
                    else:
                        await ch.send(
                            'Please wait for the czar to pick an answer before joining.'
                        )

            # playing cards
            if msg.startswith('c!play'):
                await self.play(ch, au, msg[6:])
                try:
                    await message.delete()
                except:
                    pass
            elif msg.startswith(c + '!p '):
                await self.play(ch, au, msg[4:])
                try:
                    await message.delete()
                except:
                    pass

            # admin override
            if au.id == 252249185112293376 or au.permissions_in(
                    ch).administrator:
                if msg == c + '!display':
                    config.C[ch]['msg'] = None
                    await self.displayMid(ch)
                elif msg == c + '!reset':
                    await config.reset(ch)
                    await ch.send('Game reset!')