diff --git a/src/commands/account.rs b/src/commands/account.rs deleted file mode 100644 index 777bc41..0000000 --- a/src/commands/account.rs +++ /dev/null @@ -1,258 +0,0 @@ -use poise::CreateReply; -use serde::{Deserialize, Serialize}; -use serenity::all::{ChannelId, CreateActionRow, CreateButton, CreateMessage, ReactionType, User}; -use serenity::builder::CreateAllowedMentions; -use sqlx::{Pool, query_as, Sqlite}; - -use crate::{Context, Error}; - -#[poise::command(slash_command, subcommands("add", "list"))] -pub(crate) async fn account(_ctx: Context<'_>) -> Result<(), Error> { - Ok(()) -} - -#[poise::command(slash_command)] -pub(crate) async fn add(ctx: Context<'_>, ign: String) -> Result<(), Error> { - ctx.defer_ephemeral().await?; - let pool = ctx.data().sqlite_pool.clone(); - let minecraft_uuid = minecraft_uuid_for_username(ign.clone()).await?; - let hypixel_linked_discord = linked_discord_for_uuid( - ctx.data().hypixel_api_client.clone(), - minecraft_uuid.as_str(), - ) - .await?; - if hypixel_linked_discord.eq(ctx.author().name.as_str()) { - link( - ctx.author().id.get(), - minecraft_uuid.as_str(), - &pool, - ) - .await; - let s = format!("## User <@{}> added an account:\n### added:\n- name: {}\n- uuid: {}", - ctx.author().id.get(), - ign.clone(), - minecraft_uuid - ); - 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?; - ctx.send(CreateReply::default().content("Linked accounts.")).await?; - } else { - ctx.send(CreateReply::default().content("This Minecraft account's link doesn't seem to match your discord username. Be sure to not link using the display name and remove the @.")).await?; - } - Ok(()) -} - -#[poise::command(slash_command)] -pub(crate) async fn remove(ctx: Context<'_>) -> Result<(), Error> { - ctx.say("hi").await?; - Ok(()) -} - -#[poise::command(slash_command)] -pub(crate) async fn list(ctx: Context<'_>, user: Option) -> Result<(), Error> { - ctx.defer_ephemeral().await?; - let user_id = user.clone().map(|user| user.id.get()); - let user_name = user.clone().map(|user| user.name); - let author_name = ctx.author().name.clone(); - let pool = ctx.data().sqlite_pool.clone(); - let link_id = link_id_from_discord(&pool, user_id.unwrap_or(ctx.author().id.get())).await; - - let t = match link_id { - Some(id) => minecraft_uuids(&pool, id).await, - None => Vec::new(), - }; - let mut content = format!( - "## {}'s linked accounts: ", - user_name.unwrap_or(author_name) - ); - for l in t { - content.push_str(format!("\nuuid: {}", l).as_str()) - } - let reply = CreateReply::default().ephemeral(true).content(content); - if let Err(why) = ctx.send(reply).await { - println!("Error sending message: {why}"); - } - Ok(()) -} - -async fn link(discord_id: u64, uuid: &str, pool: &Pool) { - let link_id = match link_id_from_minecraft(pool, uuid.to_string()).await { - None => new_link_id(pool).await, - Some(link_id_mc_old) => { - // merge sets - let new_link_id_discord = link_id_from_discord(pool, discord_id) - .await - .unwrap_or(u16::MAX) - .cast_signed(); - sqlx::query(format!("UPDATE minecraft_links SET link_id = {} WHERE link_id = {new_link_id_discord};", link_id_mc_old.cast_signed()).as_str()).execute(pool).await.expect("Database Error: linking previously linked accounts by another user"); - sqlx::query( - format!( - "UPDATE discord_links SET link_id = {} WHERE link_id = {new_link_id_discord};", - link_id_mc_old.cast_signed() - ) - .as_str(), - ) - .execute(pool) - .await.expect("Database Error: linking previously linked accounts by another user"); - link_id_mc_old - } - }; - - let link_id = link_id.cast_signed(); - let discord_id = discord_id.cast_signed(); - sqlx::query( - format!("INSERT INTO minecraft_links VALUES ({link_id}, \"{uuid}\");").as_str(), - ) - .execute(pool) - .await.expect("Database Error: inserting new minecraft value"); - sqlx::query( - format!("INSERT INTO discord_links VALUES ({link_id}, \"{discord_id}\");").as_str(), - ) - .execute(pool) - .await.expect("Database Error: inserting new discord value"); -} - -#[derive(Serialize, Deserialize)] -struct Links { - #[serde(rename = "DISCORD")] - pub discord: String, -} -#[derive(Serialize, Deserialize)] -struct SocialMedia { - pub links: Links, - pub prompt: bool, -} -#[derive(Serialize, Deserialize)] -struct HypixelPlayer { - #[serde(rename = "socialMedia")] - pub social_media: SocialMedia, -} - -#[derive(Serialize, Deserialize)] -struct HypixelResponse { - #[serde(rename = "player")] - pub player: HypixelPlayer, -} - -#[derive(Serialize, Deserialize)] -struct MojangPlayer { - pub id: String, - pub name: String, -} - -async fn minecraft_uuid_for_username(name: String) -> Result { - let url = format!("https://api.mojang.com/users/profiles/minecraft/{name}"); - let response = reqwest::get(url).await.expect(format!("Failed retrieving hypixel response for {name}").as_str()); - let response_text = response.text().await.unwrap(); - return (serde_json::from_str(response_text.as_str()) - as Result) - .map(|mojang_player: MojangPlayer| mojang_player.id); -} - -async fn linked_discord_for_uuid( - hypixel_client: reqwest::Client, - uuid: &str, -) -> Result { - let hypixel_url = format!("https://api.hypixel.net/v2/player?uuid={uuid}"); - return match hypixel_client.get(hypixel_url).send().await { - Ok(response) => { - let response_text = response.text().await.unwrap(); - match (serde_json::from_str(response_text.as_str()) - as Result) - .map(|hypixel_response: HypixelResponse| { - hypixel_response.player.social_media.links.discord - }) { - Ok(discord) => Ok(discord), - Err(why) => Err(Error::try_from(why).unwrap()), - } - } - Err(why) => Err(Error::try_from(why).unwrap()), - }; -} - -#[derive(sqlx::FromRow)] -struct DiscordLink { - link_id: i16, - discord_id: i64, -} - -#[derive(sqlx::FromRow)] -struct MinecraftLink { - link_id: i16, - minecraft_uuid: String, -} -#[derive(sqlx::FromRow)] -struct LinkId { - link_id: i16, -} - -async fn link_id_from_discord(pool: &Pool, snowflake: u64) -> Option { - let discord_id: i64 = snowflake.cast_signed(); - return query_as( - format!("SELECT * FROM discord_links WHERE discord_id = {discord_id} LIMIT 1;").as_str(), - ) - .fetch_optional(pool) - .await - .expect("Database error: fetching link id by discord") - .map(|discord_link: DiscordLink| discord_link.link_id.cast_unsigned()); -} -async fn link_id_from_minecraft(pool: &Pool, minecraft_uuid: String) -> Option { - return query_as( - format!( - "SELECT * 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(|minecraft_link: MinecraftLink| minecraft_link.link_id.cast_unsigned()); -} - -async fn new_link_id(pool: &Pool) -> u16 { - let result: Result = query_as("SELECT link_id FROM minecraft_links WHERE link_id = (SELECT MAX(link_id) FROM minecraft_links) LIMIT 1;") - .fetch_one(pool) - .await; - result - .expect("Database error: fetching new id") - .link_id.cast_unsigned() + 1 -} - -async fn minecraft_uuids(pool: &Pool, link_id: u16) -> Vec { - let link_id: i16 = link_id.cast_signed(); - let link_result: Result, sqlx::Error> = - query_as(format!("SELECT * FROM minecraft_links WHERE link_id = {link_id};").as_str()) - .fetch_all(pool) - .await; - return match link_result { - Ok(links) => links - .into_iter() - .map(|minecraft_link: MinecraftLink| minecraft_link.minecraft_uuid) - .collect(), - Err(why) => { - println!("Error: {}", why); - Vec::new() - } - }; -} -/* -async fn discord_ids(pool: &Pool, link_id: u16) -> Vec { - let link_id: i16 = link_id.cast_signed(); - let link_result: Result, sqlx::Error> = query_as(format!("SELECT * FROM discord_links WHERE link_id = {link_id}").as_str()) - .fetch_all(pool) - .await; - return match link_result { - Ok(links) => links.into_iter().map(|discord_link: DiscordLink| discord_link.discord_id.cast_unsigned()).collect(), - Err(why) => { - println!("Error: {}", why); - Vec::new() - } - } -}*/ diff --git a/src/commands/accountv2.rs b/src/commands/accountv2.rs index 6d4c7cf..db6ab86 100644 --- a/src/commands/accountv2.rs +++ b/src/commands/accountv2.rs @@ -3,15 +3,15 @@ use reqwest::{Client, Response}; use serde::Deserialize; use serenity::{ all::{ + ChannelId, + CreateActionRow, CreateAllowedMentions, CreateButton, - CreateActionRow, - User, + CreateMessage, ReactionType, - ChannelId, - CreateMessage + User, }, - json::JsonError + json::JsonError, }; use sqlx::{Pool, query_as, Sqlite}; @@ -44,7 +44,7 @@ struct MojangPlayer { #[derive(PartialEq, sqlx::FromRow)] struct Uuid { - uuid: String + uuid: String, } impl Uuid { fn get(&self) -> &str { @@ -58,9 +58,9 @@ impl Uuid { let response_text = res.text().await.unwrap(); let uuid = (serde_json::from_str(response_text.as_str()) as Result) - .map(|mojang_player: MojangPlayer| Uuid {uuid: mojang_player.id})?; + .map(|mojang_player: MojangPlayer| Uuid { uuid: mojang_player.id })?; Ok(uuid) - }, + } Err(why) => Err(Error::from(format!( "Mojang returned an error. Please make sure to enter a valid Minecraft username.\n\n\ Details: {}", why).as_str())), @@ -69,7 +69,7 @@ impl Uuid { } #[derive(PartialEq)] struct DiscordId { - id: u64 + id: u64, } impl DiscordId { async fn matches_fetch(user: &User, uuid: &str, client: &Client) -> Result { @@ -82,7 +82,7 @@ impl DiscordId { as Result) .map(|hypixel_response: HypixelResponse| user.name == hypixel_response.player.social_media.links.discord)?; Ok(matches) - }, + } Err(why) => { println!("Hypixel issue: {}", why); Err(Error::from("Hypixel returned an error.")) @@ -91,9 +91,11 @@ impl DiscordId { } } impl<'a, R: sqlx::Row> sqlx::FromRow<'a, R> for DiscordId -where &'a ::std::primitive::str: sqlx::ColumnIndex, +where + &'a ::std::primitive::str: sqlx::ColumnIndex, i64: ::sqlx::decode::Decode<'a, R::Database>, - i64: ::sqlx::types::Type { + i64: ::sqlx::types::Type, +{ fn from_row(row: &'a R) -> sqlx::Result { let discord_id: i64 = row.try_get("discord_id")?; Ok(DiscordId { @@ -123,7 +125,7 @@ impl Link { async fn discord(mut self, pool: &Pool) -> Self { 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.expect("Error getting Discord IDs."); + .fetch_all(pool).await.expect("Error getting Discord IDs."); self } } @@ -137,12 +139,10 @@ pub(crate) async fn account(_ctx: Context<'_>) -> Result<(), Error> { #[poise::command(slash_command)] pub(crate) async fn add<'a>( ctx: Context<'_>, - #[description = "Minecraft username"] #[min_length = 2] #[max_length = 16] ign: String, - user: Option, ) -> Result<(), Error> { ctx.defer_ephemeral().await?; @@ -155,7 +155,8 @@ pub(crate) async fn add<'a>( let r = CreateReply::default().ephemeral(false); 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 => { + 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()) @@ -170,13 +171,14 @@ pub(crate) async fn add<'a>( ("Your Discord account has previously had an account linked. Added the new link.", dc_id) } } - }, Some(mc_id) => { + } + 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.expect("Database Error: inserting new minecraft value"); ("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.expect("Database Error: Merging Minecraft Accounts."); @@ -198,7 +200,7 @@ pub(crate) async fn add<'a>( .components(vec![CreateActionRow::Buttons(vec![ CreateButton::new("accept_verification").emoji(ReactionType::from('✅')), CreateButton::new("deny_verification").emoji(ReactionType::from('❌')), - ])]) + ])]), ).await?; } false => { @@ -214,7 +216,7 @@ pub(crate) async fn add<'a>( #[poise::command(slash_command)] pub(crate) async fn list( ctx: Context<'_>, - user: Option + user: Option, ) -> Result<(), Error> { ctx.defer().await?; let user = user.unwrap_or(ctx.author().clone()); diff --git a/src/commands/bots.rs b/src/commands/bots.rs index 14fda88..6b34203 100644 --- a/src/commands/bots.rs +++ b/src/commands/bots.rs @@ -1,7 +1,7 @@ use std::string::String; -use crate::commands::command_helper; use crate::{Context, Error}; +use crate::commands::command_helper; #[poise::command(slash_command, guild_only, owners_only)] pub(crate) async fn bots( diff --git a/src/commands/helpstart.rs b/src/commands/helpstart.rs index d4efdd4..c390ffa 100644 --- a/src/commands/helpstart.rs +++ b/src/commands/helpstart.rs @@ -1,8 +1,8 @@ use poise::CreateReply; use serenity::all::CreateAllowedMentions; -use crate::commands::command_helper; use crate::{Context, Error}; +use crate::commands::command_helper; #[poise::command(slash_command, guild_only)] pub(crate) async fn helpstart( diff --git a/src/commands/lfg.rs b/src/commands/lfg.rs index 449d274..7daf9e6 100644 --- a/src/commands/lfg.rs +++ b/src/commands/lfg.rs @@ -1,8 +1,9 @@ use poise::{ChoiceParameter, CreateReply}; use serenity::all::{CreateAllowedMentions, RoleId}; + +use crate::{Context, Error}; //from main.rs use crate::commands::command_helper::cooldown; -use crate::{Context, Error}; // use crate::commands::lfg::Difficulty::Normal; use crate::commands::lfg::Map::*; @@ -44,29 +45,23 @@ pub enum Difficulty { #[poise::command(slash_command, guild_only)] pub(crate) async fn lfg( ctx: Context<'_>, - #[rename = "map"] map: Map, - #[description = "Normal"] #[rename = "difficulty"] difficulty: Option, - #[rename = "mode"] #[description = "play-style"] mode: Mode, - #[min = 1_u8] #[max = 3_u8] #[description = "default: 1"] #[rename = "current"] current_players: Option, - #[min = 2_u8] #[max = 4_u8] #[description = "default: 4"] #[rename = "desired"] desired_players: Option, - #[description = "optional extra message"] #[rename = "message"] note: Option, @@ -102,7 +97,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 => { @@ -142,31 +137,25 @@ enum ExpertMap { #[name = "Speedrun"] Speedrun, } -#[poise::command(slash_command, guild_only, rename = "expert-lfg")] +#[poise::command(slash_command, guild_only, rename = "lfg-expert")] pub(crate) async fn expert( ctx: Context<'_>, - #[rename = "map"] mode: ExpertMap, - #[min = 1_u8] #[max = 3_u8] #[description = "default: 1"] #[rename = "current"] current_players: Option, - #[min = 2_u8] #[max = 4_u8] #[description = "default: 4"] #[rename = "desired"] desired_players: Option, - #[description = "extra message"] #[rename = "message"] note: String, ) -> Result<(), Error> { - let mut reply: CreateReply = CreateReply::default(); - - reply = match cooldown(&ctx, 600, 300) { + 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); @@ -199,17 +188,20 @@ pub(crate) async fn expert( .iter() .any(|user_role: &RoleId| allowed_roles.contains(&user_role.get())); let reply_content: String = format!("{current}/{desired} <@&{ping}>: {note}"); + match is_expert { - true => reply + true => CreateReply::default() .content(reply_content) .ephemeral(false) .allowed_mentions(CreateAllowedMentions::new().roles(vec![ping])), - false => reply + false => CreateReply::default() .content("You do not have any of the required expert ranks.") .ephemeral(true), } } - Err(why) => reply.content(why.to_string()).ephemeral(true), + Err(why) => { + CreateReply::default().content(why.to_string()).ephemeral(true) + } }; if let Err(why) = ctx.send(reply).await { @@ -218,7 +210,54 @@ pub(crate) async fn expert( Ok(()) } -const ROLE_LIST: [[u64;6]; 9] = [ // [[basic, de, bb, aa, sr, star]; 9] +#[derive(Debug, poise::ChoiceParameter)] +enum OtherPing { + #[name = "GeoGuessr"] + GeoGuessr, +} +#[poise::command(slash_command, guild_only, rename = "lfg-other")] +pub(crate) async fn other( + ctx: Context<'_>, + #[rename = "game"] + game: OtherPing, + #[min = 1_u8] + #[max = 3_u8] + #[description = "default: 1"] + #[rename = "current"] + current_players: Option, + #[description = "extra message"] + #[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) + } + }; + + if let Err(why) = ctx.send(reply).await { + println!("Error sending message: {why}"); + } + 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 diff --git a/src/commands/xd.rs b/src/commands/xd.rs index a6ece93..e7d191a 100644 --- a/src/commands/xd.rs +++ b/src/commands/xd.rs @@ -1,6 +1,6 @@ use crate::{Context, Error}; -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/handlers/bot_interaction.rs b/src/handlers/bot_interaction.rs index c9ec6cd..ffb36d2 100644 --- a/src/handlers/bot_interaction.rs +++ b/src/handlers/bot_interaction.rs @@ -1,10 +1,11 @@ use serenity::all::{ComponentInteraction, ComponentInteractionDataKind, Context, CreateMessage, EditMessage, GuildId, Interaction, RoleId}; + use crate::Error; pub(crate) async fn component(ctx: &Context, interaction: &Interaction) -> Result<(), Error> { let component = interaction.clone().message_component().unwrap(); match component.data.kind { - ComponentInteractionDataKind::Button => button(ctx, component, ).await, + ComponentInteractionDataKind::Button => button(ctx, component).await, _ => Ok(()) } } @@ -21,7 +22,7 @@ async fn button(ctx: &Context, mut component: ComponentInteraction) -> Result<() member.remove_role(ctx, RoleId::new(1256253358701023232_u64)).await?; component.message.edit(ctx, EditMessage::new().components(vec![])).await?; Ok(()) - }, + } "deny_verification" => { let _dm = u.direct_message(ctx, CreateMessage::new() .content("Your verified minecraft account was denied.")).await?; diff --git a/src/handlers/message.rs b/src/handlers/message.rs index 6de1365..881e2b2 100644 --- a/src/handlers/message.rs +++ b/src/handlers/message.rs @@ -1,12 +1,13 @@ use serenity::all::{Context, Message}; + use crate::Error; -pub(crate) async fn create(ctx: &Context, msg: &Message) -> Result<(), 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(()) } } @@ -17,7 +18,7 @@ async fn zmp_create(ctx: &Context, msg: &Message) -> Result<(), Error> { msg.react(ctx, '🇼').await?; msg.react(ctx, '🇱').await?; Ok(()) - }, + } _ => Ok(()) } } diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 150e345..543de19 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -1,2 +1,3 @@ pub(crate) mod bot_interaction; -pub(crate) mod message; \ No newline at end of file +pub(crate) mod message; +pub(crate) mod thread; \ No newline at end of file diff --git a/src/handlers/thread.rs b/src/handlers/thread.rs new file mode 100644 index 0000000..ebb57d8 --- /dev/null +++ b/src/handlers/thread.rs @@ -0,0 +1,15 @@ +use serenity::all::{Context, GuildChannel}; +use serenity::builder::EditThread; + +use crate::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?; + Ok(()) + } + Some(_) => Ok(()), + None => Ok(()) + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index f0cac39..78ac607 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ use poise::serenity_prelude as serenity; use serenity::{FullEvent, model::id::UserId}; use serenity::all::{ActivityData, InteractionType, RoleId}; use serenity::prelude::GatewayIntents; -use sqlx::{Sqlite}; +use sqlx::Sqlite; use tokio::sync::RwLock; mod commands; @@ -59,12 +59,11 @@ async fn main() { on_error: |error| { Box::pin(async move { match error { - other => poise::builtins::on_error(other).await.unwrap(), } }) }, - owners: { HashSet::from([UserId::new(449579075531440128_u64),UserId::new(659112817508745216_u64)]) }, + 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)) }, @@ -103,22 +102,25 @@ async fn event_handler( match event { FullEvent::Ready { data_about_bot, .. } => { println!("Logged in as {}", data_about_bot.user.name); - }, + } FullEvent::GuildMemberAddition { new_member } => { println!("join event"); if new_member.guild_id.get() == 1256217633959841853_u64 { new_member.add_role(ctx, RoleId::new(1256253358701023232_u64)).await?; println!("gave member role"); } - }, - FullEvent::InteractionCreate {interaction} => { + } + FullEvent::InteractionCreate { interaction } => { if interaction.application_id().get() == 1165594074473037824 && interaction.kind() == InteractionType::Component { handlers::bot_interaction::component(ctx, interaction).await?; } - }, + } FullEvent::Message { new_message } => { - handlers::message::create(ctx, new_message).await?; + handlers::message::on_create(ctx, new_message).await?; + } + FullEvent::ThreadCreate { thread } => { + handlers::thread::on_create(ctx, thread).await?; } _ => {} }