diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..6585b03 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,4 @@ +max_width = 140 +use_small_heuristics = "Default" +reorder_imports = true +format_strings = true \ No newline at end of file diff --git a/src/commands/accountv2.rs b/src/commands/accountv2.rs index 8596cae..687e550 100644 --- a/src/commands/accountv2.rs +++ b/src/commands/accountv2.rs @@ -2,21 +2,14 @@ use poise::CreateReply; use reqwest::{Client, Response}; use serde::Deserialize; use serenity::{ - all::{ - ChannelId, - CreateActionRow, - CreateAllowedMentions, - CreateButton, - CreateMessage, - ReactionType, - User, - }, + all::{ChannelId, CreateActionRow, CreateAllowedMentions, CreateButton, CreateMessage, ReactionType, User}, json::JsonError, }; -use sqlx::{Pool, query_as, Sqlite}; +use sqlx::{query_as, Pool, Sqlite}; -use crate::Context; +use crate::commands::command_helper::cooldown; use crate::error::Error; +use crate::Context; #[derive(Deserialize)] struct Links { @@ -40,7 +33,7 @@ struct HypixelResponse { #[derive(Deserialize)] struct MojangPlayer { pub id: String, - //pub name: String, + pub name: String, } #[derive(PartialEq, sqlx::FromRow)] @@ -55,8 +48,7 @@ impl Uuid { let url: String = format!("https://api.mojang.com/users/profiles/minecraft/{ign}"); let response: Response = reqwest::get(url).await?; let response_text = response.error_for_status()?.text().await.unwrap(); - let uuid = (serde_json::from_str(response_text.as_str()) - as Result) + let uuid = (serde_json::from_str(response_text.as_str()) as Result) .map(|mojang_player: MojangPlayer| Uuid { uuid: mojang_player.id })?; Ok(uuid) /*match response.error_for_status() { @@ -72,6 +64,15 @@ impl Uuid { Details: {}", why).as_str())), }*/ } + + async fn ign(&self) -> Result { + let url: String = format!("https://sessionserver.mojang.com/session/minecraft/profile/{}", self.uuid); + let response: Response = reqwest::get(url).await?; + let response_text = response.error_for_status()?.text().await.unwrap(); + let ign = (serde_json::from_str(response_text.as_str()) as Result) + .map(|mojang_player: MojangPlayer| mojang_player.name)?; + Ok(ign) + } } #[derive(PartialEq)] struct DiscordId { @@ -82,8 +83,7 @@ impl DiscordId { let url: String = format!("https://api.hypixel.net/v2/player?uuid={}", uuid); let response: Response = client.get(url).send().await?; let response_text = response.error_for_status()?.text().await.unwrap(); - let matches = (serde_json::from_str(response_text.as_str()) - as Result) + let matches = (serde_json::from_str(response_text.as_str()) as Result) .map(|hypixel_response: HypixelResponse| user.name == hypixel_response.player.social_media.links.discord)?; Ok(matches) } @@ -97,7 +97,7 @@ where fn from_row(row: &'a R) -> sqlx::Result { let discord_id: i64 = row.try_get("discord_id")?; Ok(DiscordId { - id: discord_id.cast_unsigned() + id: discord_id.cast_unsigned(), }) } } @@ -116,14 +116,17 @@ impl Link { } async fn minecraft(mut self, pool: &Pool) -> Result { let link_id: i16 = self.link_id.cast_signed(); - self.minecraft_accounts = query_as(format!("SELECT minecraft_uuid AS uuid FROM minecraft_links WHERE link_id = {link_id};").as_str()) - .fetch_all(pool).await?; + self.minecraft_accounts = + query_as(format!("SELECT minecraft_uuid AS uuid FROM minecraft_links WHERE link_id = {link_id};").as_str()) + .fetch_all(pool) + .await?; Ok(self) } async fn discord(mut self, pool: &Pool) -> Result { let link_id: i16 = self.link_id.cast_signed(); self.discord_ids = query_as(format!("SELECT discord_id FROM discord_links WHERE link_id = {link_id};").as_str()) - .fetch_all(pool).await?; + .fetch_all(pool) + .await?; Ok(self) } } @@ -133,7 +136,6 @@ pub(crate) async fn account(_ctx: Context<'_>) -> Result<(), Error> { unreachable!() } - #[poise::command(slash_command)] pub(crate) async fn add<'a>( ctx: Context<'_>, @@ -141,115 +143,153 @@ pub(crate) async fn add<'a>( #[min_length = 2] #[max_length = 16] ign: String, - user: Option, + #[description = "Discord User"] user: Option, + #[description = "Minecraft username"] force: Option, ) -> Result<(), Error> { ctx.defer_ephemeral().await?; - let user = user.unwrap_or(ctx.author().clone()); - let uuid = Uuid::fetch(ign.as_str()).await?; - match DiscordId::matches_fetch(&user, uuid.get(), &ctx.data().hypixel_api_client).await? { + let user: User = user.unwrap_or(ctx.author().clone()); + let uuid: Uuid = Uuid::fetch(ign.as_str()).await?; + let force: bool = force.unwrap_or(false) && ctx.framework().options.owners.contains(&ctx.author().id); + match DiscordId::matches_fetch(&user, uuid.get(), &ctx.data().hypixel_api_client).await? || force { true => { let pool: Pool = ctx.data().sqlite_pool.clone(); - let (status, link_id) = match link_id_from_minecraft(&pool, uuid.get()).await { - None => { - match link_id_from_discord(&pool, user.id.get()).await { - None => { - let id = new_link_id(&pool).await?; - sqlx::query(format!("INSERT INTO discord_links VALUES ({}, {});", id.cast_signed(), user.id.get()).as_str()) - .execute(&pool).await?; - sqlx::query(format!("INSERT INTO minecraft_links VALUES ({}, \"{}\");", id.cast_signed(), uuid.get()).as_str()) - .execute(&pool).await?; - ("Linked your Discord and Minecraft account.", id) - } - Some(dc_id) => { - sqlx::query(format!("INSERT INTO minecraft_links VALUES ({}, \"{}\");", dc_id.cast_signed(), uuid.get()).as_str()) - .execute(&pool).await?; - ("Your Discord account has previously had an account linked. Added the new link.", dc_id) - } + let status: &str = match link_id_from_minecraft(&pool, uuid.get()).await { + None => match link_id_from_discord(&pool, user.id.get()).await { + None => { + let id = new_link_id(&pool).await?; + sqlx::query(format!("INSERT INTO discord_links VALUES ({}, {});", id.cast_signed(), user.id.get()).as_str()) + .execute(&pool) + .await?; + sqlx::query(format!("INSERT INTO minecraft_links VALUES ({}, \"{}\");", id.cast_signed(), uuid.get()).as_str()) + .execute(&pool) + .await?; + "Linked your Discord and Minecraft account." } - } - Some(mc_id) => { - match link_id_from_discord(&pool, user.id.get()).await { - None => { - sqlx::query(format!("INSERT INTO discord_links VALUES ({}, {});", mc_id.cast_signed(), user.id.get()).as_str()) - .execute(&pool).await?; - ("Your Minecraft account has previously had an account linked. Added the new link.", mc_id) - } - Some(dc_id) => { - sqlx::query(format!("UPDATE minecraft_links SET link_id = {} WHERE link_id = {};", mc_id.cast_signed(), dc_id.cast_signed()).as_str()) - .execute(&pool).await?; - sqlx::query(format!("UPDATE discord_links SET link_id = {} WHERE link_id = {};", mc_id.cast_signed(), dc_id.cast_signed()).as_str()) - .execute(&pool).await?; - ("Both your Discord and Minecraft account had linked accounts. Merged all account links.", mc_id) - } + Some(dc_id) => { + sqlx::query(format!("INSERT INTO minecraft_links VALUES ({}, \"{}\");", dc_id.cast_signed(), uuid.get()).as_str()) + .execute(&pool) + .await?; + "Your Discord account has previously had an account linked. Added the new link." } - } + }, + Some(mc_id) => match link_id_from_discord(&pool, user.id.get()).await { + None => { + sqlx::query(format!("INSERT INTO discord_links VALUES ({}, {});", mc_id.cast_signed(), user.id.get()).as_str()) + .execute(&pool) + .await?; + "Your Minecraft account has previously had an account linked. Added the new link." + } + Some(dc_id) => { + sqlx::query( + format!( + "UPDATE minecraft_links SET link_id = {} WHERE link_id = {};", + mc_id.cast_signed(), + dc_id.cast_signed() + ) + .as_str(), + ) + .execute(&pool) + .await?; + sqlx::query( + format!( + "UPDATE discord_links SET link_id = {} WHERE link_id = {};", + mc_id.cast_signed(), + dc_id.cast_signed() + ) + .as_str(), + ) + .execute(&pool) + .await?; + "Both your Discord and Minecraft account had linked accounts. Merged all account links." + } + }, }; - let link = Link::new(link_id).minecraft(&pool).await?.discord(&pool).await?; - let s = list_string(link, user.id.get()); - ChannelId::new(1257776992497959075).send_message( - ctx, - CreateMessage::new() - .content(s) - .allowed_mentions(CreateAllowedMentions::new().empty_roles().all_users(true)) - .components(vec![CreateActionRow::Buttons(vec![ - CreateButton::new("accept_verification").emoji(ReactionType::from('✅')), - CreateButton::new("deny_verification").emoji(ReactionType::from('❌')), - ])]), - ).await?; + let s = format!("Verification request for {} with IGN `{}`", user.id.get(), ign); + ChannelId::new(1257776992497959075) + .send_message( + ctx, + CreateMessage::new() + .content(s) + .allowed_mentions(CreateAllowedMentions::new().empty_roles().all_users(true)) + .components(vec![CreateActionRow::Buttons(vec![ + CreateButton::new("accept_verification").emoji(ReactionType::from('✅')), + CreateButton::new("deny_verification").emoji(ReactionType::from('❌')), + CreateButton::new("list_accounts").emoji(ReactionType::from('📜')), + ])]), + ) + .await?; ctx.send(CreateReply::default().ephemeral(false).content(status)).await?; Ok(()) - }, - false => { - Err(Error::Other(format!("The Discord account linked on Hypixel does not match the specified discord account.\n\ - Please set your linked Discord account on Hypixel to `{}`.", user.name))) } + false => Err(Error::Other(format!( + "The Discord account linked on Hypixel does not match the specified discord account.\nPlease set your linked Discord account \ + on Hypixel to `{}`.", + user.name + ))), } } #[poise::command(slash_command)] -pub(crate) async fn list( - ctx: Context<'_>, - user: Option, -) -> Result<(), Error> { - ctx.defer().await?; - let user = user.unwrap_or(ctx.author().clone()); - let r = CreateReply::default().ephemeral(false); - let pool: Pool = ctx.data().sqlite_pool.clone(); - let link_id = link_id_from_discord(&pool, user.id.get()).await.expect("This user has no linked accounts"); - let link = Link::new(link_id).minecraft(&pool).await?.discord(&pool).await?; - let s = list_string(link, user.id.get()); - ctx.send(r.content(s).allowed_mentions(CreateAllowedMentions::new().empty_roles().empty_users())).await?; +pub(crate) async fn list(ctx: Context<'_>, user: Option) -> Result<(), Error> { + ctx.defer_ephemeral().await?; + cooldown(&ctx, 600, 300)?; + let user: User = user.unwrap_or(ctx.author().clone()); + let pool: &Pool = &ctx.data().sqlite_pool; + let s: String = list_string(pool, &user).await?; + let r: CreateReply = CreateReply::default().ephemeral(false); + ctx.send( + r.content(s) + .allowed_mentions(CreateAllowedMentions::new().empty_roles().empty_users()), + ) + .await?; Ok(()) } +pub(crate) async fn list_string(pool: &Pool, user: &User) -> Result { + let link_id: u16 = link_id_from_discord(pool, user.id.get()) + .await + .expect("This user has no linked accounts"); + let link: Link = Link::new(link_id).minecraft(pool).await?.discord(pool).await?; + let mut discord_list = String::from("### Discord:"); + for dc in link.discord_ids { + discord_list.push_str(format!("\n- <@{}>", dc.id).as_str()); + } + let mut minecraft_list = String::from("### Minecraft:"); + for mc in link.minecraft_accounts { + minecraft_list.push_str(format!("\n- `{}`", mc.ign().await?).as_str()); + } + Ok(format!( + "## Account list for member #{}:\n{}\n{}", + link.link_id, + discord_list.as_str(), + minecraft_list.as_str() + )) +} + #[poise::command(slash_command)] pub(crate) async fn remove(_ctx: Context<'_>) -> Result<(), Error> { unimplemented!() } -fn list_string(link: Link, user_id: u64) -> String { - let mut discord_list = String::from("### Discord:"); - for dc in link.discord_ids { - discord_list.push_str(format!("\n- <@{}>", dc.id).as_str()); - } - let mut minecraft_list = String::from("### Minecraft:"); - for mc in link.minecraft_accounts { - minecraft_list.push_str(format!("\n- `{}`", mc.get()).as_str()); - } - format!("## Account list for <@{user_id}>:\n{}\n{}", discord_list.as_str(), minecraft_list.as_str()) -} - async fn link_id_from_minecraft(pool: &Pool, minecraft_uuid: &str) -> Option { query_as(format!("SELECT link_id FROM minecraft_links WHERE minecraft_uuid = \"{minecraft_uuid}\" LIMIT 1;").as_str()) .fetch_optional(pool) - .await.expect("Database error: fetching link id by uuid") + .await + .expect("Database error: fetching link id by uuid") .map(|link_id: LinkId| link_id.link_id.cast_unsigned()) } async fn link_id_from_discord(pool: &Pool, snowflake: u64) -> Option { - query_as(format!("SELECT link_id FROM discord_links WHERE discord_id = {} LIMIT 1;", snowflake.cast_signed()).as_str()) - .fetch_optional(pool) - .await.expect("Database error: fetching link id by discord") - .map(|link_id: LinkId| link_id.link_id.cast_unsigned()) + query_as( + format!( + "SELECT link_id FROM discord_links WHERE discord_id = {} LIMIT 1;", + snowflake.cast_signed() + ) + .as_str(), + ) + .fetch_optional(pool) + .await + .expect("Database error: fetching link id by discord") + .map(|link_id: LinkId| link_id.link_id.cast_unsigned()) } #[derive(sqlx::FromRow)] @@ -262,4 +302,4 @@ async fn new_link_id(pool: &Pool) -> Result { .fetch_one(pool) .await?; Ok(result.link_id.cast_unsigned() + 1) -} \ No newline at end of file +} diff --git a/src/commands/bots.rs b/src/commands/bots.rs index d6ee489..7e1fe03 100644 --- a/src/commands/bots.rs +++ b/src/commands/bots.rs @@ -1,7 +1,9 @@ use std::string::String; + use poise::CreateReply; -use crate::Context; + use crate::error::Error; +use crate::Context; #[poise::command(slash_command, guild_only, owners_only)] pub(crate) async fn bots( diff --git a/src/commands/command_helper.rs b/src/commands/command_helper.rs index adf37ce..856c18b 100644 --- a/src/commands/command_helper.rs +++ b/src/commands/command_helper.rs @@ -1,7 +1,7 @@ use std::time::Duration; -use crate::Context; use crate::error::Error; +use crate::Context; pub(crate) fn cooldown(ctx: &Context, user: u64, guild: u64) -> Result<(), Error> { let mut cooldown_tracker = ctx.command().cooldowns.lock().unwrap(); diff --git a/src/commands/helpstart.rs b/src/commands/helpstart.rs index b0d06b1..44fdb3f 100644 --- a/src/commands/helpstart.rs +++ b/src/commands/helpstart.rs @@ -1,9 +1,9 @@ use poise::CreateReply; use serenity::all::CreateAllowedMentions; -use crate::Context; use crate::commands::command_helper; use crate::error::Error; +use crate::Context; #[poise::command(slash_command, guild_only)] pub(crate) async fn helpstart( @@ -20,23 +20,19 @@ pub(crate) async fn helpstart( let mut reply = CreateReply::default(); let ping = match g { 1256217633959841853_u64 => 1257411572092113017_u64, - _ => 0_u64 + _ => 0_u64, }; reply = if bots >= needed_players { - reply.content("Bots available. Please use <@424767825001971715> in the bot-commands channel instead.") + reply + .content("Bots available. Please use <@424767825001971715> in the bot-commands channel instead.") .ephemeral(true) } else { - match command_helper::cooldown(&ctx, 1200, 600) { - Ok(_) => reply - .content(format!( - "<@&{ping}>\nneed: {}", - needed_players - bots - )) - .ephemeral(false) - .allowed_mentions(CreateAllowedMentions::new().roles(vec![ping])), - Err(why) => reply.content(why.to_string()).ephemeral(true), - } + command_helper::cooldown(&ctx, 1200, 600)?; + reply + .content(format!("<@&{ping}>\nneed: {}", needed_players - bots)) + .ephemeral(false) + .allowed_mentions(CreateAllowedMentions::new().roles(vec![ping])) }; if let Err(why) = ctx.send(reply).await { println!("Error sending message: {why}") diff --git a/src/commands/lfg.rs b/src/commands/lfg.rs index 11ab79e..39f79e7 100644 --- a/src/commands/lfg.rs +++ b/src/commands/lfg.rs @@ -1,7 +1,6 @@ use poise::{ChoiceParameter, CreateReply}; use serenity::all::{CreateAllowedMentions, RoleId}; -use crate::Context; //from main.rs use crate::commands::command_helper::cooldown; // @@ -9,6 +8,7 @@ use crate::commands::lfg::Difficulty::Normal; use crate::commands::lfg::Map::*; use crate::commands::lfg::Mode::*; use crate::error::Error; +use crate::Context; #[derive(Debug, poise::ChoiceParameter, PartialEq)] pub enum Map { @@ -68,57 +68,52 @@ pub(crate) async fn lfg( note: Option, ) -> Result<(), Error> { let guild_id = ctx.guild_id().unwrap().get(); - let mut reply: CreateReply = CreateReply::default(); - reply = match cooldown(&ctx, 600, 300) { - Ok(_) => { - let current: u8 = current_players.unwrap_or(1); - let mut desired: u8 = desired_players.unwrap_or(4); - if current >= desired { - desired = 4 - } - let map_name: &str = map.name(); - let new_ping: u64 = match mode { - Casual => match map { - DeadEnd => 1257408106783178752, - BadBlood => 1257408198541836459, - AlienArcadium => 1257408233757343815, - Prison => 1257408303835644029, - }, - Speedrun => 1257408362367287367, - Challenge => 1257408398631370762, - Event => 1257408432063905915, - //Tournament => 1210508966036242445, - }; - let ping = match guild_id { - 1256217633959841853 => new_ping, - _ => 0, - }; - let difficulty: Difficulty = match map { - DeadEnd | BadBlood | Prison => difficulty.unwrap_or(Normal), - AlienArcadium => Normal, - }; - - let mut reply_content: String = format!("<@&{ping}> {current}/{desired} {map_name}", ); - match difficulty { - Normal => {} - Difficulty::Hard | Difficulty::Rip => { - reply_content.push(' '); - reply_content.push_str(difficulty.name()); - } - } - match note { - None => {} - Some(note) => { - reply_content.push_str(format!("\nNote: {note}").as_str()); - } - } - reply - .content(reply_content) - .ephemeral(false) - .allowed_mentions(CreateAllowedMentions::new().roles(vec![ping])) - } - Err(why) => reply.content(why.to_string()).ephemeral(true), + cooldown(&ctx, 600, 300)?; + let current: u8 = current_players.unwrap_or(1); + let mut desired: u8 = desired_players.unwrap_or(4); + if current >= desired { + desired = 4 + } + let map_name: &str = map.name(); + let new_ping: u64 = match mode { + Casual => match map { + DeadEnd => 1257408106783178752, + BadBlood => 1257408198541836459, + AlienArcadium => 1257408233757343815, + Prison => 1257408303835644029, + }, + Speedrun => 1257408362367287367, + Challenge => 1257408398631370762, + Event => 1257408432063905915, + //Tournament => 1210508966036242445, }; + let ping = match guild_id { + 1256217633959841853 => new_ping, + _ => 0, + }; + let difficulty: Difficulty = match map { + DeadEnd | BadBlood | Prison => difficulty.unwrap_or(Normal), + AlienArcadium => Normal, + }; + + let mut reply_content: String = format!("<@&{ping}> {current}/{desired} {map_name}",); + match difficulty { + Normal => {} + Difficulty::Hard | Difficulty::Rip => { + reply_content.push(' '); + reply_content.push_str(difficulty.name()); + } + } + match note { + None => {} + Some(note) => { + reply_content.push_str(format!("\nNote: {note}").as_str()); + } + } + let reply: CreateReply = CreateReply::default() + .content(reply_content) + .ephemeral(false) + .allowed_mentions(CreateAllowedMentions::new().roles(vec![ping])); if let Err(why) = ctx.send(reply).await { println!("Error sending message: {why}"); @@ -156,55 +151,47 @@ pub(crate) async fn expert( #[rename = "message"] note: String, ) -> Result<(), Error> { - let reply: CreateReply = match cooldown(&ctx, 600, 300) { - Ok(_) => { - let current: u8 = current_players.unwrap_or(1); - let mut desired: u8 = desired_players.unwrap_or(4); - if current >= desired { - desired = 4; - }; - let (ping, allowed_roles): (u64, Vec) = match mode { - ExpertMap::Speedrun => ( - 1295322375637958716, - ROLE_LIST.iter().skip(2).map(|tier| [tier[4], tier[5]]).flatten().collect() - ), - ExpertMap::DeadEnd => ( - 1295321319344177172, - ROLE_LIST.iter().skip(2).map(|tier| [tier[1], tier[5]]).flatten().collect() - ), - ExpertMap::BadBlood => ( - 1295322259631640607, - ROLE_LIST.iter().skip(2).map(|tier| [tier[2], tier[5]]).flatten().collect() - ), - ExpertMap::AlienArcadium => ( - 1295322327910842441, - ROLE_LIST.iter().skip(2).map(|tier| [tier[3], tier[5]]).flatten().collect() - ), - }; - let is_expert: bool = ctx - .author_member() - .await - .unwrap() - .roles - .iter() - .any(|user_role: &RoleId| allowed_roles.contains(&user_role.get())); - let reply_content: String = format!("{current}/{desired} <@&{ping}>: {note}"); - - match is_expert { - true => CreateReply::default() - .content(reply_content) - .ephemeral(false) - .allowed_mentions(CreateAllowedMentions::new().roles(vec![ping])), - false => CreateReply::default() - .content("You do not have any of the required expert ranks.") - .ephemeral(true), - } - } - Err(why) => { - CreateReply::default().content(why.to_string()).ephemeral(true) - } + cooldown(&ctx, 600, 300)?; + let current: u8 = current_players.unwrap_or(1); + let mut desired: u8 = desired_players.unwrap_or(4); + if current >= desired { + desired = 4; + }; + let (ping, allowed_roles): (u64, Vec) = match mode { + ExpertMap::Speedrun => ( + 1295322375637958716, + ROLE_LIST.iter().skip(2).map(|tier| [tier[4], tier[5]]).flatten().collect(), + ), + ExpertMap::DeadEnd => ( + 1295321319344177172, + ROLE_LIST.iter().skip(2).map(|tier| [tier[1], tier[5]]).flatten().collect(), + ), + ExpertMap::BadBlood => ( + 1295322259631640607, + ROLE_LIST.iter().skip(2).map(|tier| [tier[2], tier[5]]).flatten().collect(), + ), + ExpertMap::AlienArcadium => ( + 1295322327910842441, + ROLE_LIST.iter().skip(2).map(|tier| [tier[3], tier[5]]).flatten().collect(), + ), + }; + let is_expert: bool = ctx + .author_member() + .await + .unwrap() + .roles + .iter() + .any(|user_role: &RoleId| allowed_roles.contains(&user_role.get())); + let reply_content: String = format!("{current}/{desired} <@&{ping}>: {note}"); + let reply: CreateReply = match is_expert { + true => CreateReply::default() + .content(reply_content) + .ephemeral(false) + .allowed_mentions(CreateAllowedMentions::new().roles(vec![ping])), + false => CreateReply::default() + .content("You do not have any of the required expert ranks.") + .ephemeral(true), }; - if let Err(why) = ctx.send(reply).await { println!("Error sending message: {why}"); } @@ -219,8 +206,7 @@ enum OtherPing { #[poise::command(slash_command, guild_only, rename = "lfg-other")] pub(crate) async fn other( ctx: Context<'_>, - #[rename = "game"] - game: OtherPing, + #[rename = "game"] game: OtherPing, #[min = 1_u8] #[max = 3_u8] #[description = "default: 1"] @@ -230,26 +216,20 @@ pub(crate) async fn other( #[rename = "message"] note: String, ) -> Result<(), Error> { - let reply: CreateReply = match cooldown(&ctx, 0, 7200) { - Ok(_) => { - let current: u8 = current_players.unwrap_or(1); - let desired: u8 = match game { - OtherPing::GeoGuessr => 20_u8, - }; - let ping: u64 = match game { - OtherPing::GeoGuessr => 1302249562999885824_u64, - }; - let reply_content: String = format!("{current}/{desired} <@&{ping}>: {note}"); - - CreateReply::default() - .content(reply_content) - .ephemeral(false) - .allowed_mentions(CreateAllowedMentions::new().roles(vec![ping])) - } - Err(why) => { - CreateReply::default().content(why.to_string()).ephemeral(true) - } + cooldown(&ctx, 0, 7200)?; + let current: u8 = current_players.unwrap_or(1); + let desired: u8 = match game { + OtherPing::GeoGuessr => 20_u8, }; + let ping: u64 = match game { + OtherPing::GeoGuessr => 1302249562999885824_u64, + }; + let reply_content: String = format!("{current}/{desired} <@&{ping}>: {note}"); + + let reply: CreateReply = CreateReply::default() + .content(reply_content) + .ephemeral(false) + .allowed_mentions(CreateAllowedMentions::new().roles(vec![ping])); if let Err(why) = ctx.send(reply).await { println!("Error sending message: {why}"); @@ -257,15 +237,78 @@ pub(crate) async fn other( Ok(()) } - -const ROLE_LIST: [[u64; 6]; 9] = [ // [[basic, de, bb, aa, sr, star]; 9] - [1256229103678259311, 1256229192744304670, 1256229223450935377, 1256229498899271754, 1256229540900900996, 1256229575269154866], //novice - [1256230831131983932, 1256230750827577447, 1256230776828334143, 1256230793630715975, 1256230818444214333, 1256230734642024468], //seasoned - [1256230723455553556, 1256230653083521045, 1256230666786443310, 1256230686214324255, 1256230704061353995, 1256230636721537097], //expert - [1256230625635995718, 1256230573203128370, 1256230582908747776, 1256230600025706506, 1256230610998005872, 1256230557897986068], //pro - [1256230543532626002, 1256230480823582861, 1256230502273126421, 1256230515355160597, 1256230531478065243, 1256230463241191494], //master - [1256230442907074703, 1256230359419588700, 1256230396719403141, 1256230416516649012, 1256230429212545025, 1256230346848997396], //grandmaster - [1256230332169060362, 1256230266889044020, 1256230288888168458, 1256230416516649012, 1256230316528631870, 1256230242943766651], //legend - [1256230231732387950, 1256230157967163495, 1256230181199151254, 1256230194499420223, 1256230207099244646, 1256230102627258449], //divine - [1256230002597302322, 1256229873064869939, 1256229929247440906, 1256229963166646314, 1256229982569627792, 1256229672598110218], //goat +const ROLE_LIST: [[u64; 6]; 9] = [ + // [[basic, de, bb, aa, sr, star]; 9] + [ + 1256229103678259311, + 1256229192744304670, + 1256229223450935377, + 1256229498899271754, + 1256229540900900996, + 1256229575269154866, + ], //novice + [ + 1256230831131983932, + 1256230750827577447, + 1256230776828334143, + 1256230793630715975, + 1256230818444214333, + 1256230734642024468, + ], //seasoned + [ + 1256230723455553556, + 1256230653083521045, + 1256230666786443310, + 1256230686214324255, + 1256230704061353995, + 1256230636721537097, + ], //expert + [ + 1256230625635995718, + 1256230573203128370, + 1256230582908747776, + 1256230600025706506, + 1256230610998005872, + 1256230557897986068, + ], //pro + [ + 1256230543532626002, + 1256230480823582861, + 1256230502273126421, + 1256230515355160597, + 1256230531478065243, + 1256230463241191494, + ], //master + [ + 1256230442907074703, + 1256230359419588700, + 1256230396719403141, + 1256230416516649012, + 1256230429212545025, + 1256230346848997396, + ], //grandmaster + [ + 1256230332169060362, + 1256230266889044020, + 1256230288888168458, + 1256230416516649012, + 1256230316528631870, + 1256230242943766651, + ], //legend + [ + 1256230231732387950, + 1256230157967163495, + 1256230181199151254, + 1256230194499420223, + 1256230207099244646, + 1256230102627258449, + ], //divine + [ + 1256230002597302322, + 1256229873064869939, + 1256229929247440906, + 1256229963166646314, + 1256229982569627792, + 1256229672598110218, + ], //goat ]; diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 59f4ada..906a531 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,6 +1,6 @@ +pub(crate) mod accountv2; pub(crate) mod bots; pub(crate) mod command_helper; pub(crate) mod helpstart; pub(crate) mod lfg; pub(crate) mod xd; -pub(crate) mod accountv2; \ No newline at end of file diff --git a/src/commands/xd.rs b/src/commands/xd.rs index 19c03a0..095cfc3 100644 --- a/src/commands/xd.rs +++ b/src/commands/xd.rs @@ -1,7 +1,14 @@ -use crate::Context; use crate::error::Error; +use crate::Context; -const XD: &str = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⡿⠿⠿⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⡿⠿⠿⠿⠿⠿⠿⠿⢿⡿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣧⣄⡀⠀⠀⠀⢀⣠⣼⣿⣿⣿⣿⣧⣄⡀⠀⠀⠀⣀⣤⣼⣷⣦⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⢿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⠟⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣶⣦⣄⡀⠀⠀⠙⢿⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠙⣿⣿⣿⣿⠋⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠈⢿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠈⢿⡿⠁⠀⠀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⢸⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡗⠀⠀⠀⠐⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀⠀⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⠀⣠⡀⠀⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀⠀⣰⣿⣷⡄⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⠀⣾⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⡟⠁⠀⢀⣼⣿⣿⣿⣿⣆⠀⠀⠈⠻⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⢀⣼⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⠋⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠙⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⠿⠛⠁⠀⠀⣠⣾⣿⣿⣿⣿⣿\n⣿⣿⣿⠿⠛⠁⠀⠀⠀⠙⠻⣿⣿⣿⣿⣿⡿⠟⠋⠀⠀⠀⠈⠛⠻⡿⠟⠛⠁⠀⠀⠈⠉⠉⠉⠉⠀⠀⠀⠀⣀⣴⣾⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣿⣿⣿⣿⣿⣷⣶⣶⣶⣶⣶⣶⣶⣶⣷⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n"; +const XD: &str = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⡿⠿⠿⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⡿⠿⠿⠿⠿⠿⠿⠿⢿⡿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\\ + n⣿⣿⣿⣧⣄⡀⠀⠀⠀⢀⣠⣼⣿⣿⣿⣿⣧⣄⡀⠀⠀⠀⣀⣤⣼⣷⣦⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⢿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⠟⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣶⣦⣄⡀⠀⠀⠙⢿⣿⣿⣿⣿\\ + n⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠙⣿⣿⣿⣿⠋⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠈⢿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠈⢿⡿⠁⠀⠀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⢸⣿⣿⣿\\ + n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡗⠀⠀⠀⠐⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀⠀⣿⣿⣿\\ + n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⠀⣠⡀⠀⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀⠀⣰⣿⣷⡄⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⠀⣾⣿⣿⣿\\ + n⣿⣿⣿⣿⣿⣿⣿⡟⠁⠀⢀⣼⣿⣿⣿⣿⣆⠀⠀⠈⠻⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⢀⣼⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⠋⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠙⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⠿⠛⠁⠀⠀⣠⣾⣿⣿⣿⣿⣿\\ + n⣿⣿⣿⠿⠛⠁⠀⠀⠀⠙⠻⣿⣿⣿⣿⣿⡿⠟⠋⠀⠀⠀⠈⠛⠻⡿⠟⠛⠁⠀⠀⠈⠉⠉⠉⠉⠀⠀⠀⠀⣀⣴⣾⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣿⣿⣿⣿⣿⣷⣶⣶⣶⣶⣶⣶⣶⣶⣷⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\\ + n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n"; #[poise::command(slash_command)] pub(crate) async fn xd(ctx: Context<'_>) -> Result<(), Error> { diff --git a/src/error.rs b/src/error.rs index 57b8d6f..bea832b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -5,7 +5,7 @@ pub enum Error { ParsingError(serde_json::Error), SerenityError(serenity::Error), OnCooldown(std::time::Duration), - Other(String) + Other(String), } impl std::fmt::Display for Error { @@ -15,7 +15,9 @@ impl std::fmt::Display for Error { Error::HttpsError(e) => write!(f, "HTTPS Error (Hypixel / Mojang API):\n{}", e), Error::ParsingError(e) => write!(f, "Parsing Error:\n {}", e), Error::SerenityError(e) => write!(f, "Serenity Error:\n {}", e), - Error::OnCooldown(d) => write!(f, "This command is on cooldown. {}s remaining.", d.as_secs()), + Error::OnCooldown(d) => { + write!(f, "This command is on cooldown. {}s remaining.", d.as_secs()) + } Error::Other(s) => write!(f, "{}", s), } } @@ -43,4 +45,4 @@ impl From for Error { fn from(error: serenity::Error) -> Self { Error::SerenityError(error) } -} \ No newline at end of file +} diff --git a/src/handlers/bot_interaction.rs b/src/handlers/bot_interaction.rs index 227a01b..bd4f9b5 100644 --- a/src/handlers/bot_interaction.rs +++ b/src/handlers/bot_interaction.rs @@ -1,34 +1,93 @@ -use serenity::all::{ComponentInteraction, ComponentInteractionDataKind, Context, CreateMessage, EditMessage, GuildId, Interaction, RoleId}; +use serenity::all::ButtonStyle::Success; +use serenity::all::ComponentInteractionDataKind; +use serenity::all::Context; +use serenity::all::CreateActionRow; +use serenity::all::CreateButton; +use serenity::all::CreateInteractionResponse::Message; +use serenity::all::CreateInteractionResponseMessage; +use serenity::all::CreateMessage; +use serenity::all::EditMessage; +use serenity::all::GuildId; +use serenity::all::Interaction; +use serenity::all::ReactionType; +use serenity::all::RoleId; +use serenity::all::{ButtonStyle, ComponentInteraction}; use crate::error::Error; +use crate::Data; -pub(crate) async fn component(ctx: &Context, interaction: &Interaction) -> Result<(), Error> { +pub(crate) async fn component(ctx: &Context, interaction: &Interaction, data: &Data) -> Result<(), Error> { let component = interaction.clone().message_component().unwrap(); match component.data.kind { - ComponentInteractionDataKind::Button => button(ctx, component).await, - _ => Ok(()) + ComponentInteractionDataKind::Button => button(ctx, component, data).await, + _ => Ok(()), } } -async fn button(ctx: &Context, mut component: ComponentInteraction) -> Result<(), Error> { - let m = component.message.clone(); +async fn button(ctx: &Context, mut interaction: ComponentInteraction, data: &Data) -> Result<(), Error> { + let m = &interaction.message; let u = m.mentions.first().expect("Message did not mention a user."); - match component.data.custom_id.as_str() { + match interaction.data.custom_id.as_str() { "accept_verification" => { - let _dm = u.direct_message(ctx, CreateMessage::new() - .content("Your verified minecraft account was approved.")).await?; - let member = m.guild_id.unwrap_or(GuildId::new(1256217633959841853_u64)).member(ctx, u.id).await?; + let _dm = u + .direct_message(ctx, CreateMessage::new().content("Your verified minecraft account was approved.")) + .await?; + let member = m + .guild_id + .unwrap_or(GuildId::new(1256217633959841853_u64)) + .member(ctx, u.id) + .await?; member.add_role(ctx, RoleId::new(1256218805911425066_u64)).await?; member.remove_role(ctx, RoleId::new(1256253358701023232_u64)).await?; - component.message.edit(ctx, EditMessage::new().components(vec![])).await?; + interaction + .message + .edit( + ctx, + EditMessage::new().components(vec![CreateActionRow::Buttons(vec![ + CreateButton::new("accept_verification") + .emoji(ReactionType::from('✅')) + .style(Success) + .disabled(true), + CreateButton::new("deny_verification") + .emoji(ReactionType::from('❌')) + .disabled(true), + CreateButton::new("list_accounts").emoji(ReactionType::from('📜')), + ])]), + ) + .await?; Ok(()) } "deny_verification" => { - let _dm = u.direct_message(ctx, CreateMessage::new() - .content("Your verified minecraft account was denied.")).await?; - component.message.edit(ctx, EditMessage::new().components(vec![])).await?; + let _dm = u + .direct_message(ctx, CreateMessage::new().content("Your verified minecraft account was denied.")) + .await?; + interaction + .message + .edit( + ctx, + EditMessage::new().components(vec![CreateActionRow::Buttons(vec![ + CreateButton::new("accept_verification") + .emoji(ReactionType::from('✅')) + .disabled(true), + CreateButton::new("deny_verification") + .emoji(ReactionType::from('❌')) + .style(ButtonStyle::Danger) + .disabled(true), + CreateButton::new("list_accounts").emoji(ReactionType::from('📜')), + ])]), + ) + .await?; + Ok(()) } - _ => Ok(()) + "list_accounts" => { + let user = interaction.message.mentions.first().unwrap(); + let s: String = crate::commands::accountv2::list_string(&data.sqlite_pool, user).await?; + interaction + .create_response(ctx, Message(CreateInteractionResponseMessage::new().content(s).ephemeral(true))) + .await?; + Ok(()) + } + _ => Ok(()), } -} \ No newline at end of file +} diff --git a/src/handlers/message.rs b/src/handlers/message.rs index b302db4..eaba071 100644 --- a/src/handlers/message.rs +++ b/src/handlers/message.rs @@ -5,10 +5,8 @@ use crate::error::Error; pub(crate) async fn on_create(ctx: &Context, msg: &Message) -> Result<(), Error> { match msg.guild_id.map(|g| g.get()) { None => Ok(()), - Some(1256217633959841853_u64) => { - zmp_create(ctx, msg).await - } - _ => Ok(()) + Some(1256217633959841853_u64) => zmp_create(ctx, msg).await, + _ => Ok(()), } } @@ -19,7 +17,6 @@ async fn zmp_create(ctx: &Context, msg: &Message) -> Result<(), Error> { msg.react(ctx, '🇱').await?; Ok(()) } - _ => Ok(()) + _ => Ok(()), } } - diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 543de19..c5aa98a 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -1,3 +1,3 @@ pub(crate) mod bot_interaction; pub(crate) mod message; -pub(crate) mod thread; \ No newline at end of file +pub(crate) mod thread; diff --git a/src/handlers/thread.rs b/src/handlers/thread.rs index bb8a053..a53845f 100644 --- a/src/handlers/thread.rs +++ b/src/handlers/thread.rs @@ -6,10 +6,10 @@ use crate::error::Error; pub(crate) async fn on_create(ctx: &Context, thread: &GuildChannel) -> Result<(), Error> { match thread.parent_id.map(|parent| parent.get()) { Some(1295108216388325386) => { - thread.id.edit_thread(ctx, EditThread::new().rate_limit_per_user(7200_u16)).await?; + thread.id.edit_thread(ctx, EditThread::new().rate_limit_per_user(60_u16)).await?; Ok(()) } Some(_) => Ok(()), - None => Ok(()) + None => Ok(()), } -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index 68a263b..ffaa475 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,17 +5,18 @@ use std::convert::Into; use std::sync::Arc; use std::time::Duration; -use poise::{CreateReply, FrameworkError, serenity_prelude as serenity}; -use serenity::{FullEvent, model::id::UserId}; +use poise::{serenity_prelude as serenity, CreateReply, FrameworkError}; use serenity::all::{ActivityData, InteractionType, RoleId}; use serenity::prelude::GatewayIntents; +use serenity::{model::id::UserId, FullEvent}; use sqlx::Sqlite; use tokio::sync::RwLock; + use error::Error; mod commands; -mod handlers; mod error; +mod handlers; struct Data { bots: Arc>, @@ -23,7 +24,6 @@ struct Data { hypixel_api_client: reqwest::Client, } // User data, which is stored and accessible in all command invocations - type Context<'a> = poise::Context<'a, Data, Error>; #[tokio::main] async fn main() { @@ -35,14 +35,8 @@ async fn main() { let hypixel_api: String = std::env::var("HYPIXEL_API_KEY").unwrap(); let hypixel_api_client = { let mut headers = reqwest::header::HeaderMap::new(); - headers.insert( - "API-Key", - reqwest::header::HeaderValue::try_from(hypixel_api).unwrap(), - ); - reqwest::ClientBuilder::new() - .default_headers(headers) - .build() - .unwrap() + headers.insert("API-Key", reqwest::header::HeaderValue::try_from(hypixel_api).unwrap()); + reqwest::ClientBuilder::new().default_headers(headers).build().unwrap() }; let options = poise::FrameworkOptions { @@ -64,9 +58,14 @@ async fn main() { Box::pin(async move { match error { FrameworkError::CommandStructureMismatch { description, ctx, .. } => { - if let Err(e) = ctx.send(CreateReply::default() - .content(format!("# Command arguments did not match. The command probably has been updated recently. Try reloading Discord. Description:\n{}", description))) - .await { + if let Err(e) = ctx + .send(CreateReply::default().content(format!( + "# Command arguments did not match. The command probably has been updated recently. Try reloading \ + Discord. Description:\n{}", + description + ))) + .await + { tracing::error!("Fatal error while sending error message: {}", e); } } @@ -79,9 +78,7 @@ async fn main() { }) }, owners: { HashSet::from([UserId::new(449579075531440128_u64), UserId::new(659112817508745216_u64)]) }, - event_handler: |_ctx, event, _framework, _data| { - Box::pin(event_handler(_ctx, event, _framework, _data)) - }, + event_handler: |ctx, event, framework, data| Box::pin(event_handler(ctx, event, framework, data)), ..Default::default() }; @@ -100,8 +97,7 @@ async fn main() { .build(); let token = std::env::var("DISCORD_TOKEN").unwrap(); - let intents = - GatewayIntents::non_privileged() | GatewayIntents::MESSAGE_CONTENT | GatewayIntents::GUILD_MEMBERS; + let intents = GatewayIntents::non_privileged() | GatewayIntents::MESSAGE_CONTENT | GatewayIntents::GUILD_MEMBERS; let client = serenity::ClientBuilder::new(token, intents) .framework(framework) .activity(ActivityData::custom("NPC moment...")) @@ -112,7 +108,7 @@ async fn event_handler( ctx: &serenity::Context, event: &FullEvent, _framework: poise::FrameworkContext<'_, Data, Error>, - _data: &Data, + data: &Data, ) -> Result<(), Error> { match event { FullEvent::Ready { data_about_bot, .. } => { @@ -126,9 +122,8 @@ async fn event_handler( } } FullEvent::InteractionCreate { interaction } => { - if interaction.application_id().get() == 1165594074473037824 - && interaction.kind() == InteractionType::Component { - handlers::bot_interaction::component(ctx, interaction).await?; + if interaction.application_id().get() == 1165594074473037824 && interaction.kind() == InteractionType::Component { + handlers::bot_interaction::component(ctx, interaction, data).await?; } } FullEvent::Message { new_message } => {