diff --git a/src/commands/accountv2.rs b/src/commands/accountv2.rs index b1d731c..fc6d27e 100644 --- a/src/commands/accountv2.rs +++ b/src/commands/accountv2.rs @@ -1,3 +1,4 @@ +use std::ops::Add; use poise::CreateReply; use reqwest::{Client, Response}; use serde::Deserialize; @@ -65,9 +66,9 @@ impl Uuid { struct DiscordId { id: u64, } -impl DiscordId { - async fn matches_fetch(user: &User, uuid: &str, client: &Client) -> Result { - let url: String = format!("https://api.hypixel.net/v2/player?uuid={}", uuid); +impl Uuid { + async fn has_discord_user(&self, user: &User, client: &Client) -> Result { + let url: String = format!("https://api.hypixel.net/v2/player?uuid={}", self.uuid); let response_400: Response = client.get(url).send().await?.error_for_status()?; let deserialized = response_400.json::().await?; let matches = deserialized.player.social_media.links.discord == user.name; @@ -142,32 +143,32 @@ pub(crate) async fn add<'a>( let user: User = user.unwrap_or(ctx.author().clone()); let uuid: Uuid = Uuid::for_ign(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 { + match uuid.has_discord_user(&user, &ctx.data().hypixel_api_client).await? || force { true => { - let pool: Pool = ctx.data().sqlite_pool.clone(); - let status: &str = match link_id_from_minecraft(&pool, uuid.get()).await { - None => match link_id_from_discord(&pool, user.id.get()).await { + let pool = &ctx.data().sqlite_pool; + 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) + let id = new_link_id(pool).await?; + sqlx::query(format!("INSERT INTO discord_links VALUES ({}, {});", id.inner, 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) + sqlx::query(format!("INSERT INTO minecraft_links VALUES ({}, \"{}\");", id.inner, uuid.get()).as_str()) + .execute(pool) .await?; "Linked your Discord and Minecraft account." } Some(dc_id) => { - sqlx::query(format!("INSERT INTO minecraft_links VALUES ({}, \"{}\");", dc_id.cast_signed(), uuid.get()).as_str()) - .execute(&pool) + sqlx::query(format!("INSERT INTO minecraft_links VALUES ({}, \"{}\");", dc_id.inner, 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 { + 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) + sqlx::query(format!("INSERT INTO discord_links VALUES ({}, {});", mc_id.inner, user.id.get()).as_str()) + .execute(pool) .await?; "Your Minecraft account has previously had an account linked. Added the new link." } @@ -175,22 +176,22 @@ pub(crate) async fn add<'a>( sqlx::query( format!( "UPDATE minecraft_links SET link_id = {} WHERE link_id = {};", - mc_id.cast_signed(), - dc_id.cast_signed() + mc_id.inner, + dc_id.inner ) .as_str(), ) - .execute(&pool) + .execute(pool) .await?; sqlx::query( format!( "UPDATE discord_links SET link_id = {} WHERE link_id = {};", - mc_id.cast_signed(), - dc_id.cast_signed() + mc_id.inner, + dc_id.inner ) .as_str(), ) - .execute(&pool) + .execute(pool) .await?; "Both your Discord and Minecraft account had linked accounts. Merged all account links." } @@ -251,7 +252,8 @@ pub(crate) async fn list(ctx: Context<'_>, user: User) -> Result<(), Error> { 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"); + .expect("This user has no linked accounts") + .into(); 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 { @@ -271,17 +273,16 @@ pub(crate) async fn list_string(pool: &Pool, user: &User) -> Result) -> Result<(), Error> { - todo!() + unimplemented!(); } -async fn link_id_from_minecraft(pool: &Pool, minecraft_uuid: &str) -> Option { +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") - .map(|link_id: LinkId| link_id.link_id.cast_unsigned()) } -async fn link_id_from_discord(pool: &Pool, snowflake: u64) -> Option { +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;", @@ -292,17 +293,40 @@ async fn link_id_from_discord(pool: &Pool, snowflake: u64) -> Option) -> Result { +impl From for LinkId { + fn from(unsigned: u16) -> Self { + Self { + inner: unsigned.cast_signed() + } + } +} + +impl Into for LinkId { + fn into(self) -> u16 { + self.inner.cast_unsigned() + } +} + +impl Add for LinkId { + type Output = LinkId; + + fn add(mut self, rhs: i16) -> Self::Output { + self.inner += rhs; + self + } +} + +async fn new_link_id(pool: &Pool) -> Result { let result: LinkId = query_as("SELECT MAX(link_id) AS link_id FROM minecraft_links;") .fetch_one(pool) .await?; - Ok(result.link_id.cast_unsigned() + 1) + Ok(result + 1) } diff --git a/src/commands/helpstart.rs b/src/commands/helpstart.rs index 95f381b..bb22d20 100644 --- a/src/commands/helpstart.rs +++ b/src/commands/helpstart.rs @@ -36,7 +36,7 @@ pub(crate) async fn helpstart( } else { command_helper::cooldown(&ctx, 1200, 600)?; reply - .content(format!("<@&{ping}>\nneed: {}", needed_players - bots)) + .content(format!("## <@&{ping}>\nneed: {}", needed_players - bots)) .ephemeral(false) .allowed_mentions(CreateAllowedMentions::new().roles(vec![ping])) }; diff --git a/src/commands/lfg.rs b/src/commands/lfg.rs index 85b1f28..0fbdcb1 100644 --- a/src/commands/lfg.rs +++ b/src/commands/lfg.rs @@ -102,7 +102,7 @@ pub(crate) async fn lfg( AlienArcadium => Normal, }; - let mut reply_content: String = format!("<@&{ping}> {current}/{desired} {map_name}", ); + let mut reply_content: String = format!("## <@&{ping}> {current}/{desired} {map_name}", ); match difficulty { Normal => {} Difficulty::Hard | Difficulty::Rip => { @@ -113,7 +113,7 @@ pub(crate) async fn lfg( match note { None => {} Some(note) => { - reply_content.push_str(format!("\nNote: {note}").as_str()); + reply_content.push_str(format!("\n**Note:** {note}").as_str()); } } let reply: CreateReply = CreateReply::default() @@ -193,7 +193,7 @@ pub(crate) async fn expert( .roles .iter() .any(|user_role: &RoleId| allowed_roles.contains(&user_role.get())); - let reply_content: String = format!("{current}/{desired} <@&{ping}>: {note}"); + let reply_content: String = format!("## {current}/{desired} <@&{ping}>: {note}"); let reply: CreateReply = match is_expert { true => CreateReply::default() .content(reply_content) @@ -240,7 +240,7 @@ pub(crate) async fn other( let ping: u64 = match game { OtherPing::GeoGuessr => 1302249562999885824_u64, }; - let reply_content: String = format!("{current}/{desired} <@&{ping}>: {note}"); + let reply_content: String = format!("## {current}/{desired} <@&{ping}>: {note}"); let reply: CreateReply = CreateReply::default() .content(reply_content) diff --git a/src/error.rs b/src/error.rs index af9961c..8eda55c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,3 +1,4 @@ +use std::fmt::{Display, Formatter, Result as FmtResult}; use poise::{CreateReply, FrameworkError}; use crate::Data; @@ -19,8 +20,8 @@ pub enum Error { Other(String), } -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl Display for Error { + fn fmt(&self, f: &mut Formatter) -> FmtResult { match self { Error::SqlxError(e) => write!(f, "SQLx Error: {}", e), Error::HttpsError(e) => write!(f, "HTTPS Error (Hypixel / Mojang API):\n{}", e),