예제 #1
0
    def add_name(self, u, dusr):
        self._logger.trace("add_name")
        usr = cassandra.get_user(u)

        name = dusr.name + "#" + dusr.discriminator

        if name in usr.names:
            # Dispatch event
            cassandra.dispatch("name-change", {
                "user": usr,
                "name": name,
                "known": True
            })
            return False  # Known name

        # Dispatch event
        cassandra.dispatch("name-change", {
            "user": usr,
            "name": dusr.nick,
            "known": False
        })

        usr.names.append(name)

        return True  # New name
예제 #2
0
    async def whois(self, ctx, member: discord.Member):
        self._logger.trace("whois")
        usr = cassandra.get_user((ctx.guild.id, member.id))
        if usr is None:
            await ctx.send("Couldn't get user information")
            return

        title = "%s#%s" % (member.name, member.discriminator)
        if member.nick is not None:
            title = title + ("(%s)" % member.nick)

        nicknames = "No nicknames tracked"
        nicklist = self.get_nicknames(usr)
        if len(nicklist) > 0:
            nicknames = "```" + ', '.join(nicklist) + '```'

        names = "No names tracked"
        namelist = self.get_names(usr)
        if len(namelist) > 0:
            names = "```" + ', '.join(namelist) + '```'

        embed = discord.Embed(title=title)
        embed.set_thumbnail(url=member.avatar_url)

        embed.add_field(name="ID", value=str(member.id))
        embed.add_field(name="Account Created",
                        value=str(member.created_at),
                        inline=True)
        embed.add_field(name="Joined At",
                        value=str(member.joined_at),
                        inline=True)
        embed.add_field(name="Nicknames", value=nicknames)
        embed.add_field(name="Names", value=names)

        await ctx.send(embed=embed)
예제 #3
0
    async def warn(self, ctx, member: discord.Member, *, reason=None):
        self._logger.trace("warn")
        # Audit log
        caudit = self.client.get_cog('Audit')
        if caudit is not None:
            if reason is None:
                await caudit.print_audit(
                    ctx.author, 'warning', "Warned %s#%s for no reason." %
                    (member.name, member.discriminator))
            else:
                await caudit.print_audit(
                    ctx.author, 'warning', "Warned %s#%s for **\"%s\"**." %
                    (member.name, member.discriminator, reason))

        reason_str = reason
        if reason is None:
            reason_str = "No reason given"

        embed = discord.Embed(title="%s %s: You have been warned!" %
                              (EMOJI_WARN, ctx.guild.name),
                              description="Reason: %s" % reason_str,
                              colour=discord.Colour.gold())

        await member.send(embed=embed)

        usr = cassandra.get_user((guild.id, member.id))

        # Dispatch event
        cassandra.dispatch("mod-warning", {
            "dauthor": ctx.author,
            "reason": reason,
            "duser": member,
            "user": usr
        })
예제 #4
0
    def add_nickname(self, u, dusr):
        self._logger.trace("add_nickname")
        usr = cassandra.get_user(u)

        if dusr.nick is None:
            return False  # Has no nick

        if dusr.nick in usr.nicknames:
            # Dispatch event
            cassandra.dispatch("nickname-change", {
                "user": usr,
                "nick": dusr.nick,
                "known": True
            })
            return False  # Known nick

        # Dispatch event
        cassandra.dispatch("nickname-change", {
            "user": usr,
            "nick": dusr.nick,
            "known": False
        })

        usr.nicknames.append(dusr.nick)

        return True  # New nick
