Exemplo n.º 1
0
    async def on_reaction_add(self, reaction, user):
        ch = reaction.message.channel

        if (ch not in config.C) or (not config.C[ch]['started']):
            return

        czar = config.C[ch]['players'][config.C[ch]['pov']]
        letters = [
            '\U0001F1E6', '\U0001F1E7', '\U0001F1E8', '\U0001F1E9',
            '\U0001F1EA', '\U0001F1EB', '\U0001F1EC', '\U0001F1ED',
            '\U0001F1EE', '\U0001F1EF'
        ][:config.C[ch]['nPlayers'] - 1]

        if config.done(ch) and config.C[ch][
                'msg'] != None and reaction.message.content == config.C[ch][
                    'msg'].content and czar == user:
            if reaction.emoji in letters:
                try:
                    p = config.C[ch]['mid'][letters.index(reaction.emoji)][1]

                    config.C[ch]['score'][p] += 1

                    msg = czar.display_name + ' selected ' + 'ABCDEFGHIJ'[
                        letters.index(reaction.emoji)] + '.\n'
                    msg += config.C[ch]['players'][
                        p].display_name + ' wins the round!'
                    await self.client.send_message(ch, msg)
                    await self.pass_(ch)

                    if config.C[ch]['win'] in config.C[ch]['score']:
                        await self.displayWinners(ch)
                        await config.reset(ch)
                except:
                    print('\nError with answer selection\n' + time.asctime() +
                          '\n')
Exemplo n.º 2
0
    async def play(self, ch, p, s):
        s = s.strip().replace(' ',
                              '').replace(',',
                                          '').replace('<',
                                                      '').replace('>', '')

        # check that player is in current game
        try:
            player = config.C[ch]['players'].index(p)
        except:
            return

        if config.C[ch]['played'][player] or player == config.C[ch]['pov']:
            return

        try:
            newMid = []
            for x in s:
                card = config.C[ch]['hands'][player]['abcdefghijkl'.index(x)]
                if card in newMid:
                    return
                # check for blank
                if card == '':
                    await self.client.send_message(
                        p,
                        "You tried to send a blank card without filling it in first!\nMessage me what you'd like to put in the blank."
                    )
                    return
                newMid.append(card)

            if len(newMid) == config.nCards(ch):
                config.C[ch]['mid'].append([newMid, player])
                for c in newMid:
                    #config.C[ch]['white'].append(c)
                    config.C[ch]['hands'][player].remove(c)
                config.C[ch]['played'][player] = True
                await self.client.send_message(ch,
                                               p.display_name + ' has played!')
            else:
                await self.client.send_message(
                    p, 'This prompt requires ' + str(config.nCards(ch)) +
                    ' white card(s).')
                return

            # update kicks
            for k in range(len(config.C[ch]['kick'])):
                if config.C[ch]['kick'][k] == p.mention:
                    config.C[ch]['kick'][k] = ''

            # all players are done
            if config.done(ch):
                random.shuffle(config.C[ch]['mid'])
                config.C[ch]['time'] = time.time()

            await self.displayMid(ch)
        except:
            pass
Exemplo n.º 3
0
    async def removePlayer(self, ch, p, kick=False):
        if p in config.C[ch]['players']:
            i = config.C[ch]['players'].index(p)

            if config.C[ch]['played'][i]:
                await self.client.send_message(
                    ch,
                    'You have already played your cards and may not leave.')
                return

            for s in ['players', 'played', 'hands', 'score', 'kick']:
                config.C[ch][s].pop(i)

            if i < config.C[ch]['pov']:
                config.C[ch]['pov'] -= 1

            config.C[ch]['nPlayers'] = len(config.C[ch]['players'])
            config.C[ch]['pov'] %= config.C[ch]['nPlayers']

            # update cards already in the middle
            for j in range(len(config.C[ch]['mid'])):
                if config.C[ch]['mid'][j][1] > i:
                    config.C[ch]['mid'][j][1] -= 1

            # all players are done
            if config.done(ch):
                random.shuffle(config.C[ch]['mid'])

            if not kick:
                await self.client.send_message(
                    ch, p.display_name + ' has left the game.')
            await self.displayMid(ch)
        if config.C[ch][
                'nPlayers'] < 2:  # number of players has been reduced to 1
            await config.reset(ch)
            await self.client.send_message(
                ch, 'Not enough players, game has been reset.')
