Add p.rh command
This commit is contained in:
Generated
+1
-1
@@ -2013,7 +2013,7 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "payphone"
|
name = "payphone"
|
||||||
version = "4.4.47"
|
version = "4.4.48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "payphone"
|
name = "payphone"
|
||||||
version = "4.4.47"
|
version = "4.4.48"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
default-run = "payphone"
|
default-run = "payphone"
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use scylla::client::session::Session;
|
use scylla::client::session::Session;
|
||||||
|
|
||||||
use crate::database::models::{Message, User};
|
use crate::database::models::{Channel, Message, User};
|
||||||
use crate::extras::Extras;
|
use crate::extras::Extras;
|
||||||
use crate::framework::commands::arguments::{ArgumentParsingError, FromArguments, NeedyString};
|
use crate::framework::commands::arguments::{ArgumentParsingError, FromArguments, NeedyString};
|
||||||
use crate::framework::commands::context::CommandContext;
|
use crate::framework::commands::context::CommandContext;
|
||||||
@@ -206,3 +206,63 @@ impl DerefMut for DurationArgument {
|
|||||||
&mut self.0
|
&mut self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ChannelArgument(pub Channel);
|
||||||
|
|
||||||
|
impl FromArguments<State, Extras> for ChannelArgument {
|
||||||
|
async fn from_args<'a>(
|
||||||
|
args: &'a str,
|
||||||
|
ctx: &'a CommandContext<'_, State, Extras>,
|
||||||
|
) -> Result<(Self, &'a str), ArgumentParsingError> {
|
||||||
|
let (identifier, args) = NeedyString::from_args(args, ctx).await?;
|
||||||
|
let identifier = identifier.0.trim();
|
||||||
|
|
||||||
|
if identifier == "." || identifier == "this" || identifier == "here" {
|
||||||
|
let channel = Channel::get_by_id(ctx.event.channel_id.get(), &ctx.rt.state.db).await?;
|
||||||
|
|
||||||
|
if let Some(channel) = channel {
|
||||||
|
return Ok((Self(channel), args));
|
||||||
|
}
|
||||||
|
} else if identifier.starts_with("<#") && identifier.ends_with(">") {
|
||||||
|
// The argument is a Discord mention.
|
||||||
|
|
||||||
|
let channel_id: u64 = identifier[2..identifier.len() - 1]
|
||||||
|
.to_string()
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| ArgumentParsingError::InvalidArgument)?;
|
||||||
|
|
||||||
|
let channel = Channel::get_by_id(channel_id, &ctx.rt.state.db).await?;
|
||||||
|
|
||||||
|
if let Some(channel) = channel {
|
||||||
|
return Ok((Self(channel), args));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let channel_id: u64 = identifier
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| ArgumentParsingError::InvalidArgument)?;
|
||||||
|
|
||||||
|
let channel = Channel::get_by_id(channel_id, &ctx.rt.state.db).await?;
|
||||||
|
|
||||||
|
if let Some(channel) = channel {
|
||||||
|
return Ok((Self(channel), args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(ArgumentParsingError::MissingArgument)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for ChannelArgument {
|
||||||
|
type Target = Channel;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for ChannelArgument {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use deadpool_redis::redis::AsyncTypedCommands;
|
||||||
use time::UtcDateTime;
|
use time::UtcDateTime;
|
||||||
|
|
||||||
use crate::database::models::{UserIncident, UserIncidentType};
|
use crate::database::models::{Call, UserIncident, UserIncidentType};
|
||||||
use crate::extras::Extras;
|
use crate::extras::Extras;
|
||||||
use crate::framework::commands::arguments::{
|
use crate::framework::commands::arguments::{
|
||||||
Arg, Argument, ArgumentParsingError, NeedyGreedyString, ParseArguments,
|
Arg, Argument, ArgumentParsingError, NeedyGreedyString, ParseArguments,
|
||||||
@@ -10,11 +11,11 @@ use crate::framework::commands::context::CommandContext;
|
|||||||
use crate::framework::commands::permissions::Permission;
|
use crate::framework::commands::permissions::Permission;
|
||||||
use crate::framework::commands::{Command, CommandError};
|
use crate::framework::commands::{Command, CommandError};
|
||||||
use crate::framework::runtime::Runtime;
|
use crate::framework::runtime::Runtime;
|
||||||
use crate::groups::moderation::arguments::{DurationArgument, UserArgument};
|
use crate::groups::moderation::arguments::{ChannelArgument, DurationArgument, UserArgument};
|
||||||
use crate::groups::moderation::get_incident_page;
|
use crate::groups::moderation::get_incident_page;
|
||||||
use crate::groups::moderation::permissions::{BotModeratorPermission, BotOwnerPermission};
|
use crate::groups::moderation::permissions::{BotModeratorPermission, BotOwnerPermission};
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use crate::utils::get_random_u64;
|
use crate::utils::{Bye, get_random_u64};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ModeratorCommand;
|
pub struct ModeratorCommand;
|
||||||
@@ -246,3 +247,114 @@ impl Command<State, Extras> for BanCommand {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RemoteHangupCommand;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Command<State, Extras> for RemoteHangupCommand {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"remotehangup"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn aliases(&self) -> &'static [&'static str] {
|
||||||
|
&["rh"]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn permissions(&self) -> Vec<Box<dyn Permission<State, Extras> + Send + Sync + 'static>> {
|
||||||
|
vec![Box::new(BotModeratorPermission)]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_in_help(&self, _rt: &Runtime<State, Extras>, extras: &Extras) -> bool {
|
||||||
|
extras.user.is_moderator
|
||||||
|
}
|
||||||
|
|
||||||
|
fn arguments(&self) -> &'static [Argument] {
|
||||||
|
&[Argument {
|
||||||
|
name: "channel",
|
||||||
|
is_optional: false,
|
||||||
|
is_greedy: false,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn execute(
|
||||||
|
&self,
|
||||||
|
ctx: CommandContext<'_, State, Extras>,
|
||||||
|
args: &str,
|
||||||
|
) -> Result<(), CommandError> {
|
||||||
|
let Arg(mut channel) = match Arg::<ChannelArgument>::parse(args, &ctx).await {
|
||||||
|
Ok(arg) => arg,
|
||||||
|
Err(e) => match e {
|
||||||
|
ArgumentParsingError::InvalidArgument => {
|
||||||
|
ctx.send().content("❌ Channel not found in DB.").await?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
ArgumentParsingError::DatabaseFailed(e) => {
|
||||||
|
return Err(CommandError::DatabaseFailed(e));
|
||||||
|
}
|
||||||
|
e => {
|
||||||
|
unreachable!("Unexpected error: {e}");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if channel.is_searching {
|
||||||
|
channel
|
||||||
|
.cancel_search(&ctx.rt.state.db)
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| {
|
||||||
|
log::error!("Failed to cancel search: {e:?}");
|
||||||
|
})?;
|
||||||
|
|
||||||
|
ctx.send()
|
||||||
|
.content("The channel was remotely made to stop searching for a call!")
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(call_id) = channel.call_id {
|
||||||
|
let mut redis = ctx.rt.state.redis.get().await?;
|
||||||
|
|
||||||
|
let Some(call) = Call::get_by_id(call_id, &ctx.rt.state.db)
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| log::error!("Failed to get call: {e:?}"))?
|
||||||
|
else {
|
||||||
|
ctx.send().content("❌ The call could not be found.\n-# This is not supposed to happen. The channel is pointing to an ID in the database that does not exist.").await?;
|
||||||
|
|
||||||
|
channel.call_id = None;
|
||||||
|
channel.upsert(&ctx.rt.state.db).await.bye();
|
||||||
|
|
||||||
|
redis
|
||||||
|
.zrem("active-calls", format!("{}:{}", call_id, channel.id))
|
||||||
|
.await
|
||||||
|
.bye();
|
||||||
|
|
||||||
|
return Err(CommandError::DatabaseInconsistentState);
|
||||||
|
};
|
||||||
|
|
||||||
|
let channel_keys = [
|
||||||
|
format!("{call_id}:{}", call.channel_ids[0]),
|
||||||
|
format!("{call_id}:{}", call.channel_ids[1]),
|
||||||
|
];
|
||||||
|
|
||||||
|
redis
|
||||||
|
.zrem("active-calls", &channel_keys)
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| log::error!("Failed to remove inactive call from redis: {e}"))
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
call.hangup(&ctx.rt.state.db)
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| log::error!("Failed to hang up call: {e:?}"))?;
|
||||||
|
} else {
|
||||||
|
ctx.send()
|
||||||
|
.content("❌ This channel is not in a call.")
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+2
-1
@@ -137,7 +137,7 @@ use crate::groups::calls::events::{
|
|||||||
use crate::groups::gateway::events::{ReadyHandler, ReconnectHandler};
|
use crate::groups::gateway::events::{ReadyHandler, ReconnectHandler};
|
||||||
use crate::groups::leveling::commands::LeaderboardCommand;
|
use crate::groups::leveling::commands::LeaderboardCommand;
|
||||||
use crate::groups::leveling::events::MessageLevelingHandler;
|
use crate::groups::leveling::events::MessageLevelingHandler;
|
||||||
use crate::groups::moderation::commands::{BanCommand, IncidentsCommand, ModeratorCommand};
|
use crate::groups::moderation::commands::{BanCommand, IncidentsCommand, ModeratorCommand, RemoteHangupCommand};
|
||||||
use crate::groups::servers::commands::PrefixCommand;
|
use crate::groups::servers::commands::PrefixCommand;
|
||||||
use crate::groups::servers::events::{
|
use crate::groups::servers::events::{
|
||||||
ServerCreateHandler, ServerDeleteHandler, ServerUpdateHandler,
|
ServerCreateHandler, ServerDeleteHandler, ServerUpdateHandler,
|
||||||
@@ -298,6 +298,7 @@ async fn start(
|
|||||||
.command(ModeratorCommand)
|
.command(ModeratorCommand)
|
||||||
.command(IncidentsCommand)
|
.command(IncidentsCommand)
|
||||||
.command(BanCommand)
|
.command(BanCommand)
|
||||||
|
.command(RemoteHangupCommand)
|
||||||
.component(HelpGoBackButton)
|
.component(HelpGoBackButton)
|
||||||
.cache_resource_type(ResourceType::GUILD)
|
.cache_resource_type(ResourceType::GUILD)
|
||||||
.cache_resource_type(ResourceType::CHANNEL)
|
.cache_resource_type(ResourceType::CHANNEL)
|
||||||
|
|||||||
Reference in New Issue
Block a user