Ejemplo n.º 1
0
async def get_fighter_names(db_acc, channel):
    try:
        data = db_acc.execute(
            '''
            SELECT 
                name AS alias,
                name
            FROM 
                fighter.fighter
            UNION ALL
            SELECT
                fa.alias,
                f.name
            FROM
                fighter.fighter_alias fa
            INNER JOIN
                fighter.fighter f
                ON f.id = fa.fighter_id''', {})

        fighter_names = {
            data[i]["alias"]: data[i]["name"]
            for i in range(0, len(data))
        }

        return fighter_names
    except dberr.Error as e:
        print(e)
        #TODO: add user name
        await channel.send(DB_ERROR_MSG.format("Unknown"))
        raise
Ejemplo n.º 2
0
async def is_registered(db_acc, discord_id, channel):
    try:
        return db_acc.execute(
            '''
            SELECT 
                COUNT(1) as registered
            FROM 
                player 
            WHERE 
                discord_id = %(discord_id)s''',
            {"discord_id": discord_id})[0]["registered"] > 0
    except dberr.Error as e:
        print(e)
        await channel.send(DB_ERROR_MSG.format(user.id))
        raise
Ejemplo n.º 3
0
async def player_list(client, message, db_acc):
    channel = message.channel
    author = message.author
    rows = None

    try:
        rows = db_acc.execute(
            '''
            SELECT
                discord_id, switch_tag, switch_code
            FROM
                player.player p
            INNER JOIN
                player.guild_member g
                ON p.discord_id = g.player_discord_id
            WHERE
                g.guild_id=%(guild_id)s''', {"guild_id": channel.guild.id})
    except dberr.Error as e:
        print(e)
        await channel.send(DB_ERROR_MSG.format(author.mention))
        raise

    names = ''
    tags = ''
    codes = ''

    for row in rows:
        # TODO: guild is optional? maybe in PMs?
        #names += '{:<20}{:<22}\n'.format(message.guild.get_member(int(row[0])).display_name[:20], row[2])
        try:
            names += '{}\n'.format(
                message.guild.get_member(int(row["discord_id"])).display_name)
            #tags += '{}\n'.format(row[1])
            codes += '{}\n'.format(row["switch_code"])
        # Likely player no longer exists in server
        except Exception as e:
            print(e)
            continue

    embed = discord.Embed(color=embed_color)
    embed.set_author(name='Players in {}'.format(message.guild))
    embed.set_thumbnail(url=channel.guild.icon_url)
    #embed.add_field(name='{:<45}{:<17}'.format('Name', 'Switch Code'), value='```{}```'.format(names), inline=True)
    embed.add_field(name='Name', value=names, inline=True)
    embed.add_field(name='Switch Code', value=codes, inline=True)

    await channel.send(embed=embed)
Ejemplo n.º 4
0
async def update(client, message, db_acc):
    channel = message.channel
    author = message.author

    # Tokenize input
    tokens = message.content.split(' ')

    if len(tokens) < 3:
        await channel.send('8!update usage: 8!update <tag|code> <value>')
        return

    update_stmt = "SET "
    val = None

    if (tokens[1].lower() == "tag"):
        update_stmt += "switch_tag = %(val)s"
        val = ' '.join(tokens[2:])
    elif (tokens[1].lower() == "code"):
        if (len(tokens) > 3 or not tokens[2].lower().startswith('sw-')):
            await channel.send(
                'Note: Switch code should look like SW-####-####-####')
            return
        val = tokens[2]
        update_stmt += "switch_code = %(val)s"
    else:
        await channel.send(
            'Not sure what you\'re trying to do. Remember: 8!update usage: 8!update <tag|code> <value>'
        )
        return
    try:
        db_acc.execute_update(
            '''
            UPDATE player
                ''' + update_stmt + '''
            WHERE 
                discord_id = %(discord_id)s''', {
                "val": val,
                "discord_id": author.id
            })
    except dberr.Error as e:
        print(e)
        await channel.send(DB_ERROR_MSG.format(author.mention))
        raise

    await channel.send('Updated {}\'s profile.'.format(author.mention))
