예제 #1
0
    async def deleterr(self, ctx, rolename: str):
        """Deletes a reward role

        Usage: deleterr rolename"""

        conn = self.bot.pool

        try:
            sql = """SELECT * FROM roles WHERE rolename = $1 AND server_id = $2;"""
            fetch = await conn.fetch(sql, rolename, ctx.guild.id)

            if (fetch == []):
                response = emb.gen_embed_red("Warning!", "This is not a leveling role.")
                await ctx.send(embed=response)
                return

            await ctx.guild.get_role(fetch[0]["role_id"]).delete()

            await conn.execute("""DELETE FROM roles WHERE rolename = $1;""", rolename)

            response = emb.gen_embed_cobalt("Well done!", "The role has been deleted.")
            await ctx.send(embed=response)

        except Exception as e:
            log.warning(e)
            log.error(traceback.format_exc())
예제 #2
0
    async def rewards(self, ctx, *args):
        """Fetches all the possible rewards for levels

        Usage: `rewards`"""

        conn = self.bot.pool

        try:
            sql = """SELECT * FROM roles WHERE server_id = $1 ORDER BY level ASC;"""
            fetch = await conn.fetch(sql, ctx.guild.id)

            if (fetch == []):
                response = emb.gen_embed_red("Warning!", """There are no roles yet.
You can add roles using 'createrole Name Level (Colour)'.""")
                await ctx.send(embed=response)
                return

            table = []
            for fetched in fetch:
                line = [fetched["rolename"], fetched["level"]]
                table.append(line)

            headers = ["Role", "Level"]
            content = tabulate.tabulate(table, headers, tablefmt="simple", stralign="left",
                                        numalign="right")

            response = emb.gen_embed_cobalt("Roles on this server:", f"```{content}```")
            await ctx.send(embed=response)

        except Exception as e:
            log.warning(e)
            log.error(traceback.format_exc())
예제 #3
0
    async def on_message(self, message):
        regex = "^[^\"\'\.\w]" # noqa

        if re.search(regex, message.content) or message.author.bot:
            return

        conn = self.bot.pool

        guild = message.guild
        author = message.author
        time = message.created_at

        # Try block
        try:
            sql = """SELECT * FROM lb WHERE server_id = $1 AND user_id = $2; """
            fetch = await conn.fetchrow(sql, guild.id, author.id)

            # Case 1: First message by user
            if fetch is None:
                newxp = random.randint(15, 25)
                sql = """INSERT INTO lb VALUES ( $1, $2, $3, $4, $5, $6 )"""
                await conn.execute(sql, guild.id, author.id, time, 1, newxp, 1)

                string = f"Welcome to the server, {author.name}! \n{author.name} is now level 1."
                e = emb.gen_embed_cobalt("A new adventure is starting.", string)
                await message.channel.send(embed=e)
                return

            # Case 2: Less than 1 min has elasped since last message.
            if (time - fetch["last_exp"]).seconds < 60:
                sql = """UPDATE lb SET msg_amt = $1 WHERE server_id = $2 AND user_id = $3"""
                await conn.execute(sql, fetch[3]+1, guild.id, author.id)
                return

            # Case 3: Awarding new xp. Then,
            newxp = fetch[4] + random.randint(15, 25)
            level = fetch[5]

            # If leveled up call leveling Function
            if newxp >= level_up(level):
                newlevel = await leveling_up(message.channel, guild, conn, author, level, newxp)
                sql = """UPDATE lb SET msg_amt = $1,
                                       total_exp = $2,
                                       last_exp = $3,
                                       level = $4 WHERE server_id = $5 AND user_id = $6"""

                await conn.execute(sql, fetch[3] + 1, newxp, time, newlevel, guild.id, author.id)

            # Otherwise, silently add the awarded xp to the database
            else:
                sql = """UPDATE lb SET msg_amt = $1,
                                       total_exp = $2,
                                       last_exp = $3 WHERE server_id = $4 AND user_id = $5"""

                await conn.execute(sql, fetch[3] + 1, newxp, time, guild.id, author.id)

        except Exception as e:
            log.warning(e)
            log.error(traceback.format_exc())
