Beispiel #1
0
    async def unban(self, ctx, username, *, reason='It\'s your lucky day!'):
        await ctx.message.delete()
        log_channel = await commands.TextChannelConverter().convert(ctx, config.read('log_channel_id'))

        username = self.username_is_player_id(username)

        if not self.valid_username_format(username):
            await ctx.author.send(f"Invalid username format: `{username}`")
            raise commands.UserInputError

        # Check that user is banned
        with db_conn() as db:
            db.execute(f'SELECT blocked, discord_id FROM ticketServer_tickets WHERE email = \'{username}\'')
            row = db.fetchone()

        if row == None:
            await ctx.author.send(f'Could not find an account with the username: `{username}`')
            return

        if row[0] == 0:
            print(f'{ctx.author} tried to unban {username} but they\'re not already banned.')
            await ctx.author.send(f'`{username}` is not already banned.')
            return

        # Unban the user
        with db_conn() as db:
            db.execute(f'UPDATE ticketServer_tickets SET blocked = 0 WHERE email = \'{username}\'')

        print(f'{ctx.author} unbanned {username} for: {reason}')

        discord_user = ctx.guild.get_member(int(row[1]))

        # Notify the user
        try:
            embed = discord.Embed(title='You were unbanned from 2HOL', colour=discord.Colour.green())
            embed.add_field(name='Reason:', value=f'{reason}', inline=True)
            await discord_user.send(embed=embed)

        except:
            # Message can fail if the user does not allow messages from anyone
            notify_user = False

        else:
            notify_user = True

        # Embed log
        embed = discord.Embed(title='Unbanned a user from the game', colour=discord.Colour.green())
        embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url)
        embed.add_field(name='Member:', value=f'{discord_user.name}#{discord_user.discriminator}', inline=True)
        embed.add_field(name='Username:'******'{username}', inline=True)
        embed.add_field(name='Reason:', value=f'{reason}', inline=True)
        embed.add_field(name='Notification:', value='Successful' if notify_user else 'Failed', inline=True)
        embed.set_footer(text=f"Member ID: {discord_user.id}", icon_url=discord_user.avatar_url)
        await log_channel.send(embed=embed)
Beispiel #2
0
    async def regenerate(self, ctx, user: discord.User):
        await ctx.message.delete()

        log_channel = await commands.TextChannelConverter().convert(ctx, config.read('log_channel_id'))

        key = await self.dictator.get_cog('User').create_key()

        with db_conn() as db:
            db.execute(f'UPDATE ticketServer_tickets SET login_key = \'{key}\' WHERE discord_id = \'{user.id}\'')

        # Notify the user
        try:
            embed = discord.Embed(title='Your key to access 2HOL has been regenerated.', colour=discord.Colour.green())
            await user.send(embed=embed)

        except:
            notify_user = False

        else:
            notify_user = True

        # Embed log
        embed = discord.Embed(title='User key regenerated', colour=discord.Colour.green())
        embed.add_field(name='User:'******'{user.mention}', inline=True)
        embed.add_field(name='Moderator:', value=f'{ctx.author.mention}', inline=True)
        embed.add_field(name='User notification:', value='Successful' if notify_user else 'Failed', inline=True)
        await log_channel.send(embed=embed)
Beispiel #3
0
    def playtime_less_than(self, discord_id, less_than_minutes):
        with db_conn() as db:
            db.execute(
                f'SELECT time_played FROM ticketServer_tickets WHERE discord_id = {discord_id}'
            )
            time_played = db.fetchone()

        return True if int(time_played[0]) < less_than_minutes else False