Ejemplo n.º 5
0
async def find_users_in_guild_by_switch_tag(db_acc, message, test_user_string,
                                            confidence_threshold):
    try:
        rows = db_acc.execute(
            '''
            SELECT 
                switch_tag,
                discord_id 
            FROM
                player p 
            INNER JOIN 
                guild_member g 
                ON p.discord_id = g.player_discord_id 
            WHERE 
                g.guild_id=%(guild_id)s''', {"guild_id": message.guild.id})
    except dberr.Error as e:
        print(e)
        await message.channel.send(DB_ERROR_MSG.format(message.author.mention))
        raise

    member_dict = {}
    for row in rows:
        member_dict[row["switch_tag"]] = row["discord_id"]

    confidence_list = process.extract(test_user_string,
                                      member_dict.keys(),
                                      scorer=fuzz.token_sort_ratio)
    return_list = []

    found_exact = False
    for (tag, confidence) in confidence_list:
        if tag == test_user_string:
            found_exact = True
            return_list.append(member_dict[tag])
        elif not found_exact and confidence > confidence_threshold:
            return_list.append(member_dict[tag])

    return return_list
Ejemplo n.º 6
0
async def send_profile(channel, db_acc, user):
    params = {"discord_id": user.id}
    rows = None
    try:
        rows = db_acc.execute('''
            SELECT
                switch_tag, switch_code
            FROM 
                player.player p
            WHERE 
                p.discord_id = %(discord_id)s''',
            params
        )
    except dberr.Error as e:
        print(e)
        await channel.send(DB_ERROR_MSG.format(user.mention))
        raise

    if rows is None or len(rows) == 0:
        await channel.send('{} hasn\'t registered yet. Tell them to get on it! (8!register)'.format(user.display_name))
        return
    prof_rec = rows[0]
    tag = prof_rec["switch_tag"]
    code = prof_rec["switch_code"]

    rows = None
    # get list of fighters used
    try:
        rows = db_acc.execute('''
            SELECT
                f.id,
                f.name,
                pf.is_main,
                pf.is_true_main,
                pf.is_pocket,
                pf.costume_number
            FROM 
                fighter.fighter f
            INNER JOIN 
                player.player_fighter pf
            ON 
                pf.fighter_id = f.id
            WHERE 
                pf.player_discord_id = %(discord_id)s
            ORDER BY
                CASE WHEN pf.is_true_main THEN 1 ELSE 0 END DESC,
                CASE WHEN pf.is_main THEN 1 ELSE 0 END DESC,
                CASE WHEN pf.is_pocket THEN 1 ELSE 0 END DESC,
                f.name''', 
            {
                "discord_id": user.id
            }
        )
    except dberr.Error as e:
        print(e)
        await channel.send(DB_ERROR_MSG.format(user.mention))
        raise

    fighters = [
        {
            "name": row["name"],
            "is_main": row["is_main"],
            "is_true_main": row["is_true_main"],
            "is_pocket": row["is_pocket"],
            "costume_number": row["costume_number"]
        }
        for row in rows
    ]
        
    embed = discord.Embed(color=embed_color)
    embed.set_author(name = user.display_name, icon_url=user.avatar_url)
    embed.add_field(name='Switch Tag', value=tag, inline=True)
    embed.add_field(name='Switch Code', value=code, inline=True)
    
    # If any fighters were found
    if(len(rows) > 0):
        try:
            #embed.add_field(name='Fighters', value=' ', inline=False)
            amalgam_url = create_stitched_image(fighters)
            embed.set_image(url=amalgam_url)
            embed.set_footer(text='Green "M" means "main"; Red "P" means "pocket"')
        # If creating the image fails, still post the profile just without the image
        except Exception as e:
            print(e)

    await channel.send(embed=embed)