예제 #4
0
    async def weather(self, ctx):
        """Generate a random npc

        `weather`"""
        # Create embed
        e = emb.gen_embed_cobalt('Weather Generator', None)

        # Generate Precipitation
        precip = [
            'No Precipitation', 'Light rain or snowfall',
            'Heavy rain or snowfall'
        ]
        precip = np.random.choice(precip, p=[0.6, 0.25, 0.15])
        e.add_field(name='Precipitation', value=precip, inline=False)

        # Generate Temps
        roll = random.randint(1, 4)
        temp = [
            'Normal for the season',
            f'{roll*10} degrees Fahrenheit colder than normal',
            f'{roll*10} degrees Fahrenheit colder than normal'
        ]
        temp = np.random.choice(temp, p=[0.7, 0.15, 0.15])
        e.add_field(name='Temperature', value=temp, inline=False)

        # Generate Wind
        wind = ['No Wind', 'Light Wind', 'Medium Wind', 'Heavy/Strong Wind']
        wind = np.random.choice(wind, p=[0.1, 0.55, 0.2, 0.15])
        e.add_field(name='Wind', value=wind, inline=False)

        # Generate speeds
        roll = random.randint(1, 6) + random.randint(1, 6)
        direction = [
            'North', 'North-East', 'East', 'South-East', 'South', 'South-West',
            'West', 'North-West'
        ]

        if wind == 'Medium Wind':
            speed = [50, 40, 30, 20, 10, 0, 0, 10, 20, 30, 40, 50]
            speed = str(speed[roll - 1]) + ' feet'
            e.add_field(name='Speed', value=speed, inline=False)
            direction = np.random.choice(direction)
            e.add_field(name='Direction', value=direction, inline=False)

        elif wind == 'Heavy/Strong Wind':
            speed = [110, 100, 90, 80, 70, 60, 60, 70, 80, 90, 100, 110]
            speed = str(speed[roll - 1]) + ' feet'
            e.add_field(name='Speed', value=speed, inline=True)
            direction = np.random.choice(direction)
            e.add_field(name='Direction', value=direction, inline=False)

        await ctx.send(embed=e)
예제 #5
0
    async def gnpc(self, ctx, *args):
        """Generate a random npc

        `gnpc m/f/t[Optional] race[Optional]`"""
        sex = None
        race = None

        for arg in args:
            if len(arg) == 1:
                sex = arg
            else:
                race = arg
        response = npcgen.main(sex, race)
        response = emb.gen_embed_cobalt('NPC Generator', response)
        await ctx.send(embed=response)
예제 #6
0
    async def ranking(self, ctx, max: int = 15):
        """Lists top 15 ranked adventurers on the server

        Usage: `rank`"""

        conn = self.bot.pool

        try:
            sql = """SELECT * FROM lb WHERE server_id=$1 ORDER BY total_exp DESC;"""
            fetch = await conn.fetch(sql, ctx.guild.id)
        except Exception as e:
            print(e)

        if fetch == []:
            e = emb.gen_embed_red("Warning!", "There are no adventurers in this guild.")
            await ctx.send(embed=e)
            return

        rank = 1
        table = []

        for fetched in fetch:
            try:
                line = [rank, ctx.guild.get_member(fetched["user_id"]).name, fetched["level"]]
            except Exception:
                sql = """DELETE FROM lb WHERE server_id=$1 and user_id=$2;"""
                await conn.execute(sql, ctx.guild.id, fetched["user_id"])
                log.warning(f"Deleted {fetched['user_id']} from db")
                continue

            table.append(line)
            if rank > max:
                break
            else:
                rank += 1

        headers = ["Rank", "Name", "Level"]
        content = tabulate.tabulate(table, headers, tablefmt="simple", stralign="left",
                                    numalign="center")

        if len(content) > 2000:
            await ctx.send("Too many entries. Fix coming soon-ish.")

        else:
            e = emb.gen_embed_cobalt("Ranking", f"```{content}```")
            await ctx.send(embed=e)