예제 #5
0
    async def quarantine(self, ctx, member: discord.Member, *, reason=None):
        self._logger.trace("quarantine")

        usr = cassandra.get_user((ctx.guild.id, member.id))
        if usr.quarantine_status == True:
            await ctx.send("This user is already in quarantine!")
            return

        # Audit log
        caudit = self.client.get_cog('Audit')
        if caudit is not None:
            if reason is None:
                await caudit.print_audit(
                    ctx.author, 'quarantine',
                    "Quarantined %s#%s for no reason." %
                    (member.name, member.discriminator))
            else:
                await caudit.print_audit(
                    ctx.author, 'quarantine',
                    "Quarantined %s#%s for **\"%s\"**." %
                    (member.name, member.discriminator, reason))

        old_roles = []
        for role in member.roles:
            if role == ctx.guild.default_role:
                continue
            old_roles.append(role.id)
            try:
                await member.remove_roles(role, reason="Quarantine")
            except Exception as ex:
                self._logger.warn(
                    "Failed to remove role %s from member %s: %s" %
                    (role.name, member.name, ex))

        if usr.server.quarantine_role is not None:
            qrole = get(ctx.guild.roles, id=usr.server.quarantine_role)
            if qrole is not None:
                try:
                    await member.add_roles(qrole, reason="Quarantine")
                except Exception as ex:
                    self._logger.warn(
                        "Failed to add role %s to member %s: %s" %
                        (qrole.name, member.name, ex))

        # Dispatch event
        cassandra.dispatch("mod-quarantine", {
            "dauthor": ctx.author,
            "reason": reason,
            "duser": member,
            "user": usr
        })

        usr.quarantine_status = True
        usr.quarantine_roles = old_roles
        cassandra.save_user(usr)

        await ctx.send("User %s#%s has been quarantined." %
                       (member.name, member.discriminator))
예제 #6
0
    async def unquarantine(self, ctx, member: discord.Member):
        self._logger.trace("unquarantine")

        usr = cassandra.get_user((ctx.guild.id, member.id))
        if usr.quarantine_status == False:
            await ctx.send("This user is not in quarantine!")
            return


# Audit log
        caudit = self.client.get_cog('Audit')
        if caudit is not None:
            if reason is None:
                await caudit.print_audit(
                    ctx.author, 'unquarantine', "Unquarantined %s#%s." %
                    (member.name, member.discriminator))

        if usr.server.quarantine_role is not None:
            qrole = get(ctx.guild.roles, id=usr.server.quarantine_role)
            if qrole is not None:
                try:
                    await member.remove_roles(qrole, reason="Unquarantine")
                except Exception as ex:
                    self._logger.warn(
                        "Failed to remove role %s from member %s: %s" %
                        (qrole.name, member.name, ex))

        for roleid in usr.quarantine_roles:
            role = get(ctx.guild.roles, id=roleid)
            if role is None:
                continue
            if role == ctx.guild.default_role:
                continue
            try:
                await member.add_roles(role, reason="Unquarantine")
            except Exception as ex:
                self._logger.warn("Failed to add role %s to member %s: %s" %
                                  (role.name, member.name, ex))

        # Dispatch event
        cassandra.dispatch("mod-unquarantine", {
            "dauthor": ctx.author,
            "duser": member,
            "user": usr
        })

        usr.quarantine_status = False
        usr.quarantine_roles = []
        cassandra.save_user(usr)

        await ctx.send("User %s#%s has been released form quarantine." %
                       (member.name, member.discriminator))
예제 #7
0
    def add_balance(self, u, amt):
        self._logger.trace("add_balance")
        usr = cassandra.get_user(u)
        old = usr.balance

        resp = cassandra.dispatch("balance-change", {
            "old": old,
            "new": old + amt,
            "user": usr
        })

        usr.balance = resp.new
        return usr.balance  # New balance