Ejemplo n.º 7
0
async def who_plays(client, message, db_acc):
    channel = message.channel
    author = message.author

    tokens = message.content.split(' ')

    if len(tokens) < 2:
        await channel.send('8!whoplays usage: 8!whoplays <character>')
        return

    # Assume everything after is the fighter name
    test_fighter_string = ' '.join(tokens[1:])

    fighter_name, confidence = await find_fighter(db_acc, channel,
                                                  test_fighter_string)

    # Might want to fine tune this later, but 80 seems good
    if (confidence < 80):
        await channel.send(
            'I\'m really not sure who {} is. Remember: 8!whoplays usage: 8!whoplays <character>'
            .format(test_fighter_string))
        return

    try:
        rows = db_acc.execute(
            '''
            SELECT
                pf.player_discord_id as discord_id
            FROM
                player_fighter pf
            INNER JOIN
                fighter f
                ON f.id = pf.fighter_id
            INNER JOIN
                guild_member gm
                ON gm.player_discord_id = pf.player_discord_id
            WHERE 
                f.name=%(fighter_name)s AND
                gm.guild_id = %(guild_id)s''', {
                "fighter_name": fighter_name,
                "guild_id": channel.guild.id
            })

        #  msg = 'The following users play {}:\n\n'.format(fighter_name)
        msg = ''

        # Gross but cool list generators to concatenate user names
        users = [
            message.guild.get_member(int(row["discord_id"])) for row in rows
        ]
        msg += ', '.join([user.display_name for user in users])

    except dberr.Error as e:
        print(e)
        await channel.send(DB_ERROR_MSG.format(author.mention))
        raise

    embed = discord.Embed(color=embed_color,
                          description="No one." if msg == '' else msg)
    # Regex to remove ALL special characters from fighter name, then create url
    # Example: Pokemon Trainer becomes Pokmon Trainer due to special e
    embed.set_author(name="{} Players".format(fighter_name),
                     icon_url=fighter_icon_url(fighter_name))

    #embed.add_field(name='', value=tag, inline=True)
    await channel.send(embed=embed)
Ejemplo n.º 8
0
async def register(client, message, db_acc):
    channel = message.channel
    author = message.author
    record = None
    # Verify user hasn't registered for this server
    try:
        record = db_acc.execute(
            '''
            SELECT 
                COUNT(1) AS registered
            FROM 
                guild_member
            WHERE 
                player_discord_id = %(discord_id)s AND 
                guild_id = %(guild_id)s''', {
                "discord_id": author.id,
                "guild_id": channel.guild.id
            })[0]
    except dberr.Error as e:
        print(e)
        await channel.send(DB_ERROR_MSG.format(author.mention))
        raise

    if (record["registered"] > 0):
        await channel.send(
            '{}, you\'re already registered in this channel, silly!'.format(
                author.mention))
        return

    # See if user has been registered at all
    is_reg = await is_registered(db_acc, author.id, channel)

    # Tokenize input
    tokens = message.content.split(' ')

    # First time registration, wrong number of arguments
    if (not is_reg and len(tokens) != 3):
        await channel.send(
            '8!register usage: 8!register switch_tag switch_code')
        return
    # First time registration, wrong switch code format
    #TODO: use regex to enforce more rigid structure
    elif (not is_reg and not tokens[2].lower().startswith('sw-')):
        await channel.send(
            'Note: Switch code should look like SW-####-####-####')
        return
    # First time registration, correct input
    elif (not is_reg):
        tag = tokens[1]
        code = tokens[2].upper()
        await channel.send('Registering {} as {} with Switch code {}. Is this good? (Y/N)' \
            .format(author.mention, tag, code))

        def check(m):
            return m.author == author and m.channel == channel

        try:
            msg = await client.wait_for('message', check=check, timeout=15)

            if(msg.content.lower() != 'y' and msg.content.lower() != 'yes' \
                 and msg.content.lower() != '8!y'  and msg.content.lower() != '8!yes'):
                await channel.send('Not registering {}.'.format(author.mention)
                                   )
                return

            try:
                db_acc.execute_update(
                    '''
                    INSERT INTO 
                        player (discord_id, switch_tag, switch_code) 
                    VALUES
                        (%(discord_id)s, %(tag)s, %(code)s)''', {
                        "discord_id": author.id,
                        "tag": tag,
                        "code": code
                    })
            except dberr.Error as e:
                print(e)
                await channel.send(DB_ERROR_MSG.format(author.mention))
                raise
            await channel.send(
                'Registered {.author.mention} in the player database!'.format(
                    msg))
            if not isinstance(channel, discord.DMChannel):
                await channel.send(
                    'Try DMing me to set up the rest of your profile!')
        except asyncio.TimeoutError:
            await channel.send(
                'Time ran out to confirm. Try again, {}.'.format(
                    author.mention))
            return

    # Already registered or just registered, add them to this channel
    try:
        db_acc.execute_update(
            '''
            INSERT INTO 
                guild_member (player_discord_id, guild_id) 
            VALUES 
                (%(discord_id)s, %(guild_id)s)''', {
                "discord_id": author.id,
                "guild_id": channel.guild.id
            })
    except dberr.Error as e:
        print(e)
        await channel.send(DB_ERROR_MSG.format(author.mention))
        raise
    await channel.send(
        'Registered {.author.mention} in this server!'.format(message))