Exemplo n.º 4
0
    async def timer_check(self):
        await self.client.wait_until_ready()

        while not self.client.is_closed:
            start_time = time.time()

            channels = list(config.C.keys())
            for ch in channels:
                if config.C[ch]['started'] and 'time' in config.C[ch]:
                    if config.C[ch]['timer'] != 0 and time.time(
                    ) - config.C[ch]['time'] >= config.C[ch]['timer']:
                        if config.done(ch):
                            try:
                                # pick random letter
                                l = len(config.C[ch]['mid'])
                                if l == 0:
                                    return
                                else:
                                    letter = random.randint(0, l - 1)

                                p = config.C[ch]['mid'][letter][1]
                                config.C[ch]['score'][p] += 1

                                msg = "**TIME'S UP!**\nThe bot randomly selected " + 'ABCDEFGHIJ'[
                                    letter] + '.\n'
                                msg += config.C[ch]['players'][
                                    p].display_name + ' wins the round!'
                                await self.client.send_message(ch, msg)
                                await self.pass_(ch)

                                if config.C[ch]['win'] in config.C[ch][
                                        'score']:
                                    await self.displayWinners(ch)
                                    await config.reset(ch)
                            except Exception as e:
                                print('Error at', time.asctime())
                                print(e)
                                # unknown channel/missing access
                                if 'unknown' in str(e).lower(
                                ) or 'missing' in str(e).lower():
                                    config.C.pop(ch)
                        else:
                            await self.client.send_message(
                                ch,
                                "**TIME'S UP!**\nFor those who haven't played, cards will be automatically selected."
                            )

                            N = config.nCards(ch)
                            for p in range(len(config.C[ch]['players'])):
                                if not config.C[ch]['played'][
                                        p] and config.C[ch]['pov'] != p:
                                    cards = ''
                                    for c in range(
                                            len(config.C[ch]['hands'][p])):
                                        if config.C[ch]['hands'][p][c]:
                                            cards += 'abcdefghijkl'[c]
                                            if len(cards) == N:
                                                await self.play(
                                                    ch,
                                                    config.C[ch]['players'][p],
                                                    cards)
                                                break

            # debug
            elapsed_time = time.time() - start_time
            if elapsed_time > 2:
                print('timer_check: {0}'.format(time.time() - start_time))
            #print('number of channels: {0}'.format(len(channels)))

            await asyncio.sleep(2)
Exemplo 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!')
Exemplo n.º 6
0
    async def displayMid(self, ch):
        # don't display if not enough players
        if config.C[ch]['nPlayers'] < 2: return

        msg = '─' * 20 + '\n'
        for i in range(config.C[ch]['nPlayers']):
            msg += config.C[ch]['players'][i].display_name + ' - ' + str(
                config.C[ch]['score'][i])
            if config.C[ch]['played'][i] and not config.done(ch):
                msg += ' **Played!**'
            elif config.C[ch]['pov'] == i:
                msg += ' **Czar**'
            msg += '\n'

        if config.C[ch]['win'] not in config.C[ch]['score']:
            msg += '\nCurrent Czar: ' + config.C[ch]['players'][
                config.C[ch]['pov']].mention + '\n\n'
            msg += 'Black card:\n' + config.C[ch]['curr'].replace(
                '_', '\_' * 5) + '\n'

        if config.done(ch):
            msg += '\n'
            for m in range(len(config.C[ch]['mid'])):
                msg += '**' + 'ABCDEFGHIJKL'[m] + ')** '
                for card in config.C[ch]['mid'][m][0]:
                    msg += card + '\n'

        msg += '─' * 20

        try:
            #em = discord.Embed(description=msg, colour=0xBBBBBB)
            if config.C[ch]['msg'] == None or config.done(ch):
                #config.C[ch]['msg'] = await self.client.send_message(ch, embed=em)
                config.C[ch]['msg'] = await self.client.send_message(ch, msg)
                config.C[ch]['time'] = time.time()
            else:
                #await self.client.edit_message(config.C[ch]['msg'], embed=em)
                await self.client.edit_message(config.C[ch]['msg'], msg)
        except:
            print('Error in displayMid() at\n' + time.asctime() + '\n')
            c = config.pre[ch.id] if ch.id in config.pre else 'c'
            await self.client.send_message(
                ch,
                'Encountered error while displaying - answer selection may not function normally. If the czar is unable to select, try using `'
                + c + '!display`.')
            return

        if config.done(ch):
            letters = [
                '\U0001F1E6', '\U0001F1E7', '\U0001F1E8', '\U0001F1E9',
                '\U0001F1EA', '\U0001F1EB', '\U0001F1EC', '\U0001F1ED',
                '\U0001F1EE', '\U0001F1EF'
            ]
            error_occured = False
            for i in range(config.C[ch]['nPlayers'] - 1):
                try:
                    await self.client.add_reaction(config.C[ch]['msg'],
                                                   letters[i])
                except:
                    if not error_occured:
                        error_occured = True
                        await self.client.send_message(
                            ch,
                            'An error occurred while adding a letter; if the letter of your choice is not shown, please choose it by adding the letter manually.'
                        )