예제 #1
0
def deposit(user, amt):
    """
    Deposits coins into a user's account.

    :param user: the user ID string or User object to give funds to
    :param amt: the amount of funds to give
    :return: a string containing a success/failure message to be sent to the
    Discord channel where the command was issued
    """
    if hasattr(user, "id"):
        mention = user.mention
        user = user.id
    else:
        mention = "<@" + user + ">"

    try:
        amt = int(amt)
    except ValueError:
        return "You can only give amounts that are whole numbers " + mention + "!"

    balance = db.child("users").child(user).child("balance").get().val()

    if amt <= 0:
        return "Can't deposit a negative/zerp amount into " + mention + "'s account!"
    else:
        db.child("users").child(user).child("balance").set(balance + amt)
        return "<:chumcoin:337841443907305473> x" + str(
            amt) + "  :arrow_right:  " + mention
예제 #2
0
def withdraw(user, amt):
    """
    Withdraws coins from a user's account. Checks to make sure the user has sufficient funds.

    :param user: the user ID string or User object to withdraw funds from
    :param amt: the amount of funds to withdraw
    :return: a string containing a success/failure message to be sent to the
    Discord channel where the command was issued
    """
    if hasattr(user, "id"):
        mention = user.mention
        user = user.id
    else:
        mention = "<@" + user + ">"

    try:
        amt = int(amt)
    except ValueError:
        return "You can only take amounts that are whole numbers " + mention + "!"

    balance = db.child("users").child(user).child("balance").get().val()

    if amt <= 0:
        return "Can't take a negative/zero amount from " + mention + "'s account!"
    elif amt > balance:
        return "That's more than " + mention + "'s account has!"
    else:
        db.child("users").child(user).child("balance").set(balance - amt)
        return "<@" + user + ">  :arrow_right:  <:chumcoin:337841443907305473> x" + str(
            amt)
예제 #3
0
def update_lotto_status(server, state):
    """
    Updates the lottery-in-progress status of a server.

    :param server: the server ID
    :param state: the state to set (True if a lottery is in progress)
    """
    db.child("lotteries").child(server.id).child("lottoInProgress").set(state)
예제 #4
0
def reset_deal_attempts(user):
    """
    Resets a users deal attempts to 0.

    :param user: the user ID string or User object to reset attempts for
    """
    if hasattr(user, "id"):
        user = user.id

    db.child("cooldowns").child(user).child("dealAttempts").set(0)
예제 #5
0
def push_bot_response(msg, response):
    """
    Pushes a response from the bot to an analytics datapoint.

    :param msg: the message the bot is responding to
    :param response: the response the bot has given
    """

    db.child("analytics").child(msg.server.id).child("commands").child(
        msg.id).child("botResponses").push(response)
예제 #6
0
def set_deal_status(user, status):
    """
    Sets the deal status of a user.

    :param user: the user ID string or User object to set the status for
    :param status: the status to set. True indicates the user is in a deal
    """
    if hasattr(user, "id"):
        user = user.id

    db.child("users").child(user).child("isInDeal").set(status)
예제 #7
0
def update_last_nodeal_time(user):
    """
    Sets the last time a user rejected a deal to the current time.

    :param user: the user ID string or User object to update the time for
    """
    if hasattr(user, "id"):
        user = user.id

    db.child("cooldowns").child(user).child("lastDealRejection").set(
        int(time.time()))
예제 #8
0
def award_medal(user, medal):
    """
    Awards a medal to a user.

    :param user: the user ID string or User object to award the medal to
    :param medal: the medal to award
    """
    if hasattr(user, "id"):
        user = user.id

    db.child("users").child(user).child("medals").child(medal).set(True)
예제 #9
0
def take_medal(user, medal):
    """
    Takes a medal from a user.

    :param user: the user ID string or User object to take the medal from
    :param medal: the medal to take
    """
    if hasattr(user, "id"):
        user = user.id

    db.child("users").child(user).child("medals").child(medal).set(False)
예제 #10
0
def update_user_metadata(user):
    """
    Updates the username for the user.

    :param user: the User object to update the username for
    """

    db.child("users").child(user.id).child("metadata").child("userName").set(
        user.name)
    db.child("users").child(
        user.id).child("metadata").child("discriminator").set(
            user.discriminator)