Ejemplo n.º 9
0
async def i_pocket(client, message, db_acc):
    channel = message.channel
    author = message.author

    tokens = message.content.split(' ')

    if len(tokens) < 2:
        await channel.send(
            '8!ipocket usage: 8!ipocket [add|remove] <character>')
        return

    remove_fighter = False

    # Figure out where the fighter name starts
    # to determine between 8!ipocket pit and 8!ipocket remove/add pit
    fighter_name_start_idx = 1

    if (tokens[1].lower() == "add"):
        fighter_name_start_idx = 2
    elif (tokens[1].lower() == "remove"):
        fighter_name_start_idx = 2
        remove_fighter = True

    if not remove_fighter:
        # First add character, if necessary
        await i_play(client, message, db_acc, False)

    # Assume everything after is the fighter name
    test_fighter_string = ' '.join(tokens[fighter_name_start_idx:])
    fighter_name, confidence = await find_fighter(db_acc, channel,
                                                  test_fighter_string)

    # Might want to fine tune this later, but 80 seems good
    if (confidence < 80):
        await channel.send(
            'I\'m really not sure who {} is. Remember: 8!ipocket usage: 8!ipocket [add/remove] <character>'
            .format(test_fighter_string))
        return

    if (not await is_registered(db_acc, author.id, channel)):
        await channel.send('Please register with 8!register first!')
        return
    # Adding or removing that you pocket this character
    else:
        try:
            db_acc.execute_update(
                '''
                UPDATE
                    player_fighter
                SET
                    is_main      = IF(%(set_pocket)s = 1, 0, is_main),
                    is_pocket    = %(set_pocket)s,
                    is_true_main = IF(%(set_pocket)s = 1, 0, is_true_main)
                WHERE 
                    player_discord_id = %(discord_id)s AND
                    fighter_id = (SELECT id FROM fighter WHERE name=%(name)s)''',
                {
                    "discord_id": author.id,
                    "name": fighter_name,
                    "set_pocket": 0 if remove_fighter else 1
                })
        except dberr.Error as e:
            print(e)
            await channel.send(DB_ERROR_MSG.format(author.mention))
            raise

        if remove_fighter:
            await channel.send('{0} no longer pockets {1}. If you want ' \
                           'to remove this character entirely, use 8!iplay remove {1}'.format(author.mention, fighter_name))
        else:
            await channel.send('I see, so {} pockets {}. {}'.format(
                author.mention, fighter_name, random_snarky_comment()))