예제 #7
0
    async def levels(self, ctx, max: int = 10):
        """Lists the xp required for levels

        Usage: `levels level`"""
        string = ""

        if max < 3:
            min = max
        else:
            min = max - 3
        max = max + 3

        for i in range(min, max):
            string += f"To level {i+1}: {level_up(i)} xp\n"

        e = emb.gen_embed_cobalt("XP requirements by level", string)
        await ctx.send(embed=e)
예제 #8
0
    async def createrr(self, ctx, rolename: str, level: int,
                       colour: discord.Colour = discord.Colour.default()):
        """Creates a reward role

        Usage: `createrr rolename level colour`"""

        conn = self.bot.pool
        try:
            # checking if the role already exists, or if there is another role at that level
            sql = """SELECT * FROM roles WHERE rolename = $1 AND server_id = $2"""
            fetch = await conn.fetch(sql, rolename, ctx.guild.id)

            if (fetch != []):
                response = emb.gen_embed_red("Warning!", "This rolename already exists.")
                await ctx.send(embed=response)
                return

            fetch = await conn.fetch("""SELECT * FROM roles WHERE level = $1 AND server_id = $2;""",
                                     level, ctx.guild.id)

            if (fetch != []):
                response = emb.gen_embed_red("Warning!", "There already is a role at this level.")
                await ctx.send(embed=response)
                return

            # Creating a new role in the server
            # (note: this doesn't check if another role with the same name already exists).
            role = await ctx.guild.create_role(name=rolename, colour=colour)

            # creating a new role in the database and linking to the server role by id
            await conn.execute("""INSERT INTO roles VALUES ( $1, $2, $3, $4 )""", rolename,
                               ctx.guild.id, role.id, level)

            response = emb.gen_embed_cobalt("Well done!", "New role created!")
            await ctx.send(embed=response)

        except Exception as e:
            log.warning(e)
            log.error(traceback.format_exc())
예제 #9
0
    async def rank(self, ctx, member: discord.Member = None):
        """Gets rank on the server

        Usage: `rank id[Optional]`"""

        conn = self.bot.pool

        # Verification
        if member is None:
            member = ctx.author

        try:
            sql = """SELECT * FROM lb WHERE server_id=$1 AND user_id=$2"""
            fetch = await conn.fetchrow(sql, ctx.guild.id, member.id)

            if fetch is None:
                e = emb.gen_embed_red("", "This adventurer doesn't have any xp on this server.")
                await ctx.send(embed=e)
                return

            xp = fetch[4]
            level = fetch[5]
            nxp = level_up(level)
            missxp = nxp - xp

            string = f"You are level {level} on this server, with {xp} xp.\n"
            string += f"You last gained xp {(ctx.message.created_at - fetch[2]).seconds} seconds ago."
            string += f"\n\n Level {level+1} requires {nxp} xp: You need {missxp} more."

            e = emb.gen_embed_cobalt(f"{member}", string)
            e.set_thumbnail(url=member.avatar_url)
            e.add_field(name="XP", value=f"{xp}/{nxp}", inline=True)
            e.add_field(name="Level", value=level, inline=True)
            e.add_field(name="Messages", value=fetch[3], inline=True)
            await ctx.send(embed=e)

        except Exception as e:
            log.warning(e)
            log.error(traceback.format_exc())