예제 #11
0
def get_cooldown_multiplier(user):
    """
    Currently unused. Gets the current cooldown time multiplier for a user.

    :param user: the user ID string or User object to get the multiplier of
    :return: the current multiplier
    """
    if hasattr(user, "id"):
        user = user.id

    print(
        "Got mult: " +
        str(db.child("cooldowns").child(user).child("multiplier").get().val()))

    return db.child("cooldowns").child(user).child("multiplier").get().val()
예제 #12
0
def adjust_cooldown_multiplier(user, dealstarttime):
    """
    Determines whether to increase or decrease a user's cooldown multiplier based on how long they have waited between
    making deals. If a user has waited longer than the "patience time" the multiplier is reduced by 0.1, otherwise it
    is increased by 0.1. If the multiplier is already at 1.0 it will not be reduced further.

    :param user: the user ID string or User object to adjust the multiplier for
    :param dealstarttime: the time the current deal was started as a Unix timestamp
    """
    print("Adjusting mult")
    if hasattr(user, "id"):
        user = user.id

    cooldownend = get_cooldown_end_time(user)
    print("End: " + str(cooldownend))
    if cooldownend is not None:
        print("There is an end time!")
        currentmultiplier = db.child("cooldowns").child(user).child(
            "multiplier").get().val()
        if currentmultiplier is None:
            currentmultiplier = 1.0
            db.child("cooldowns").child(user).child("multiplier").set(
                currentmultiplier)

        if dealstarttime - cooldownend > patiencerange:
            if not currentmultiplier == 1.0:
                print("Decreasing cooldown")
                db.child("cooldowns").child(user).child("multiplier").set(
                    round(currentmultiplier - 0.1, 1))
            else:
                print("Leaving mult at 1.0")
        else:
            print("Increasing cooldown")
            db.child("cooldowns").child(user).child("multiplier").set(
                round(currentmultiplier + 0.1, 1))
예제 #13
0
def get_lotto_status(server):
    """
    Gets the lottery-in-progress status of a server.

    :param server: the server ID
    :return: True if a lottery is in progress
    """
    return db.child("lotteries").child(
        server.id).child("lottoInProgress").get().val()
예제 #14
0
def get_deal_attempts(user):
    """
    Gets the number of deal attempts for a user.

    :param user: the user ID string or User object to get attempts for
    :return: the number of attempts
    """
    if hasattr(user, "id"):
        user = user.id

    return db.child("cooldowns").child(user).child("dealAttempts").get().val()
예제 #15
0
def is_in_deal(user):
    """
    Checks the deal status of a user.

    :param user: the user ID string or User object to check the status of
    :return: True if the user is in a deal
    """
    if hasattr(user, "id"):
        user = user.id

    return db.child("users").child(user).child("isInDeal").get().val()
예제 #16
0
def get_balance(user):
    """
    Gets a user's coin balance.

    :param user: the user ID string or User object to get the balance for
    :return: the user's balance as an int
    """
    if hasattr(user, "id"):
        user = user.id

    return db.child("users").child(user).child("balance").get().val()
예제 #17
0
def get_cooldown_end_time(user):
    """
    Gets the timestamp for the end time of a user's cooldown.

    :param user: the user ID string or User object to get the cooldown end of
    :return: a Unix timestamp of the end time for the user's cooldown
    """
    if hasattr(user, "id"):
        user = user.id

    return db.child("cooldowns").child(user).child("cooldownEnd").get().val()
예제 #18
0
def get_last_nodeal_time(user):
    """
    Gets the last time a user rejected a deal.

    :param user: the user ID string or User object to get the time for
    :return: the time as a Unix timestamp
    """
    if hasattr(user, "id"):
        user = user.id

    return db.child("cooldowns").child(user).child(
        "lastDealRejection").get().val()
예제 #19
0
def update_deal_attempts(user):
    """
    Updates the number of times a user has rejected a deal. If there is no recorded last rejection or no recorded
    attempts the number is set to 1.

    :param user: the user ID string or User object to set attempts for
    """
    if hasattr(user, "id"):
        user = user.id

    if get_last_nodeal_time(user) is not None and int(
            time.time()) - get_last_nodeal_time(user) <= cooldowntime:
        attempts = db.child("cooldowns").child(user).child(
            "dealAttempts").get().val()

        if attempts is None:
            attempts = 1
        else:
            attempts = attempts + 1

        db.child("cooldowns").child(user).child("dealAttempts").set(attempts)
    else:
        db.child("cooldowns").child(user).child("dealAttempts").set(1)
