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)
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)
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)
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)