From 5d57c19f62f0033eaf1b43c94a1a4f49439227f7 Mon Sep 17 00:00:00 2001 From: jude Date: Thu, 3 Sep 2020 14:52:19 +0100 Subject: [PATCH] changed mutex for rwlock. switched custom permission check for the serenity built in one. changed cargo.toml to use 0.9.0-rc.0 --- .env | 6 ++++ .gitignore | 2 -- Cargo.lock | 33 ++++++++++++++----- Cargo.toml | 2 +- src/main.rs | 95 +++++++++++++++++++++-------------------------------- 5 files changed, 69 insertions(+), 69 deletions(-) create mode 100644 .env delete mode 100644 .gitignore diff --git a/.env b/.env new file mode 100644 index 0000000..3393f2d --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +DATABASE_URL=mysql://jude@localhost/soundfx +DISCORD_TOKEN=NjAzMjc3NDk1NDA3NjA3ODA4.XqYJQg.dNcBX635-BN1S8-qw9odF7T-9Dk +CLIENT_ID=603277495407607808 +MAX_SOUNDS=8 +PATREON_GUILD=355102571561484289 +PATREON_ROLE=742091767322509433 diff --git a/.gitignore b/.gitignore deleted file mode 100644 index fedaa2b..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target -.env diff --git a/Cargo.lock b/Cargo.lock index ac9a870..6ed5681 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -143,9 +143,9 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" [[package]] name = "base64" -version = "0.12.0" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5ca2cd0adc3f48f9e9ea5a6bbdf9ccc0bfade884847e484d452414c7ccffb3" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" [[package]] name = "bigdecimal" @@ -235,7 +235,9 @@ dependencies = [ [[package]] name = "command_attr" -version = "0.2.0" +version = "0.3.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093ee06b40fcba41b22ddf85de7ed33728fe2e246fcdbc1b1d3ab26f87fabf3b" dependencies = [ "proc-macro2", "quote", @@ -1085,7 +1087,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b82c9238b305f26f53443e3a4bc8528d64b8d0bee408ec949eb7bf5635ec680" dependencies = [ - "base64 0.12.0", + "base64 0.12.3", "bytes", "encoding_rs", "futures-core", @@ -1159,6 +1161,19 @@ dependencies = [ "webpki", ] +[[package]] +name = "rustls" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81" +dependencies = [ + "base64 0.12.3", + "log", + "ring", + "sct", + "webpki", +] + [[package]] name = "ryu" version = "1.0.3" @@ -1263,13 +1278,15 @@ dependencies = [ [[package]] name = "serenity" -version = "0.8.6" +version = "0.9.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f2b6557e836289a35b45ecc9da78b464de79cec3aa9b7cfd07f654cbc478c00" dependencies = [ "async-tls", "async-trait", "async-tungstenite", "audiopus", - "base64 0.12.0", + "base64 0.12.3", "bitflags", "byteorder", "bytes", @@ -1280,7 +1297,7 @@ dependencies = [ "log", "rand", "reqwest", - "rustls 0.17.0", + "rustls 0.18.1", "serde", "serde_json", "static_assertions", @@ -1398,7 +1415,7 @@ checksum = "88ac5a436f941c42eac509471a730df5c3c58e1450e68cd39afedbd948206273" dependencies = [ "async-native-tls", "async-stream", - "base64 0.12.0", + "base64 0.12.3", "bigdecimal", "bitflags", "byteorder", diff --git a/Cargo.toml b/Cargo.toml index 158cc83..87b98f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ authors = ["jude-lafitteIII "] edition = "2018" [dependencies] -serenity = {path = "/home/jude/serenity", features = ["voice", "collector"]} +serenity = {version = "0.9.0-rc.0", features = ["voice", "collector"]} sqlx = {version = "0.3.5", default-features = false, features = ["runtime-tokio", "macros", "mysql", "bigdecimal"]} dotenv = "0.15" tokio = {version = "0.2.19", features = ["fs", "sync", "process", "io-util"]} diff --git a/src/main.rs b/src/main.rs index 49e818d..58ca8db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -56,20 +56,21 @@ use dotenv::dotenv; use tokio::{ sync::{ - Mutex, - MutexGuard + RwLock, + RwLockWriteGuard, }, time, }; use std::{ - collections::{ - HashMap, - HashSet, - }, + collections::HashMap, env, sync::Arc, - time::Duration, + time::{ + Duration, + SystemTime, + UNIX_EPOCH, + }, }; @@ -88,7 +89,7 @@ impl TypeMapKey for VoiceManager { struct VoiceGuilds; impl TypeMapKey for VoiceGuilds { - type Value = Arc>>; + type Value = Arc>>; } struct ReqwestClient; @@ -114,11 +115,6 @@ lazy_static! { dotenv().unwrap(); env::var("PATREON_ROLE").unwrap().parse::().unwrap() }; - - static ref DISCONNECT_CYCLES: u8 = { - dotenv().unwrap(); - env::var("DISCONNECT_CYCLES").unwrap_or("2".to_string()).parse::().unwrap() - }; } #[group] @@ -245,27 +241,17 @@ async fn permission_check(ctx: &Context, msg: &Message, _args: &mut Args) -> Che } async fn perform_permission_check(ctx: &Context, msg: &&Message) -> CheckResult { - if let Some(guild_id) = msg.guild_id { - if let Ok(member) = guild_id.member(ctx.clone(), msg.author.id).await { - if let Ok(perms) = member.permissions(ctx).await { - if perms.manage_guild() || perms.administrator() { - return CheckResult::Success - } - } - - if let Some(roles) = member.roles(ctx).await { - if roles - .iter() - .filter(|r| r.permissions.manage_guild() || r.permissions.administrator() ) - .next() - .is_some() { - return CheckResult::Success - } - } + if let Some(guild) = msg.guild(&ctx).await { + if guild.member_permissions(&msg.author).manage_guild() { + CheckResult::Success + } + else { + CheckResult::Failure(Reason::User(String::from("User needs `Manage Guild` permission"))) } } - - CheckResult::Failure(Reason::User(String::from("User needs `Manage Guild` permission"))) + else { + CheckResult::Failure(Reason::User(String::from("Guild not cached"))) + } } // create event handler for bot @@ -344,7 +330,7 @@ SELECT name, id, plays, public, server_id, uploader_id let voice_guilds_lock = ctx.data.read().await .get::().cloned().expect("Could not get VoiceGuilds from data"); - let voice_guilds = voice_guilds_lock.lock().await; + let voice_guilds = voice_guilds_lock.write().await; let mut voice_manager = voice_manager_lock.lock().await; @@ -360,7 +346,7 @@ SELECT name, id, plays, public, server_id, uploader_id } } -async fn play_audio(sound: &mut Sound, guild: GuildData, handler: &mut VoiceHandler, mut voice_guilds: MutexGuard<'_, HashMap>, pool: MySqlPool) +async fn play_audio(sound: &mut Sound, guild: GuildData, handler: &mut VoiceHandler, mut voice_guilds: RwLockWriteGuard<'_, HashMap>, pool: MySqlPool) -> Result<(), Box> { let audio = handler.play_only(sound.store_sound_source(pool.clone()).await?); @@ -374,7 +360,10 @@ async fn play_audio(sound: &mut Sound, guild: GuildData, handler: &mut VoiceHand sound.plays += 1; sound.commit(pool).await?; - voice_guilds.insert(GuildId(guild.id), *DISCONNECT_CYCLES); + let start = SystemTime::now(); + let since_epoch = start.duration_since(UNIX_EPOCH).unwrap(); + + voice_guilds.insert(GuildId(guild.id), since_epoch.as_secs()); Ok(()) } @@ -405,7 +394,7 @@ async fn main() -> Result<(), Box> { dotenv()?; - let voice_guilds = Arc::new(Mutex::new(HashMap::new())); + let voice_guilds = Arc::new(RwLock::new(HashMap::new())); let framework = StandardFramework::new() .configure(|c| c @@ -484,17 +473,17 @@ async fn main() -> Result<(), Box> { Ok(()) } -async fn disconnect_from_inactive(voice_manager_mutex: Arc>, voice_guilds: Arc>>, wait_time: u64) { +async fn disconnect_from_inactive(voice_manager_mutex: Arc>, voice_guilds: Arc>>, wait_time: u64) { loop { time::delay_for(Duration::from_secs(wait_time)).await; - let mut voice_guilds_acquired = voice_guilds.lock().await; + let voice_guilds_acquired = voice_guilds.read().await; - let mut to_remove = HashSet::new(); + let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); - for (guild, ticker) in voice_guilds_acquired.iter_mut() { + for (guild, last_active) in voice_guilds_acquired.iter() { - if *ticker == 0 { + if (now - last_active) > wait_time { let mut voice_manager = voice_manager_mutex.lock().await; @@ -503,17 +492,7 @@ async fn disconnect_from_inactive(voice_manager_mutex: Arc CommandResult { let voice_manager_lock = ctx.data.read().await .get::().cloned().expect("Could not get VoiceManager from data"); - let voice_guilds_lock = ctx.data.read().await - .get::().cloned().expect("Could not get VoiceGuilds from data"); - - let voice_guilds = voice_guilds_lock.lock().await; - - let guild_data = GuildData::get_from_id(guild, pool.clone()).await.unwrap(); - let mut voice_manager = voice_manager_lock.lock().await; match voice_manager.join(guild_id, user_channel) { Some(handler) => { + let guild_data = GuildData::get_from_id(guild, pool.clone()).await.unwrap(); + + let voice_guilds_lock = ctx.data.read().await + .get::().cloned().expect("Could not get VoiceGuilds from data"); + + let voice_guilds = voice_guilds_lock.write().await; + play_audio(sound, guild_data, handler, voice_guilds, pool).await?; msg.channel_id.say(&ctx, format!("Playing sound {} with ID {}", sound.name, sound.id)).await?;