예제 #10
0
    async def giverep(self, ctx, member: discord.Member, rep: int = 1):
        """ Gives another member rep. (Max of 1)
        
        Usage: `giverep "username"/@mention/id rep`
        """

        # Set Varaibles
        author = ctx.author
        conn = self.bot.pool
        roles = ctx.author.roles
        is_admin = False

        for role in roles:
            if role.name == "Admin":
                is_admin = True

        # Validation
        if rep == 0:
            e = emb.gen_embed_cobalt("Eh?", f"{member.name} was given 0 rep??")
            await ctx.send(embed=e, delete_after=5)
            return

        if member.bot:
            await ctx.send("`Can't give rep to a bot.`")
            return

        if not is_admin and (ctx.author.id == member.id):
            e = emb.gen_embed_red("Hunh",
                                  "Sneakily trying to give yourself xp eh.")
            await ctx.send(embed=e, delete_after=5)
            return

        for elem, user in enumerate(self.cooldown):
            curr_time = time.time()
            if user[0] == author.id and (curr_time - user[1]) < 120:
                e = emb.gen_embed_red("Cooldown", f"Currently in cooldown.")
                await ctx.send(embed=e, delete_after=5)
                return
            elif user[0] == author.id and (curr_time - user[1] > 120):
                self.cooldown.pop(elem)
            else:
                pass

        if not is_admin and (rep > 1 or rep < 0):
            e = emb.gen_embed_red("Eh??", f"Unable to give more than 1 rep.")
            await ctx.send(embed=e, delete_after=5)
            return

        try:
            sql = """INSERT INTO rep (server_id, user_id, rep)
                    VALUES ($1, $2, $3)
                    ON CONFLICT ON CONSTRAINT server_user 
                    DO UPDATE SET rep = rep.rep + $3;"""

            await conn.execute(sql, ctx.guild.id, member.id, rep)
            e = emb.gen_embed_green("Rep", f"Gave {member.name} {rep} rep.")

            await ctx.send(embed=e, delete_after=5)
            await ctx.message.add_reaction('<:tick:741279181895106592>')

            if not is_admin:
                curr_time = time.time()
                self.cooldown.append((author.id, curr_time))

        except Exception as e:
            log.error(traceback.format_exc())
예제 #11
0
    async def toprep(self, ctx, page: int = 1):
        """ Displays the ranking by reputation.
        
        Usage: `toprep (page_num)` 
        """

        # Validation
        if page < 1:
            return

        # Variables
        conn = self.bot.pool

        try:
            sql = """SELECT * FROM rep WHERE server_id=$1 ORDER BY rep.rep DESC;"""
            fetch = await conn.fetch(sql, ctx.guild.id)
        except Exception as e:
            log.error(traceback.format_exc())

        if fetch is []:
            message = "No one in this server has reputation points."
            await ctx.send(message)
            return

        table = list()

        if len(fetch) < (15 * (page - 1)):
            message = f"Not enough users with rep to display page {page}"
            await ctx.send(message)
            return

        fetch = fetch[15 * (page - 1):]
        rank = 15 * (page - 1) + 1

        for elem, fetched in enumerate(fetch):

            try:
                line = [
                    rank,
                    ctx.guild.get_member(fetched["user_id"]).name,
                    fetched["rep"]
                ]
            except Exception:
                sql = """DELETE FROM rep WHERE server_id=$1 and user_id=$2;"""
                await conn.execute(sql, ctx.guild.id, fetched["user_id"])
                log.warning(f"Deleted {fetched['user_id']} from db")
                continue

            table.append(line)
            rank += 1
            if elem > 14:
                break

        headers = ["Rank", "Name", "Rep"]
        content = tabulate.tabulate(table,
                                    headers,
                                    tablefmt="simple",
                                    stralign="left",
                                    numalign="center")

        if len(content) > 2000:
            await ctx.send("Too many entries. Fix coming soon-ish ")

        else:
            e = emb.gen_embed_cobalt("Ranking", f"```{content}```")
            await ctx.send(embed=e)
