From 0f774258a1d4e5027e3ee6aed1c0f169ff9bf59e Mon Sep 17 00:00:00 2001 From: Brendan Golden Date: Mon, 3 Jun 2024 02:04:26 +0100 Subject: [PATCH] feat: added support for multiple minecraft servers per discord server Closes #9 --- src/bin/update_minecraft.rs | 20 +++++++++------- src/commands/add_minecraft.rs | 40 +++++++++++++------------------ src/commands/add_server.rs | 14 +++-------- src/lib.rs | 45 +++++++++++++++++++++++++++-------- 4 files changed, 66 insertions(+), 53 deletions(-) diff --git a/src/bin/update_minecraft.rs b/src/bin/update_minecraft.rs index 3105167..05e8831 100644 --- a/src/bin/update_minecraft.rs +++ b/src/bin/update_minecraft.rs @@ -1,4 +1,5 @@ -use skynet_discord_bot::{db_init, get_config, get_server_config_bulk, update_server, whitelist_wipe}; +use std::collections::HashSet; +use skynet_discord_bot::{db_init, get_config, get_minecraft_config, update_server, whitelist_wipe}; #[tokio::main] async fn main() { @@ -8,16 +9,17 @@ async fn main() { Err(_) => return, }; - let servers = get_server_config_bulk(&db).await; + let servers = get_minecraft_config(&db).await; + let mut wiped = HashSet::new(); - // wipe whitelist first - for server_config in &servers { - if let Some(server_id) = &server_config.server_minecraft { - whitelist_wipe(server_id, &config.discord_minecraft).await; + for server in &servers { + // wipe whitelist first + if !wiped.contains(&server.minecraft) { + whitelist_wipe(&server.minecraft, &config.discord_minecraft).await; + // add it to teh done list so its not done again + wiped.insert(&server.minecraft); } - } - for server_config in &servers { - update_server(&server_config.server_minecraft, &db, &server_config.server, &config).await; + update_server(&server.minecraft, &db, &server.discord, &config).await; } } diff --git a/src/commands/add_minecraft.rs b/src/commands/add_minecraft.rs index b22dfaa..8b3ad0a 100644 --- a/src/commands/add_minecraft.rs +++ b/src/commands/add_minecraft.rs @@ -14,7 +14,7 @@ pub(crate) mod user { use super::*; use crate::commands::link_email::link::get_server_member_discord; use serenity::model::id::UserId; - use skynet_discord_bot::{whitelist_update, Config, Wolves}; + use skynet_discord_bot::{whitelist_update, Config, Wolves, get_minecraft_config_server, Minecraft}; use sqlx::Error; pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { @@ -71,10 +71,7 @@ pub(crate) mod user { // get a list of servers that the user is a member of if let Ok(servers) = get_servers(&db, &command.user.id).await { for server in servers { - if let Some(server_minecraft) = server.server_minecraft { - // activate the user on all linked servers - whitelist_update(&vec![username.to_string()], &server_minecraft, &config.discord_minecraft).await; - } + whitelist_update(&vec![username.to_string()], &server.minecraft, &config.discord_minecraft).await; } } @@ -95,18 +92,17 @@ pub(crate) mod user { .await } - async fn get_servers(db: &Pool, discord: &UserId) -> Result, Error> { - sqlx::query_as::<_, Servers>( + async fn get_servers(db: &Pool, discord: &UserId) -> Result, Error> { + sqlx::query_as::<_, Minecraft>( " - SELECT servers.* - FROM servers + SELECT minecraft.* + FROM minecraft JOIN ( SELECT server FROM server_members JOIN wolves USING (id_wolves) WHERE discord = ?1 - ) USING (server) - WHERE server_minecraft IS NOT NULL + ) sub on minecraft.server_discord = sub.server ", ) .bind(*discord.as_u64() as i64) @@ -153,9 +149,9 @@ pub(crate) mod server { .as_ref() .expect("Expected server_id object") { - Some(id.to_owned()) + id.to_owned() } else { - None + return String::from("Expected Server ID"); }; let db_lock = { @@ -168,17 +164,16 @@ pub(crate) mod server { None => { return "No existing server config, have you used ``/add``?".to_string(); } - Some(mut x) => { - x.server_minecraft.clone_from(&server_minecraft); + Some(x) => { x } }; - match add_server(&db, &server_data).await { + match add_server(&db, *server_data.server.as_u64() as i64, &server_minecraft).await { Ok(_) => {} Err(e) => { println!("{:?}", e); - return format!("Failure to insert into Servers {:?}", server_data); + return format!("Failure to insert into Minecraft {} {}", *server_data.server.as_u64(), &server_minecraft); } } @@ -193,16 +188,15 @@ pub(crate) mod server { "Added/Updated minecraft_server info".to_string() } - async fn add_server(db: &Pool, server: &Servers) -> Result, Error> { + async fn add_server(db: &Pool, discord: i64, minecraft: &str ) -> Result, Error> { sqlx::query_as::<_, Servers>( " - UPDATE servers - SET server_minecraft = ?2 - WHERE server = ?1; + INSERT OR REPLACE INTO minecraft (server_discord, server_minecraft) + VALUES (?1, ?2) ", ) - .bind(*server.server.as_u64() as i64) - .bind(&server.server_minecraft) + .bind(discord) + .bind(minecraft) .fetch_optional(db) .await } diff --git a/src/commands/add_server.rs b/src/commands/add_server.rs index cd66500..fd192d2 100644 --- a/src/commands/add_server.rs +++ b/src/commands/add_server.rs @@ -63,9 +63,7 @@ pub async fn run(command: &ApplicationCommandInteraction, ctx: &Context) -> Stri role_past, role_current, member_past: 0, - member_current: 0, - // this gets added later - server_minecraft: None, + member_current: 0 }; match add_server(&db, ctx, &server_data).await { @@ -111,22 +109,16 @@ async fn add_server(db: &Pool, ctx: &Context, server: &Servers) -> Resul let role_past = server.role_past.map(|x| *x.as_u64() as i64); let role_current = server.role_current.map(|x| *x.as_u64() as i64); - let server_minecraft = match get_server_config(db, &server.server).await { - None => None, - Some(x) => x.server_minecraft, - }; - let insert = sqlx::query_as::<_, Servers>( " - INSERT OR REPLACE INTO servers (server, wolves_api, role_past, role_current, server_minecraft) - VALUES (?1, ?2, ?3, ?4, ?5) + INSERT OR REPLACE INTO servers (server, wolves_api, role_past, role_current) + VALUES (?1, ?2, ?3, ?4) ", ) .bind(*server.server.as_u64() as i64) .bind(&server.wolves_api) .bind(role_past) .bind(role_current) - .bind(server_minecraft) .fetch_optional(db) .await; diff --git a/src/lib.rs b/src/lib.rs index 1535325..f2857b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -697,18 +697,16 @@ loop through all members of server get a list of folks with mc accounts that are members and a list that arent members */ -pub async fn update_server(server_minecraft: &Option, db: &Pool, g_id: &GuildId, config: &Config) { - if let Some(server_id) = server_minecraft { - let mut usernames = vec![]; - for member in get_server_member_bulk(db, g_id).await { - if let Some(x) = member.minecraft { - usernames.push(x); - } - } - if !usernames.is_empty() { - whitelist_update(&usernames, server_id, &config.discord_minecraft).await; +pub async fn update_server(server_id: &String, db: &Pool, g_id: &GuildId, config: &Config) { + let mut usernames = vec![]; + for member in get_server_member_bulk(db, g_id).await { + if let Some(x) = member.minecraft { + usernames.push(x); } } + if !usernames.is_empty() { + whitelist_update(&usernames, server_id, &config.discord_minecraft).await; + } } async fn post(url: &str, bearer: &str, data: &T) { @@ -770,3 +768,30 @@ pub async fn whitelist_wipe(server: &str, token: &str) { }; post(&format!("{url_base}/command"), &bearer, &data).await; } + + +pub async fn get_minecraft_config(db: &Pool) -> Vec { + sqlx::query_as::<_, Minecraft>( + r#" + SELECT * + FROM minecraft + "#, + ) + .fetch_all(db) + .await + .unwrap_or_default() +} + +pub async fn get_minecraft_config_server(db: &Pool, g_id: GuildId) -> Option { + sqlx::query_as::<_, Minecraft>( + r#" + SELECT * + FROM minecraft + WHERE server_discord = ?1 + "#, + ) + .bind(*g_id.as_u64() as i64) + .fetch_optional(db) + .await + .unwrap_or_default() +} \ No newline at end of file