예제 #8
0
    async def profile(self, ctx, name=None):
        self._logger.trace("profile")
        # Do not do anything on private messages
        if ctx.guild == None:
            return

        uid = ctx.author.id
        if name is not None:
            if name.startswith("<@!") and name.endswith(">"):
                uid = name[3:len(name) - 1]

        usr = cassandra.get_user((ctx.guild.id, uid))
        if usr is None:
            await ctx.send("User not found.")
            return

        discord_user = self.client.get_user(usr.ID)
        if discord_user is None:
            await ctx.send("User not found.")
            return

        content = ""
        cecon = self.client.get_cog('Economy')
        if cecon is not None:
            content = content + ":moneybag: Coins: %s" % cecon.get_balance(usr)

        cxp = self.client.get_cog('Xp')
        if cxp is not None:
            content = content + "\n:star: XP:    %s" % cxp.get_xp(usr)
            content = content + "\n:star2: Level: %s" % cxp.get_level(usr)

        embed = discord.Embed(title="Profile for %s on server %s" %
                              (discord_user.name, ctx.guild.name),
                              description=content,
                              colour=discord.Colour.gold())
        embed.set_thumbnail(url=discord_user.avatar_url)

        stats = self.client.get_cog('Stats')
        if stats is not None:
            embed.add_field(name=":writing_hand: Messages",
                            value="Total: %s" % stats.get_msg(usr),
                            inline=True)
            embed.add_field(name=":heart: Reactions",
                            value="Total: %s" % stats.get_reaction(usr),
                            inline=True)
            embed.add_field(name=":microphone2: Voice",
                            value="Time: %s" %
                            util.sec2human(stats.get_voice(usr)),
                            inline=True)

        await ctx.send(embed=embed)
예제 #9
0
    async def on_member_join(self, member):
        self._logger.trace("on_member_join")
        usr = cassandra.get_user((member.guild.id, member.id))

        update = False

        if self.add_name(usr, member):
            update = True

        if self.add_nickname(usr, member):
            update = True

        if update:
            cassandra.save_user(usr)
예제 #10
0
    async def update(self):
        self._logger.trace("update")

        for guild in self.client.guilds:
            # Do not do anything for unavailable guilds
            if guild.unavailable == True:
                continue

            for member in guild.members:
                # If member is a bot, ignore
                if member.bot:
                    continue

                usr = cassandra.get_user((guild.id, member.id))
                self.add_nickname(usr, member)
                self.add_name(usr, member)
예제 #11
0
    async def on_message(self, message):
        # Ignore messages from bots
        if message.author.bot == True:
            return

        # Ignore direct messages
        if message.guild is None:
            return

        self._logger.trace("on_message(%s)" % message.content)

        srv = cassandra.get_server(message.guild.id)
        # TODO: Check if server is not found

        # Ignore commands to cassandra
        if message.content.startswith(srv.prefix_used):
            return

        # Ignore commands to other bots
        for prefix in srv.prefix_blocked:
            if message.content.startswith(prefix):
                return

        usr = cassandra.get_user((srv, message.author.id))
        # TODO: Check if user is not found

        ts = util.getts()
        usr.msg_last = ts
        usr.msg_count = usr.msg_count + 1

        #if msg timeout is reached award coins
        if ts - usr.msg_awarded > MSG_TIMEOUT:
            usr.msg_awarded = ts

            # Add balance if economy cog is loaded
            cecon = self.client.get_cog('Economy')
            if cecon is not None:
                cecon.add_balance(usr, MSG_BONUS_COINS)

            # Add xp if xp cog is loaded
            cxp = self.client.get_cog('Xp')
            if cxp is not None:
                cxp.add_xp(usr, MSG_BONUS_XP)

        cassandra.save_user(usr)
예제 #12
0
    async def update_voice(self):
        self._logger.trace("update_voice")

        # For all voice channels on each guild
        for guild in self.client.guilds:

            # Do not do anything for unavailable guilds
            if guild.unavailable == True:
                continue

            # For each voice channel in each guild
            for vchannel in guild.voice_channels:
                vchmem = len(vchannel.members)

                # No need to look into a voice channel with one or no active members
                if vchmem < 2:
                    continue

                # For each current member
                for member in vchannel.members:
                    if member.voice.afk:
                        continue
                    elif member.voice.deaf or member.voice.self_deaf:
                        continue
                    elif member.voice.mute or member.voice.self_mute:
                        continue

                    usr = cassandra.get_user((guild.id, member.id))
                    usr.voice_time = usr.voice_time + VOICE_TIMEOUT

                    # Add balance if economy cog is loaded
                    cecon = self.client.get_cog('Economy')
                    if cecon is not None:
                        cecon.add_balance(usr, VOICE_BONUS_COINS)

                    # Add xp if xp cog is loaded
                    cxp = self.client.get_cog('Xp')
                    if cxp is not None:

                        # Give an xp bonus for more people in the voicechat
                        xp = VOICE_BONUS_XP + (vchmem - 2)
                        cxp.add_xp(usr, xp)

                    cassandra.save_user(usr)
