Add support for extras, conditionally displaying commands in the help command, and start working on moderation commands

This commit is contained in:
2025-08-22 18:06:52 -03:00
parent 55ae1c8937
commit 8868b18be3
41 changed files with 1075 additions and 368 deletions
+25 -24
View File
@@ -5,6 +5,7 @@ use twilight_model::id::Id;
use crate::{
database::models::{Call, Channel},
discord::sanitizing::SanitizeDiscordMarkdown,
extras::Extras,
framework::commands::{
Command, CommandError, context::CommandContext, permissions::Permission,
},
@@ -39,7 +40,7 @@ impl CallCommand {
}
#[async_trait]
impl Command<State> for CallCommand {
impl Command<State, Extras> for CallCommand {
fn name(&self) -> &'static str {
"call"
}
@@ -48,13 +49,13 @@ impl Command<State> for CallCommand {
&["c"]
}
fn permissions(&self) -> Vec<Box<dyn Permission<State> + Send + Sync + 'static>> {
fn permissions(&self) -> Vec<Box<dyn Permission<State, Extras> + Send + Sync + 'static>> {
vec![Box::new(NotBannedPermission)]
}
async fn execute(
&self,
ctx: CommandContext<'_, State>,
ctx: CommandContext<'_, State, Extras>,
_args: &str,
) -> Result<(), CommandError> {
let channel = Channel::get_or_create_by_id(
@@ -66,7 +67,7 @@ impl Command<State> for CallCommand {
.inspect_err(|e| {
log::error!("Failed to get or create channel: {e:?}");
})
.map_err(|_| CommandError::DatabaseQueryFailed)?;
.map_err(|_| CommandError::DatabaseFailed)?;
if channel.is_searching || self.channel_lock.contains(&ctx.event.channel_id.get()) {
ctx.send()
@@ -100,7 +101,7 @@ impl Command<State> for CallCommand {
log::error!("Failed to start call: {e:?}");
self.channel_lock.remove(&ctx.event.channel_id.get());
})
.map_err(|_| CommandError::DatabaseQueryFailed)?;
.map_err(|_| CommandError::DatabaseFailed)?;
self.channel_lock
.remove_async(&ctx.event.channel_id.get())
@@ -141,7 +142,7 @@ impl Command<State> for CallCommand {
pub struct SkipCommand;
#[async_trait]
impl Command<State> for SkipCommand {
impl Command<State, Extras> for SkipCommand {
fn name(&self) -> &'static str {
"skip"
}
@@ -150,13 +151,13 @@ impl Command<State> for SkipCommand {
&["s", "next"]
}
fn permissions(&self) -> Vec<Box<dyn Permission<State> + Send + Sync + 'static>> {
fn permissions(&self) -> Vec<Box<dyn Permission<State, Extras> + Send + Sync + 'static>> {
vec![Box::new(NotBannedPermission)]
}
async fn execute(
&self,
ctx: CommandContext<'_, State>,
ctx: CommandContext<'_, State, Extras>,
_args: &str,
) -> Result<(), CommandError> {
let channel = Channel::get_or_create_by_id(
@@ -168,7 +169,7 @@ impl Command<State> for SkipCommand {
.inspect_err(|e| {
log::error!("Failed to get or create channel: {e:?}");
})
.map_err(|_| CommandError::DatabaseQueryFailed)?;
.map_err(|_| CommandError::DatabaseFailed)?;
if channel.call_id.is_none() {
ctx.send()
@@ -197,13 +198,13 @@ impl Command<State> for SkipCommand {
let call = Call::get_by_id(channel.call_id.unwrap(), &ctx.rt.state.db)
.await
.inspect_err(|e| log::error!("Failed to get call: {e:?}"))
.map_err(|_| CommandError::DatabaseQueryFailed)?
.map_err(|_| CommandError::DatabaseFailed)?
.ok_or(CommandError::DatabaseInconsistentState)?;
call.hangup(&ctx.rt.state.db)
.await
.inspect_err(|e| log::error!("Failed to hang up call: {e:?}"))
.map_err(|_| CommandError::DatabaseQueryFailed)?;
.map_err(|_| CommandError::DatabaseFailed)?;
let other_channel_id = call.other_party_channel_id(ctx.event.channel_id.get());
@@ -225,7 +226,7 @@ impl Command<State> for SkipCommand {
.inspect_err(|e| {
log::error!("Failed to start (skipped) call: {e:?}");
})
.map_err(|_| CommandError::DatabaseQueryFailed)?;
.map_err(|_| CommandError::DatabaseFailed)?;
if let Some(call) = call {
ctx.send()
@@ -259,7 +260,7 @@ impl Command<State> for SkipCommand {
pub struct HangupCommand;
#[async_trait]
impl Command<State> for HangupCommand {
impl Command<State, Extras> for HangupCommand {
fn name(&self) -> &'static str {
"hangup"
}
@@ -268,19 +269,19 @@ impl Command<State> for HangupCommand {
&["h", "hang"]
}
fn permissions(&self) -> Vec<Box<dyn Permission<State> + Send + Sync + 'static>> {
fn permissions(&self) -> Vec<Box<dyn Permission<State, Extras> + Send + Sync + 'static>> {
vec![Box::new(NotBannedPermission)]
}
async fn execute(
&self,
ctx: CommandContext<'_, State>,
ctx: CommandContext<'_, State, Extras>,
_args: &str,
) -> Result<(), CommandError> {
let Some(channel) = Channel::get_by_id(ctx.event.channel_id.get(), &ctx.rt.state.db)
.await
.inspect_err(|e| log::error!("Failed to get channel: {e:?}"))
.map_err(|_| CommandError::DatabaseQueryFailed)?
.map_err(|_| CommandError::DatabaseFailed)?
else {
ctx.send()
.content(format!(
@@ -300,7 +301,7 @@ impl Command<State> for HangupCommand {
.inspect_err(|e| {
log::error!("Failed to cancel search: {e:?}");
})
.map_err(|_| CommandError::DatabaseQueryFailed)?;
.map_err(|_| CommandError::DatabaseFailed)?;
ctx.send()
.content(format!("☎️ {}", get_string_call_no_answer(ctx.prefix)))
@@ -314,7 +315,7 @@ impl Command<State> for HangupCommand {
let Some(call) = Call::get_by_id(call_id, &ctx.rt.state.db)
.await
.inspect_err(|e| log::error!("Failed to get call: {e:?}"))
.map_err(|_| CommandError::DatabaseQueryFailed)?
.map_err(|_| CommandError::DatabaseFailed)?
else {
ctx.send()
.content("❌ Call not found.")
@@ -327,7 +328,7 @@ impl Command<State> for HangupCommand {
call.hangup(&ctx.rt.state.db)
.await
.inspect_err(|e| log::error!("Failed to hang up call: {e:?}"))
.map_err(|_| CommandError::DatabaseQueryFailed)?;
.map_err(|_| CommandError::DatabaseFailed)?;
ctx.send()
.content(format!(
@@ -366,7 +367,7 @@ impl Command<State> for HangupCommand {
pub struct FriendRequestCommand;
#[async_trait]
impl Command<State> for FriendRequestCommand {
impl Command<State, Extras> for FriendRequestCommand {
fn name(&self) -> &'static str {
"friendreq"
}
@@ -379,19 +380,19 @@ impl Command<State> for FriendRequestCommand {
"Shows your username to the other party and asks them to send you a friend request on Discord."
}
fn permissions(&self) -> Vec<Box<dyn Permission<State> + Send + Sync + 'static>> {
fn permissions(&self) -> Vec<Box<dyn Permission<State, Extras> + Send + Sync + 'static>> {
vec![Box::new(NotBannedPermission)]
}
async fn execute(
&self,
ctx: CommandContext<'_, State>,
ctx: CommandContext<'_, State, Extras>,
_args: &str,
) -> Result<(), CommandError> {
let channel = Channel::get_by_id(ctx.event.channel_id.get(), &ctx.rt.state.db)
.await
.inspect_err(|e| log::error!("Failed to get channel: {e:?}"))
.map_err(|_| CommandError::DatabaseQueryFailed)?;
.map_err(|_| CommandError::DatabaseFailed)?;
let Some(channel) = channel else {
ctx.send()
@@ -409,7 +410,7 @@ impl Command<State> for FriendRequestCommand {
Call::get_by_id(call_id, &ctx.rt.state.db)
.await
.inspect_err(|e| log::error!("Failed to get call: {e:?}"))
.map_err(|_| CommandError::DatabaseQueryFailed)?
.map_err(|_| CommandError::DatabaseFailed)?
} else {
ctx.send()
.content(format!(