From 0a84a0c07c8a7dca21ce3e9ba4bba310c6af2997 Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Sat, 22 Mar 2025 17:35:50 -0600 Subject: [PATCH] Add in fren coin commands --- src/discord/fren_coin.rs | 125 ++++++++++++--------------------------- src/discord/mod.rs | 50 +++++++++++++++- src/models/task.rs | 2 +- 3 files changed, 87 insertions(+), 90 deletions(-) diff --git a/src/discord/fren_coin.rs b/src/discord/fren_coin.rs index e9f6ff9..3902434 100644 --- a/src/discord/fren_coin.rs +++ b/src/discord/fren_coin.rs @@ -1,94 +1,48 @@ -use crate::config::GlobalData; +use crate::discord::Context; use crate::error::Error; use crate::user::{User, UserError}; -use crate::{command, group}; -use rand::{thread_rng, Rng}; -use serenity::all::parse_user_mention; -use serenity::client::Context; -use serenity::framework::standard::{Args, CommandResult}; -use serenity::model::channel::Message; -use serenity::model::id::UserId; -use serenity::prelude::Mentionable; +use j_db::database::Database; +use log::info; +use poise::serenity_prelude::model::id::UserId; +use poise::serenity_prelude::prelude::Mentionable; +use rand::{rng, Rng}; -#[group] -#[commands(balance, gift)] -pub struct FrenCoin; +#[poise::command(prefix_command, category = "FrenCoin", aliases("audit"))] +pub async fn balance( + ctx: Context<'_>, + #[description = "User to get balance of"] user: Option, +) -> Result<(), Error> { + let user = user.unwrap_or(ctx.author().id); -#[command] -#[description("Get your current balance")] -#[aliases("audit")] -async fn balance(ctx: &Context, msg: &Message, args: Args) -> CommandResult { - let mut data = ctx.data.write().await; - let global_data = data.get_mut::().unwrap(); + let wallet = User::get_user(&ctx.data().db, user)?; - let user = if args.is_empty() { - msg.author.id - } else { - let mention = args.parse::().unwrap(); - parse_user_mention(&mention).unwrap() - }; - - let wallet = User::get_user(&global_data.db, user)?; - - msg.reply( - &ctx.http, - format!( - "{}'s current balance is {} fren coins!", - user.mention(), - wallet.coin_count - ), - ) + ctx.reply(format!( + "{}'s current balance is {} fren coins!", + user.mention(), + wallet.coin_count + )) .await?; Ok(()) } -#[command] -#[only_in(guilds)] -#[description("Gift your frens coins!")] -#[usage("@fren 25")] -async fn gift(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { - let target = args.parse::().unwrap(); - - let target = match parse_user_mention(&target) { - None => { - msg.reply( - &ctx.http, - "Gonna be real honest with you gamer, no clue who that is", - ) - .await?; - return Ok(()); - } - Some(t) => t, - }; - - args.advance(); - - let amount = match args.parse::() { - Ok(amount) => amount, - Err(err) => { - msg.reply(&ctx.http, format!("Invalid coin amount: {}", err)) - .await?; - return Ok(()); - } - }; - - let mut data = ctx.data.write().await; - let global_data = data.get_mut::().unwrap(); - - if let Err(e) = User::transfer_funds(&global_data.db, msg.author.id, target, amount) { +#[poise::command(prefix_command, category = "FrenCoin", aliases("audit"))] +pub async fn gift( + ctx: Context<'_>, + #[description = "User to gift coin to"] target: UserId, + #[description = "Amount of coins to give"] amount: u32, +) -> Result<(), Error> { + if let Err(e) = User::transfer_funds(&ctx.data().db, ctx.author().id, target, amount) { if let Error::UserError(err) = e { match err { UserError::NotEnoughFunds => { - msg.reply( - &ctx.http, + ctx.reply( "Sorry pal, I can't give credit. Come back when you're a bit mmmm richer.", ) .await?; } UserError::InvalidTarget => { - msg.reply( - &ctx.http, + ctx.reply( "Sorry pal, I can't make a friend up for you. Come back when you got friends.", ) .await?; @@ -97,14 +51,11 @@ async fn gift(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { } } } else { - msg.reply( - &ctx.http, - format!( - "You have gifted {} {} fren coins!", - target.mention(), - amount - ), - ) + ctx.reply(format!( + "You have gifted {} {} fren coins!", + target.mention(), + amount + )) .await?; } @@ -112,22 +63,20 @@ async fn gift(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { } pub async fn give_coin( - ctx: &Context, + db: &Database, user: UserId, percent: f64, number_of_coins: i64, ) -> Result { let should_get_coin = { - let mut thread_rng = thread_rng(); + let mut rng = rng(); - thread_rng.gen_bool(percent) + rng.random_bool(percent) }; if should_get_coin { - let mut data = ctx.data.write().await; - let global_data = data.get_mut::().unwrap(); - - User::give_funds(&global_data.db, user, number_of_coins as u32)?; + info!("Randomly giving {} {} fren coins", user, number_of_coins); + User::give_funds(db, user, number_of_coins as u32)?; } Ok(should_get_coin) diff --git a/src/discord/mod.rs b/src/discord/mod.rs index aea5efd..f5d0346 100644 --- a/src/discord/mod.rs +++ b/src/discord/mod.rs @@ -4,6 +4,7 @@ mod birthday; mod celeryman; mod color; mod emoji_race; +mod fren_coin; use crate::config::GlobalData; use crate::error::Error; @@ -11,9 +12,12 @@ use log::info; use std::sync::Arc; use std::time::Duration; +use crate::discord::fren_coin::give_coin; use crate::models::task::Task; -use poise::serenity_prelude::Message; +use poise::serenity_prelude::{Message, ReactionType}; use poise::{find_command, serenity_prelude as serenity, FrameworkOptions}; +use rand::prelude::IteratorRandom; +use rand::rng; pub type Context<'a> = poise::Context<'a, Arc, Error>; @@ -52,12 +56,54 @@ async fn event_handler( handle_unrecognised_commands(ctx, new_message, data).await?; } } + + handle_message(ctx, data, new_message).await?; } _ => {} } Ok(()) } +async fn handle_message( + ctx: &serenity::Context, + data: &Arc, + new_message: &Message, +) -> Result<(), Error> { + if new_message.content.to_lowercase().contains("good bot") { + let recv_coin = give_coin(&data.db, new_message.author.id, 0.50, 25).await?; + + if recv_coin { + let emojis = &new_message.guild_id.unwrap().emojis(&ctx.http).await?; + + let emoji = { + let mut rng = rng(); + emojis.iter().choose(&mut rng) + }; + + if let Some(emoji) = emoji { + new_message + .react( + &ctx.http, + ReactionType::Custom { + animated: emoji.animated, + id: emoji.id, + name: Some(emoji.name.clone()), + }, + ) + .await?; + }; + } + }; + + if new_message.content.to_lowercase().contains("bad bot") { + new_message.react(&ctx.http, '😭').await?; + } + + give_coin(&data.db, new_message.author.id, 0.05, 10).await?; + + Ok(()) +} + async fn handle_unrecognised_commands( ctx: &serenity::Context, message: &Message, @@ -125,6 +171,8 @@ pub async fn run_bot(global_data: GlobalData) { emoji_race::bet(), emoji_race::race(), emoji_race::start_race(), + fren_coin::balance(), + fren_coin::gift(), ], event_handler: |ctx, event, framework, data| { Box::pin(event_handler(ctx, event, framework, data)) diff --git a/src/models/task.rs b/src/models/task.rs index 0cadbee..57c24ad 100644 --- a/src/models/task.rs +++ b/src/models/task.rs @@ -76,7 +76,7 @@ impl Task { time, })?; - println!("Adding {:?} task to run at {}", task_type, time); + info!("Adding {:?} task to run at {}", task_type, time); Ok(()) }