async def tipfavorites_cmd(self, ctx: Context):
        if ctx.error:
            await Messages.add_x_reaction(ctx.message)
            return

        msg = ctx.message
        user = ctx.user
        send_amount = ctx.send_amount

        # Check anti-spam
        if not ctx.god and await RedisDB.instance().exists(f"tipfavoritesspam{msg.author.id}"):
            await Messages.add_timer_reaction(msg)
            await Messages.send_basic_dm(msg.author, "You can only tipfavorites once every 5 minutes")
            return

        # Get their favorites
        favorites = await Favorite.filter(user=user).prefetch_related('favorited_user').all()
        if len(favorites) < 1:
            await Messages.add_x_reaction(msg)
            await Messages.send_error_dm(msg.author, "You don't have any favorites, add some first.")
            return

        individual_send_amount = NumberUtil.truncate_digits(send_amount / len(favorites), max_digits=Env.precision_digits())
        if individual_send_amount < Constants.TIP_MINIMUM:
            await Messages.add_x_reaction(msg)
            await Messages.send_error_dm(msg.author, f"Tip amount too small, each user needs to receive at least {Constants.TIP_MINIMUM}. With your tip they'd only be getting {individual_send_amount}")
            return

        # See how much they need to make this tip.
        amount_needed = individual_send_amount * len(favorites)
        available_balance = Env.raw_to_amount(await user.get_available_balance())
        if amount_needed > available_balance:
            await Messages.add_x_reaction(msg)
            await Messages.send_error_dm(msg.author, f"Your balance isn't high enough to complete this tip. You have **{available_balance} {Env.currency_symbol()}**, but this tip would cost you **{amount_needed} {Env.currency_symbol()}**")
            return

        # Make the transactions in the database
        tx_list = []
        task_list = []

        for u in favorites:
            tx = await Transaction.create_transaction_internal_dbuser(
                sending_user=user,
                amount=individual_send_amount,
                receiving_user=u.favorited_user
            )
            if tx is not None:
                tx_list.append(tx)
                if not await user.is_muted_by(u.favorited_user.id):
                    task_list.append(
                        Messages.send_basic_dm(
                            member=self.bot.get_user(u.favorited_user.id),
                            message=f"You were tipped **{individual_send_amount} {Env.currency_symbol()}** by {msg.author.name.replace('`', '')}.\nUse `{config.Config.instance().command_prefix}mute {msg.author.id}` to disable notifications for this user."
                        )
                    )
        if len(tx_list) < 1:
            await Messages.add_x_reaction(msg)
            await Messages.send_error_dm(msg.author, f"No users you mentioned are eligible to receive tips.")
            return
        # Send DMs
        asyncio.ensure_future(Utils.run_task_list(task_list))
        # Add reactions
        await Messages.add_tip_reaction(msg, amount_needed)
        # Queue the actual sends
        for tx in tx_list:
            await TransactionQueue.instance().put(tx)
        # anti spam
        await RedisDB.instance().set(f"tipfavoritesspam{msg.author.id}", "as", expires=300)
        # Update stats
        stats: Stats = await user.get_stats(server_id=msg.guild.id)
        if msg.channel.id not in config.Config.instance().get_no_stats_channels():
            await stats.update_tip_stats(amount_needed)