예제 #12
0
    async def givexp(self, ctx, member: discord.Member, exp: int):
        """Gives another member xp

        Usage: `givexp "username"/@mention/id xp_amt`"""

        # Validation
        if exp < 0:
            e = emb.gen_embed_red("Warning!", "You can't give negative xp.")
            await ctx.send(embed=e)
            return

        if exp == 0:
            e = emb.gen_embed_cobalt("Eh?",
                                     f"{member.name} was given 0 xp. Nothing to write home about...")
            await ctx.send(embed=e)
            return

        # Set connection
        conn = self.bot.pool

        try:
            sql = """SELECT * FROM lb WHERE server_id=$1 AND user_id=$2;"""
            fetch = await conn.fetchrow(sql, ctx.guild.id, member.id)

            #  If no previous entry
            if fetch is None:
                sql = """INSERT INTO lb VALUES ($1, $2, $3, $4, $5, $6)"""
                await conn.execute(sql, ctx.guild.id, member.id, ctx.message.created_at, 1, 0, 0)
                string = f"Welcome to this server, {member.name}!\n{member.name} is now level 1."

                e = emb.gen_embed_green("A new adventure is starting", string)
                await ctx.send(embed=e)

                newxp = exp
                level = 1

            else:
                string = f"{member.name} was given {exp} exp!"
                e = emb.gen_embed_green("", string)
                await ctx.send(embed=e)

                newxp = fetch[4] + exp
                level = fetch[5]

            # If threshold reached next level
            if newxp >= level_up(level):
                newlevel = await leveling_up(ctx.channel, ctx.guild, conn, member, level, newxp)
                sql = """UPDATE lb SET total_exp = $1,
                                       last_exp = $2,
                                       level = $3 WHERE server_id = $4 AND user_id = $5"""

                await conn.execute(sql, newxp, ctx.message.created_at, newlevel, ctx.guild.id, member.id)

            else:
                sql = """UPDATE lb SET total_exp = $1,
                                       last_exp = $2 WHERE server_id = $3 AND user_id = $4"""

                await conn.execute(sql, newxp, ctx.message.created_at, ctx.guild.id, member.id)

        except Exception as e:
            log.warning(e)
            log.error(traceback.format_exc())
예제 #13
0
    async def gletter(self, ctx):
        """ Creates a letter handout. Asks for a Title(Optional), Content and Signature(Optional).

            The command has a timeout of 30 secs at each stage."""

        from utils import letter_gen as lettergen  # noqa

        # Get variables
        author = ctx.author

        def check(message):
            return author == message.author

        # Create initial embeds
        msg = "Let's begin the process. Please type the title on the letter or c to cancel"
        msg += "\n(Note: Title and Signature can be left empty by typing None.)\n"
        msg += "(Note: Every section has a 30 secs time limit.)"

        # Send inital embed
        e = emb.gen_embed_cobalt('Creating Letter', "")
        preview = await ctx.send(msg, embed=e)

        # Getting the title
        try:
            title = await self.bot.wait_for('message', timeout=30, check=check)
        except asyncio.TimeoutError:
            await ctx.channel.send('Timed out. 👎')
            return

        if title.content == 'c':
            return
        elif title.content.lower() == 'none':
            title.content = None
        else:
            title.content = str(title.content)

        # Getting Content
        msg = 'Next type in the content or enter c to cancel...'
        e = emb.gen_embed_cobalt('Creating Letter', "")
        e.set_thumbnail(url=ctx.author.avatar_url)
        e.add_field(name='Title', value=title.content, inline=False)

        await preview.edit(content=msg, embed=e)

        try:
            content = await self.bot.wait_for('message',
                                              timeout=30,
                                              check=check)
        except asyncio.TimeoutError:
            await ctx.channel.send('Timed out. 👎')
            return

        if content.content == 'c':
            return
        else:
            content.content = str(content.content)
            if len(content.content) > 770:
                content.content = content.content[:770]
                val = f'{content.content[:500]}...'
            val = content.content

        e.add_field(name='Content', value=val, inline=False)

        # Getting the signature
        await preview.edit(content="Next enter the signature", embed=e)

        try:
            signature = await self.bot.wait_for('message',
                                                timeout=30,
                                                check=check)
        except asyncio.TimeoutError:
            await ctx.channel.send('Timed out. 👎')
            return

        if signature.content == 'c':
            return
        elif signature.content.lower() == 'none':
            signature.content = None
        else:
            signature.content = str(signature.content)

        e.add_field(name='Signature', value=signature.content, inline=False)
        await preview.edit(content='Generating...', embed=e)

        async with ctx.typing():
            image = lettergen.main(title.content, content.content,
                                   signature.content)
            file = discord.File(filename="circle.png", fp=image)
        await preview.delete()

        await ctx.send(file=file)