Ejemplo n.º 10
0
async def i_play(client, message, db_acc, send_message=True):
    channel = message.channel
    author = message.author

    tokens = message.content.split(' ')

    if len(tokens) < 2:
        if send_message:
            await channel.send(
                '8!iplay usage: 8!iplay [add|remove] <character>')
        return

    remove_fighter = False

    # Figure out where the fighter name starts
    # to determine between 8!iplay pit and 8!iplay remove/add pit
    fighter_name_start_idx = 1

    if (tokens[1].lower() == "add"):
        fighter_name_start_idx = 2
    elif (tokens[1].lower() == "remove"):
        fighter_name_start_idx = 2
        remove_fighter = True

    # Assume everything after is the fighter name
    test_fighter_string = ' '.join(tokens[fighter_name_start_idx:])

    fighter_name, confidence = await find_fighter(db_acc, channel,
                                                  test_fighter_string)

    # Might want to fine tune this later, but 80 seems good
    if (confidence < 80):
        if send_message:
            await channel.send('I\'m really not sure who {} is. Remember: 8!iplay usage:' \
                           ' Check 8!help for command usage.'.format(test_fighter_string))
        return

    if (not await is_registered(db_acc, author.id, channel)):
        if send_message:
            await channel.send('Please register with 8!register first!')
        return

    # Removing that you play this character
    if (remove_fighter):
        try:
            db_acc.execute_update(
                '''
                DELETE FROM
                    player_fighter 
                WHERE 
                    player_discord_id = %(discord_id)s AND
                    fighter_id = (SELECT id FROM fighter WHERE name=%(name)s)''',
                {
                    "discord_id": author.id,
                    "name": fighter_name
                })
        except dberr.Error as e:
            print(e)
            if send_message:
                await channel.send(DB_ERROR_MSG.format(author.mention))
            raise
        if send_message:
            await channel.send('{} does not play {}, okay.'.format(
                author.mention, fighter_name))
    # Adding that you play this character
    else:
        try:
            db_acc.execute_update(
                '''
                INSERT INTO
                    player_fighter (player_discord_id, fighter_id, is_main, is_true_main)
                SELECT 
                    %(discord_id)s,
                    id as fighter_id,
                    0,
                    0
                FROM
                    fighter
                WHERE 
                    name=%(name)s''', {
                    "discord_id": author.id,
                    "name": fighter_name
                })
        except dberr.DuplicateKeyError as e:
            if send_message:
                await channel.send('I already know you play {}, {}!'.format(
                    fighter_name, author.mention))
            return
        except dberr.Error as e:
            print(e)
            if send_message:
                await channel.send(DB_ERROR_MSG.format(author.mention))
            raise

        if send_message:
            await channel.send('Okay, noted that {} plays {}. {}'.format(
                author.mention, fighter_name, random_snarky_comment()))
Ejemplo n.º 11
0
async def who_plays(client, message, db_acc):
    channel = message.channel
    author = message.author

    tokens = message.content.split(' ')

    if len(tokens) < 2:
        await channel.send('8!whoplays usage: 8!whoplays <character>')
        return

    # Assume everything after is the fighter name
    test_fighter_string = ' '.join(tokens[1:])

    fighter_name, confidence = await find_fighter(db_acc, channel,
                                                  test_fighter_string)

    # Might want to fine tune this later, but 80 seems good
    if (confidence < 80):
        await channel.send(
            'I\'m really not sure who {} is. Remember: 8!whoplays usage: 8!whoplays <character>'
            .format(test_fighter_string))
        return

    try:
        rows = db_acc.execute(
            '''
            SELECT
                pf.player_discord_id as discord_id
            FROM
                player.player_fighter pf
            INNER JOIN
                fighter.fighter f
                ON f.id = pf.fighter_id
            INNER JOIN
                player.guild_member gm
                ON gm.player_discord_id = pf.player_discord_id
            WHERE
                f.name=%(fighter_name)s AND
                gm.guild_id = %(guild_id)s''', {
                "fighter_name": fighter_name,
                "guild_id": channel.guild.id
            })

        msg = ''

        users = [
            message.guild.get_member(int(row["discord_id"])) for row in rows
        ]
        msg += ', '.join([user.display_name for user in users])

    except dberr.Error as e:
        print(e)
        await channel.send(DB_ERROR_MSG.format(author.mention))
        raise

    embed = discord.Embed(color=embed_color,
                          description="No one." if msg == '' else msg)
    embed.set_author(name="{} Players".format(fighter_name),
                     icon_url=fighter_icon_url(fighter_name))

    await channel.send(embed=embed)