Add support for extras, conditionally displaying commands in the help command, and start working on moderation commands
This commit is contained in:
@@ -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!(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::{framework::interactions::components::Button, state::State};
|
||||
use crate::{extras::Extras, framework::interactions::components::Button, state::State};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CodeOfConductButton;
|
||||
|
||||
impl Button<State> for CodeOfConductButton {
|
||||
impl Button<State, Extras> for CodeOfConductButton {
|
||||
fn label(&self) -> Option<&'static str> {
|
||||
Some("Code of Conduct")
|
||||
}
|
||||
@@ -16,7 +16,7 @@ impl Button<State> for CodeOfConductButton {
|
||||
#[derive(Debug)]
|
||||
pub struct NeedHelpButton;
|
||||
|
||||
impl Button<State> for NeedHelpButton {
|
||||
impl Button<State, Extras> for NeedHelpButton {
|
||||
fn label(&self) -> Option<&'static str> {
|
||||
Some("Need Help?")
|
||||
}
|
||||
|
||||
+26
-17
@@ -11,21 +11,18 @@ use twilight_util::builder::embed::{EmbedAuthorBuilder, EmbedBuilder, ImageSourc
|
||||
|
||||
use crate::{
|
||||
constants::COLOR_WHITE,
|
||||
database::models::{
|
||||
Call, Channel, Message, User, UserIncident, get_or_create_user_and_set_last_seen,
|
||||
},
|
||||
database::models::{Call, Channel, Message, User, UserIncident},
|
||||
discord::sanitizing::SanitizeDiscordMarkdown,
|
||||
extras::Extras,
|
||||
framework::{
|
||||
events::traits::{
|
||||
commands::extras::ExtrasGetter, events::traits::{
|
||||
EventResult, OnMessageDeleteHandler, OnMessageEditHandler, OnMessageHandler,
|
||||
},
|
||||
interactions::components::ActionRow,
|
||||
runtime::Runtime,
|
||||
}, interactions::components::ActionRow, runtime::Runtime
|
||||
},
|
||||
groups::calls::{
|
||||
components::{CodeOfConductButton, NeedHelpButton},
|
||||
embeds, get_display_profile,
|
||||
moderation::{Action, Rule, escape_message},
|
||||
moderation::{escape_message, Action, Rule},
|
||||
},
|
||||
state::State,
|
||||
utils::{ellipse, i64_to_u64},
|
||||
@@ -35,7 +32,7 @@ async fn penalize_user(
|
||||
user: User,
|
||||
message: Message,
|
||||
broken_rules: Vec<Arc<dyn Rule>>,
|
||||
rt: &Runtime<State>,
|
||||
rt: &Runtime<State, Extras>,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let reason = format!(
|
||||
"You broke the following rules during a call:\n{}",
|
||||
@@ -88,8 +85,13 @@ async fn penalize_user(
|
||||
pub struct CallMessageHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl OnMessageHandler<State> for CallMessageHandler {
|
||||
async fn on_message(&self, event: &MessageCreate, rt: Arc<Runtime<State>>) -> EventResult {
|
||||
impl OnMessageHandler<State, Extras> for CallMessageHandler {
|
||||
async fn on_message(
|
||||
&self,
|
||||
event: &MessageCreate,
|
||||
rt: Arc<Runtime<State, Extras>>,
|
||||
extras: Arc<dyn ExtrasGetter<State, Extras = Extras>>,
|
||||
) -> EventResult {
|
||||
if event.author.bot || event.author.system.unwrap_or(false) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -144,7 +146,8 @@ impl OnMessageHandler<State> for CallMessageHandler {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let user = get_or_create_user_and_set_last_seen(event.author.clone(), &rt.state.db).await?;
|
||||
let user =
|
||||
User::get_or_create_and_set_last_seen(event.author.clone(), &rt.state.db).await?;
|
||||
|
||||
let user_incidents = UserIncident::get_for_user(event.author.id.get(), &rt.state.db)
|
||||
.await?
|
||||
@@ -314,8 +317,12 @@ impl OnMessageHandler<State> for CallMessageHandler {
|
||||
pub struct CallMessageEditHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl OnMessageEditHandler<State> for CallMessageEditHandler {
|
||||
async fn on_message_edit(&self, event: &MessageUpdate, rt: Arc<Runtime<State>>) -> EventResult {
|
||||
impl OnMessageEditHandler<State, Extras> for CallMessageEditHandler {
|
||||
async fn on_message_edit(
|
||||
&self,
|
||||
event: &MessageUpdate,
|
||||
rt: Arc<Runtime<State, Extras>>,
|
||||
) -> EventResult {
|
||||
log::trace!(
|
||||
"Edited message was '{}' sent by {} (bot? {:?})",
|
||||
event.content,
|
||||
@@ -368,7 +375,9 @@ impl OnMessageEditHandler<State> for CallMessageEditHandler {
|
||||
.reply(event.id)
|
||||
.await?;
|
||||
|
||||
let user = get_or_create_user_and_set_last_seen(event.author.clone(), &rt.state.db).await?;
|
||||
let user =
|
||||
User::get_or_create_and_set_last_seen(event.author.clone(), &rt.state.db)
|
||||
.await?;
|
||||
|
||||
penalize_user(user, message, rules, &rt).await?;
|
||||
|
||||
@@ -404,11 +413,11 @@ impl OnMessageEditHandler<State> for CallMessageEditHandler {
|
||||
pub struct CallMessageDeleteHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl OnMessageDeleteHandler<State> for CallMessageDeleteHandler {
|
||||
impl OnMessageDeleteHandler<State, Extras> for CallMessageDeleteHandler {
|
||||
async fn on_message_delete(
|
||||
&self,
|
||||
event: &MessageDelete,
|
||||
rt: Arc<Runtime<State>>,
|
||||
rt: Arc<Runtime<State, Extras>>,
|
||||
) -> EventResult {
|
||||
let Some(channel) = Channel::get_by_id(event.channel_id.get(), &rt.state.db).await? else {
|
||||
return Ok(());
|
||||
|
||||
@@ -80,6 +80,8 @@ gooncream
|
||||
gooncreaming
|
||||
goonbud
|
||||
goonbuds
|
||||
goonete
|
||||
goonetes
|
||||
boty hole
|
||||
suck my pp
|
||||
ass cracker
|
||||
@@ -98,7 +100,7 @@ masterbaiting
|
||||
masturbatigng
|
||||
horny
|
||||
hrny
|
||||
whore
|
||||
whore / who re
|
||||
whre
|
||||
tickle your pickle
|
||||
tickle yr pickle
|
||||
|
||||
@@ -2,6 +2,7 @@ use async_trait::async_trait;
|
||||
|
||||
use crate::{
|
||||
database::models::UserIncident,
|
||||
extras::Extras,
|
||||
framework::commands::{CommandError, context::CommandContext, permissions::Permission},
|
||||
groups::calls::components::{CodeOfConductButton, NeedHelpButton},
|
||||
state::State,
|
||||
@@ -11,12 +12,12 @@ use crate::{
|
||||
pub struct NotBannedPermission;
|
||||
|
||||
#[async_trait]
|
||||
impl Permission<State> for NotBannedPermission {
|
||||
async fn check(&self, ctx: &CommandContext<State>) -> Result<bool, CommandError> {
|
||||
impl Permission<State, Extras> for NotBannedPermission {
|
||||
async fn check(&self, ctx: &CommandContext<State, Extras>) -> Result<bool, CommandError> {
|
||||
let incidents = UserIncident::get_for_user(ctx.event.author.id.get(), &ctx.rt.state.db)
|
||||
.await
|
||||
.inspect_err(|e| log::error!("Failed to get user incidents: {e}"))
|
||||
.map_err(|_| CommandError::DatabaseQueryFailed)?;
|
||||
.map_err(|_| CommandError::DatabaseFailed)?;
|
||||
|
||||
if incidents.iter().any(|i| i.is_active()) {
|
||||
Ok(false)
|
||||
@@ -25,7 +26,10 @@ impl Permission<State> for NotBannedPermission {
|
||||
}
|
||||
}
|
||||
|
||||
async fn on_handle_denied(&self, ctx: &CommandContext<State>) -> Result<(), CommandError> {
|
||||
async fn on_handle_denied(
|
||||
&self,
|
||||
ctx: &CommandContext<State, Extras>,
|
||||
) -> Result<(), CommandError> {
|
||||
ctx.send()
|
||||
.content("❌ You've been banned from Payphone.")
|
||||
.component(CodeOfConductButton, 1)
|
||||
|
||||
Reference in New Issue
Block a user