changed mutex for rwlock. switched custom permission check for the serenity built in one. changed cargo.toml to use 0.9.0-rc.0

This commit is contained in:
jude 2020-09-03 14:52:19 +01:00
parent bcdfe83cc6
commit 5d57c19f62
5 changed files with 69 additions and 69 deletions

6
.env Normal file
View File

@ -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

2
.gitignore vendored
View File

@ -1,2 +0,0 @@
/target
.env

33
Cargo.lock generated
View File

@ -143,9 +143,9 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.12.0" version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5ca2cd0adc3f48f9e9ea5a6bbdf9ccc0bfade884847e484d452414c7ccffb3" checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
[[package]] [[package]]
name = "bigdecimal" name = "bigdecimal"
@ -235,7 +235,9 @@ dependencies = [
[[package]] [[package]]
name = "command_attr" 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 = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1085,7 +1087,7 @@ version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b82c9238b305f26f53443e3a4bc8528d64b8d0bee408ec949eb7bf5635ec680" checksum = "3b82c9238b305f26f53443e3a4bc8528d64b8d0bee408ec949eb7bf5635ec680"
dependencies = [ dependencies = [
"base64 0.12.0", "base64 0.12.3",
"bytes", "bytes",
"encoding_rs", "encoding_rs",
"futures-core", "futures-core",
@ -1159,6 +1161,19 @@ dependencies = [
"webpki", "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]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.3" version = "1.0.3"
@ -1263,13 +1278,15 @@ dependencies = [
[[package]] [[package]]
name = "serenity" 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 = [ dependencies = [
"async-tls", "async-tls",
"async-trait", "async-trait",
"async-tungstenite", "async-tungstenite",
"audiopus", "audiopus",
"base64 0.12.0", "base64 0.12.3",
"bitflags", "bitflags",
"byteorder", "byteorder",
"bytes", "bytes",
@ -1280,7 +1297,7 @@ dependencies = [
"log", "log",
"rand", "rand",
"reqwest", "reqwest",
"rustls 0.17.0", "rustls 0.18.1",
"serde", "serde",
"serde_json", "serde_json",
"static_assertions", "static_assertions",
@ -1398,7 +1415,7 @@ checksum = "88ac5a436f941c42eac509471a730df5c3c58e1450e68cd39afedbd948206273"
dependencies = [ dependencies = [
"async-native-tls", "async-native-tls",
"async-stream", "async-stream",
"base64 0.12.0", "base64 0.12.3",
"bigdecimal", "bigdecimal",
"bitflags", "bitflags",
"byteorder", "byteorder",

View File

@ -5,7 +5,7 @@ authors = ["jude-lafitteIII <judewrs@gmail.com>"]
edition = "2018" edition = "2018"
[dependencies] [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"]} sqlx = {version = "0.3.5", default-features = false, features = ["runtime-tokio", "macros", "mysql", "bigdecimal"]}
dotenv = "0.15" dotenv = "0.15"
tokio = {version = "0.2.19", features = ["fs", "sync", "process", "io-util"]} tokio = {version = "0.2.19", features = ["fs", "sync", "process", "io-util"]}

View File

@ -56,20 +56,21 @@ use dotenv::dotenv;
use tokio::{ use tokio::{
sync::{ sync::{
Mutex, RwLock,
MutexGuard RwLockWriteGuard,
}, },
time, time,
}; };
use std::{ use std::{
collections::{ collections::HashMap,
HashMap,
HashSet,
},
env, env,
sync::Arc, sync::Arc,
time::Duration, time::{
Duration,
SystemTime,
UNIX_EPOCH,
},
}; };
@ -88,7 +89,7 @@ impl TypeMapKey for VoiceManager {
struct VoiceGuilds; struct VoiceGuilds;
impl TypeMapKey for VoiceGuilds { impl TypeMapKey for VoiceGuilds {
type Value = Arc<Mutex<HashMap<GuildId, u8>>>; type Value = Arc<RwLock<HashMap<GuildId, u64>>>;
} }
struct ReqwestClient; struct ReqwestClient;
@ -114,11 +115,6 @@ lazy_static! {
dotenv().unwrap(); dotenv().unwrap();
env::var("PATREON_ROLE").unwrap().parse::<u64>().unwrap() env::var("PATREON_ROLE").unwrap().parse::<u64>().unwrap()
}; };
static ref DISCONNECT_CYCLES: u8 = {
dotenv().unwrap();
env::var("DISCONNECT_CYCLES").unwrap_or("2".to_string()).parse::<u8>().unwrap()
};
} }
#[group] #[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 { async fn perform_permission_check(ctx: &Context, msg: &&Message) -> CheckResult {
if let Some(guild_id) = msg.guild_id { if let Some(guild) = msg.guild(&ctx).await {
if let Ok(member) = guild_id.member(ctx.clone(), msg.author.id).await { if guild.member_permissions(&msg.author).manage_guild() {
if let Ok(perms) = member.permissions(ctx).await { CheckResult::Success
if perms.manage_guild() || perms.administrator() {
return CheckResult::Success
} }
} else {
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
}
}
}
}
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 // 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 let voice_guilds_lock = ctx.data.read().await
.get::<VoiceGuilds>().cloned().expect("Could not get VoiceGuilds from data"); .get::<VoiceGuilds>().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; 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<GuildId, u8>>, pool: MySqlPool) async fn play_audio(sound: &mut Sound, guild: GuildData, handler: &mut VoiceHandler, mut voice_guilds: RwLockWriteGuard<'_, HashMap<GuildId, u64>>, pool: MySqlPool)
-> Result<(), Box<dyn std::error::Error + Send + Sync>> { -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let audio = handler.play_only(sound.store_sound_source(pool.clone()).await?); 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.plays += 1;
sound.commit(pool).await?; 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(()) Ok(())
} }
@ -405,7 +394,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
dotenv()?; dotenv()?;
let voice_guilds = Arc::new(Mutex::new(HashMap::new())); let voice_guilds = Arc::new(RwLock::new(HashMap::new()));
let framework = StandardFramework::new() let framework = StandardFramework::new()
.configure(|c| c .configure(|c| c
@ -484,17 +473,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
Ok(()) Ok(())
} }
async fn disconnect_from_inactive(voice_manager_mutex: Arc<SerenityMutex<ClientVoiceManager>>, voice_guilds: Arc<Mutex<HashMap<GuildId, u8>>>, wait_time: u64) { async fn disconnect_from_inactive(voice_manager_mutex: Arc<SerenityMutex<ClientVoiceManager>>, voice_guilds: Arc<RwLock<HashMap<GuildId, u64>>>, wait_time: u64) {
loop { loop {
time::delay_for(Duration::from_secs(wait_time)).await; 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; let mut voice_manager = voice_manager_mutex.lock().await;
@ -503,17 +492,7 @@ async fn disconnect_from_inactive(voice_manager_mutex: Arc<SerenityMutex<ClientV
if let Some(manager) = manager_opt { if let Some(manager) = manager_opt {
manager.leave(); manager.leave();
} }
to_remove.insert(guild.clone());
} }
else {
*ticker -= 1;
}
}
for val in to_remove.iter() {
voice_guilds_acquired.remove(val);
} }
} }
} }
@ -557,17 +536,17 @@ async fn play(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
let voice_manager_lock = ctx.data.read().await let voice_manager_lock = ctx.data.read().await
.get::<VoiceManager>().cloned().expect("Could not get VoiceManager from data"); .get::<VoiceManager>().cloned().expect("Could not get VoiceManager from data");
let voice_guilds_lock = ctx.data.read().await
.get::<VoiceGuilds>().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; let mut voice_manager = voice_manager_lock.lock().await;
match voice_manager.join(guild_id, user_channel) { match voice_manager.join(guild_id, user_channel) {
Some(handler) => { Some(handler) => {
let guild_data = GuildData::get_from_id(guild, pool.clone()).await.unwrap();
let voice_guilds_lock = ctx.data.read().await
.get::<VoiceGuilds>().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?; 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?; msg.channel_id.say(&ctx, format!("Playing sound {} with ID {}", sound.name, sound.id)).await?;