diff --git a/src/discord/color.rs b/src/discord/color.rs index 4362524..81fb25c 100644 --- a/src/discord/color.rs +++ b/src/discord/color.rs @@ -3,7 +3,7 @@ use crate::error::Error; use poise::serenity_prelude::builder::EditRole; use poise::serenity_prelude::model::Colour; -#[poise::command(prefix_command, guild_only, category = "Color")] +#[poise::command(prefix_command, guild_only, category = "color")] pub async fn set_color( ctx: Context<'_>, #[description = "Color you want your role to be"] diff --git a/src/discord/fren_coin.rs b/src/discord/fren_coin.rs index 3902434..7c80af0 100644 --- a/src/discord/fren_coin.rs +++ b/src/discord/fren_coin.rs @@ -10,9 +10,9 @@ use rand::{rng, Rng}; #[poise::command(prefix_command, category = "FrenCoin", aliases("audit"))] pub async fn balance( ctx: Context<'_>, - #[description = "User to get balance of"] user: Option, + #[description = "User to get balance of"] user: Option, ) -> Result<(), Error> { - let user = user.unwrap_or(ctx.author().id); + let user = user.map(|u| u.id).unwrap_or(ctx.author().id); let wallet = User::get_user(&ctx.data().db, user)?; @@ -29,10 +29,10 @@ pub async fn balance( #[poise::command(prefix_command, category = "FrenCoin", aliases("audit"))] pub async fn gift( ctx: Context<'_>, - #[description = "User to gift coin to"] target: UserId, + #[description = "User to gift coin to"] target: poise::serenity_prelude::User, #[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 Err(e) = User::transfer_funds(&ctx.data().db, ctx.author().id, target.id, amount) { if let Error::UserError(err) = e { match err { UserError::NotEnoughFunds => { diff --git a/src/discord/mod.rs b/src/discord/mod.rs index 5d3564e..042ddb5 100644 --- a/src/discord/mod.rs +++ b/src/discord/mod.rs @@ -8,6 +8,7 @@ mod fren_coin; mod joke; mod little_fren; mod motivate; +pub(crate) mod shop; use crate::config::GlobalData; use crate::error::Error; @@ -19,7 +20,7 @@ use crate::discord::fren_coin::give_coin; use crate::discord::joke::random; use crate::models::lil_fren::lil_fren_task; use crate::models::task::Task; -use poise::serenity_prelude::{Message, ReactionType}; +use poise::serenity_prelude::{GuildId, Http, Message, ReactionType, RoleId}; use poise::{find_command, serenity_prelude as serenity, FrameworkOptions}; use rand::prelude::IteratorRandom; use rand::rng; @@ -200,6 +201,12 @@ pub async fn run_bot(global_data: GlobalData) { little_fren::play(), motivate::motivation(), motivate::motivation_add_album(), + shop::buy(), + shop::inventory(), + shop::item_help(), + shop::sell_item(), + shop::shop(), + shop::use_item(), ], event_handler: |ctx, event, framework, data| { Box::pin(event_handler(ctx, event, framework, data)) @@ -232,3 +239,17 @@ pub async fn run_bot(global_data: GlobalData) { client.start().await.unwrap(); } + +pub async fn get_role( + http: &Http, + guild_id: GuildId, + role_name: &str, +) -> Result, Error> { + Ok(guild_id + .roles(http) + .await? + .iter() + .find(|(_, role)| role.name == role_name) + .map(|(role_id, _)| role_id) + .copied()) +} diff --git a/src/discord/shop.rs b/src/discord/shop.rs index f7d6aed..0a9aa61 100644 --- a/src/discord/shop.rs +++ b/src/discord/shop.rs @@ -1,40 +1,31 @@ -use crate::discord::get_role; +use crate::config::GlobalData; use crate::discord::motivate::create_motivation_image; +use crate::discord::{get_role, Context}; use crate::error::Error; use crate::inventory::{nft_value, InventoryError, ItemData, ItemType, Operation}; use crate::models::motivation::MotivationConfig; use crate::models::task::{Task, TaskType}; use crate::user::{User, UserError}; -use crate::{command, group, GlobalData}; -use rand::prelude::IndexedRandom; -use rand::{rng, Rng}; -use serenity::all::{ +use poise::serenity_prelude::all::{ parse_user_mention, CreateAttachment, CreateMessage, EditRole, GuildId, Member, }; -use serenity::client::Context; -use serenity::framework::standard::{Args, CommandError, CommandResult}; -use serenity::model::channel::Message; -use serenity::model::Colour; -use serenity::prelude::Mentionable; -use serenity::utils::MessageBuilder; +use poise::serenity_prelude::model::channel::Message; +use poise::serenity_prelude::model::Colour; +use poise::serenity_prelude::prelude::Mentionable; +use poise::serenity_prelude::utils::MessageBuilder; +use rand::prelude::IndexedRandom; +use rand::{rng, Rng}; use std::collections::hash_map::DefaultHasher; use std::hash::Hasher; +use std::sync::Arc; use tokio::io::AsyncWriteExt; -#[group] -#[commands(shop, buy, inventory, use_item, sell_item, item_help)] -pub struct Shop; - -#[command] -#[description("Fren has wares if you have coin")] -async fn shop(ctx: &Context, msg: &Message, _args: Args) -> CommandResult { - let mut data = ctx.data.write().await; - let global_data = data.get_mut::().unwrap(); - - let bot_user = User::get_user(&global_data.db, ctx.cache.current_user().id)?; +#[poise::command(prefix_command, category = "Shop")] +pub async fn shop(ctx: Context<'_>) -> Result<(), Error> { + let bot_user = User::get_user(&ctx.data().db, ctx.cache().current_user().id)?; if bot_user.inventory.inventory.is_empty() { - msg.reply(&ctx.http, "Sorry shop is closed until we get more wares.") + ctx.reply("Sorry shop is closed until we get more wares.") .await?; } else { let mut inv_msg = MessageBuilder::new(); @@ -43,63 +34,42 @@ async fn shop(ctx: &Context, msg: &Message, _args: Args) -> CommandResult { inv_msg.push_safe(bot_user.inventory.list_items(true)); - msg.reply(&ctx.http, inv_msg.build()).await?; + ctx.reply(inv_msg.build()).await?; } Ok(()) } -#[command] -#[description("Open your inventory, it specifically can not be rebound to the B key")] -async fn inventory(ctx: &Context, msg: &Message, _args: Args) -> CommandResult { - let mut data = ctx.data.write().await; - let global_data = data.get_mut::().unwrap(); - +#[poise::command(prefix_command, category = "Shop")] +pub async fn inventory(ctx: Context<'_>) -> Result<(), Error> { let mut inv_msg = MessageBuilder::new(); - let user = User::get_user(&global_data.db, msg.author.id)?; + let user = User::get_user(&ctx.data().db, ctx.author().id)?; if user.inventory.inventory.is_empty() { - msg.reply(&ctx, "Sorry your inventory is empty.").await?; + ctx.reply("Sorry your inventory is empty.").await?; } else { inv_msg.push_bold_line("Your inventory: "); inv_msg.push_safe(user.inventory.list_items(false)); - msg.reply(&ctx.http, inv_msg.build()).await?; + ctx.reply(inv_msg.build()).await?; } Ok(()) } -#[command] -#[description("Buying something?")] -async fn buy(ctx: &Context, msg: &Message, args: Args) -> CommandResult { - let mut data = ctx.data.write().await; - let global_data = data.get_mut::().unwrap(); - - if args.is_empty() { - msg.reply( - &ctx.http, - "You gonna buy something or do you just like to stare?", - ) - .await?; - return Ok(()); - } - - let item = match args.rest().parse::() { - Ok(i) => i, - Err(_) => { - msg.reply(&ctx.http, "I don't know what the heck that is tbh.") - .await?; - return Ok(()); - } - }; - +#[poise::command(prefix_command, category = "Shop")] +pub async fn buy( + ctx: Context<'_>, + #[description = "Item to buy"] + #[rest] + item: ItemType, +) -> Result<(), Error> { let res = User::item_transaction( - &global_data.db, - ctx.cache.current_user().id, - msg.author.id, + &ctx.data().db, + ctx.cache().current_user().id, + ctx.author().id, item, Operation::Buy, ); @@ -112,12 +82,12 @@ async fn buy(ctx: &Context, msg: &Message, args: Args) -> CommandResult { UserError::InventoryError(err) => format!("Something went wrong with that item: {}", err) }; - msg.reply(&ctx.http, resp).await?; + ctx.reply(resp).await?; } else { return Err(err.into()); } } else { - msg.reply(&ctx, format!("Congrats, you now own a '{}'", item)) + ctx.reply(format!("Congrats, you now own a '{}'", item)) .await?; } @@ -125,93 +95,89 @@ async fn buy(ctx: &Context, msg: &Message, args: Args) -> CommandResult { } async fn blockable_item( - ctx: &Context, - global_data: &GlobalData, + ctx: Context<'_>, guild_id: GuildId, msg_content: &str, role_name: &str, weapon_name: &str, block_item: ItemType, -) -> CommandResult<(bool, Member)> { +) -> Result<(bool, Member), Error> { let split = msg_content.split(weapon_name); let target = parse_user_mention(split.last().unwrap()).unwrap(); - let target_member = match guild_id.member(&ctx.http, target).await { + let target_member = match guild_id.member(ctx, target).await { Ok(member) => member, - Err(_) => return Err(CommandError::from("I have no clue who that is tbh")), + Err(_) => { + return Err(Error::CommandError( + "I have no clue who that is tbh".to_string(), + )) + } }; - if target_member.user.id == ctx.cache.current_user().id { - return Err(CommandError::from( - "You can not harm me in a way that matters.", + if target_member.user.id == ctx.cache().current_user().id { + return Err(Error::CommandError( + "You can not harm me in a way that matters.".to_string(), )); } - if User::try_use_item(&global_data.db, target, block_item, true).is_ok() { + if User::try_use_item(&ctx.data().db, target, block_item, true).is_ok() { Ok((false, target_member)) } else { - let role = if let Some(role) = get_role(&ctx.http, guild_id, role_name).await { + let role = if let Some(role) = get_role(ctx.http(), guild_id, role_name).await? { role } else { guild_id .create_role( - &ctx.http, + &ctx, EditRole::new() .name(role_name) .colour(Colour::from_rgb(1, 1, 1)), ) - .await - .unwrap() + .await? .id }; - target_member.add_role(&ctx.http, role).await?; + target_member.add_role(&ctx, role).await?; Task::add_task( - &global_data.db, + &ctx.data().db, TaskType::RemoveRole { role_id: role.get(), user_id: target_member.user.id.get(), }, - chrono::Utc::now() + chrono::Duration::seconds(global_data.cfg.effect_role_duration), + chrono::Utc::now() + chrono::Duration::seconds(ctx.data().cfg.effect_role_duration), )?; Ok((true, target_member)) } } -#[command] -#[only_in(guilds)] -#[aliases("use")] -#[description("Use it or lose it")] -async fn use_item(ctx: &Context, msg: &Message, args: Args) -> CommandResult { - let mut data = ctx.data.write().await; - let global_data = data.get_mut::().unwrap(); - - if args.is_empty() { - msg.reply(&ctx.http, "You need to select one item to use.") - .await?; +#[poise::command(prefix_command, category = "Shop", guild_only, aliases("use"))] +pub async fn use_item( + ctx: Context<'_>, + #[description = "item to use"] + #[rest] + item: String, +) -> Result<(), Error> { + if item.is_empty() { + ctx.reply("You need to select one item to use.").await?; return Ok(()); } - let msg_content = args.rest().to_lowercase(); + let msg_content = item.to_lowercase(); let item = match msg_content.parse::() { Ok(i) => i, Err(_) => { - msg.reply(&ctx.http, "I don't know what the heck that is tbh.") - .await?; + ctx.reply("I don't know what the heck that is tbh.").await?; return Ok(()); } }; - let item_data = match User::try_use_item(&global_data.db, msg.author.id, item, false) { + let item_data = match User::try_use_item(&ctx.data().db, ctx.author().id, item, false) { Ok(i) => i, Err(err) => { if let Error::UserError(UserError::InventoryError(InventoryError::NotEnoughItems)) = err { - msg.reply( - &ctx.http, - "Looks like you don't have enough of that item to use it", - ) - .await?; + ctx.reply("Looks like you don't have enough of that item to use it") + .await?; } return Ok(()); } @@ -219,19 +185,18 @@ async fn use_item(ctx: &Context, msg: &Message, args: Args) -> CommandResult { match item { ItemType::CancelInsurance => { - msg.reply(&ctx.http, "You are immune to the next (1) cancelings.") + ctx.reply("You are immune to the next (1) cancelings.") .await?; } ItemType::TheConceptOfLove => { - msg.reply(&ctx.http, "I have DMed you the concept of love.") - .await?; + ctx.reply("I have DMed you the concept of love.").await?; - msg.author + ctx.author() .id - .create_dm_channel(&ctx.http) + .create_dm_channel(ctx) .await? .say( - &ctx.http, + ctx, "DO NOT SHARE\nhttps://www.youtube.com/watch?v=HNy_retSME0", ) .await?; @@ -247,23 +212,22 @@ async fn use_item(ctx: &Context, msg: &Message, args: Args) -> CommandResult { ]; let fortune = good_fortunes.choose(&mut rng()).unwrap(); - msg.reply(&ctx.http, fortune.to_string()).await?; + ctx.reply(fortune.to_string()).await?; } ItemType::Nft => { if let Some(ItemData::Nft(path)) = item_data { let file: tokio::fs::File = match tokio::fs::File::open(&path).await { Ok(f) => f, Err(_) => { - msg.reply(&ctx.http, "Sorry this was a pump and dump") - .await?; + ctx.reply("Sorry this was a pump and dump").await?; return Ok(()); } }; let value = nft_value(&path); - msg.channel_id + ctx.channel_id() .send_message( - &ctx.http, + ctx, CreateMessage::new() .content(format!( "Your NFT my good friend. It's worth **{} FC**!", @@ -277,21 +241,17 @@ async fn use_item(ctx: &Context, msg: &Message, args: Args) -> CommandResult { ) .await?; } else { - msg.reply( - &ctx.http, - "Fren NFTs were never my creation, I merely promoted the brand", - ) - .await?; + ctx.reply("Fren NFTs were never my creation, I merely promoted the brand") + .await?; } } ItemType::LicenseToBeHorny => { - msg.reply(&ctx.http, "https://media.discordapp.net/attachments/840015650286075945/1127022083919069184/Img_2022_10_21_05_08_12.jpg").await?; + ctx.reply("https://media.discordapp.net/attachments/840015650286075945/1127022083919069184/Img_2022_10_21_05_08_12.jpg").await?; } ItemType::KillGun => { let (outcome, target) = match blockable_item( ctx, - global_data, - msg.guild_id.unwrap(), + ctx.guild_id().unwrap(), &msg_content, "Dead", "kill gun ", @@ -301,22 +261,21 @@ async fn use_item(ctx: &Context, msg: &Message, args: Args) -> CommandResult { { Ok(ret) => ret, Err(err) => { - msg.reply(&ctx.http, err.to_string()).await?; + ctx.reply(err.to_string()).await?; return Ok(()); } }; if outcome { - msg.reply(&ctx.http, format!("You draw your trusty kill gun and shoot one kill bullet. It hits it mark between {}'s eyes, killing them instantly. They are now dead.", target.mention())).await?; + ctx.reply(format!("You draw your trusty kill gun and shoot one kill bullet. It hits it mark between {}'s eyes, killing them instantly. They are now dead.", target.mention())).await?; } else { - msg.reply(&ctx.http, format!("The kill bullet shoots at kill velocity toward {}! They smirk, and simply pull out their Helmet and put it on, the bullet bounces off and falls to the floor. The crowd gasps (like they do in my animes). \"No death today pal\"", target.mention())).await?; + ctx.reply(format!("The kill bullet shoots at kill velocity toward {}! They smirk, and simply pull out their Helmet and put it on, the bullet bounces off and falls to the floor. The crowd gasps (like they do in my animes). \"No death today pal\"", target.mention())).await?; } } ItemType::CancelRay => { let (outcome, target) = match blockable_item( ctx, - global_data, - msg.guild_id.unwrap(), + ctx.guild_id().unwrap(), &msg_content, "Cancelled", "cancel ray ", @@ -326,23 +285,22 @@ async fn use_item(ctx: &Context, msg: &Message, args: Args) -> CommandResult { { Ok(ret) => ret, Err(err) => { - msg.reply(&ctx.http, err.to_string()).await?; + ctx.reply(err.to_string()).await?; return Ok(()); } }; if outcome { - msg.reply(&ctx.http, format!("You shoot the cancel ray at {}. As the ray impacts them, you can here their phone buzz. They have been cancelled, you hear the liberal media in the distance.", target.mention())).await?; + ctx.reply( format!("You shoot the cancel ray at {}. As the ray impacts them, you can hear their phone buzz. They have been cancelled, you hear the liberal media in the distance.", target.mention())).await?; } else { - msg.reply(&ctx.http, format!("The ray nearly hits {}, but they are surrounded in a a shimmering blue energy shield. \"The liberal media won't strike this time!\"", target.mention())).await?; + ctx.reply(format!("The ray nearly hits {}, but they are surrounded in a a shimmering blue energy shield. \"The liberal media won't strike this time!\"", target.mention())).await?; } } ItemType::Helmet => { - msg.reply(&ctx.http, "You're trusty helmet regards you helmetly") - .await?; + ctx.reply("Your trusty helmet regards you helmetly").await?; } ItemType::TacticalNuke => { - let mut users: Vec = global_data.db.filter(|_, _user: &User| true)?.collect(); + let mut users: Vec = ctx.data().db.filter(|_, _user: &User| true)?.collect(); for user in &mut users { for item in &mut user.inventory.inventory { @@ -355,62 +313,48 @@ async fn use_item(ctx: &Context, msg: &Message, args: Args) -> CommandResult { } } - global_data.db.insert(user.clone())?; + ctx.data().db.insert(user.clone())?; } - msg.reply(&ctx.http, "I have become cancel, the canceller of worlds. https://tenor.com/view/explosion-mushroom-cloud-atomic-bomb-bomb-boom-gif-4464831").await?; + ctx.reply("I have become cancel, the canceller of worlds. https://tenor.com/view/explosion-mushroom-cloud-atomic-bomb-bomb-boom-gif-4464831").await?; } } Ok(()) } -#[command] -#[only_in(guilds)] -#[aliases("sell")] -#[description("Sell it or smell it")] -async fn sell_item(ctx: &Context, msg: &Message, args: Args) -> CommandResult { - let mut data = ctx.data.write().await; - let global_data = data.get_mut::().unwrap(); - - let item = match args.rest().parse::() { - Ok(i) => i, - Err(_) => { - msg.reply(&ctx.http, "I don't know what the heck that is tbh.") - .await?; - return Ok(()); - } - }; - - let bot_user = ctx.cache.current_user().id; +#[poise::command(prefix_command, category = "Shop", aliases("sell"))] +pub async fn sell_item( + ctx: Context<'_>, + #[description = "Item to sell"] + #[rest] + item: ItemType, +) -> Result<(), Error> { + let bot_user = ctx.cache().current_user().id; match User::item_transaction( - &global_data.db, - msg.author.id, + &ctx.data().db, + ctx.author().id, bot_user, item, Operation::Sell, ) { Ok(_) => { - msg.reply(&ctx.http, "I guess I could buy that...").await?; + ctx.reply("I guess I could buy that...").await?; } Err(err) => { if let Error::UserError(err) = err { match err { UserError::NotEnoughFunds => { - msg.reply(&ctx.http, "What do I look like a charity service?") - .await?; + ctx.reply("What do I look like a charity service?").await?; } UserError::InvalidTarget => { - msg.reply(&ctx.http, "If you got here, that means I'm not real...????") + ctx.reply("If you got here, that means I'm not real...????") .await?; } UserError::InventoryError(InventoryError::NotEnoughItems) => { - msg.reply( - &ctx.http, - "You don't have enough of that item to sell it lmao", - ) - .await?; + ctx.reply("You don't have enough of that item to sell it lmao") + .await?; } _ => {} } @@ -422,56 +366,52 @@ async fn sell_item(ctx: &Context, msg: &Message, args: Args) -> CommandResult { Ok(()) } - -#[command] -#[only_in(guilds)] -#[description("Get help with an item")] -async fn item_help(ctx: &Context, msg: &Message, args: Args) -> CommandResult { - let item = match args.rest().parse::() { - Ok(i) => i, - Err(_) => { - msg.reply(&ctx.http, "I don't know what the heck that is tbh.") - .await?; - return Ok(()); - } - }; - - msg.reply(&ctx.http, format!("**{}**: {}", item, item.description())) +#[poise::command(prefix_command, category = "Shop")] +pub async fn item_help( + ctx: Context<'_>, + #[description = "I"] + #[rest] + item: ItemType, +) -> Result<(), Error> { + ctx.reply(format!("**{}**: {}", item, item.description())) .await?; Ok(()) } -pub async fn restock_shop(ctx: &Context, global_data: &GlobalData) -> Result<(), CommandError> { +pub async fn restock_shop( + ctx: &poise::serenity_prelude::Context, + global_data: &Arc, +) -> Result<(), Error> { let mut bot_user = User::get_user(&global_data.db, ctx.cache.current_user().id)?; bot_user.inventory.inventory.clear(); bot_user .inventory - .give_item(ItemType::TheConceptOfLove, rng().gen_range(0..=5), None); + .give_item(ItemType::TheConceptOfLove, rng().random_range(0..=5), None); bot_user .inventory - .give_item(ItemType::GoodFortune, rng().gen_range(0..10), None); + .give_item(ItemType::GoodFortune, rng().random_range(0..10), None); bot_user .inventory - .give_item(ItemType::CancelInsurance, rng().gen_range(1..=3), None); + .give_item(ItemType::CancelInsurance, rng().random_range(1..=3), None); bot_user .inventory - .give_item(ItemType::LicenseToBeHorny, rng().gen_range(0..=25), None); + .give_item(ItemType::LicenseToBeHorny, rng().random_range(0..=25), None); bot_user .inventory - .give_item(ItemType::KillGun, rng().gen_range(1..=3), None); + .give_item(ItemType::KillGun, rng().random_range(1..=3), None); bot_user .inventory - .give_item(ItemType::CancelRay, rng().gen_range(1..=3), None); + .give_item(ItemType::CancelRay, rng().random_range(1..=3), None); bot_user .inventory - .give_item(ItemType::Helmet, rng().gen_range(1..=3), None); + .give_item(ItemType::Helmet, rng().random_range(1..=3), None); bot_user .inventory - .give_item(ItemType::TacticalNuke, rng().gen_range(0..=1), None); + .give_item(ItemType::TacticalNuke, rng().random_range(0..=1), None); loop { let mut dir = tokio::fs::read_dir(&global_data.cfg.nft_path).await?; @@ -492,9 +432,8 @@ pub async fn restock_shop(ctx: &Context, global_data: &GlobalData) -> Result<(), "gold", None, ) - .await - .unwrap(); - let nft = create_motivation_image(nft_motivation).await.unwrap(); + .await?; + let nft = create_motivation_image(nft_motivation).await?; let mut hasher = DefaultHasher::new(); hasher.write(&nft); let nft_hash = hasher.finish(); diff --git a/src/error.rs b/src/error.rs index be87c09..c7c1773 100644 --- a/src/error.rs +++ b/src/error.rs @@ -17,6 +17,8 @@ pub enum Error { ParseFailure, RaasError(String), MagickError(magick_rust::MagickError), + CommandError(String), + IoError(std::io::Error), } impl StdError for Error {} @@ -63,6 +65,12 @@ impl From for Error { } } +impl From for Error { + fn from(value: std::io::Error) -> Self { + Self::IoError(value) + } +} + impl Display for Error { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { @@ -76,6 +84,8 @@ impl Display for Error { Error::ParseFailure => write!(f, "Failed to parse something or other"), Error::RaasError(msg) => write!(f, "Got error from RaaS: {}", msg), Error::MagickError(err) => write!(f, "ImageMagick error: {}", err), + Error::CommandError(err_msg) => write!(f, "{}", err_msg), + Error::IoError(err) => write!(f, "IO Error: {}", err), } } } diff --git a/src/models/task.rs b/src/models/task.rs index 57c24ad..ca95ab5 100644 --- a/src/models/task.rs +++ b/src/models/task.rs @@ -1,7 +1,5 @@ use crate::config::GlobalData; -use std::sync::Arc; -//use crate::discord::shop::restock_shop; -use crate::discord::Context; +use crate::discord::shop::restock_shop; use crate::error::Error; use crate::models::birthday::BirthdayEntry; use crate::models::insult_compliment::{RandomResponseTemplate, ResponseType}; @@ -11,6 +9,7 @@ use j_db::model::JdbModel; use log::{error, info}; use poise::serenity_prelude::all::Mentionable; use serde::{Deserialize, Serialize}; +use std::sync::Arc; #[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq)] pub enum TaskType { @@ -160,12 +159,12 @@ impl Task { } TaskType::RestockShop => { info!("Restocking Shop..."); - //let res = restock_shop(ctx, global_data).await; + let res = restock_shop(ctx, data).await; - //match res { - // Ok(_) => info!("Finished restocking shop!"), - // Err(err) => error!("Error restocking shop: {:?}", err), - // } + match res { + Ok(_) => info!("Finished restocking shop!"), + Err(err) => error!("Error restocking shop: {:?}", err), + } Task::add_task( &data.db,