예제 #13
0
    async def print_audit(self, author, type, message):
        self._logger.trace("print_audit")
        usr = cassandra.get_user((author.guild.id, author.id))
        # TODO: Passed user class

        # TODO: Check for user not found

        # Check if the server audit log is enabled
        if usr.server.audit_channel is None:
            return False

        # Check if the audit log channel exists
        ch = self.client.get_channel(usr.server.audit_channel)
        if ch is None:
            return False

        # TODO: Check if audits of this type are enabled

        # Send audit log
        await ch.send("<@!%s>: %s" % (usr.ID, message))

        return True
예제 #14
0
    async def ban(self, ctx, member: discord.Member, *, reason=None):
        self._logger.trace("ban")
        # TODO: Tempban

        # Audit log
        caudit = self.client.get_cog('Audit')
        if caudit is not None:
            if reason is None:
                await caudit.print_audit(
                    ctx.author, 'ban', "Baned %s#%s for no reason." %
                    (member.name, member.discriminator))
            else:
                await caudit.print_audit(
                    ctx.author, 'ban', "Baned %s#%s for **\"%s\"**." %
                    (member.name, member.discriminator, reason))

        if reason is None:
            reason = "No reason given"

        embed = discord.Embed(title="%s %s: The BAN-HAMMER has spoken!" %
                              (EMOJI_BAN, ctx.guild.name),
                              description="Reason: %s" % reason,
                              colour=discord.Colour.red())

        # We need to send the message first because discord does not let you send messages to users that have no servers in common
        await member.send(embed=embed)

        usr = cassandra.get_user((guild.id, member.id))

        # Dispatch event
        cassandra.dispatch("mod-ban", {
            "dauthor": ctx.author,
            "reason": reason,
            "duser": member,
            "user": usr
        })

        await member.ban(reason=reason)
예제 #15
0
    async def update_user(self, guild, user, lv_role_cache=None):
        self._logger.trace("update_user(%s)" % user.id)
        if lv_role_cache is None:
            lv_role_cache = self._build_level_rank_cache(guild)

        # If user is a bot, ignore
        if user.bot:
            return

        level = self.client.get_cog('Xp').get_level((guild.id, user.id))

        highest_role = None
        for lv in lv_role_cache:
            role = lv_role_cache[lv]
            if level < lv:
                break
            highest_role = role

        if highest_role is None:
            return

        if highest_role in user.roles:
            return

        for urole in user.roles:
            if urole in lv_role_cache.values():
                await user.remove_roles(
                    urole, reason="Userlevel rank"
                )  # TODO: There must be a more efficient way to do this
        await user.add_roles(highest_role, reason="Userlevel change")

        # Dispatch event
        cassandra.dispatch(
            "lvrole-change", {
                "duser": user,
                "user": cassandra.get_user((guild.id, user.id)),
                "role": highest_role
            })
예제 #16
0
    async def on_reaction_add(self, reaction, user):
        self._logger.trace("on_reaction_add")
        # Ignore reactions from bots
        if user.bot == True:
            return

        # Ignore private messages
        if reaction.message.guild is None:
            return

        # Ignore reactions made to messages written by bots
        if reaction.message.author.bot == True:
            return

        usr = cassandra.get_user((reaction.message.guild.id, user.id))

        # TODO: Handle user not found

        ts = util.getts()
        usr.reaction_last = ts

        # if reaction timeout is reached award coins
        if ts - usr.reaction_awarded > REACTION_TIMEOUT:
            usr.reaction_awarded = ts

            # Add balance if economy cog is loaded
            cecon = self.client.get_cog('Economy')
            if cecon is not None:
                cecon.add_balance(usr, REACTION_BONUS_COINS)

            # Add xp if xp cog is loaded
            cxp = self.client.get_cog('Xp')
            if cxp is not None:
                cxp.add_xp(usr, REACTION_BONUS_XP)

        usr.reaction_count = usr.reaction_count + 1

        cassandra.save_user(usr)
