Skip to content

Commit

Permalink
Add debug command
Browse files Browse the repository at this point in the history
  • Loading branch information
tazz4843 committed Nov 24, 2024
1 parent b02484c commit c0b8978
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 3 deletions.
12 changes: 9 additions & 3 deletions scripty_audio_handler/src/audio_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl AudioHandler {
kiai_client: KiaiApiClient,
ephemeral: bool,
) -> Result<Self, Error> {

Check warning on line 90 in scripty_audio_handler/src/audio_handler.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

this function has too many arguments (10/7)

warning: this function has too many arguments (10/7) --> scripty_audio_handler/src/audio_handler.rs:79:2 | 79 | / pub async fn new( 80 | | guild_id: GuildId, 81 | | webhook: Webhook, 82 | | context: Context, ... | 89 | | ephemeral: bool, 90 | | ) -> Result<Self, Error> { | |____________________________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments = note: `#[warn(clippy::too_many_arguments)]` on by default
let maps = SsrcMaps {
let ssrc_state = Arc::new(SsrcMaps {
ssrc_user_id_map: DashMap::with_capacity_and_hasher(10, RandomState::new()),
ssrc_stream_map: DashMap::with_capacity_and_hasher(10, RandomState::new()),
ssrc_user_data_map: DashMap::with_capacity_and_hasher(10, RandomState::new()),
Expand All @@ -97,7 +97,10 @@ impl AudioHandler {
ssrc_speaking_set: DashSet::with_capacity_and_hasher(10, RandomState::new()),
active_user_set: DashSet::with_capacity_and_hasher(10, RandomState::new()),
next_user_list: RwLock::new(VecDeque::with_capacity(10)),
};
});
crate::INTERNAL_SSRC_MAPS
.get_or_init(|| DashMap::with_hasher(RandomState::new()))
.insert(guild_id, ssrc_state.clone());
let alive_call = CallDeath::new(
get_data(&context).existing_calls.clone(),
guild_id,
Expand All @@ -106,7 +109,7 @@ impl AudioHandler {
.ok_or_else(Error::already_exists)?;

let this = Self {
ssrc_state: Arc::new(maps),
ssrc_state,
guild_id,
channel_id,
voice_channel_id,
Expand Down Expand Up @@ -179,6 +182,9 @@ impl AudioHandler {
crate::VOICE_HANDLER_UPDATES
.get_or_init(|| DashMap::with_hasher(RandomState::new()))
.remove(&guild_id);
crate::INTERNAL_SSRC_MAPS
.get_or_init(|| DashMap::with_hasher(RandomState::new()))
.remove(&guild_id);

break;
}
Expand Down
43 changes: 43 additions & 0 deletions scripty_audio_handler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ use songbird::{driver::DecodeMode, Config};
pub use songbird::{error::JoinError, Songbird};
use tokio::sync::{broadcast, oneshot::Sender};

use crate::audio_handler::SsrcMaps;

pub fn get_songbird_config() -> Config {
Config::default().decode_mode(DecodeMode::Decode)
}
Expand Down Expand Up @@ -52,6 +54,8 @@ static AUTO_LEAVE_TASKS: OnceCell<DashMap<GuildId, Sender<()>, ahash::RandomStat
static VOICE_HANDLER_UPDATES: OnceCell<
DashMap<GuildId, broadcast::Sender<()>, ahash::RandomState>,
> = OnceCell::new();
static INTERNAL_SSRC_MAPS: OnceCell<DashMap<GuildId, Arc<SsrcMaps>, ahash::RandomState>> =
OnceCell::new();

/// Asynchronously force a handler update. If the bot has left the VC, this will run cleanup
/// tasks.
Expand All @@ -68,3 +72,42 @@ pub fn force_handler_update(guild_id: &GuildId) {
None => debug!(%guild_id, "not actively in call for this server"),
}
}

#[derive(Debug)]
pub struct InternalSsrcStateDetails {
/// All seen SSRCs
seen_users: Vec<u32>,

Check warning on line 79 in scripty_audio_handler/src/lib.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

multiple fields are never read

warning: multiple fields are never read --> scripty_audio_handler/src/lib.rs:79:2 | 77 | pub struct InternalSsrcStateDetails { | ------------------------ fields in this struct 78 | /// All seen SSRCs 79 | seen_users: Vec<u32>, | ^^^^^^^^^^ 80 | /// List of SSRCs who have an active stream pending 81 | ssrcs_with_stream: Vec<u32>, | ^^^^^^^^^^^^^^^^^ 82 | /// All SSRCs that have a user details tuple attached 83 | ssrcs_with_attached_data: Vec<u32>, | ^^^^^^^^^^^^^^^^^^^^^^^^ 84 | /// List of SSRCs that are currently being ignored by the bot 85 | ignored_ssrcs: Vec<u32>, | ^^^^^^^^^^^^^ 86 | /// All actively speaking SSRCs 87 | ssrcs_actively_speaking_this_tick: Vec<u32>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 88 | /// All SSRCs currently being transcribed 89 | actively_transcribed_ssrcs: Vec<u32>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 90 | /// Next SSRCs to be pushed to actively_transcribed_ssrcs when it drops below the required threshold 91 | next_ssrcs: Vec<u32>, | ^^^^^^^^^^ | = note: `InternalSsrcStateDetails` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis = note: `#[warn(dead_code)]` on by default
/// List of SSRCs who have an active stream pending
ssrcs_with_stream: Vec<u32>,
/// All SSRCs that have a user details tuple attached
ssrcs_with_attached_data: Vec<u32>,
/// List of SSRCs that are currently being ignored by the bot
ignored_ssrcs: Vec<u32>,
/// All actively speaking SSRCs
ssrcs_actively_speaking_this_tick: Vec<u32>,
/// All SSRCs currently being transcribed
actively_transcribed_ssrcs: Vec<u32>,
/// Next SSRCs to be pushed to actively_transcribed_ssrcs when it drops below the required threshold
next_ssrcs: Vec<u32>,
}

/// Get details about internal state of Scripty
pub fn get_internal_state(guild_id: &GuildId) -> Option<InternalSsrcStateDetails> {
let maps = INTERNAL_SSRC_MAPS.get_or_init(|| DashMap::with_hasher(ahash::RandomState::new()));

let internal_maps = maps.get(guild_id)?;
let v = internal_maps.value();

// go ahead and try getting rid of this binding i dare you :)
let ret = Some(InternalSsrcStateDetails {
seen_users: v.ssrc_user_id_map.iter().map(|x| *x.key()).collect(),
ssrcs_with_stream: v.ssrc_stream_map.iter().map(|x| *x.key()).collect(),
ssrcs_with_attached_data: v.ssrc_user_data_map.iter().map(|x| *x.key()).collect(),
ignored_ssrcs: v.ssrc_ignored_map.iter().map(|x| *x.key()).collect(),
ssrcs_actively_speaking_this_tick: v.ssrc_speaking_set.iter().map(|x| *x).collect(),
actively_transcribed_ssrcs: v.active_user_set.iter().map(|x| *x).collect(),
next_ssrcs: v.next_user_list.read().iter().map(|x| *x).collect(),

Check warning on line 109 in scripty_audio_handler/src/lib.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

you are using an explicit closure for copying elements

warning: you are using an explicit closure for copying elements --> scripty_audio_handler/src/lib.rs:109:15 | 109 | next_ssrcs: v.next_user_list.read().iter().map(|x| *x).collect(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `v.next_user_list.read().iter().copied()` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#map_clone = note: `#[warn(clippy::map_clone)]` on by default
});

ret
}
31 changes: 31 additions & 0 deletions scripty_commands/src/cmds/debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use poise::CreateReply;
use serenity::builder::CreateAttachment;

use crate::{Context, Error};

/// Output some data useful for debugging Scripty
#[poise::command(prefix_command, slash_command, guild_only)]
pub async fn debug(ctx: Context<'_>) -> Result<(), Error> {
let guild_id = ctx.guild_id().ok_or_else(Error::expected_guild)?;
let resolved_language =
scripty_i18n::get_resolved_language(ctx.author().id.get(), Some(guild_id.get())).await;
let state = scripty_audio_handler::get_internal_state(&guild_id);
if let Some(state) = state {
ctx.send(
CreateReply::new()
.content(format_message!(resolved_language, "debug-info-message"))
.attachment(CreateAttachment::bytes(
format!("{:?}", state),
Cow::Borrowed("debug_info.txt"),
)),
)
.await?;
} else {
ctx.send(
CreateReply::new().content(format_message!(resolved_language, "debug-not-in-call")),
)
.await?;
}

Ok(())
}
2 changes: 2 additions & 0 deletions scripty_commands/src/cmds/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod admin;
pub mod automod;
pub mod config;
mod data_storage;
mod debug;
pub mod dm_support;
mod entity_block;
mod help;
Expand All @@ -17,6 +18,7 @@ mod vote_reminders;

pub use admin::*;
pub use data_storage::*;
pub use debug::debug;
pub use dm_support::*;
pub use entity_block::*;
pub use help::help;
Expand Down
1 change: 1 addition & 0 deletions scripty_commands/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub fn build_commands() -> Vec<poise::Command<Data, Error>> {
cmds::user_language(),
cmds::vote_reminder(),
cmds::transcribe_message(),
cmds::debug(),
poise::Command {
subcommands: vec![cmds::block_user(), cmds::block_guild()],
..cmds::block()
Expand Down
6 changes: 6 additions & 0 deletions scripty_i18n/locales/en.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@ config-kiai-info = You can find more info about Kiai at [kiai.app](https://www.k
If you use this integration, be sure to disable Kiai's voice XP module as they will conflict.
config-kiai-missing-perms = Scripty is missing permissions to work in this server. Authorize it with the `/application authorize` command, using an application ID of `811652199100317726`, and giving Scripty the "view and edit all levels and XP" permission.
## debug command
cmds_debug = debug
.description = Output debugging information about Scripty internal state.
debug-info-message = Forward this message to whoever in the Scripty support server is asking you for it.
debug-not-in-call = This command is useless if Scripty isn't in a VC.
## Help menu translation strings

command-not-found = No command with name `{ $commandName }` found.
Expand Down

0 comments on commit c0b8978

Please sign in to comment.