예제 #20
0
def update_cooldown_end(user):
    """
    Gets the current time and adds the cooldown length to it. Stores the result at cooldowns/user/cooldownEnd in the
    database.

    :param user: the user ID string or User object to set the cooldown end for
    """
    if hasattr(user, "id"):
        user = user.id

        now = int(time.time())
        print("Base end time: " + (str(now + cooldowntime)))
        multiplier = db.child("cooldowns").child(user).child(
            "multiplier").get().val()
        print("Mult: " + str(multiplier))

        try:
            db.child("cooldowns").child(user).child("cooldownEnd").set(
                now + (cooldowntime * multiplier))
        except ValueError:
            print("Mult error!")
            db.child("cooldowns").child(user).child("cooldownEnd").set(
                now + cooldowntime)
예제 #21
0
def check_for_funds(user, amt):
    """
    Checks if a user has sufficient funds for a given amount.

    :param user: the user ID string or User object to check the funds of
    :param amt: the amount of funds to check for
    :return: True if the user has sufficient funds
    """
    if hasattr(user, "id"):
        user = user.id

    currentbalance = db.child("users").child(user).child(
        "balance").get().val()
    return currentbalance >= amt
예제 #22
0
def is_registered(user):
    """
    Checks if a user is registered in the database.

    :param user: the user ID string or User object to check
    :return: True if the user is registered
    """
    if hasattr(user, "id"):
        user = user.id

    dbusername = db.child("users").child(user).get()

    if dbusername.val() is None:
        return False
    else:
        return True
예제 #23
0
def get_remaining_cooldown_time(user):
    """
    Gets the remaining amount of time in a user's cooldown.

    :param user: the user ID string or User object to get the time remaining of
    :return: the remaining time in seconds
    """
    if hasattr(user, "id"):
        user = user.id

    try:
        return db.child("cooldowns").child(user).child(
            "cooldownEnd").get().val() - int(time.time())
    except ValueError:
        print("Error calculating time left in cooldown!")
        return None
예제 #24
0
def push_analytics_datapoint(msg):
    """
    Push a command use.

    :param msg: the message containing the command
    """
    db.child("analytics").child(msg.server.id).child("serverName").set(
        msg.server.name)
    db.child("analytics").child(msg.server.id).child("serverRegion").set(
        str(msg.server.region))
    db.child("analytics").child(msg.server.id).child("memberCount").set(
        msg.server.member_count)
    db.child("analytics").child(msg.server.id).child("commands").child(
        msg.id).set({
            "command": msg.content,
            "issuingUser": msg.author.id,
            "timeIssued": str(msg.timestamp)
        })
예제 #25
0
def get_medals(user):
    """
    Gets all of the medals a user has aquired.

    :param user: the user ID string or User object to get the medals of
    :return: the user's medals as a dict
    """
    if hasattr(user, "id"):
        user = user.id

    try:
        medals = db.child("users").child(user).child(
            "medals").order_by_value().equal_to(True).get().val()
    except IndexError:
        return None

    return medals
예제 #26
0
def transfer(payer, payee, amt):
    """
    Transfers funds from one user's account to another.

    :param payer: the user ID string or User object to withdraw funds from
    :param payee: the user ID string or User object to give funds to
    :param amt: the amount of funds to transer
    :return:
    """
    if hasattr(payer, "id"):
        payermention = payer.mention
        payer = payer.id
    else:
        payermention = "<@" + payer + ">"

    if hasattr(payee, "id"):
        payeemention = payee.mention
        payee = payee.id
    else:
        payeemention = "<@" + payee + ">"

    try:
        amt = int(amt)
    except ValueError:
        return "You can only pay amounts that are whole numbers " + payermention + "!"

    payerbalance = db.child("users").child(payer).child("balance").get().val()

    if payer == payee:
        return "You can't pay yourself " + payermention + "!"
    elif amt <= 0:
        return "You can only pay amounts above 0 " + payermention + "!"
    elif amt > payerbalance:
        return "You don't have enough Chumcoins " + payermention + "!"
    else:
        withdraw(payer, amt)
        deposit(payee, amt)
        return "" + payermention + "  :arrow_right:  " + "<:chumcoin:337841443907305473> x" \
               + str(amt) + "  :arrow_right:  " + payeemention