예제 #17
0
    async def kick(self, ctx, member: discord.Member, *, reason=None):
        self._logger.trace("kick")

        # Audit log
        caudit = self.client.get_cog('Audit')
        if caudit is not None:
            if reason is None:
                await caudit.print_audit(
                    ctx.author, 'kick', "Kicked %s#%s for no reason." %
                    (member.name, member.discriminator))
            else:
                await caudit.print_audit(
                    ctx.author, 'kick', "Kicked %s#%s for **\"%s\"**." %
                    (member.name, member.discriminator, reason))

        if reason is None:
            reason = "No reason given"

        embed = discord.Embed(title="%s %s: You have beed kicked!" %
                              (EMOJI_INFO, ctx.guild.name),
                              description="Reason: %s" % reason,
                              colour=discord.Colour.dark_orange())

        # We need to send the message first because discord does not let you send messages to users that have no servers in common
        await member.send(embed=embed)

        usr = cassandra.get_user((guild.id, member.id))

        # Dispatch event
        cassandra.dispatch("mod-kick", {
            "dauthor": ctx.author,
            "reason": reason,
            "duser": member,
            "user": usr
        })

        await member.kick(reason=reason)
예제 #18
0
 def get_balance(self, u):
     self._logger.trace("get_balance")
     usr = cassandra.get_user(u)
     return usr.balance  # Balance
예제 #19
0
 def has_balance(self, u, amt):
     self._logger.trace("has_balance")
     usr = cassandra.get_user(u)
     return usr.balance >= amt
예제 #20
0
 def get_reaction(self, u):
     self._logger.trace("get_reaction")
     usr = cassandra.get_user(u)
     return usr.reaction_count
예제 #21
0
 def get_voice(self, u):
     self._logger.trace("get_voice")
     usr = cassandra.get_user(u)
     return usr.voice_time
예제 #22
0
 def is_user_quarantined(self, u):
     usr = cassandra.get_user(u)
     return usr.quarantine_status
예제 #23
0
 def get_msg(self, u):
     self._logger.trace("get_msg")
     usr = cassandra.get_user(u)
     return usr.msg_count
예제 #24
0
    async def coinflip(self, ctx, side=None, bet=None):
        self._logger.trace("coinflip")
        if side is None:
            await self._usage_coinflip(ctx)
            return

        bet = self._get_bet(bet)
        if bet is None:
            await self._usage_coinflip(ctx)
            return

        usr = None
        if bet > 0:
            usr = cassandra.get_user((ctx.guild.id, ctx.author.id))

            #  Check if the user of this command has that much money
            if not await self._can_afford(ctx, usr, bet):
                return

        rng_side = -1
        if side == "heads":
            rng_side = 0
        elif side == "tails":
            rng_side = 1
        else:
            await self._usage_coinflip(ctx)
            return

        flip = random.randint(0, 1)

        thumbnail = None
        flip_str = None
        if flip == 1:
            flip_str = "tails"
            thumbnail = IMAGE_TAILS
        else:
            flip_str = "heads"
            thumbnail = IMAGE_HEADS

        won = (flip == rng_side)

        color = None
        description = "It's **%s**\n" % flip_str

        if won:
            color = discord.Colour.green()
            description = description + "You won"
        else:
            color = discord.Colour.red()
            description = description + "You lost"

        if bet > 0:
            cecon = self.client.get_cog(
                'Economy'
            )  # This can always be found because of the _can_afford check

            if won:
                cecon.add_balance(usr, bet)
            else:
                cecon.add_balance(usr, -bet)

            description = description + (" %s " % bet) + EMOJI_MONEY + (
                "\nYou now have %s " % usr.balance) + EMOJI_MONEY

        embed = discord.Embed(title="Coinflip",
                              colour=color,
                              description=description)
        embed.set_thumbnail(url=thumbnail)

        await ctx.send(embed=embed)

        if usr:
            cassandra.save_user(usr)