Beispiel #4
0
    async def info(self, ctx, user: discord.User):
        await ctx.message.delete()

        with db_conn() as db:
            db.execute(
                f'SELECT time_played, blocked, email, last_activity FROM ticketServer_tickets WHERE discord_id = \'{user.id}\''
            )
            user_info = db.fetchone()

        if not user_info:
            embed = discord.Embed(
                title=f'No results for the user \'{user.mention}\'.',
                colour=0xffbb35)
            await ctx.author.send(embed=embed)
            return

        # User hasn't lived a single life yet
        if user_info[0] == 0:
            embed = discord.Embed(
                title=
                f'\'{user.name}#{user.discriminator}\' (or {user_info[2]}) has not lived any lives yet.',
                colour=0xffbb35)
            await ctx.author.send(embed=embed)
            return

        # Time formatting
        current_time = datetime.datetime.now(tz=datetime.timezone.utc)
        current_time = current_time.replace(microsecond=0)
        last_active = datetime.datetime(year=user_info[3].year,
                                        month=user_info[3].month,
                                        day=user_info[3].day,
                                        hour=user_info[3].hour,
                                        minute=user_info[3].minute,
                                        second=user_info[3].second,
                                        tzinfo=datetime.timezone.utc)
        diff = current_time - last_active
        diff_split = str(diff).split(':')
        # diff_split[0] appears as '3 days, 4' where 3 = amount of days and 4 = amount of hours.
        diff_formatted = f'{diff_split[0]} hours, {diff_split[1]} minutes ago'

        member = ctx.guild.get_member(user.id)

        # Form embed
        embed = discord.Embed(
            title=f'Results for the user \'{user.name}#{user.discriminator}\':',
            colour=0xffbb35)
        embed.add_field(name='Time played:',
                        value=f'{round(user_info[0] / 60, 1)} hours')
        embed.add_field(name='Blocked:', value='Yes' if user_info[1] else 'No')
        embed.add_field(name='Joined guild:',
                        value=member.joined_at.date() if member else 'Unknown')
        embed.add_field(name='Username:'******'Last activity:', value=diff_formatted)
        embed.set_footer(text='Data range: August 2019 - Current')
        await ctx.author.send(embed=embed)
Beispiel #5
0
    async def create_bot(self, ctx, prefix, amount: int):
        await ctx.message.delete()

        # Filter prefix
        prefix = (re.sub('[^a-zA-Z0-9]', '', prefix))

        for i in range(amount):
            username = f'{prefix}-{i}'
            key = await self.create_key()

            with db_conn() as db:
                db.execute(f'INSERT INTO ticketServer_tickets (email, login_key) VALUES (\'{username}\', \'{key}\')')

            await ctx.author.send(f'{username} :: {key}')
Beispiel #6
0
    def username_from_player_id(self, player_id: int) -> str:
        """Takes an int as a players life ID and returns the associated username."""
        with db_conn() as db:
            """
            A player life ID can be repeated between different servers.
            We have made use of a single server for four years and do not intend to change this in the short term, so are largely unaffected by this.
            To resolve this, we assume we're only interested in the most recent player who lived with this ID.
            This is achieved with 'ORDER BY death_time DESC LIMIT 1'
            """
            db.execute(f'SELECT lineageServer_users.email FROM lineageServer_lives INNER JOIN lineageServer_users ON lineageServer_lives.user_id = lineageServer_users.id WHERE player_id = {player_id} ORDER BY death_time DESC LIMIT 1')
            username = db.fetchone()

        if not username:
            return
        else:
            # We really only want the first result of the tuple
            username = username[0]

        return username
Beispiel #7
0
    async def whowas(self, ctx, *, character_name):
        await ctx.message.delete()

        # Result limt, due to embed length limitations, the maxium is 8.
        history = 5

        player_id = None

        # Safe characters only
        character_name = re.sub(('[^a-zA-Z0-9 ]'), '', character_name)

        if self.is_int(character_name):
            # character_name is a player life ID, retrieve the associated character name.
            player_id = character_name    
            with db_conn() as db:
                """
                A player life ID can be repeated between different servers.
                We have made use of a single server for four years and do not intend to change this in the short term, so are largely unaffected by this.
                To resolve this, we assume we're only interested in the most recent player who lived with this ID.
                This is achieved with 'ORDER BY death_time DESC LIMIT 1'
                """
                db.execute(f'SELECT lineageServer_lives.name FROM lineageServer_lives WHERE player_id = {character_name} ORDER BY death_time DESC LIMIT 1')
                character_name = db.fetchone()

            if not character_name:
                embed = discord.Embed(title=f'No results for that player ID.', colour=0xffbb35)
                await ctx.send(embed=embed)
                return
            else:
                # We really only want the first result of the tuple
                character_name = character_name[0]

        with db_conn() as db:
            # I don't understand why I need to use %s instead of F strings. But it doesn't work otherwise.
            db.execute('SELECT ticketServer_tickets.discord_id, lineageServer_lives.death_time, lineageServer_users.email, lineageServer_lives.id, ticketServer_tickets.time_played FROM lineageServer_lives INNER JOIN lineageServer_users ON lineageServer_lives.user_id = lineageServer_users.id INNER JOIN ticketServer_tickets ON lineageServer_users.email = ticketServer_tickets.email WHERE name = %s ORDER BY death_time DESC LIMIT %s', (character_name, history))
            users = db.fetchall()

        if not users:
            embed = discord.Embed(title=f'No results for the character \'{character_name}\'.', description=f"Found name \'{character_name}\' from Player ID \'{player_id}\'" if player_id else "", colour=0xffbb35)
            await ctx.send(embed=embed)
            return

        current_time = datetime.datetime.now(tz=datetime.timezone.utc)
        current_time = current_time.replace(microsecond=0)
        embed = discord.Embed(title=f"Latest {history} results for the name \'{character_name}\':", description=f"Found name \'{character_name}\' from Player ID \'{player_id}\'" if player_id else "", colour=0xffbb35)
        embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar_url)

        for u in users:
            try:
                found_user = await self.dictator.fetch_user(u[0])

            except:
                raise commands.CommandError

            else:
                # Format death time as timezone aware
                death_time = datetime.datetime(year=u[1].year, month=u[1].month, day=u[1].day, hour=u[1].hour, minute=u[1].minute, second=u[1].second, tzinfo=datetime.timezone.utc)
                diff = current_time - death_time
                diff_split = str(diff).split(':')
                # diff_split[0] appears as '3 days, 4' where 3 = amount of days and 4 = amount of hours. I aplogise if you have to debug this.
                diff_formatted = f'{diff_split[0]} hours, {diff_split[1]} minutes ago'
                embed.add_field(name='Username:'******'{u[2]}', inline=True)
                embed.add_field(name='Member:', value=f'{found_user}', inline=True)
                embed.add_field(name='Died:', value=f'{diff_formatted}', inline=True)

        if len(users) < history:
            embed.add_field(name='\u200b', value='End of results')

        await ctx.send(embed=embed)