Beispiel #2
0
    async def tiprandom_cmd(self, ctx: Context):
        if ctx.error:
            await Messages.add_x_reaction(ctx.message)
            return

        msg = ctx.message
        user = ctx.user
        send_amount = ctx.send_amount

        # Check anti-spam
        if not ctx.god and await RedisDB.instance().exists(
                f"tiprandomspam{msg.guild.id}{msg.author.id}"):
            await Messages.add_timer_reaction(msg)
            await Messages.send_basic_dm(
                msg.author, "You can only tiprandom once every minute")
            return

        active_users = await rain.RainCog.get_active(ctx,
                                                     excluding=msg.author.id)

        if len(active_users) < Constants.RAIN_MIN_ACTIVE_COUNT:
            await Messages.send_error_dm(
                msg.author,
                f"There aren't enough active people to do a random tip. Only **{len(active_users)}** are active, but I'd like to see at least **{Constants.RAIN_MIN_ACTIVE_COUNT}**"
            )
            return

        target_user = secrets.choice(active_users)

        # See how much they need to make this tip.
        available_balance = Env.raw_to_amount(await
                                              user.get_available_balance())
        if send_amount > available_balance:
            await Messages.add_x_reaction(ctx.message)
            await Messages.send_error_dm(
                msg.author,
                f"Your balance isn't high enough to complete this tip. You have **{available_balance} {Env.currency_symbol()}**, but this tip would cost you **{send_amount} {Env.currency_symbol()}**"
            )
            return

        # Make the transactions in the database
        tx = await Transaction.create_transaction_internal_dbuser(
            sending_user=user, amount=send_amount, receiving_user=target_user)
        task_list = []
        if not await user.is_muted_by(target_user.id):
            task_list.append(
                Messages.send_basic_dm(
                    member=msg.guild.get_member(target_user.id),
                    message=
                    f"You were randomly selected and received **{send_amount} {Env.currency_symbol()}** from {msg.author.name.replace('`', '')}.\nUse `{config.Config.instance().command_prefix}mute {msg.author.id}` to disable notifications for this user.",
                    skip_dnd=True))
        task_list.append(
            Messages.send_basic_dm(
                member=msg.author,
                message=
                f'"{target_user.name}" was the recipient of your random tip of {send_amount} {Env.currency_symbol()}'
            ))
        asyncio.ensure_future(Utils.run_task_list(task_list))
        # Add reactions
        await Messages.add_tip_reaction(msg, send_amount)
        # Queue the actual send
        await TransactionQueue.instance().put(tx)
        # anti spam
        await RedisDB.instance().set(
            f"tiprandomspam{msg.guild.id}{msg.author.id}", "as", expires=60)
        # Update stats
        stats: Stats = await user.get_stats(server_id=msg.guild.id)
        if msg.channel.id not in config.Config.instance(
        ).get_no_stats_channels():
            await stats.update_tip_stats(send_amount)
Beispiel #3
0
    async def rain_cmd(self, ctx: Context):
        if ctx.error:
            return

        msg = ctx.message
        user = ctx.user
        send_amount = ctx.send_amount

        anon = 'anon' in msg.content

        # Get active users
        active_users = await self.get_active(ctx, excluding=msg.author.id)

        if len(active_users) < Constants.RAIN_MIN_ACTIVE_COUNT:
            await Messages.add_x_reaction(msg)
            await Messages.send_error_dm(
                msg.author,
                f"Not enough users are active to rain - I need at least {Constants.RAIN_MIN_ACTIVE_COUNT} but there's only {len(active_users)} active bros"
            )
            return

        individual_send_amount = Env.truncate_digits(
            send_amount / len(active_users), max_digits=Env.precision_digits())
        individual_send_amount_str = f"{individual_send_amount:.2f}" if Env.banano(
        ) else f"{individual_send_amount:.6f}"
        if individual_send_amount < Constants.TIP_MINIMUM:
            await Messages.add_x_reaction(msg)
            await Messages.send_error_dm(
                msg.author,
                f"Amount is too small to divide across {len(active_users)} users"
            )
            return

        # See how much they need to make this tip.
        amount_needed = Env.truncate_digits(individual_send_amount *
                                            len(active_users),
                                            max_digits=Env.precision_digits())
        available_balance = Env.raw_to_amount(await
                                              user.get_available_balance())
        if amount_needed > available_balance:
            await Messages.add_x_reaction(msg)
            await Messages.send_error_dm(
                msg.author,
                f"Your balance isn't high enough to complete this tip. You have **{available_balance} {Env.currency_symbol()}**, but this tip would cost you **{amount_needed} {Env.currency_symbol()}**"
            )
            return

        # Make the transactions in the database
        tx_list = []
        task_list = []
        for u in active_users:
            tx = await Transaction.create_transaction_internal_dbuser(
                sending_user=user,
                amount=individual_send_amount,
                receiving_user=u)
            tx_list.append(tx)
            if not await user.is_muted_by(u.id):
                if not anon:
                    task_list.append(
                        Messages.send_basic_dm(
                            member=msg.guild.get_member(u.id),
                            message=
                            f"You were tipped **{individual_send_amount_str} {Env.currency_symbol()}** by {msg.author.name.replace('`', '')}.\nUse `{config.Config.instance().command_prefix}mute {msg.author.id}` to disable notifications for this user.",
                            skip_dnd=True))
                else:
                    task_list.append(
                        Messages.send_basic_dm(
                            member=msg.guild.get_member(u.id),
                            message=
                            f"You were tipped **{individual_send_amount_str} {Env.currency_symbol()}** anonymously!",
                            skip_dnd=True))
        # Send DMs in the background
        asyncio.ensure_future(Utils.run_task_list(task_list))
        # Add reactions
        await Messages.add_tip_reaction(msg, amount_needed, rain=True)
        # Queue the actual sends
        for tx in tx_list:
            await TransactionQueue.instance().put(tx)
        # Add anti-spam
        await RedisDB.instance().set(f"rainspam{msg.author.id}",
                                     "as",
                                     expires=300)
        # Update stats
        stats: Stats = await user.get_stats(server_id=msg.guild.id)
        if msg.channel.id not in config.Config.instance(
        ).get_no_stats_channels():
            await stats.update_tip_stats(amount_needed)
        # DM creator
        await Messages.send_success_dm(
            msg.author,
            f"You rained **{amount_needed} {Env.currency_symbol()}** to **{len(tx_list)} users**, they received **{individual_send_amount_str} {Env.currency_symbol()}** each.",
            header="Make it Rain")
        # Make the rainer auto-rain eligible
        await self.auto_rain_eligible(msg)
