diff --git a/src/commands/role_adder.rs b/src/commands/role_adder.rs index ef7effb..3f224ef 100644 --- a/src/commands/role_adder.rs +++ b/src/commands/role_adder.rs @@ -61,19 +61,24 @@ pub mod edit { return "Please provide a valid role for ``Role Current``".to_string(); }; - let delete = if let CommandDataOptionValue::Boolean(delete) = command + + let mut delete = false; + + if let Some(x) = command .data .options - .get(3) - .expect("Expected true/false option") - .resolved - .as_ref() - .expect("Expected true/False object") - { - delete.to_owned() - } else { - false - }; + .get(3) { + + let tmp = x.to_owned(); + if let Some(y) = tmp.resolved { + match y { + CommandDataOptionValue::Boolean(z) => { + delete = z; + } + _ => {} + } + } + } let db_lock = { let data_read = ctx.data.read().await; @@ -169,4 +174,67 @@ pub mod edit { } // TODO -pub mod list {} \ No newline at end of file +pub mod list {} + + +pub mod tools { + use serenity::client::Context; + use serenity::model::guild::Member; + use sqlx::{Pool, Sqlite}; + use skynet_discord_bot::RoleAdder; + + pub async fn on_role_change(db: &Pool, ctx: &Context, mut new_data: Member){ + + + // check if the role changed is part of the oens for this server + if let Some(role_adders) = sqlx::query_as::<_, RoleAdder>( + r#" + SELECT * + FROM roles_adder + WHERE server = ? + "#, + ) + .bind(*new_data.guild_id.as_u64() as i64) + .fetch_all(db) + .await + .ok() { + + + let mut roles_add = vec![]; + let mut roles_remove = vec![]; + + for role_adder in role_adders { + // if the user has both A dnd B give them C + if new_data.roles.contains(&role_adder.role_a) && + new_data.roles.contains(&role_adder.role_b) && + !new_data.roles.contains(&role_adder.role_c) { + roles_add.push(role_adder.role_c); + } + + // If the suer has C but not A or B remove C + if new_data.roles.contains(&role_adder.role_c) && + ( + !new_data.roles.contains(&role_adder.role_a) || !new_data.roles.contains(&role_adder.role_b) + ) { + roles_remove.push(role_adder.role_c); + } + } + + + + if !roles_add.is_empty(){ + if let Err(e) = new_data.add_roles(&ctx, &roles_add).await { + println!("{:?}", e); + } + } + + if !roles_remove.is_empty(){ + if let Err(e) = new_data.remove_roles(&ctx, &roles_remove).await{ + println!("{:?}", e); + } + } + } + } + + +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index c6ba064..09315f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -302,7 +302,7 @@ pub struct RoleAdder { } impl<'r> FromRow<'r, SqliteRow> for RoleAdder { fn from_row(row: &'r SqliteRow) -> Result { - let server_tmp: i64 = row.try_get("server_discord")?; + let server_tmp: i64 = row.try_get("server")?; let server = GuildId::from(server_tmp as u64); Ok(Self { diff --git a/src/main.rs b/src/main.rs index 413dc6f..275212d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,6 @@ use serenity::{ model::{ application::{command::Command, interaction::Interaction}, gateway::{GatewayIntents, Ready}, - guild, prelude::Activity, user::OnlineStatus, }, @@ -16,13 +15,14 @@ use std::sync::Arc; use serenity::model::guild::Member; use skynet_discord_bot::{db_init, get_config, get_server_config, get_server_member, Config, DataBase}; use tokio::sync::RwLock; +use crate::commands::role_adder::tools::on_role_change; struct Handler; #[async_trait] impl EventHandler for Handler { // handles previously linked accounts joining the server - async fn guild_member_addition(&self, ctx: Context, mut new_member: guild::Member) { + async fn guild_member_addition(&self, ctx: Context, mut new_member: Member) { let db_lock = { let data_read = ctx.data.read().await; data_read.get::().expect("Expected Config in TypeMap.").clone() @@ -76,6 +76,7 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use match Command::set_global_application_commands(&ctx.http, |commands| { commands .create_application_command(|command| commands::add_server::register(command)) + .create_application_command(|command| commands::role_adder::edit::register(command)) .create_application_command(|command| commands::link_email::link::register(command)) .create_application_command(|command| commands::link_email::verify::register(command)) .create_application_command(|command| commands::minecraft::server::add::register(command)) @@ -107,6 +108,7 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use "link_minecraft" => commands::minecraft::user::add::run(&command, &ctx).await, // admin commands "add" => commands::add_server::run(&command, &ctx).await, + "roles_adder" => commands::role_adder::edit::run(&command, &ctx).await, "minecraft_add" => commands::minecraft::server::add::run(&command, &ctx).await, "minecraft_list" => commands::minecraft::server::list::run(&command, &ctx).await, "minecraft_delete" => commands::minecraft::server::delete::run(&command, &ctx).await, @@ -123,22 +125,18 @@ Sign up on [UL Wolves]({}) and go to https://discord.com/channels/{}/{} and use } // handles role updates - async fn guild_member_update(&self, _ctx: Context, _old_if_available: Option, _new: Member){ - if let Some(x) = _old_if_available { - if x.roles.len() != _new.roles.len() { - return; - } - //do we need to do more comparison here? - } - + async fn guild_member_update(&self, ctx: Context, _old_data: Option, new_data: Member){ // get config/db + let db_lock = { + let data_read = ctx.data.read().await; + data_read.get::().expect("Expected Config in TypeMap.").clone() + }; + + let db = db_lock.read().await; // check if the role changed is part of the oens for this server - - // if so add or remove the resultant one - - // TODO: Finish + on_role_change(&db, &ctx, new_data).await; } }