From 792bc70cd025356ae32a0e386091773cd459c1fa Mon Sep 17 00:00:00 2001 From: minneelyyyy Date: Thu, 20 Feb 2025 22:30:35 -0500 Subject: [PATCH] better setting handling, position setting --- src/commands/self_roles/mod.rs | 10 +++- src/commands/settings.rs | 99 ++++++++++++++++++++++++++++++---- src/main.rs | 8 +-- 3 files changed, 100 insertions(+), 17 deletions(-) diff --git a/src/commands/self_roles/mod.rs b/src/commands/self_roles/mod.rs index 52d50b7..e6587e1 100644 --- a/src/commands/self_roles/mod.rs +++ b/src/commands/self_roles/mod.rs @@ -39,11 +39,17 @@ pub async fn edit_role<'a, E>(ctx: Context<'a>, user: UserId, guild: GuildId, ed } async fn create_role<'a, E>(ctx: Context<'a>, user: UserId, guild: GuildId, edit: EditRole<'a>, db: E) -> Result - where E: PgExecutor<'a>, + where E: PgExecutor<'a> + Clone, { let def = EditRole::new() .name(user.to_user(ctx).await?.name) - .permissions(Permissions::empty()); + .permissions(Permissions::empty()) + .position({ + match crate::commands::settings::get_positional_role(ctx, guild).await? { + Some(role) => guild.role(ctx, role).await?.position, + None => 0u16, + } + }); let member = guild.member(ctx, user).await?; diff --git a/src/commands/settings.rs b/src/commands/settings.rs index 5278b70..82d864d 100644 --- a/src/commands/settings.rs +++ b/src/commands/settings.rs @@ -1,7 +1,20 @@ use crate::common::{Context, Error}; -#[poise::command(prefix_command, slash_command, required_permissions = "MANAGE_GUILD")] -async fn prefix(ctx: Context<'_>, prefix: String) -> Result<(), Error> { +use poise::serenity_prelude::{Role, RoleId, GuildId}; +use sqlx::Row; + +async fn get_prefix(ctx: Context<'_>, guild: GuildId) -> Result, Error> { + let db = &ctx.data().database; + + let prefix: Option = sqlx::query("SELECT prefix FROM settings WHERE guildid = $1") + .bind(guild.get() as i64) + .fetch_one(db).await?.get(0); + + Ok(prefix.or(ctx.data().prefix.clone())) +} + +#[poise::command(prefix_command, slash_command)] +async fn prefix(ctx: Context<'_>, prefix: Option) -> Result<(), Error> { let guild = match ctx.guild_id() { Some(g) => g, None => { @@ -10,21 +23,85 @@ async fn prefix(ctx: Context<'_>, prefix: String) -> Result<(), Error> { } }; - let mut tx = ctx.data().database.begin().await?; + match prefix { + Some(prefix) => { + if !ctx.author_member().await.unwrap().permissions.iter().any(|p| p.manage_guild()) { + ctx.reply("You do not have permission to change this setting.").await?; + return Ok(()); + } - sqlx::query("INSERT INTO settings (guildid, prefix) VALUES ($1, $2) ON CONFLICT (guildid) DO UPDATE SET prefix = EXCLUDED.prefix") - .bind(guild.get() as i64) - .bind(&prefix) - .execute(&mut *tx).await?; + let mut tx = ctx.data().database.begin().await?; - tx.commit().await?; - - ctx.reply(format!("This server's custom prefix has been updated to `{prefix}`.")).await?; + sqlx::query("INSERT INTO settings (guildid, prefix) VALUES ($1, $2) ON CONFLICT (guildid) DO UPDATE SET prefix = EXCLUDED.prefix") + .bind(guild.get() as i64) + .bind(&prefix) + .execute(&mut *tx).await?; + + tx.commit().await?; + + ctx.reply(format!("This server's custom prefix has been updated to `{prefix}`.")).await?; + } + None => { + let s = get_prefix(ctx, guild).await?.map(|s| format!("`{s}`")).unwrap_or("not set".into()); + ctx.reply(format!("This server's command prefix is {s}.")).await?; + } + } Ok(()) } -#[poise::command(prefix_command, slash_command, subcommands("prefix"), subcommand_required)] +pub async fn get_positional_role(ctx: Context<'_>, guild: GuildId) -> Result, Error> { + let db = &ctx.data().database; + + let role: Option = sqlx::query("SELECT positional_role FROM settings WHERE guildid = $1") + .bind(guild.get() as i64) + .fetch_one(db).await?.get(0); + + Ok(role.map(|sf| RoleId::new(sf as u64))) +} + +#[poise::command(prefix_command, slash_command)] +pub async fn position(ctx: Context<'_>, role: Option) -> Result<(), Error> { + let guild = match ctx.guild_id() { + Some(g) => g, + None => { + ctx.reply("This command must be ran within a guild.").await?; + return Ok(()); + } + }; + + if !ctx.author_member().await.unwrap().permissions.iter().any(|p| p.manage_guild()) { + ctx.reply("You do not have permission to see or change this setting.").await?; + return Ok(()); + } + + match role { + Some(role) => { + let mut tx = ctx.data().database.begin().await?; + + sqlx::query("INSERT INTO settings (guildid, positional_role) VALUES ($1, $2) ON CONFLICT (guildid) DO UPDATE SET positional_role = EXCLUDED.positional_role") + .bind(guild.get() as i64) + .bind(role.id.get() as i64) + .execute(&mut *tx).await?; + + tx.commit().await?; + + ctx.reply(format!("The bot will now place newly created self roles below `{role}`.")).await?; + } + None => { + let s = match get_positional_role(ctx, guild).await? { + Some(r) => format!("{}", guild.role(ctx, r).await?), + None => "not set".into() + }; + + ctx.reply(format!("This server's positional role is {s}.")).await?; + } + } + + Ok(()) +} + +#[poise::command(prefix_command, slash_command, subcommands("prefix", "position"), subcommand_required)] pub async fn setting(_ctx: Context<'_>) -> Result<(), Error> { Ok(()) } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index a5c94dc..9f3dc20 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,12 +62,11 @@ async fn get_prefix(ctx: PartialContext<'_, Data, Error>) -> Result = sqlx::query("SELECT prefix FROM settings WHERE guildid = $1") .bind(guild.get() as i64) - .fetch_one(db).await.ok() - .map(|x| x.get(0)).unwrap_or(ctx.data.prefix.clone()); + .fetch_one(db).await?.get(0); - Ok(prefix) + Ok(prefix.or(ctx.data.prefix.clone())) } #[tokio::main] @@ -164,6 +163,7 @@ async fn main() -> Result<(), Error> { r#" CREATE TABLE IF NOT EXISTS settings ( guildid BIGINT NOT NULL PRIMARY KEY, + positional_role BIGINT, prefix TEXT ) "#