diff options
Diffstat (limited to 'src/bot.rs')
| -rw-r--r-- | src/bot.rs | 61 |
1 files changed, 58 insertions, 3 deletions
@@ -72,7 +72,7 @@ impl TypeMapKey for VolumeKey { pub struct PlaybackKey; impl TypeMapKey for PlaybackKey { - type Value = Arc<DashMap<uuid::Uuid, songbird::input::AuxMetadata>>; + type Value = Arc<DashMap<uuid::Uuid, commands::playback::Metadata>>; } #[cfg(debug_assertions)] @@ -97,18 +97,73 @@ async fn ready_guild(ctx: &Context, guild_id: GuildId) { call.add_global_event(Event::Track(TrackEvent::End), SongbirdHandler(c.clone())); } +async fn perm_check(ctx: &Context, guild: &Guild) -> anyhow::Result<()> { + // "Requested permissions" through the discord OAuth flow don't actually apply in a way that's + // reflected in the guild member permission object. There is a dedicated role type created to + // protect bot perms when you do this, which I'd like to read and verify, but I suspect it's + // behind BotIntegration, which you need `GUILD_MANAGE` to even read. I don't want to give this + // permission only for this reason. + + let me = ctx.cache.current_user().id; + + let member = guild.member(&ctx, me).await?; + let perms = member.permissions(&ctx)?; + + let lacking_perms = util::REQUIRED_PERMS.difference(perms); + + if !lacking_perms.is_empty() { + tracing::error!( + guild_id = %guild.id, + guild_name = %guild.name, + %lacking_perms, + "insufficient permissions for guild" + ); + } + + let lacking_desired_perms = + util::DESIRED_PERMS.difference(*util::REQUIRED_PERMS).difference(perms); + + if !lacking_desired_perms.is_empty() { + tracing::warn!( + guild_id = %guild.id, + guild_name = %guild.name, + %lacking_desired_perms, + "bot is lacking requested permissions" + ); + } + + let excess_perms = perms.difference(*util::DESIRED_PERMS); + + if !excess_perms.is_empty() { + tracing::debug!( + guild_id = %guild.id, + guild_name = %guild.name, + %excess_perms, + "bot has permissions in excess of requirements" + ); + } + + Ok(()) +} + #[serenity::async_trait] impl EventHandler for Handler { - async fn ready(&self, _ctx: Context, r: Ready) { + async fn ready(&self, ctx: Context, r: Ready) { tracing::info!( - join_url = OAUTH_URL.as_str(), + join_url = %OAUTH_URL.as_str(), visible_guilds = r.guilds.len(), + my_user_id = %ctx.cache.current_user().id, "connected to discord" ); } async fn guild_create(&self, ctx: Context, guild: Guild, _is_new: Option<bool>) { tracing::info!(disc_event = "guild_create", guild_id = %guild.id, guild_name = %guild.name); + + if let Err(e) = perm_check(&ctx, &guild).await { + tracing::error!(error = %e, "checking permissions"); + } + ready_guild(&ctx, guild.id).await; } |
