Add p.rh command
This commit is contained in:
Generated
+1
-1
@@ -2013,7 +2013,7 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
||||
|
||||
[[package]]
|
||||
name = "payphone"
|
||||
version = "4.4.47"
|
||||
version = "4.4.48"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "payphone"
|
||||
version = "4.4.47"
|
||||
version = "4.4.48"
|
||||
edition = "2024"
|
||||
default-run = "payphone"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::time::Duration;
|
||||
|
||||
use scylla::client::session::Session;
|
||||
|
||||
use crate::database::models::{Message, User};
|
||||
use crate::database::models::{Channel, Message, User};
|
||||
use crate::extras::Extras;
|
||||
use crate::framework::commands::arguments::{ArgumentParsingError, FromArguments, NeedyString};
|
||||
use crate::framework::commands::context::CommandContext;
|
||||
@@ -206,3 +206,63 @@ impl DerefMut for DurationArgument {
|
||||
&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 deadpool_redis::redis::AsyncTypedCommands;
|
||||
use time::UtcDateTime;
|
||||
|
||||
use crate::database::models::{UserIncident, UserIncidentType};
|
||||
use crate::database::models::{Call, UserIncident, UserIncidentType};
|
||||
use crate::extras::Extras;
|
||||
use crate::framework::commands::arguments::{
|
||||
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::{Command, CommandError};
|
||||
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::permissions::{BotModeratorPermission, BotOwnerPermission};
|
||||
use crate::state::State;
|
||||
use crate::utils::get_random_u64;
|
||||
use crate::utils::{Bye, get_random_u64};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ModeratorCommand;
|
||||
@@ -246,3 +247,114 @@ impl Command<State, Extras> for BanCommand {
|
||||
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::leveling::commands::LeaderboardCommand;
|
||||
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::events::{
|
||||
ServerCreateHandler, ServerDeleteHandler, ServerUpdateHandler,
|
||||
@@ -298,6 +298,7 @@ async fn start(
|
||||
.command(ModeratorCommand)
|
||||
.command(IncidentsCommand)
|
||||
.command(BanCommand)
|
||||
.command(RemoteHangupCommand)
|
||||
.component(HelpGoBackButton)
|
||||
.cache_resource_type(ResourceType::GUILD)
|
||||
.cache_resource_type(ResourceType::CHANNEL)
|
||||
|
||||
Reference in New Issue
Block a user