Beispiel #8
0
    async def create_user(self, user, username=None):
        if username is None:
            username = user.name

        # Filter username, can't have any nasty characters
        # Then replaces any non whitlisted (regex) characters with empty string
        username = (re.sub('[^a-zA-Z0-9]', '', username))

        if len(username) < 3:
            # Username was only made up of special chracters, prompt for one
            chosen_username = await self.prompt_user(user, f'Hey {user.mention}, your username doesn\'t contain enough valid characters. What should I use instead?')

            if chosen_username is None:
                await user.send('You didn\'t tell me what to use instead.')
                return

            else:
                await self.create_user(user, chosen_username)
                return

        # Check if user already has an account before creating one
        check_user = await self.search_user(user.id)

        if check_user is not None:
            # User already has an account
            username = check_user[0]
            key = check_user[1]
            print(f'We tried to create an account for {user} but they already had one, so we\'ll send them their login information.')
            await user.send(f'Hey {user.mention}, you already have an account! Here is your login information:\n**Username:** {username}\n**Key:** {key}')
            return

        # Can't be having usernames too long, database allows for up to 255 but seriously?
        if len(username) > 45:
            username = username[0:45]

        username += '-' + user.discriminator

        # Check if username is already in use
        check_name = await self.search_username(username)

        if check_name is not None:
            # Username is already in use, prompt for one
            chosen_username = await self.prompt_user(user, f'Hey {user.mention}, your username is already in use. What should I use instead?')

            if chosen_username is None:
                await user.send('You didn\'t tell me what to use instead.')
                return

            else:
                await self.create_user(user, chosen_username)
                return

        # Create the users accounnt, calling on create_key for a key
        key = str(await self.create_key())
        user_id = int(user.id)
        username = str(username)

        with db_conn() as db:
            db.execute(f'INSERT INTO ticketServer_tickets (email, discord_id, login_key) VALUES (\'{username}\', \'{user_id}\', \'{key}\')')

        # Notify the user
        try:
            await user.send(f'Welcome to 2HOL {user.mention}!\nYou can read how to start playing our game at <https://twohoursonelife.com/first-time-playing>\nWhen you\'re ready, you can use the details below to log in to the game:\n**Username:** {username}\n**Key:** {key}')

        except:
            notify_user = False

        else:
            notify_user = True

        debug_log_channel = self.dictator.get_channel(int(config.read('debug_log_channel_id')))

        # Embed log
        embed = discord.Embed(title='New game account created', colour=discord.Colour.green())
        embed.add_field(name='Member:', value=f'{user.mention}', inline=True)
        embed.add_field(name='Username:'******'{username}', inline=True)
        embed.add_field(name='User notification:', value='Successful' if notify_user else 'Failed', inline=True)
        await debug_log_channel.send(embed=embed)

        print(f'Successfully created an account for {user.name}#{user.discriminator} using the username {username}.')
Beispiel #9
0
 async def search_username(self, user):
     with db_conn() as db:
         db.execute(f'SELECT email FROM ticketServer_tickets WHERE email = \'{user}\'')
         row = db.fetchone()
         return row
Beispiel #10
0
 async def search_user(self, user_id):
     with db_conn() as db:
         db.execute(f'SELECT email, login_key FROM ticketServer_tickets WHERE discord_id = \'{user_id}\'')
         row = db.fetchone()
         return row