Beispiel #4
0
    async def tipsplit_cmd(self, ctx: Context):
        if ctx.error:
            await Messages.add_x_reaction(ctx.message)
            return

        msg = ctx.message
        user = ctx.user
        send_amount = ctx.send_amount

        # Get all eligible users to tip in their message
        users_to_tip = []
        for m in msg.mentions:
            if not m.bot and m.id != msg.author.id:
                users_to_tip.append(m)
        if len(users_to_tip) < 1:
            await Messages.add_x_reaction(msg)
            await Messages.send_error_dm(
                msg.author,
                f"No users you mentioned are eligible to receive tips.")
            return

        individual_send_amount = NumberUtil.truncate_digits(
            send_amount / len(users_to_tip), max_digits=Env.precision_digits())
        if individual_send_amount < Constants.TIP_MINIMUM:
            await Messages.add_x_reaction(msg)
            await Messages.send_error_dm(
                msg.author,
                f"Tip amount too small, each user needs to receive at least {Constants.TIP_MINIMUM}. With your tip they'd only be getting {individual_send_amount}"
            )
            return

        # See how much they need to make this tip.
        amount_needed = individual_send_amount * len(users_to_tip)
        available_balance = Env.raw_to_amount(await
                                              user.get_available_balance())
        if amount_needed > available_balance:
            await Messages.add_x_reaction(msg)
            await Messages.send_error_dm(
                msg.author,
                f"Your balance isn't high enough to complete this tip. You have **{available_balance} {Env.currency_symbol()}**, but this tip would cost you **{amount_needed} {Env.currency_symbol()}**"
            )
            return

        # Make the transactions in the database
        tx_list = []
        task_list = []
        for u in users_to_tip:
            tx = await Transaction.create_transaction_internal(
                sending_user=user,
                amount=individual_send_amount,
                receiving_user=u)
            if tx is not None:
                tx_list.append(tx)
                if not await user.is_muted_by(u.id):
                    task_list.append(
                        Messages.send_basic_dm(
                            member=u,
                            message=
                            f"You were tipped **{individual_send_amount} {Env.currency_symbol()}** by {msg.author.name.replace('`', '')}.\nUse `{config.Config.instance().command_prefix}mute {msg.author.id}` to disable notifications for this user.",
                            skip_dnd=True))
        if len(tx_list) < 1:
            await Messages.add_x_reaction(msg)
            await Messages.send_error_dm(
                msg.author,
                f"No users you mentioned are eligible to receive tips.")
            return
        # Send DMs
        asyncio.ensure_future(Utils.run_task_list(task_list))
        # Add reactions
        await Messages.add_tip_reaction(msg, amount_needed)
        # Queue the actual sends
        for tx in tx_list:
            await TransactionQueue.instance().put(tx)
        # Update stats
        stats: Stats = await user.get_stats(server_id=msg.guild.id)
        if msg.channel.id not in config.Config.instance(
        ).get_no_stats_channels():
            await stats.update_tip_stats(amount_needed)