예제 #25
0
    async def spin(self, ctx):
        self._logger.trace("spin")
        ods = [{
            "symbol": "<:c500:710482148305403924>",
            "propbability": 1,
            "ods": 500,
            "name": "MYTHIC"
        }, {
            "symbol": "<:c100:710482154500653056>",
            "propbability": 2,
            "ods": 100,
            "name": "IMORTAL"
        }, {
            "symbol": "<:c50:710482156895469691>",
            "propbability": 4,
            "ods": 50,
            "name": "LEGENDARY"
        }, {
            "symbol": "<:c25:710482155310022758>",
            "propbability": 8,
            "ods": 25,
            "name": "EPIC"
        }, {
            "symbol": "<:c10:710482151484817439>",
            "propbability": 16,
            "ods": 10,
            "name": "RARE"
        }, {
            "symbol": "<:c5:710482137895403520>",
            "propbability": 24,
            "ods": 5,
            "name": "UNCOMMON"
        }, {
            "symbol": "<:c1:710482104705613845>",
            "propbability": 48,
            "ods": 1,
            "name": "COMMON"
        }]

        usr = cassandra.get_user((ctx.guild.id, ctx.author.id))

        ts = util.getts()
        if ts - usr.casino_last_spin < 300:
            await ctx.send("You have to wait " +
                           util.sec2human(300 - (ts - usr.casino_last_spin)) +
                           " for your next chance of a reward.")
            return

        total = 0
        for outcome in ods:
            total = total + outcome["propbability"]

        rand = random.randint(0, total)
        index = 0
        out = None
        while rand > 0:
            outcome = ods[index]
            rand = rand - outcome["propbability"]

            if rand <= 0:
                out = outcome
                break
            index = index + 1

        # FIX: This is a drity fix, as we should never end up here
        if out is None:
            out = ods[0]

        embed = discord.Embed(
            title=ctx.author.display_name + " spins the wheel ...",
            description="<a:spin:710491435006165032> | Spinning ...",
            colour=discord.Colour.green())

        msg = await ctx.send(embed=embed)

        # FIX: Replace this with a timer, because this forces only one player (in al servers) to be able to spin at once
        time.sleep(1)

        description = "%s | Landed on **%s**" % (out["symbol"], out["name"])

        cecon = self.client.get_cog('Economy')
        if cecon is not None:
            reward = out["ods"]

            # Multiply reward by user level
            cxp = self.client.get_cog('Xp')
            if cxp is not None:
                level = cxp.get_level(usr)
                if level > 1:
                    reward = reward * level

            description = description + ("\nYou got a reward of %s coins" %
                                         reward)
            cecon.add_balance(usr, reward)
        else:
            description = description + (
                "\n\n%s You did not get a reward, because the economy is not setup!"
                % EMOJI_WARN)

        embed = discord.Embed(title=ctx.author.display_name +
                              " Spun the wheel",
                              description=description,
                              colour=discord.Colour.green())

        await msg.edit(embed=embed)

        usr.casino_last_spin = ts
        cassandra.save_user(usr)
예제 #26
0
    async def on_member_update(self, before, after):
        self._logger.trace("on_member_update")
        usr = cassandra.get_user((after.guild.id, after.id))

        if self.add_nickname(usr, after):
            cassandra.save_user(usr)
예제 #27
0
    async def on_user_join(self, member):
        usr = cassandra.get_user((member.guild.id, member.id))

        if self.add_nickname(usr, member):
            cassandra.save_user(usr)
예제 #28
0
 def get_names(self, u):
     self._logger.trace("get_names")
     usr = cassandra.get_user(u)
     return usr.names