예제 #27
0
async def on_message(msg):
    """
    Called whenever a message is sent to somewhere the bot is connected.

    :param msg: a Message object representing the message that was sent
    """
    # Check if a message starts with a valid command. If so, show a typing indicator and ensure the command was issued
    # in an allowed place.
    if len(str.split(msg.content)) > 0 and str.split(
            msg.content)[0] in commands:
        if str.split(msg.content)[0] not in globalcommands \
                and msg.server is not None \
                and str(msg.channel) not in allowedchannels:

            await client.send_message(
                msg.channel,
                "Only **#the-pawnshop** can be used for chumlee-bot commands!")
        else:
            await client.send_typing(msg.channel)

            # Push a new analytics datapoint
            dbfunctions.push_analytics_datapoint(msg)

            if dbfunctions.is_registered(msg.author):
                # Update user info in Firebase
                dbfunctions.update_user_metadata(msg.author)

            # Displays a help/welcome message to get users started.
            if msg.content.startswith(".help"):
                welcomemsg = (
                    "Hi! I'm Chumlee, and I run this pawn shop. To get started, "
                    "use **.register** to register yourself in the database. "
                    "Then use **.commands** to see what I can do!  If you "
                    "haven't already, set up a channel called **#the-pawnshop** "
                    "so you can interact with me!"
                    "\n\n"
                    "By having me in your server, you're agreeing to the terms of service "
                    "which can be found here https://sites.google.com/view/chumlee-bot-tos/home"
                )
                await client.send_message(msg.channel, welcomemsg)

            # Displays available commands and their uses.
            elif msg.content.startswith(".commands"):
                commandinfo = (
                    "*Commands*:\n"
                    "**.register:** register in the <:chumcoin:337841443907305473> database\n\n"
                    "**.balance [@user]:** check your or another user's "
                    "<:chumcoin:337841443907305473> balance\n\n"
                    "**.appraise <text/attachment>:** get an appraisal for an item\n\n"
                    "**.pay <@user> <amount>:** pay someone <:chumcoin:337841443907305473>s\n\n"
                    "**.profile:** see your Chumprofile\n\n"
                    "**.medals:** see available Chummedals\n\n"
                    "**.buymedal <medal>:** buy a Chummedal\n\n"
                    "**.cooldown:** check how long you still need to wait until your next deal\n\n"
                    "**.item:** gets a random item from the _Pawn Stars: The Game_ Wiki\n\n"
                    "**.purge:** delete the last 100 commands and bot messages\n\n"
                    "**.kevincostner:** dances with swolves\n\n"
                    "\n*Admin Commands:*\n"
                    "**.give <@user> <amount>:** (admin command) give a user "
                    "<:chumcoin:337841443907305473>s\n\n"
                    "**.take <@user> <amount>:** (admin command) take a user's "
                    "<:chumcoin:337841443907305473>s\n\n"
                    "**.forceenddeal [@user]:** set your or another user's deal status to false\n\n"
                    "**.forceendcooldown [@user]:** end your or another user's deal cooldown"
                )
                await client.send_message(msg.author, commandinfo)
                await client.send_message(msg.channel, "Command info sent!")

            # Registers a user in the database by adding their user ID to the "users" node and setting an initial
            # balance and value for "isInDeal".
            elif msg.content.startswith(".register"):
                if not dbfunctions.is_registered(msg.author):
                    newuserdata = {
                        "userName": msg.author.name,
                        "discriminator": msg.author.discriminator,
                        "balance": 20,
                        "isInDeal": False,
                        "medals": {
                            "tin": False,
                            "bronze": False,
                            "silver": False,
                            "gold": False,
                            "platinum": False
                        }
                    }

                    newcooldowndata = {"multiplier": 1.0}

                    db.child("users").child(msg.author.id).set(newuserdata)
                    db.child("cooldowns").child(
                        msg.author.id).set(newcooldowndata)
                    await client.send_message(
                        msg.channel,
                        "Okay, you're all set up " + msg.author.mention + "!")
                else:
                    await client.send_message(
                        msg.channel, "Looks like you're already registered " +
                        msg.author.mention + ".")

            # Gets a user's balance from the database and prints it in the chat.
            elif msg.content.startswith(".balance"):
                args = str.split(msg.content)
                print(args)

                if not dbfunctions.is_registered(msg.author):
                    await client.send_message(
                        msg.channel, "You need to use **.register** first " +
                        msg.author.mention + "!")
                elif len(args) == 2:
                    if not functions.user_is_admin(msg.author):
                        await client.send_message(
                            msg.channel,
                            "You must be an admin to get the balance "
                            "of another user.")
                    elif not functions.is_valid_userid(args[1]):
                        await client.send_message(
                            msg.channel, "That doesn't look like a username.")
                    elif not dbfunctions.is_registered(
                            re.sub('[^0-9]', "", args[1])):
                        await client.send_message(
                            msg.channel, "That user isn't registered!")
                    else:
                        await client.send_message(
                            msg.author, args[1] + "'s balance is " + str(
                                dbfunctions.get_balance(
                                    re.sub('[^0-9]', "", args[1]))) +
                            " <:chumcoin:337841443907305473>")
                else:
                    await client.send_message(
                        msg.channel, msg.author.mention + "'s balance is " +
                        str(dbfunctions.get_balance(msg.author)) +
                        " <:chumcoin:337841443907305473>")

            # Transfers money between users.
            elif msg.content.startswith(".pay"):
                if not dbfunctions.is_registered(msg.author):
                    await client.send_message(
                        msg.channel, "You need to use **.register** first " +
                        msg.author.mention + "!")
                else:

                    args = str.split(msg.content)

                    if len(args) != 3:
                        await client.send_message(
                            msg.channel, "Usage: .pay <user> <amount>")
                    elif functions.is_valid_userid(args[1]) is None:
                        await client.send_message(
                            msg.channel, "That doesn't look like a username.")
                    elif not dbfunctions.is_registered(
                            re.sub('[^0-9]', "", args[1])):
                        await client.send_message(
                            msg.channel, "That user isn't registered!")
                    else:
                        await client.send_message(
                            msg.channel,
                            dbfunctions.transfer(msg.author,
                                                 re.sub('[^0-9]', "", args[1]),
                                                 args[2]))

            # Adds money to the balance of the user specified in the first command argument. Only usable by users
            # with admin rank.
            elif msg.content.startswith(".give"):
                if not functions.user_is_admin(msg.author):
                    await client.send_message(
                        msg.channel, "You must be an admin to use .give")
                else:
                    args = str.split(msg.content)

                    if len(args) != 3:
                        await client.send_message(
                            msg.channel, "Usage: .give <user> <amount>")
                    elif functions.is_valid_userid(args[1]) is None:
                        await client.send_message(
                            msg.channel, "That doesn't look like a username.")
                    elif not dbfunctions.is_registered(
                            re.sub('[^0-9]', "", args[1])):
                        await client.send_message(
                            msg.channel, "That user isn't registered!")
                    else:
                        await client.send_message(
                            msg.channel,
                            dbfunctions.deposit(re.sub('[^0-9]', "", args[1]),
                                                args[2]))

            # Takes money from the balance of the user specified in the first command argument. Only usable by users
            # with admin rank.
            elif msg.content.startswith(".take"):
                if not functions.user_is_admin(msg.author):
                    await client.send_message(
                        msg.channel, "You must be an admin to use .take")
                else:
                    args = str.split(msg.content)

                    if len(args) != 3:
                        await client.send_message(
                            msg.channel, "Usage: .take <user> <amount>")
                    elif functions.is_valid_userid(args[1]) is None:
                        await client.send_message(
                            msg.channel, "That doesn't look like a username.")
                    elif not dbfunctions.is_registered(
                            re.sub('[^0-9]', "", args[1])):
                        await client.send_message(
                            msg.channel, "That user isn't registered!")
                    elif not dbfunctions.check_for_funds(
                            re.sub('[^0-9]', "", args[1]), int(args[2])):
                        await client.send_message(
                            msg.channel,
                            "That's more Chumcoins than that user has!")
                    else:
                        await client.send_message(
                            msg.channel,
                            dbfunctions.withdraw(re.sub('[^0-9]', "", args[1]),
                                                 args[2]))

            # Force-sets a user's "isInDeal" status to false. Intended to be used if this status gets stuck
            # when the bot disconnects while a user in in a deal. Using this while a user in in a deal and the bot
            # is still online will still allow the deal to be completeed, and will also allow a user to be
            # in multiple deals at once. If no user is specified the command affects the issuer. Only usable by users
            # with admin rank.
            elif msg.content.startswith(".forceenddeal"):
                if not functions.user_is_admin(msg.author):
                    await client.send_message(
                        msg.channel,
                        "You must be an admin to use .forceenddeal")
                else:
                    args = str.split(msg.content)

                    if len(args) > 2:
                        await client.send_message(
                            msg.channel, "Usage: .forceenddeal [user]")
                    elif len(args) == 2:
                        dbfunctions.set_deal_status(
                            re.sub('[^0-9]', "", args[1]), False)
                        await client.send_message(msg.channel,
                                                  "Ended deal for " + args[1])
                    else:
                        dbfunctions.set_deal_status(msg.author.id, False)
                        await client.send_message(
                            msg.channel,
                            "Ended deal for " + msg.author.mention)

            # Deletes the "lastDealTime" key for a user. If no user is specified the command affects the issuer.
            # Only usable by users with admin rank.
            elif msg.content.startswith(".forceendcooldown"):
                if not functions.user_is_admin(msg.author):
                    await client.send_message(
                        msg.channel,
                        "You must be an admin to use .forceendcooldown")
                else:
                    args = str.split(msg.content)

                    if len(args) > 2:
                        await client.send_message(
                            msg.channel, "Usage: .forceendcooldown [user]")
                    elif len(args) == 2:
                        db.child("cooldowns").child(
                            re.sub('[^0-9]', "",
                                   args[1])).child("cooldownEnd").remove()
                        await client.send_message(
                            msg.channel, "Ended cooldown for " + args[1])
                    else:
                        db.child("cooldowns").child(
                            msg.author.id).child("cooldownEnd").remove()
                        await client.send_message(
                            msg.channel,
                            "Ended cooldown for " + msg.author.mention)

            # Starts an appraisal of a string or an attachment.
            elif msg.content.startswith(".appraise"):

                if not dbfunctions.is_registered(msg.author):
                    dbfunctions.push_bot_response(
                        msg, "You need to use **.register** first " +
                        msg.author.mention + "!")
                    await client.send_message(
                        msg.channel, "You need to use **.register** first " +
                        msg.author.mention + "!")
                elif dbfunctions.is_in_deal(msg.author):
                    dbfunctions.push_bot_response(
                        msg,
                        "Looks like you've already got a deal on the table " +
                        msg.author.mention + "!")
                    await client.send_message(
                        msg.channel,
                        "Looks like you've already got a deal on the table " +
                        msg.author.mention + "!")
                elif not functions.cooldown_expired(msg.author):
                    secondstonextdeal = dbfunctions.get_remaining_cooldown_time(
                        msg.author)
                    if secondstonextdeal <= 60:
                        timetodealstring = "" + str(
                            int(round(secondstonextdeal, 0))) + " more seconds"
                    else:
                        timetodealstring = "" + str(
                            int(round(secondstonextdeal / 60,
                                      0))) + " more minutes"
                    dbfunctions.push_bot_response(
                        msg, "You've gotta wait " + timetodealstring +
                        " until your next deal " + msg.author.mention + ".")
                    await client.send_message(
                        msg.channel, "You've gotta wait " + timetodealstring +
                        " until your next deal " + msg.author.mention + ".")
                # check if nodeal count is >= 3
                # if true, say you can't make a deal and start cooldown
                # reset count to 0
                elif dbfunctions.get_deal_attempts(msg.author) is not None \
                        and dbfunctions.get_deal_attempts(msg.author) >= 3:
                    print("too many attempts!")
                    dbfunctions.push_bot_response(
                        msg, "You've tried to make too many deals lately " +
                        msg.author.mention + "! Come back a bit later.")
                    await client.send_message(
                        msg.channel,
                        "You've tried to make too many deals lately " +
                        msg.author.mention + "! Come back a bit later.")
                    dbfunctions.reset_deal_attempts(msg.author)
                    dbfunctions.update_cooldown_end(msg.author)
                else:
                    seller = msg.author
                    dbfunctions.set_deal_status(seller, True)

                    args = str.split(msg.content)
                    files = msg.attachments

                    random.seed()
                    base = random.random()

                    value = functions.calc_appraisal_value(base)
                    quote = functions.get_appraisal_quote(base)

                    if len(args) == 1 and len(files) == 0:
                        dbfunctions.push_bot_response(
                            msg, "You must include something to appraise")
                        await client.send_message(
                            msg.channel,
                            "You must include something to appraise")
                        dbfunctions.set_deal_status(seller, False)
                    elif len(args) > 1 and re.match('<@!?338421932426919936>',
                                                    args[1]):
                        dbfunctions.push_bot_response(
                            msg,
                            "I'll all about self love " + msg.author.mention +
                            ", so I'll give myself a 10/10.")
                        await client.send_message(
                            msg.channel,
                            "I'll all about self love " + msg.author.mention +
                            ", so I'll give myself a 10/10.")
                        dbfunctions.set_deal_status(msg.author, False)
                    else:
                        if not value == 0:
                            dbfunctions.push_bot_response(
                                msg, "\n\n" + msg.author.mention + " Offer: " +
                                str(value) +
                                " <:chumcoin:337841443907305473> (.deal/.nodeal)"
                            )
                            await client.send_message(
                                msg.channel, quote + "\n\n" +
                                msg.author.mention + " Offer: " + str(value) +
                                " <:chumcoin:337841443907305473> (.deal/.nodeal)"
                            )

                            def check(i):
                                return i.content == ".deal" or i.content == ".nodeal"

                            response = await client.wait_for_message(
                                timeout=30.0, author=msg.author, check=check)

                            if response is None:
                                dbfunctions.push_bot_response(
                                    msg.id, "Alright, no deal then.")
                                await client.send_message(
                                    msg.channel, "Alright, no deal then.")

                                dbfunctions.set_deal_status(seller, False)
                                dbfunctions.update_cooldown_end(seller)

                            elif response.content == ".deal":
                                dbfunctions.adjust_cooldown_multiplier(
                                    seller, int(time.time()))

                                dbfunctions.push_bot_response(
                                    msg,
                                    "Alright! I'll meet you over there and do some paperwork."
                                )
                                await client.send_message(
                                    msg.channel,
                                    "Alright! I'll meet you over there and do some paperwork."
                                )
                                dbfunctions.push_bot_response(
                                    msg,
                                    "<:chumlee:337842115931537408>  :arrow_right:  "
                                    "<:chumcoin:337841443907305473> x" +
                                    str(value) + "  :arrow_right:  " +
                                    msg.author.mention)
                                await client.send_message(
                                    msg.channel,
                                    "<:chumlee:337842115931537408>  :arrow_right:  "
                                    "<:chumcoin:337841443907305473> x" +
                                    str(value) + "  :arrow_right:  " +
                                    msg.author.mention)

                                dbfunctions.deposit(msg.author, value)
                                dbfunctions.set_deal_status(seller, False)
                                dbfunctions.reset_deal_attempts(seller)
                                dbfunctions.update_cooldown_end(seller)

                            elif response.content == ".nodeal":
                                await client.send_message(
                                    msg.channel, "Alright, no deal then.")

                                dbfunctions.set_deal_status(seller, False)
                                # increment nodeal counter
                                dbfunctions.update_deal_attempts(seller)
                                dbfunctions.update_last_nodeal_time(seller)
                            else:
                                await client.send_message(
                                    msg.channel, "Something went wrong!")

                                dbfunctions.set_deal_status(seller, False)

                        else:
                            await client.send_message(
                                msg.channel,
                                quote + "\n\nNo deal :no_entry_sign:")

                            dbfunctions.set_deal_status(seller, False)
                            dbfunctions.update_cooldown_end(seller)

            # Lets a user check how much longer they have to wait until making their next deal.
            elif msg.content.startswith(".cooldown"):
                if not dbfunctions.is_registered(msg.author):
                    await client.send_message(
                        msg.channel, "You need to use **.register** first " +
                        msg.author.mention + "!")
                elif functions.cooldown_expired(msg.author):
                    await client.send_message(
                        msg.channel, "You're not in the cooldown period " +
                        msg.author.mention + "!")
                else:
                    secondstonextdeal = dbfunctions.get_remaining_cooldown_time(
                        msg.author)
                    if secondstonextdeal <= 60:
                        timetodealstring = "" + str(
                            int(round(secondstonextdeal, 0))) + " more seconds"
                    else:
                        timetodealstring = "" + str(
                            int(round(secondstonextdeal / 60,
                                      0))) + " more minutes"

                    await client.send_message(
                        msg.channel, "You've gotta wait " + timetodealstring +
                        " until your next deal " + msg.author.mention + ".")

            # Posts a link to DaThings1's "Prawn Srars" along with a random quote from the video.
            elif msg.content.startswith(".kevincostner"):
                await client.send_message(
                    msg.channel, random.choice(resources.prawnsrars.ytpquotes))
                await client.send_message(
                    msg.channel, "https://www.youtube.com/watch?v=5mEJbX5pio8")

            # Posts a random item from the Pawn Stars: The Game wiki.
            elif msg.content.startswith(".item"):
                baseurl = "http://pawnstarsthegame.wikia.com"

                with open('resources/items.json') as data_file:
                    data = json.load(data_file)

                await client.send_message(
                    msg.channel,
                    baseurl + data[random.randint(0,
                                                  len(data) - 1)]["value"])

            # Deletes chumlee-bot messages and issued commands sent in the last 100 messages.
            elif msg.content.startswith(".purge"):

                def check(i):
                    return i.author.id == client.user.id or i.content[:1] == "."

                try:
                    await client.purge_from(channel=msg.channel,
                                            limit=100,
                                            check=check)
                    await client.send_message(
                        msg.channel, "Deleted last 100 commands and responses "
                        ":put_litter_in_its_place:")
                except discord.errors.Forbidden:
                    await client.send_message(
                        msg.channel, "I need permission to manage messages "
                        "in order to use .purge!")

            # Sends a list of the available Chummedals and their prices.
            elif msg.content.startswith(".medals") or msg.content.startswith(
                    ".listmedals"):
                # await client.send_file(msg.channel, "resources/img/medals/chummedal-row.png")
                await client.send_message(msg.channel, medals.medalinfo)

            # Lists a user's medals.
            elif msg.content.startswith(".mymedals") or msg.content.startswith(
                    ".profile"):
                print("Generating profile")
                await client.send_file(msg.channel,
                                       io.BytesIO(
                                           profile.gen_profile(msg.author)),
                                       filename="profile.png")

            # Lets a user buy a Chummedal.
            elif msg.content.startswith(".buymedal"):
                args = str.split(msg.content)

                if not len(args) == 2:
                    await client.send_message(msg.channel,
                                              "Usage: .buymedal <medal>")
                else:
                    await client.send_message(
                        msg.channel, functions.buy_medal(msg.author, args[1]))

            elif msg.content.startswith(".lotto"):
                args = str.split(msg.content)

                if not dbfunctions.is_registered(msg.author):
                    await client.send_message(
                        msg.channel, "You need to use **.register** first " +
                        msg.author.mention + "!")
                elif not len(args) == 2:
                    await client.send_message(msg.channel,
                                              "Usage: .lotto <bet>")
                elif dbfunctions.get_lotto_status(msg.server):
                    await client.send_message(
                        msg.channel,
                        "Looks like a Chumlottery is already in progress on this server!"
                    )
                else:
                    dbfunctions.update_lotto_status(msg.server, True)
                    bet = int(args[1])
                    jackpot = 0

                    await client.send_message(
                        msg.channel, msg.author.mention +
                        " has started a Chumlottery! Type **.bet** to bet " +
                        str(bet) + " <:chumcoin:337841443907305473> and join!")

                    players = [msg.author]

                    def check(i):
                        if not i.author.id == msg.author.id \
                                and i.author not in players \
                                and dbfunctions.is_registered(i.author) \
                                and i.content == ".bet":

                            print(i.author.display_name + " entered the lotto")
                            players.append(i.author)
                        else:
                            print("Not a valid .bet")

                    response = await client.wait_for_message(timeout=60,
                                                             check=check)

                    if response is None:
                        print("Lotto bets ended")
                        print(players)

                        if len(players) > 1:
                            await client.send_message(
                                msg.channel, "Alright, no more bets!")

                            for user in players:
                                if not dbfunctions.check_for_funds(user, bet):
                                    print(
                                        user.display_name +
                                        " is poor and is being removed from the lotto"
                                    )
                                    await client.send_message(
                                        msg.channel, user.mention +
                                        " doesn't have the Chumcoins to play the Chumlottery!"
                                    )
                                    del players[user]
                                else:
                                    print("Withdrawing " + str(bet) +
                                          " from " + user.display_name)
                                    await client.send_message(
                                        msg.channel,
                                        dbfunctions.withdraw(user, bet))
                                    jackpot += bet

                            print(jackpot)

                            await client.send_message(
                                msg.channel,
                                "Drawing a name... :slot_machine:")

                            winner = random.choice(players)
                            print(winner.display_name)

                            await client.send_message(
                                msg.channel, "Congrats " + winner.mention +
                                "! You won " + str(jackpot) +
                                " <:chumcoin:337841443907305473>!")

                            await client.send_message(
                                msg.channel,
                                dbfunctions.deposit(winner, jackpot))
                            dbfunctions.update_lotto_status(msg.server, False)

                        else:
                            await client.send_message(
                                msg.channel,
                                "No registered users entered the Chumlottery!")

                            dbfunctions.update_lotto_status(msg.server, False)

            # Sends a random gif from the resources/img/gifs directory (currently unused).
            elif msg.content.startswith(".gif"):
                gif = random.choice(os.listdir("resources/img/gifs"))
                await client.send_file(msg.channel,
                                       "resources/img/gifs/" + gif)