Checkpoint
This commit is contained in:
Generated
+1
-1
@@ -2013,7 +2013,7 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "payphone"
|
name = "payphone"
|
||||||
version = "4.4.35"
|
version = "4.4.41"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "payphone"
|
name = "payphone"
|
||||||
version = "4.4.35"
|
version = "4.4.41"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
default-run = "payphone"
|
default-run = "payphone"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
group_imports = "StdExternalCrate"
|
||||||
|
imports_granularity = "Module"
|
||||||
+3
-1
@@ -64,7 +64,9 @@
|
|||||||
//! starting the server. You can also use the `--bind` argument to specify the address to bind the
|
//! starting the server. You can also use the `--bind` argument to specify the address to bind the
|
||||||
//! server to, which defaults to `0.0.0.0:3000`.
|
//! server to, which defaults to `0.0.0.0:3000`.
|
||||||
|
|
||||||
use std::{fmt, net::SocketAddr, str::FromStr};
|
use std::fmt;
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use twilight_gateway::ShardId;
|
use twilight_gateway::ShardId;
|
||||||
|
|
||||||
|
|||||||
+8
-6
@@ -1,15 +1,17 @@
|
|||||||
use std::{io::Cursor, sync::Arc};
|
use std::io::Cursor;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use color_thief::ColorFormat;
|
use color_thief::ColorFormat;
|
||||||
use image::{GenericImageView, ImageReader};
|
use image::{GenericImageView, ImageReader};
|
||||||
use reqwest::header::USER_AGENT;
|
use reqwest::header::USER_AGENT;
|
||||||
use rgb::Rgb;
|
use rgb::Rgb;
|
||||||
use tokio::sync::{Semaphore, mpsc::Receiver};
|
use tokio::sync::Semaphore;
|
||||||
|
use tokio::sync::mpsc::Receiver;
|
||||||
|
|
||||||
use crate::{
|
use crate::constants::VERSION;
|
||||||
constants::VERSION, database::models::User,
|
use crate::database::models::User;
|
||||||
discord::images::get_user_custom_avatar_url_or_none, state::State,
|
use crate::discord::images::get_user_custom_avatar_url_or_none;
|
||||||
};
|
use crate::state::State;
|
||||||
|
|
||||||
pub struct AvatarColorFetchingRequest {
|
pub struct AvatarColorFetchingRequest {
|
||||||
pub hash: String,
|
pub hash: String,
|
||||||
|
|||||||
+3
-4
@@ -1,10 +1,9 @@
|
|||||||
pub mod models;
|
pub mod models;
|
||||||
|
|
||||||
use include_dir::{Dir, include_dir};
|
use include_dir::{Dir, include_dir};
|
||||||
use scylla::{
|
use scylla::client::session::Session;
|
||||||
client::{session::Session, session_builder::SessionBuilder},
|
use scylla::client::session_builder::SessionBuilder;
|
||||||
errors::ExecutionError,
|
use scylla::errors::ExecutionError;
|
||||||
};
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
|
|
||||||
|
|||||||
+18
-28
@@ -1,37 +1,29 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use scylla::{
|
use scylla::client::session::Session;
|
||||||
DeserializeValue, SerializeValue,
|
use scylla::deserialize::row::DeserializeRow;
|
||||||
client::session::Session,
|
use scylla::errors::{
|
||||||
deserialize::row::DeserializeRow,
|
DeserializationError, ExecutionError, FirstRowError, IntoRowsResultError, RowsError,
|
||||||
errors::{
|
SingleRowError,
|
||||||
DeserializationError, ExecutionError, FirstRowError, IntoRowsResultError, RowsError,
|
|
||||||
SingleRowError,
|
|
||||||
},
|
|
||||||
response::query_result::QueryRowsResult,
|
|
||||||
statement::{
|
|
||||||
Statement,
|
|
||||||
batch::{Batch, BatchType},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
use scylla::response::query_result::QueryRowsResult;
|
||||||
|
use scylla::statement::Statement;
|
||||||
|
use scylla::statement::batch::{Batch, BatchType};
|
||||||
|
use scylla::{DeserializeValue, SerializeValue};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use time::{Duration, OffsetDateTime, UtcDateTime, UtcOffset};
|
use time::{Duration, OffsetDateTime, UtcDateTime, UtcOffset};
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
use twilight_http::Client;
|
use twilight_http::Client;
|
||||||
use twilight_model::{
|
use twilight_model::channel::{Message as TwilightMessage, Webhook};
|
||||||
channel::{Message as TwilightMessage, Webhook},
|
use twilight_model::guild::Guild as TwilightGuild;
|
||||||
guild::Guild as TwilightGuild,
|
use twilight_model::id::Id;
|
||||||
id::Id,
|
use twilight_model::user::User as TwilightUser;
|
||||||
user::User as TwilightUser,
|
|
||||||
};
|
|
||||||
use twilight_validate::request::{ValidationError, ValidationErrorType, webhook_username};
|
use twilight_validate::request::{ValidationError, ValidationErrorType, webhook_username};
|
||||||
|
|
||||||
use crate::{
|
use crate::colors::AvatarColorFetchingRequest;
|
||||||
colors::AvatarColorFetchingRequest,
|
use crate::constants::DEFAULT_PREFIX;
|
||||||
constants::DEFAULT_PREFIX,
|
use crate::groups::calls::masks::{get_mask_avatar_url, get_mask_display_name, get_random_mask};
|
||||||
groups::calls::masks::{get_mask_avatar_url, get_mask_display_name, get_random_mask},
|
use crate::utils::{Bye, get_random_u64, i64_to_u64, u64_to_i64};
|
||||||
utils::{Bye, get_random_u64, i64_to_u64, u64_to_i64},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum DatabaseOrDiscordError {
|
pub enum DatabaseOrDiscordError {
|
||||||
@@ -1346,9 +1338,7 @@ impl Message {
|
|||||||
propagation_message_id = ?
|
propagation_message_id = ?
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
"#,
|
"#,
|
||||||
(
|
(u64_to_i64(propagation_message_id),),
|
||||||
u64_to_i64(propagation_message_id),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.await?
|
.await?
|
||||||
.into_rows_result()?;
|
.into_rows_result()?;
|
||||||
|
|||||||
+16
-16
@@ -1,4 +1,6 @@
|
|||||||
use std::{fmt::Debug, sync::Arc, time::Duration};
|
use std::fmt::Debug;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
@@ -8,22 +10,20 @@ use twilight_gateway::{ConfigBuilder, Event, EventTypeFlags, Intents, Shard, Sha
|
|||||||
use twilight_http::Client;
|
use twilight_http::Client;
|
||||||
use twilight_model::gateway::payload::outgoing::update_presence::UpdatePresencePayload;
|
use twilight_model::gateway::payload::outgoing::update_presence::UpdatePresencePayload;
|
||||||
|
|
||||||
use crate::{
|
use crate::framework::commands::Command;
|
||||||
framework::{
|
use crate::framework::commands::extras::ExtrasGetter;
|
||||||
commands::{Command, extras::ExtrasGetter, runner::CommandRunner},
|
use crate::framework::commands::runner::CommandRunner;
|
||||||
events::traits::{
|
use crate::framework::events::traits::{
|
||||||
OnInteractionHandler, OnMessageDeleteHandler, OnMessageEditHandler, OnMessageHandler,
|
OnInteractionHandler, OnMessageDeleteHandler, OnMessageEditHandler, OnMessageHandler,
|
||||||
OnReadyHandler, OnReconnectHandler, OnServerCreateHandler, OnServerDeleteHandler,
|
OnReadyHandler, OnReconnectHandler, OnServerCreateHandler, OnServerDeleteHandler,
|
||||||
OnServerUpdateHandler,
|
OnServerUpdateHandler,
|
||||||
},
|
|
||||||
interactions::{
|
|
||||||
components::Component, registry::ComponentRegistry, runner::InteractionRunner,
|
|
||||||
},
|
|
||||||
runtime::Runtime,
|
|
||||||
tasks::Task,
|
|
||||||
},
|
|
||||||
utils::Bye,
|
|
||||||
};
|
};
|
||||||
|
use crate::framework::interactions::components::Component;
|
||||||
|
use crate::framework::interactions::registry::ComponentRegistry;
|
||||||
|
use crate::framework::interactions::runner::InteractionRunner;
|
||||||
|
use crate::framework::runtime::Runtime;
|
||||||
|
use crate::framework::tasks::Task;
|
||||||
|
use crate::utils::Bye;
|
||||||
|
|
||||||
/// Errors occurred while attempting to run the bot.
|
/// Errors occurred while attempting to run the bot.
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
use std::{
|
use std::fmt;
|
||||||
fmt,
|
use std::ops::{Deref, DerefMut};
|
||||||
ops::{Deref, DerefMut},
|
|
||||||
};
|
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::{database::models::DatabaseError, framework::commands::context::CommandContext};
|
use crate::database::models::DatabaseError;
|
||||||
|
use crate::framework::commands::context::CommandContext;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum ArgumentParsingError {
|
pub enum ArgumentParsingError {
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use twilight_http::{Error, Response};
|
use twilight_http::{Error, Response};
|
||||||
use twilight_model::{
|
use twilight_model::channel::Message;
|
||||||
channel::{Message, message::Component},
|
use twilight_model::channel::message::Component;
|
||||||
gateway::payload::incoming::MessageCreate,
|
use twilight_model::gateway::payload::incoming::MessageCreate;
|
||||||
};
|
|
||||||
|
|
||||||
use crate::framework::{
|
use crate::framework::commands::messages::MessageSender;
|
||||||
commands::messages::MessageSender, interactions::components::ActionRow,
|
use crate::framework::interactions::components::ActionRow;
|
||||||
messages::MessageBuilder, runtime::Runtime,
|
use crate::framework::messages::MessageBuilder;
|
||||||
};
|
use crate::framework::runtime::Runtime;
|
||||||
|
|
||||||
pub struct CommandContext<'a, T, E> {
|
pub struct CommandContext<'a, T, E> {
|
||||||
pub event: &'a MessageCreate,
|
pub event: &'a MessageCreate,
|
||||||
|
|||||||
@@ -1,27 +1,18 @@
|
|||||||
use std::{
|
use std::future::{Future, IntoFuture};
|
||||||
future::{Future, IntoFuture},
|
use std::pin::Pin;
|
||||||
pin::Pin,
|
use std::sync::Arc;
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use twilight_http::{Error, Response, response::marker::EmptyBody};
|
use twilight_http::response::marker::EmptyBody;
|
||||||
use twilight_model::{
|
use twilight_http::{Error, Response};
|
||||||
channel::{
|
use twilight_model::channel::Message;
|
||||||
Message,
|
use twilight_model::channel::message::{Component as TwilightComponent, Embed};
|
||||||
message::{Component as TwilightComponent, Embed},
|
use twilight_model::http::interaction::{InteractionResponse, InteractionResponseType};
|
||||||
},
|
use twilight_model::id::Id;
|
||||||
http::interaction::{InteractionResponse, InteractionResponseType},
|
use twilight_model::id::marker::{ChannelMarker, InteractionMarker};
|
||||||
id::{
|
|
||||||
Id,
|
|
||||||
marker::{ChannelMarker, InteractionMarker},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
use twilight_util::builder::InteractionResponseDataBuilder;
|
use twilight_util::builder::InteractionResponseDataBuilder;
|
||||||
|
|
||||||
use crate::framework::{
|
use crate::framework::interactions::components::{ActionRow, Component};
|
||||||
interactions::components::{ActionRow, Component},
|
use crate::framework::runtime::Runtime;
|
||||||
runtime::Runtime,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct MessageSender<T, E> {
|
pub struct MessageSender<T, E> {
|
||||||
channel_id: Id<ChannelMarker>,
|
channel_id: Id<ChannelMarker>,
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use deadpool_redis::{cluster::PoolError, redis::RedisError};
|
use deadpool_redis::cluster::PoolError;
|
||||||
|
use deadpool_redis::redis::RedisError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use twilight_http::response::DeserializeBodyError;
|
use twilight_http::response::DeserializeBodyError;
|
||||||
|
|
||||||
use crate::{
|
use crate::database::models::{DatabaseError, DatabaseOrDiscordError};
|
||||||
database::models::{DatabaseError, DatabaseOrDiscordError},
|
use crate::framework::commands::arguments::Argument;
|
||||||
framework::{
|
use crate::framework::commands::context::CommandContext;
|
||||||
commands::{arguments::Argument, context::CommandContext, permissions::Permission},
|
use crate::framework::commands::permissions::Permission;
|
||||||
runtime::Runtime,
|
use crate::framework::runtime::Runtime;
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub mod arguments;
|
pub mod arguments;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ use std::fmt::Debug;
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
use crate::framework::commands::{CommandError, context::CommandContext};
|
use crate::framework::commands::CommandError;
|
||||||
|
use crate::framework::commands::context::CommandContext;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Permission<S: Send + Sync + 'static, E>: Debug {
|
pub trait Permission<S: Send + Sync + 'static, E>: Debug {
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ use std::sync::Arc;
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use twilight_model::gateway::payload::incoming::MessageCreate;
|
use twilight_model::gateway::payload::incoming::MessageCreate;
|
||||||
|
|
||||||
use crate::framework::{
|
use crate::framework::commands::context::CommandContext;
|
||||||
commands::{context::CommandContext, extras::ExtrasGetter, get_command_parts},
|
use crate::framework::commands::extras::ExtrasGetter;
|
||||||
events::traits::{EventResult, OnMessageHandler},
|
use crate::framework::commands::get_command_parts;
|
||||||
runtime::Runtime,
|
use crate::framework::events::traits::{EventResult, OnMessageHandler};
|
||||||
};
|
use crate::framework::runtime::Runtime;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CommandRunner;
|
pub struct CommandRunner;
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
use std::{error::Error, fmt::Debug, sync::Arc};
|
use std::error::Error;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use twilight_model::gateway::payload::incoming::{
|
use twilight_model::gateway::payload::incoming::{
|
||||||
@@ -6,7 +8,8 @@ use twilight_model::gateway::payload::incoming::{
|
|||||||
MessageUpdate, Ready,
|
MessageUpdate, Ready,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::framework::{commands::extras::ExtrasGetter, runtime::Runtime};
|
use crate::framework::commands::extras::ExtrasGetter;
|
||||||
|
use crate::framework::runtime::Runtime;
|
||||||
|
|
||||||
pub type EventResult = Result<(), Box<dyn Error>>;
|
pub type EventResult = Result<(), Box<dyn Error>>;
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
use std::{fmt::Debug, sync::Arc};
|
use std::fmt::Debug;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use twilight_model::channel::message::{
|
use twilight_model::channel::message::Component as TwilightComponent;
|
||||||
Component as TwilightComponent,
|
use twilight_model::channel::message::component::{
|
||||||
component::{ActionRow as TwilightActionRow, Button as TwilightButton, ButtonStyle},
|
ActionRow as TwilightActionRow, Button as TwilightButton, ButtonStyle,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::framework::interactions::{InteractionError, context::InteractionContext};
|
use crate::framework::interactions::InteractionError;
|
||||||
|
use crate::framework::interactions::context::InteractionContext;
|
||||||
|
|
||||||
type ComponentWithID<T, E> = (Option<String>, Arc<dyn Component<T, E>>);
|
type ComponentWithID<T, E> = (Option<String>, Arc<dyn Component<T, E>>);
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use twilight_http::{Error, Response, response::marker::EmptyBody};
|
use twilight_http::response::marker::EmptyBody;
|
||||||
use twilight_model::{
|
use twilight_http::{Error, Response};
|
||||||
gateway::payload::incoming::InteractionCreate,
|
use twilight_model::gateway::payload::incoming::InteractionCreate;
|
||||||
http::interaction::{InteractionResponse, InteractionResponseType},
|
use twilight_model::http::interaction::{InteractionResponse, InteractionResponseType};
|
||||||
};
|
|
||||||
use twilight_util::builder::InteractionResponseDataBuilder;
|
use twilight_util::builder::InteractionResponseDataBuilder;
|
||||||
|
|
||||||
use crate::framework::{
|
use crate::framework::interactions::InteractionError;
|
||||||
interactions::{InteractionError, components::ActionRow},
|
use crate::framework::interactions::components::ActionRow;
|
||||||
messages::MessageEditBuilder,
|
use crate::framework::messages::MessageEditBuilder;
|
||||||
runtime::Runtime,
|
use crate::framework::runtime::Runtime;
|
||||||
};
|
|
||||||
|
|
||||||
pub struct InteractionContext<T, E> {
|
pub struct InteractionContext<T, E> {
|
||||||
pub event: InteractionCreate,
|
pub event: InteractionCreate,
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use scc::HashMap;
|
use scc::HashMap;
|
||||||
|
use twilight_model::application::interaction::InteractionData;
|
||||||
use twilight_model::{
|
use twilight_model::gateway::payload::incoming::InteractionCreate;
|
||||||
application::interaction::InteractionData, gateway::payload::incoming::InteractionCreate,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::framework::{
|
|
||||||
commands::extras::ExtrasGetter,
|
|
||||||
interactions::{InteractionError, context::InteractionContext},
|
|
||||||
runtime::Runtime,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::components::Component;
|
use super::components::Component;
|
||||||
|
use crate::framework::commands::extras::ExtrasGetter;
|
||||||
|
use crate::framework::interactions::InteractionError;
|
||||||
|
use crate::framework::interactions::context::InteractionContext;
|
||||||
|
use crate::framework::runtime::Runtime;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ComponentRegistry<T, E> {
|
pub struct ComponentRegistry<T, E> {
|
||||||
|
|||||||
@@ -3,11 +3,9 @@ use std::sync::Arc;
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use twilight_model::gateway::payload::incoming::InteractionCreate;
|
use twilight_model::gateway::payload::incoming::InteractionCreate;
|
||||||
|
|
||||||
use crate::framework::{
|
use crate::framework::commands::extras::ExtrasGetter;
|
||||||
commands::extras::ExtrasGetter,
|
use crate::framework::events::traits::{EventResult, OnInteractionHandler};
|
||||||
events::traits::{EventResult, OnInteractionHandler},
|
use crate::framework::runtime::Runtime;
|
||||||
runtime::Runtime,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InteractionRunner;
|
pub struct InteractionRunner;
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ use std::sync::Arc;
|
|||||||
use tokio::sync::mpsc::UnboundedSender;
|
use tokio::sync::mpsc::UnboundedSender;
|
||||||
use twilight_cache_inmemory::InMemoryCache;
|
use twilight_cache_inmemory::InMemoryCache;
|
||||||
use twilight_http::Client;
|
use twilight_http::Client;
|
||||||
use twilight_model::{gateway::payload::outgoing::UpdatePresence, oauth::Application};
|
use twilight_model::gateway::payload::outgoing::UpdatePresence;
|
||||||
|
use twilight_model::oauth::Application;
|
||||||
|
|
||||||
use crate::framework::{
|
use crate::framework::bot::PrefixGetter;
|
||||||
bot::PrefixGetter, commands::Command, interactions::registry::ComponentRegistry,
|
use crate::framework::commands::Command;
|
||||||
};
|
use crate::framework::interactions::registry::ComponentRegistry;
|
||||||
|
|
||||||
/// The application's runtime tools.
|
/// The application's runtime tools.
|
||||||
pub struct Runtime<T, E> {
|
pub struct Runtime<T, E> {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use std::{fmt::Debug, time::Duration};
|
use std::fmt::Debug;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,18 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
use crate::{
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::commands::arguments::{Arg, Argument, NeedyString, ParseArguments};
|
||||||
framework::{
|
use crate::framework::commands::context::CommandContext;
|
||||||
commands::{
|
use crate::framework::commands::{Command, CommandError};
|
||||||
Command, CommandError,
|
use crate::framework::runtime::Runtime;
|
||||||
arguments::{Arg, Argument, NeedyString, ParseArguments},
|
use crate::groups::about::components::{
|
||||||
context::CommandContext,
|
HelpDonateLinkButton, HelpGoBackButton, HelpSupportLinkButton, HelpWebsiteLinkButton,
|
||||||
},
|
|
||||||
runtime::Runtime,
|
|
||||||
},
|
|
||||||
groups::{
|
|
||||||
about::{
|
|
||||||
components::{
|
|
||||||
HelpDonateLinkButton, HelpGoBackButton, HelpSupportLinkButton,
|
|
||||||
HelpWebsiteLinkButton,
|
|
||||||
},
|
|
||||||
embeds::{
|
|
||||||
get_all_command_help_embed, get_command_help_embed, get_command_not_found_embed,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
calls::components::CodeOfConductButton,
|
|
||||||
},
|
|
||||||
state::State,
|
|
||||||
};
|
};
|
||||||
|
use crate::groups::about::embeds::{
|
||||||
|
get_all_command_help_embed, get_command_help_embed, get_command_not_found_embed,
|
||||||
|
};
|
||||||
|
use crate::groups::calls::components::CodeOfConductButton;
|
||||||
|
use crate::state::State;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct HelpCommand;
|
pub struct HelpCommand;
|
||||||
@@ -83,12 +72,20 @@ impl Command<State, Extras> for HelpCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TetoCommand;
|
pub struct CodeOfConductCommand;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Command<State, Extras> for TetoCommand {
|
impl Command<State, Extras> for CodeOfConductCommand {
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
"teto"
|
"codeofconduct"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn aliases(&self) -> &'static [&'static str] {
|
||||||
|
&["coc"]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn description(&self) -> &'static str {
|
||||||
|
"Shows a link to Payphone's Code of Conduct."
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_in_help(&self, _rt: &Runtime<State, Extras>, _extras: &Extras) -> bool {
|
fn show_in_help(&self, _rt: &Runtime<State, Extras>, _extras: &Extras) -> bool {
|
||||||
@@ -100,7 +97,41 @@ impl Command<State, Extras> for TetoCommand {
|
|||||||
ctx: CommandContext<'_, State, Extras>,
|
ctx: CommandContext<'_, State, Extras>,
|
||||||
_args: &str,
|
_args: &str,
|
||||||
) -> Result<(), CommandError> {
|
) -> Result<(), CommandError> {
|
||||||
ctx.send().content("GLORY TO TETOSLAVIA").await?;
|
ctx.send()
|
||||||
|
.content("https://payphone.lat/code-of-conduct")
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DonateCommand;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Command<State, Extras> for DonateCommand {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"donate"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn aliases(&self) -> &'static [&'static str] {
|
||||||
|
&["d"]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn description(&self) -> &'static str {
|
||||||
|
"Shows a link to Payphone's Ko-Fi page."
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_in_help(&self, _rt: &Runtime<State, Extras>, _extras: &Extras) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn execute(
|
||||||
|
&self,
|
||||||
|
ctx: CommandContext<'_, State, Extras>,
|
||||||
|
_args: &str,
|
||||||
|
) -> Result<(), CommandError> {
|
||||||
|
ctx.send().content("https://ko-fi.com/payphonedev").await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
use crate::{
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::interactions::InteractionError;
|
||||||
framework::{
|
use crate::framework::interactions::components::Button;
|
||||||
interactions::{InteractionError, components::Button, context::InteractionContext},
|
use crate::framework::interactions::context::InteractionContext;
|
||||||
messages::MessageEditBuilder,
|
use crate::framework::messages::MessageEditBuilder;
|
||||||
},
|
use crate::groups::about::embeds::get_all_command_help_embed;
|
||||||
groups::about::embeds::get_all_command_help_embed,
|
use crate::state::State;
|
||||||
state::State,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct HelpGoBackButton;
|
pub struct HelpGoBackButton;
|
||||||
|
|||||||
@@ -5,17 +5,15 @@ use twilight_util::builder::embed::{
|
|||||||
EmbedAuthorBuilder, EmbedBuilder, EmbedFieldBuilder, EmbedFooterBuilder, ImageSource,
|
EmbedAuthorBuilder, EmbedBuilder, EmbedFieldBuilder, EmbedFooterBuilder, ImageSource,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::constants::{COLOR_RED, COLOR_WHITE, VERSION};
|
||||||
constants::{COLOR_RED, COLOR_WHITE, VERSION},
|
use crate::discord::images;
|
||||||
discord::{images, sanitizing::SanitizeDiscordMarkdown},
|
use crate::discord::sanitizing::SanitizeDiscordMarkdown;
|
||||||
extras::Extras,
|
use crate::extras::Extras;
|
||||||
framework::{
|
use crate::framework::commands::Command;
|
||||||
commands::{Command, context::CommandContext},
|
use crate::framework::commands::context::CommandContext;
|
||||||
runtime::Runtime,
|
use crate::framework::runtime::Runtime;
|
||||||
},
|
use crate::state::State;
|
||||||
state::State,
|
use crate::utils::ToTitleCase;
|
||||||
utils::ToTitleCase,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub(super) fn get_command_help_embed(
|
pub(super) fn get_command_help_embed(
|
||||||
command: &Arc<dyn Command<State, Extras>>,
|
command: &Arc<dyn Command<State, Extras>>,
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use rand_chacha::ChaCha20Rng;
|
use rand_chacha::ChaCha20Rng;
|
||||||
use twilight_model::gateway::{
|
use twilight_model::gateway::payload::outgoing::UpdatePresence;
|
||||||
payload::outgoing::{UpdatePresence, update_presence::UpdatePresencePayload},
|
use twilight_model::gateway::payload::outgoing::update_presence::UpdatePresencePayload;
|
||||||
presence::{Activity, ActivityType, Status},
|
use twilight_model::gateway::presence::{Activity, ActivityType, Status};
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::runtime::Runtime;
|
||||||
framework::{runtime::Runtime, tasks::Task},
|
use crate::framework::tasks::Task;
|
||||||
state::State,
|
use crate::state::State;
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UpdatePresenceTask;
|
pub struct UpdatePresenceTask;
|
||||||
|
|||||||
@@ -4,28 +4,24 @@ use scc::HashSet;
|
|||||||
use time::UtcDateTime;
|
use time::UtcDateTime;
|
||||||
use twilight_model::id::Id;
|
use twilight_model::id::Id;
|
||||||
|
|
||||||
use crate::{
|
use crate::database::models::{Call, Channel, Participant};
|
||||||
database::models::{Call, Channel, Participant},
|
use crate::discord::sanitizing::SanitizeDiscordMarkdown;
|
||||||
discord::sanitizing::SanitizeDiscordMarkdown,
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::commands::arguments::{Arg, Argument, ParseArguments};
|
||||||
framework::commands::{
|
use crate::framework::commands::context::CommandContext;
|
||||||
Command, CommandError,
|
use crate::framework::commands::permissions::Permission;
|
||||||
arguments::{Arg, Argument, ParseArguments},
|
use crate::framework::commands::{Command, CommandError};
|
||||||
context::CommandContext,
|
use crate::groups::calls::masks::{get_mask_display_name, get_mask_emoji};
|
||||||
permissions::Permission,
|
use crate::groups::calls::permissions::{
|
||||||
},
|
IsCallParticipantPermission, NonNewAccountPermission, NotBannedPermission,
|
||||||
groups::calls::{
|
|
||||||
masks::{get_mask_display_name, get_mask_emoji},
|
|
||||||
permissions::{NonNewAccountPermission, NotBannedPermission},
|
|
||||||
strings::{
|
|
||||||
get_string_call_answered, get_string_call_hangup_other_party,
|
|
||||||
get_string_call_hangup_this_party, get_string_call_no_answer,
|
|
||||||
get_string_call_searching, get_string_tips,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
state::State,
|
|
||||||
utils::Bye,
|
|
||||||
};
|
};
|
||||||
|
use crate::groups::calls::strings::{
|
||||||
|
get_string_call_answered, get_string_call_hangup_other_party,
|
||||||
|
get_string_call_hangup_this_party, get_string_call_no_answer, get_string_call_searching,
|
||||||
|
get_string_tips,
|
||||||
|
};
|
||||||
|
use crate::state::State;
|
||||||
|
use crate::utils::Bye;
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct CallCommand {
|
pub struct CallCommand {
|
||||||
@@ -172,8 +168,9 @@ impl Command<State, Extras> for SkipCommand {
|
|||||||
|
|
||||||
fn permissions(&self) -> Vec<Box<dyn Permission<State, Extras> + Send + Sync + 'static>> {
|
fn permissions(&self) -> Vec<Box<dyn Permission<State, Extras> + Send + Sync + 'static>> {
|
||||||
vec![
|
vec![
|
||||||
Box::new(NotBannedPermission),
|
|
||||||
Box::new(NonNewAccountPermission),
|
Box::new(NonNewAccountPermission),
|
||||||
|
Box::new(NotBannedPermission),
|
||||||
|
Box::new(IsCallParticipantPermission),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,8 +315,9 @@ impl Command<State, Extras> for HangupCommand {
|
|||||||
|
|
||||||
fn permissions(&self) -> Vec<Box<dyn Permission<State, Extras> + Send + Sync + 'static>> {
|
fn permissions(&self) -> Vec<Box<dyn Permission<State, Extras> + Send + Sync + 'static>> {
|
||||||
vec![
|
vec![
|
||||||
Box::new(NotBannedPermission),
|
|
||||||
Box::new(NonNewAccountPermission),
|
Box::new(NonNewAccountPermission),
|
||||||
|
Box::new(NotBannedPermission),
|
||||||
|
Box::new(IsCallParticipantPermission),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,8 +440,9 @@ impl Command<State, Extras> for FriendRequestCommand {
|
|||||||
|
|
||||||
fn permissions(&self) -> Vec<Box<dyn Permission<State, Extras> + Send + Sync + 'static>> {
|
fn permissions(&self) -> Vec<Box<dyn Permission<State, Extras> + Send + Sync + 'static>> {
|
||||||
vec![
|
vec![
|
||||||
Box::new(NotBannedPermission),
|
|
||||||
Box::new(NonNewAccountPermission),
|
Box::new(NonNewAccountPermission),
|
||||||
|
Box::new(NotBannedPermission),
|
||||||
|
Box::new(IsCallParticipantPermission),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,29 +597,28 @@ impl Command<State, Extras> for MaskCommand {
|
|||||||
mask_status, ctx.prefix, ctx.prefix
|
mask_status, ctx.prefix, ctx.prefix
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(channel) = channel {
|
if let Some(channel) = channel
|
||||||
if let Some(call_id) = channel.call_id {
|
&& let Some(call_id) = channel.call_id
|
||||||
if let Some(mut participant) = Participant::get_for_user_and_channel_in_call(
|
{
|
||||||
ctx.extras.user.id,
|
if let Some(mut participant) = Participant::get_for_user_and_channel_in_call(
|
||||||
ctx.event.channel_id.get(),
|
ctx.extras.user.id,
|
||||||
call_id,
|
ctx.event.channel_id.get(),
|
||||||
&ctx.rt.state.db,
|
call_id,
|
||||||
)
|
&ctx.rt.state.db,
|
||||||
.await?
|
)
|
||||||
{
|
.await?
|
||||||
participant.is_masked = ctx.extras.user.is_masked;
|
{
|
||||||
participant.upsert(&ctx.rt.state.db).await?;
|
participant.is_masked = ctx.extras.user.is_masked;
|
||||||
|
participant.upsert(&ctx.rt.state.db).await?;
|
||||||
|
|
||||||
if ctx.extras.user.is_masked {
|
if ctx.extras.user.is_masked {
|
||||||
mask_message = format!(
|
mask_message = format!(
|
||||||
"🎭 Your mask {mask_verb} set to `on`. You're currently being displayed as **{} {}**. You can toggle your mask on or off using `{}mask on` and `{}mask off`.",
|
"🎭 Your mask {mask_verb} set to `on`. You're currently being displayed as **{} {}**. You can toggle your mask on or off using `{}mask on` and `{}mask off`.",
|
||||||
get_mask_emoji(&participant.user_mask)
|
get_mask_emoji(&participant.user_mask).expect("User's mask did not exist"),
|
||||||
.expect("User's mask did not exist"),
|
get_mask_display_name(&participant.user_mask),
|
||||||
get_mask_display_name(&participant.user_mask),
|
ctx.prefix,
|
||||||
ctx.prefix,
|
ctx.prefix
|
||||||
ctx.prefix
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
use crate::{extras::Extras, framework::interactions::components::Button, state::State};
|
use crate::extras::Extras;
|
||||||
|
use crate::framework::interactions::components::Button;
|
||||||
|
use crate::state::State;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CodeOfConductButton;
|
pub struct CodeOfConductButton;
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use twilight_model::{channel::message::Embed, oauth::Application};
|
use twilight_model::channel::message::Embed;
|
||||||
|
use twilight_model::oauth::Application;
|
||||||
use twilight_util::builder::embed::{
|
use twilight_util::builder::embed::{
|
||||||
EmbedAuthorBuilder, EmbedBuilder, EmbedFieldBuilder, EmbedFooterBuilder, ImageSource,
|
EmbedAuthorBuilder, EmbedBuilder, EmbedFieldBuilder, EmbedFooterBuilder, ImageSource,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::constants::{COLOR_RED, COLOR_YELLOW};
|
||||||
constants::{COLOR_RED, COLOR_YELLOW},
|
use crate::database::models::Message;
|
||||||
database::models::Message,
|
use crate::discord::images;
|
||||||
discord::images,
|
use crate::groups::calls::moderation::Rule;
|
||||||
groups::calls::moderation::Rule,
|
use crate::utils::ellipse;
|
||||||
utils::ellipse,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn first_warning_embed(
|
pub fn first_warning_embed(
|
||||||
app: &Application,
|
app: &Application,
|
||||||
|
|||||||
+68
-49
@@ -1,41 +1,36 @@
|
|||||||
use std::{error::Error, sync::Arc};
|
use std::error::Error;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use deadpool_redis::redis::AsyncTypedCommands;
|
use deadpool_redis::redis::AsyncTypedCommands;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use time::{Duration, UtcDateTime};
|
use time::{Duration, UtcDateTime};
|
||||||
use twilight_http::{api_error::ApiError, error::ErrorType};
|
use twilight_http::api_error::ApiError;
|
||||||
use twilight_model::{
|
use twilight_http::error::ErrorType;
|
||||||
gateway::payload::incoming::{MessageCreate, MessageDelete, MessageUpdate},
|
use twilight_model::gateway::payload::incoming::{MessageCreate, MessageDelete, MessageUpdate};
|
||||||
id::Id,
|
use twilight_model::id::Id;
|
||||||
};
|
use twilight_util::builder::embed::{
|
||||||
use twilight_util::{
|
EmbedAuthorBuilder, EmbedBuilder, EmbedFooterBuilder, ImageSource,
|
||||||
builder::embed::{EmbedAuthorBuilder, EmbedBuilder, EmbedFooterBuilder, ImageSource},
|
|
||||||
snowflake::Snowflake,
|
|
||||||
};
|
};
|
||||||
|
use twilight_util::snowflake::Snowflake;
|
||||||
|
|
||||||
use crate::{
|
use crate::constants::{COLOR_WHITE, COLOR_YELLOW};
|
||||||
constants::{COLOR_WHITE, COLOR_YELLOW},
|
use crate::database::models::{Call, Channel, Message, Participant, User, UserIncident};
|
||||||
database::models::{Call, Channel, Message, Participant, User, UserIncident},
|
use crate::discord::images;
|
||||||
discord::{images, sanitizing::SanitizeDiscordMarkdown},
|
use crate::discord::sanitizing::SanitizeDiscordMarkdown;
|
||||||
extras::Extras,
|
use crate::extras::Extras;
|
||||||
framework::{
|
use crate::framework::commands::extras::ExtrasGetter;
|
||||||
commands::extras::ExtrasGetter,
|
use crate::framework::events::traits::{
|
||||||
events::traits::{
|
EventResult, OnMessageDeleteHandler, OnMessageEditHandler, OnMessageHandler,
|
||||||
EventResult, OnMessageDeleteHandler, OnMessageEditHandler, OnMessageHandler,
|
|
||||||
},
|
|
||||||
interactions::components::ActionRow,
|
|
||||||
runtime::Runtime,
|
|
||||||
},
|
|
||||||
groups::calls::{
|
|
||||||
components::{CodeOfConductButton, NeedHelpButton},
|
|
||||||
embeds,
|
|
||||||
masks::{get_mask_avatar_url, get_mask_display_name},
|
|
||||||
moderation::{Action, Rule, escape_message, moderate_message},
|
|
||||||
},
|
|
||||||
state::State,
|
|
||||||
utils::{ellipse, i64_to_u64},
|
|
||||||
};
|
};
|
||||||
|
use crate::framework::interactions::components::ActionRow;
|
||||||
|
use crate::framework::runtime::Runtime;
|
||||||
|
use crate::groups::calls::components::{CodeOfConductButton, NeedHelpButton};
|
||||||
|
use crate::groups::calls::embeds;
|
||||||
|
use crate::groups::calls::masks::{get_mask_avatar_url, get_mask_display_name};
|
||||||
|
use crate::groups::calls::moderation::{Action, Rule, escape_message, moderate_message};
|
||||||
|
use crate::state::State;
|
||||||
|
use crate::utils::{ellipse, i64_to_u64};
|
||||||
|
|
||||||
async fn penalize_user(
|
async fn penalize_user(
|
||||||
user: User,
|
user: User,
|
||||||
@@ -349,15 +344,35 @@ impl OnMessageHandler<State, Extras> for CallMessageHandler {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Replied-to links are always
|
||||||
|
// .../{other_party_server_id}/{other_party_channel_id}/{other_party_message_id}
|
||||||
|
//
|
||||||
|
// When the message being replied to was sent by the other party, the
|
||||||
|
// `other_party_message_id` is the original message ID, given it was sent from
|
||||||
|
// their channel so the original is in their channel.
|
||||||
|
//
|
||||||
|
// When the message being replied to was sent by this party, the
|
||||||
|
// `other_party_message_id` is the propagation message ID given the other party
|
||||||
|
// will have seen the propagated message instead.
|
||||||
let message_link = if i64_to_u64(propagation_channel_id) == channel.id {
|
let message_link = if i64_to_u64(propagation_channel_id) == channel.id {
|
||||||
|
// if the message replied-to was sent by the other party
|
||||||
|
//
|
||||||
|
// replied_to.message_id -> other party's channel id
|
||||||
|
// replied_to.propagation_channel_id -> this channel's ID
|
||||||
|
// replied_to.propagation_message_id -> this channel's message ID
|
||||||
format!(
|
format!(
|
||||||
"https://discord.com/channels/{}/{}/{}",
|
"https://discord.com/channels/{}/{}/{}",
|
||||||
opposite_channel.server_id, opposite_channel.id, replying_to.message_id
|
opposite_channel.server_id, opposite_channel.id, replying_to.message_id
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
// if the message replied-to was sent by this party
|
||||||
|
//
|
||||||
|
// replied_to.message_id -> this channel's message ID
|
||||||
|
// replied_to.propagation_channel_id -> other party's channel id
|
||||||
|
// replied_to.propagation_message_id -> other party's message ID
|
||||||
format!(
|
format!(
|
||||||
"https://discord.com/channels/{}/{}/{}",
|
"https://discord.com/channels/{}/{}/{}",
|
||||||
channel.server_id, propagation_channel_id, propagation_message_id
|
opposite_channel.server_id, propagation_channel_id, propagation_message_id
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -377,7 +392,10 @@ impl OnMessageHandler<State, Extras> for CallMessageHandler {
|
|||||||
.and_then(|i| i.color.map(|c| c as u32))
|
.and_then(|i| i.color.map(|c| c as u32))
|
||||||
.unwrap_or(COLOR_WHITE)
|
.unwrap_or(COLOR_WHITE)
|
||||||
})
|
})
|
||||||
.description(ellipse(moderate_message(&replying_to.data.content, false).0, 100))
|
.description(ellipse(
|
||||||
|
moderate_message(&replying_to.data.content, false).0,
|
||||||
|
100,
|
||||||
|
))
|
||||||
.build(),
|
.build(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -440,12 +458,13 @@ impl OnMessageHandler<State, Extras> for CallMessageHandler {
|
|||||||
error: ApiError::General(error),
|
error: ApiError::General(error),
|
||||||
..
|
..
|
||||||
} = e.kind()
|
} = e.kind()
|
||||||
&& error.code == 10015 {
|
&& error.code == 10015
|
||||||
log::debug!("Webhook not found, updating...");
|
{
|
||||||
opposite_channel
|
log::debug!("Webhook not found, updating...");
|
||||||
.update_webhook(&rt.state.db, &rt.http)
|
opposite_channel
|
||||||
.await?;
|
.update_webhook(&rt.state.db, &rt.http)
|
||||||
}
|
.await?;
|
||||||
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -626,19 +645,19 @@ impl OnMessageDeleteHandler<State, Extras> for CallMessageDeleteHandler {
|
|||||||
&& let Some((webhook_id, webhook_token)) = opposite_channel
|
&& let Some((webhook_id, webhook_token)) = opposite_channel
|
||||||
.webhook_id
|
.webhook_id
|
||||||
.zip(opposite_channel.webhook_token)
|
.zip(opposite_channel.webhook_token)
|
||||||
{
|
{
|
||||||
rt.http
|
rt.http
|
||||||
.delete_webhook_message(
|
.delete_webhook_message(
|
||||||
Id::new(webhook_id),
|
Id::new(webhook_id),
|
||||||
&webhook_token,
|
&webhook_token,
|
||||||
Id::new(i64_to_u64(propagation_message_id)),
|
Id::new(i64_to_u64(propagation_message_id)),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
message.data.is_deleted = true;
|
message.data.is_deleted = true;
|
||||||
|
|
||||||
message.insert(&rt.state.db).await?;
|
message.insert(&rt.state.db).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ goonbud
|
|||||||
goonbuds
|
goonbuds
|
||||||
goonete
|
goonete
|
||||||
goonetes
|
goonetes
|
||||||
|
gooner
|
||||||
|
goonr
|
||||||
|
goner
|
||||||
boty hole
|
boty hole
|
||||||
suck my pp
|
suck my pp
|
||||||
ass cracker
|
ass cracker
|
||||||
@@ -95,6 +98,10 @@ masturbating
|
|||||||
masterbating
|
masterbating
|
||||||
masterbaiting
|
masterbaiting
|
||||||
masturbatigng
|
masturbatigng
|
||||||
|
masterbaiter
|
||||||
|
mastrbaiter
|
||||||
|
mastrbait
|
||||||
|
mastrbate
|
||||||
horny
|
horny
|
||||||
hrny
|
hrny
|
||||||
whore / who re
|
whore / who re
|
||||||
@@ -116,6 +123,8 @@ eat my bum
|
|||||||
eat mi bum
|
eat mi bum
|
||||||
ima touch you
|
ima touch you
|
||||||
ima touch u
|
ima touch u
|
||||||
|
i ma touch you
|
||||||
|
i ma touch u
|
||||||
il touch you
|
il touch you
|
||||||
il touch u
|
il touch u
|
||||||
im going to touch you
|
im going to touch you
|
||||||
@@ -125,4 +134,6 @@ im gonna touch u
|
|||||||
nude
|
nude
|
||||||
nudes
|
nudes
|
||||||
nde
|
nde
|
||||||
ndes
|
ndes
|
||||||
|
nood
|
||||||
|
noods
|
||||||
@@ -83,7 +83,9 @@
|
|||||||
//!
|
//!
|
||||||
//! All of which would be detected.
|
//! All of which would be detected.
|
||||||
|
|
||||||
use std::{collections::HashMap, fmt::Debug, sync::Arc};
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use linkify::LinkFinder;
|
use linkify::LinkFinder;
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ use async_trait::async_trait;
|
|||||||
use time::{Duration, UtcDateTime};
|
use time::{Duration, UtcDateTime};
|
||||||
use twilight_util::snowflake::Snowflake;
|
use twilight_util::snowflake::Snowflake;
|
||||||
|
|
||||||
use crate::{
|
use crate::database::models::{Call, Channel, Participant, UserIncident};
|
||||||
database::models::UserIncident,
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::commands::CommandError;
|
||||||
framework::commands::{CommandError, context::CommandContext, permissions::Permission},
|
use crate::framework::commands::context::CommandContext;
|
||||||
groups::calls::components::{CodeOfConductButton, NeedHelpButton},
|
use crate::framework::commands::permissions::Permission;
|
||||||
state::State,
|
use crate::groups::calls::components::{CodeOfConductButton, NeedHelpButton};
|
||||||
};
|
use crate::state::State;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NotBannedPermission;
|
pub struct NotBannedPermission;
|
||||||
@@ -72,3 +72,50 @@ impl Permission<State, Extras> for NonNewAccountPermission {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Requires users to have sent a message in the call to be able to use the command.
|
||||||
|
///
|
||||||
|
/// This is to prevent abuse of commands by lurkers in the call, as well as to prevent
|
||||||
|
/// non-participants from skipping or ending calls they're not in.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct IsCallParticipantPermission;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Permission<State, Extras> for IsCallParticipantPermission {
|
||||||
|
async fn check(&self, ctx: &CommandContext<State, Extras>) -> Result<bool, CommandError> {
|
||||||
|
let channel = match Channel::get_by_id(ctx.event.channel_id.get(), &ctx.rt.state.db).await?
|
||||||
|
{
|
||||||
|
Some(channel) => channel,
|
||||||
|
None => return Ok(true), // The channel isn't in the database, so it can't be in call.
|
||||||
|
};
|
||||||
|
|
||||||
|
let call_id = match channel.call_id {
|
||||||
|
Some(call_id) => call_id,
|
||||||
|
None => return Ok(true), // The channel isn't in a call, so the user can use commands in it.
|
||||||
|
};
|
||||||
|
|
||||||
|
let participants = Participant::get_for_call(call_id, &ctx.rt.state.db).await?;
|
||||||
|
|
||||||
|
for participant in participants {
|
||||||
|
if participant.user_id == ctx.event.author.id.get() {
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn on_handle_denied(
|
||||||
|
&self,
|
||||||
|
ctx: &CommandContext<State, Extras>,
|
||||||
|
) -> Result<(), CommandError> {
|
||||||
|
ctx.send()
|
||||||
|
.content("❌ You haven't sent any messages on this call. You cannot run this command.")
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| {
|
||||||
|
log::error!("Failed to send message: {e}");
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use rand::{SeedableRng, seq::IndexedRandom};
|
use rand::SeedableRng;
|
||||||
|
use rand::seq::IndexedRandom;
|
||||||
use rand_chacha::ChaCha20Rng;
|
use rand_chacha::ChaCha20Rng;
|
||||||
|
|
||||||
static STRINGS_TIPS: Lazy<Vec<String>> = Lazy::new(|| {
|
static STRINGS_TIPS: Lazy<Vec<String>> = Lazy::new(|| {
|
||||||
|
|||||||
@@ -3,12 +3,11 @@ use deadpool_redis::redis::AsyncTypedCommands;
|
|||||||
use time::{Duration, UtcDateTime};
|
use time::{Duration, UtcDateTime};
|
||||||
use twilight_model::id::Id;
|
use twilight_model::id::Id;
|
||||||
|
|
||||||
use crate::{
|
use crate::database::models::Call;
|
||||||
database::models::Call,
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::runtime::Runtime;
|
||||||
framework::{runtime::Runtime, tasks::Task},
|
use crate::framework::tasks::Task;
|
||||||
state::State,
|
use crate::state::State;
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EndInactiveCallsTask {
|
pub struct EndInactiveCallsTask {
|
||||||
|
|||||||
@@ -5,14 +5,10 @@ use std::sync::Arc;
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use twilight_model::gateway::payload::incoming::Ready;
|
use twilight_model::gateway::payload::incoming::Ready;
|
||||||
|
|
||||||
use crate::{
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::events::traits::{EventResult, OnReadyHandler, OnReconnectHandler};
|
||||||
framework::{
|
use crate::framework::runtime::Runtime;
|
||||||
events::traits::{EventResult, OnReadyHandler, OnReconnectHandler},
|
use crate::state::State;
|
||||||
runtime::Runtime,
|
|
||||||
},
|
|
||||||
state::State,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Logs a ready message when the bot is ready.
|
/// Logs a ready message when the bot is ready.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -5,15 +5,16 @@ use twilight_util::builder::embed::{
|
|||||||
EmbedAuthorBuilder, EmbedBuilder, EmbedFooterBuilder, ImageSource,
|
EmbedAuthorBuilder, EmbedBuilder, EmbedFooterBuilder, ImageSource,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::constants::COLOR_WHITE;
|
||||||
constants::COLOR_WHITE,
|
use crate::database::models::User;
|
||||||
database::models::User,
|
use crate::discord::images;
|
||||||
discord::{images, sanitizing::SanitizeDiscordMarkdown},
|
use crate::discord::sanitizing::SanitizeDiscordMarkdown;
|
||||||
extras::Extras,
|
use crate::extras::Extras;
|
||||||
framework::commands::{Command, CommandError, context::CommandContext},
|
use crate::framework::commands::context::CommandContext;
|
||||||
groups::leveling::constants::KEY_LEADERBOARD_MONTHLY,
|
use crate::framework::commands::{Command, CommandError};
|
||||||
state::State,
|
use crate::groups::leveling::constants::KEY_LEADERBOARD_MONTHLY;
|
||||||
};
|
use crate::state::State;
|
||||||
|
use crate::utils::format_thousands;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LeaderboardCommand;
|
pub struct LeaderboardCommand;
|
||||||
@@ -48,6 +49,12 @@ impl Command<State, Extras> for LeaderboardCommand {
|
|||||||
let current_user_rank: Option<usize> = redis
|
let current_user_rank: Option<usize> = redis
|
||||||
.zrevrank(KEY_LEADERBOARD_MONTHLY, ctx.event.author.id.get())
|
.zrevrank(KEY_LEADERBOARD_MONTHLY, ctx.event.author.id.get())
|
||||||
.await?;
|
.await?;
|
||||||
|
let current_user_xp: Option<f64> = redis
|
||||||
|
.zscore(KEY_LEADERBOARD_MONTHLY, ctx.event.author.id.get())
|
||||||
|
.await?;
|
||||||
|
let current_user_xp = current_user_xp.map(|xp| xp as u64);
|
||||||
|
|
||||||
|
let current_user_rank_and_xp = current_user_rank.zip(current_user_xp);
|
||||||
|
|
||||||
let mut users = Vec::new();
|
let mut users = Vec::new();
|
||||||
|
|
||||||
@@ -57,15 +64,15 @@ impl Command<State, Extras> for LeaderboardCommand {
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(is_banned_from_leaderboard) = user.is_banned_from_leaderboard {
|
if let Some(is_banned_from_leaderboard) = user.is_banned_from_leaderboard
|
||||||
if is_banned_from_leaderboard {
|
&& is_banned_from_leaderboard
|
||||||
log::trace!(
|
{
|
||||||
"Skipping user {} (ID: {}) because they are banned from the leaderboard.",
|
log::trace!(
|
||||||
user.name,
|
"Skipping user {} (ID: {}) because they are banned from the leaderboard.",
|
||||||
user.id
|
user.name,
|
||||||
);
|
user.id
|
||||||
continue;
|
);
|
||||||
}
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
users.push((user, score as u32));
|
users.push((user, score as u32));
|
||||||
@@ -76,15 +83,24 @@ impl Command<State, Extras> for LeaderboardCommand {
|
|||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, (user, xp))| {
|
.map(|(i, (user, xp))| {
|
||||||
format!("#{}: **{}** - {} XP", i + 1, user.name.sanitize(true), xp)
|
format!(
|
||||||
|
"#{}: **{}** - {} XP",
|
||||||
|
i + 1,
|
||||||
|
user.name.sanitize(true),
|
||||||
|
format_thousands(*xp as u64)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.join("\n")
|
.join("\n")
|
||||||
} else {
|
} else {
|
||||||
"*Nobody earned XP this month yet.*".to_string()
|
"*Nobody earned XP this month yet.*".to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
let footer = if let Some(rank) = current_user_rank {
|
let footer = if let Some((rank, xp)) = current_user_rank_and_xp {
|
||||||
format!("Your current rank: #{}", rank + 1)
|
format!(
|
||||||
|
"Your current rank: #{} - {} XP",
|
||||||
|
rank + 1,
|
||||||
|
format_thousands(xp)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
"You haven't earned XP this month yet.".to_string()
|
"You haven't earned XP this month yet.".to_string()
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,17 +7,13 @@ use rand_chacha::ChaCha20Rng;
|
|||||||
use time::{Date, Month, OffsetDateTime, Time};
|
use time::{Date, Month, OffsetDateTime, Time};
|
||||||
use twilight_model::gateway::payload::incoming::MessageCreate;
|
use twilight_model::gateway::payload::incoming::MessageCreate;
|
||||||
|
|
||||||
use crate::{
|
use crate::database::models::Channel;
|
||||||
database::models::Channel,
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::commands::extras::ExtrasGetter;
|
||||||
framework::{
|
use crate::framework::events::traits::{EventResult, OnMessageHandler};
|
||||||
commands::extras::ExtrasGetter,
|
use crate::framework::runtime::Runtime;
|
||||||
events::traits::{EventResult, OnMessageHandler},
|
use crate::groups::leveling::constants::KEY_LEADERBOARD_MONTHLY;
|
||||||
runtime::Runtime,
|
use crate::state::State;
|
||||||
},
|
|
||||||
groups::leveling::constants::KEY_LEADERBOARD_MONTHLY,
|
|
||||||
state::State,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn seconds_until_end_of_month() -> i64 {
|
fn seconds_until_end_of_month() -> i64 {
|
||||||
let now = OffsetDateTime::now_utc();
|
let now = OffsetDateTime::now_utc();
|
||||||
|
|||||||
@@ -1,20 +1,14 @@
|
|||||||
use std::{
|
use std::ops::{Deref, DerefMut};
|
||||||
ops::{Deref, DerefMut},
|
use std::time::Duration;
|
||||||
time::Duration,
|
|
||||||
};
|
|
||||||
|
|
||||||
use scylla::client::session::Session;
|
use scylla::client::session::Session;
|
||||||
|
|
||||||
use crate::{
|
use crate::database::models::{Message, User};
|
||||||
database::models::{Message, User},
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::commands::arguments::{ArgumentParsingError, FromArguments, NeedyString};
|
||||||
framework::commands::{
|
use crate::framework::commands::context::CommandContext;
|
||||||
arguments::{ArgumentParsingError, FromArguments, NeedyString},
|
use crate::state::State;
|
||||||
context::CommandContext,
|
use crate::utils::split_at_nth_from_end;
|
||||||
},
|
|
||||||
state::State,
|
|
||||||
utils::split_at_nth_from_end,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Fetch a user by their ID from the database.
|
/// Fetch a user by their ID from the database.
|
||||||
///
|
///
|
||||||
@@ -110,7 +104,24 @@ impl FromArguments<State, Extras> for UserArgument {
|
|||||||
.parse()
|
.parse()
|
||||||
.map_err(|_| ArgumentParsingError::InvalidArgument)?;
|
.map_err(|_| ArgumentParsingError::InvalidArgument)?;
|
||||||
|
|
||||||
user = get_user_by_id(user_id, &ctx.rt.state.db).await?;
|
match get_user_by_id(user_id, &ctx.rt.state.db).await {
|
||||||
|
Ok(result) => user = result,
|
||||||
|
Err(error) => {
|
||||||
|
if matches!(error, ArgumentParsingError::InvalidArgument) {
|
||||||
|
let message =
|
||||||
|
Message::get_by_propagation_message_id(user_id, &ctx.rt.state.db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
if let Some(message) = message {
|
||||||
|
user = get_user_by_id(message.author_id, &ctx.rt.state.db).await?;
|
||||||
|
} else {
|
||||||
|
return Err(ArgumentParsingError::InvalidArgument);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// The argument is (probably) a username.
|
// The argument is (probably) a username.
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,20 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use time::UtcDateTime;
|
use time::UtcDateTime;
|
||||||
|
|
||||||
use crate::{
|
use crate::database::models::{UserIncident, UserIncidentType};
|
||||||
database::models::{UserIncident, UserIncidentType},
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::commands::arguments::{
|
||||||
framework::{
|
Arg, Argument, ArgumentParsingError, NeedyGreedyString, ParseArguments,
|
||||||
commands::{
|
|
||||||
Command, CommandError,
|
|
||||||
arguments::{Arg, Argument, ArgumentParsingError, NeedyGreedyString, ParseArguments},
|
|
||||||
context::CommandContext,
|
|
||||||
permissions::Permission,
|
|
||||||
},
|
|
||||||
runtime::Runtime,
|
|
||||||
},
|
|
||||||
groups::moderation::{
|
|
||||||
arguments::{DurationArgument, UserArgument},
|
|
||||||
get_incident_page,
|
|
||||||
permissions::{BotModeratorPermission, BotOwnerPermission},
|
|
||||||
},
|
|
||||||
state::State,
|
|
||||||
utils::get_random_u64,
|
|
||||||
};
|
};
|
||||||
|
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::get_incident_page;
|
||||||
|
use crate::groups::moderation::permissions::{BotModeratorPermission, BotOwnerPermission};
|
||||||
|
use crate::state::State;
|
||||||
|
use crate::utils::get_random_u64;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ModeratorCommand;
|
pub struct ModeratorCommand;
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use twilight_model::channel::message::component::ButtonStyle;
|
use twilight_model::channel::message::component::ButtonStyle;
|
||||||
|
|
||||||
use crate::{
|
use crate::database::models::UserIncident;
|
||||||
database::models::UserIncident,
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::interactions::InteractionError;
|
||||||
framework::interactions::{InteractionError, components::Button, context::InteractionContext},
|
use crate::framework::interactions::components::Button;
|
||||||
groups::moderation::get_incident_page,
|
use crate::framework::interactions::context::InteractionContext;
|
||||||
state::State,
|
use crate::groups::moderation::get_incident_page;
|
||||||
utils::get_random_u64,
|
use crate::state::State;
|
||||||
};
|
use crate::utils::get_random_u64;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ArrowIncidentButton {
|
pub struct ArrowIncidentButton {
|
||||||
|
|||||||
@@ -4,11 +4,9 @@ use twilight_util::builder::embed::{
|
|||||||
EmbedAuthorBuilder, EmbedBuilder, EmbedFieldBuilder, ImageSource,
|
EmbedAuthorBuilder, EmbedBuilder, EmbedFieldBuilder, ImageSource,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::constants::{COLOR_RED, COLOR_YELLOW};
|
||||||
constants::{COLOR_RED, COLOR_YELLOW},
|
use crate::database::models::{UserIncident, UserIncidentType};
|
||||||
database::models::{UserIncident, UserIncidentType},
|
use crate::utils::ellipse;
|
||||||
utils::ellipse,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn format_timestamp(timestamp: UtcDateTime) -> String {
|
fn format_timestamp(timestamp: UtcDateTime) -> String {
|
||||||
format!(
|
format!(
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
use scylla::client::session::Session;
|
use scylla::client::session::Session;
|
||||||
|
|
||||||
use crate::{
|
use crate::database::models::{DatabaseError, UserIncident, UserIncidentType};
|
||||||
database::models::{DatabaseError, UserIncident, UserIncidentType},
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::messages::MessageBuilder;
|
||||||
framework::messages::MessageBuilder,
|
use crate::groups::moderation::components::{
|
||||||
groups::moderation::{
|
ArrowIncidentButton, CounterButton, DeleteIncidentButton, ExpireIncidentButton,
|
||||||
components::{
|
|
||||||
ArrowIncidentButton, CounterButton, DeleteIncidentButton, ExpireIncidentButton,
|
|
||||||
},
|
|
||||||
embeds::incident_embed,
|
|
||||||
},
|
|
||||||
state::State,
|
|
||||||
};
|
};
|
||||||
|
use crate::groups::moderation::embeds::incident_embed;
|
||||||
|
use crate::state::State;
|
||||||
|
|
||||||
pub mod arguments;
|
pub mod arguments;
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
use crate::{
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::commands::CommandError;
|
||||||
framework::commands::{CommandError, context::CommandContext, permissions::Permission},
|
use crate::framework::commands::context::CommandContext;
|
||||||
state::State,
|
use crate::framework::commands::permissions::Permission;
|
||||||
};
|
use crate::state::State;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BotOwnerPermission;
|
pub struct BotOwnerPermission;
|
||||||
|
|||||||
@@ -1,19 +1,15 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
use crate::{
|
use crate::constants::DEFAULT_PREFIX;
|
||||||
constants::DEFAULT_PREFIX,
|
use crate::database::models::Server;
|
||||||
database::models::Server,
|
use crate::discord::sanitizing::SanitizeDiscordMarkdown;
|
||||||
discord::sanitizing::SanitizeDiscordMarkdown,
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::commands::arguments::{Arg, Argument, GreedyString, ParseArguments};
|
||||||
framework::commands::{
|
use crate::framework::commands::context::CommandContext;
|
||||||
Command, CommandError,
|
use crate::framework::commands::permissions::Permission;
|
||||||
arguments::{Arg, Argument, GreedyString, ParseArguments},
|
use crate::framework::commands::{Command, CommandError};
|
||||||
context::CommandContext,
|
use crate::groups::servers::permissions::{GuildOnlyPermission, ServerModeratorPermission};
|
||||||
permissions::Permission,
|
use crate::state::State;
|
||||||
},
|
|
||||||
groups::servers::permissions::{GuildOnlyPermission, ServerModeratorPermission},
|
|
||||||
state::State,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PrefixCommand;
|
pub struct PrefixCommand;
|
||||||
|
|||||||
@@ -5,17 +5,13 @@ use std::sync::Arc;
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use twilight_model::gateway::payload::incoming::{GuildCreate, GuildDelete, GuildUpdate};
|
use twilight_model::gateway::payload::incoming::{GuildCreate, GuildDelete, GuildUpdate};
|
||||||
|
|
||||||
use crate::{
|
use crate::database::models::Server;
|
||||||
database::models::Server,
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::events::traits::{
|
||||||
framework::{
|
EventResult, OnServerCreateHandler, OnServerDeleteHandler, OnServerUpdateHandler,
|
||||||
events::traits::{
|
|
||||||
EventResult, OnServerCreateHandler, OnServerDeleteHandler, OnServerUpdateHandler,
|
|
||||||
},
|
|
||||||
runtime::Runtime,
|
|
||||||
},
|
|
||||||
state::State,
|
|
||||||
};
|
};
|
||||||
|
use crate::framework::runtime::Runtime;
|
||||||
|
use crate::state::State;
|
||||||
|
|
||||||
/// Adds servers to the DB when they get created.
|
/// Adds servers to the DB when they get created.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use twilight_model::{
|
use twilight_model::guild::Permissions;
|
||||||
guild::Permissions,
|
use twilight_model::id::Id;
|
||||||
id::{Id, marker::RoleMarker},
|
use twilight_model::id::marker::RoleMarker;
|
||||||
};
|
|
||||||
use twilight_util::permission_calculator::PermissionCalculator;
|
use twilight_util::permission_calculator::PermissionCalculator;
|
||||||
|
|
||||||
use crate::{
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::commands::CommandError;
|
||||||
framework::commands::{CommandError, context::CommandContext, permissions::Permission},
|
use crate::framework::commands::context::CommandContext;
|
||||||
state::State,
|
use crate::framework::commands::permissions::Permission;
|
||||||
};
|
use crate::state::State;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GuildOnlyPermission;
|
pub struct GuildOnlyPermission;
|
||||||
|
|||||||
+2
-1
@@ -39,7 +39,8 @@
|
|||||||
|
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use log::{Level, LevelFilter};
|
use log::{Level, LevelFilter};
|
||||||
use time::{OffsetDateTime, macros::format_description};
|
use time::OffsetDateTime;
|
||||||
|
use time::macros::format_description;
|
||||||
|
|
||||||
pub struct Logger;
|
pub struct Logger;
|
||||||
|
|
||||||
|
|||||||
+35
-47
@@ -100,62 +100,49 @@
|
|||||||
//! $ cargo run -- docs --open
|
//! $ cargo run -- docs --open
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use std::{
|
use std::error::Error;
|
||||||
error::Error,
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
net::{IpAddr, Ipv4Addr, SocketAddr},
|
use std::path::Path;
|
||||||
path::Path,
|
use std::process::Command;
|
||||||
process::Command,
|
use std::sync::Arc;
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use axum::{Router, response::Redirect, routing};
|
use axum::response::Redirect;
|
||||||
|
use axum::{Router, routing};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use notify::{Event, EventKind, Watcher};
|
use notify::{Event, EventKind, Watcher};
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
use tower_http::services::ServeDir;
|
use tower_http::services::ServeDir;
|
||||||
use twilight_cache_inmemory::ResourceType;
|
use twilight_cache_inmemory::ResourceType;
|
||||||
use twilight_gateway::{Intents, ShardId};
|
use twilight_gateway::{Intents, ShardId};
|
||||||
use twilight_model::{
|
use twilight_model::user::User as TwilightUser;
|
||||||
gateway::{
|
|
||||||
payload::outgoing::update_presence::UpdatePresencePayload,
|
|
||||||
presence::{Activity, ActivityType, Status},
|
|
||||||
},
|
|
||||||
user::User as TwilightUser,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::cli::{Args, Commands};
|
||||||
cli::{Args, Commands},
|
use crate::colors::init_color_fetching_queue_listener;
|
||||||
colors::init_color_fetching_queue_listener,
|
use crate::constants::{DEFAULT_PREFIX, VERSION};
|
||||||
constants::{DEFAULT_PREFIX, VERSION},
|
use crate::database::models::{Server, User};
|
||||||
database::models::{Server, User},
|
use crate::extras::Extras;
|
||||||
extras::Extras,
|
use crate::framework::bot::{Bot, PrefixGetter};
|
||||||
framework::{
|
use crate::framework::commands::extras::ExtrasGetter;
|
||||||
bot::{Bot, PrefixGetter},
|
use crate::framework::runtime::Runtime;
|
||||||
commands::extras::ExtrasGetter,
|
use crate::groups::about::commands::{CodeOfConductCommand, DonateCommand, HelpCommand};
|
||||||
runtime::Runtime,
|
use crate::groups::about::components::HelpGoBackButton;
|
||||||
},
|
use crate::groups::about::tasks::UpdatePresenceTask;
|
||||||
groups::{
|
use crate::groups::calls::commands::{
|
||||||
about::{
|
CallCommand, FriendRequestCommand, HangupCommand, MaskCommand, SkipCommand,
|
||||||
commands::{HelpCommand, TetoCommand},
|
|
||||||
components::HelpGoBackButton, tasks::UpdatePresenceTask,
|
|
||||||
},
|
|
||||||
calls::{
|
|
||||||
commands::{
|
|
||||||
CallCommand, FriendRequestCommand, HangupCommand, MaskCommand, SkipCommand,
|
|
||||||
},
|
|
||||||
events::{CallMessageDeleteHandler, CallMessageEditHandler, CallMessageHandler},
|
|
||||||
},
|
|
||||||
gateway::events::{ReadyHandler, ReconnectHandler},
|
|
||||||
leveling::{commands::LeaderboardCommand, events::MessageLevelingHandler},
|
|
||||||
moderation::commands::{BanCommand, IncidentsCommand, ModeratorCommand},
|
|
||||||
servers::{
|
|
||||||
commands::PrefixCommand,
|
|
||||||
events::{ServerCreateHandler, ServerDeleteHandler, ServerUpdateHandler},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
state::State,
|
|
||||||
};
|
};
|
||||||
|
use crate::groups::calls::events::{
|
||||||
|
CallMessageDeleteHandler, CallMessageEditHandler, CallMessageHandler,
|
||||||
|
};
|
||||||
|
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::servers::commands::PrefixCommand;
|
||||||
|
use crate::groups::servers::events::{
|
||||||
|
ServerCreateHandler, ServerDeleteHandler, ServerUpdateHandler,
|
||||||
|
};
|
||||||
|
use crate::state::State;
|
||||||
|
|
||||||
mod cli;
|
mod cli;
|
||||||
mod colors;
|
mod colors;
|
||||||
@@ -299,7 +286,8 @@ async fn start(
|
|||||||
.intent(Intents::GUILD_MESSAGES)
|
.intent(Intents::GUILD_MESSAGES)
|
||||||
.intent(Intents::MESSAGE_CONTENT)
|
.intent(Intents::MESSAGE_CONTENT)
|
||||||
.command(HelpCommand)
|
.command(HelpCommand)
|
||||||
.command(TetoCommand)
|
.command(CodeOfConductCommand)
|
||||||
|
.command(DonateCommand)
|
||||||
.command(CallCommand::new())
|
.command(CallCommand::new())
|
||||||
.command(SkipCommand)
|
.command(SkipCommand)
|
||||||
.command(HangupCommand)
|
.command(HangupCommand)
|
||||||
|
|||||||
+2
-4
@@ -1,7 +1,5 @@
|
|||||||
use deadpool_redis::{
|
use deadpool_redis::Runtime;
|
||||||
Runtime,
|
use deadpool_redis::cluster::{Config, CreatePoolError, Pool};
|
||||||
cluster::{Config, CreatePoolError, Pool},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn init(urls: Vec<String>) -> Result<Pool, CreatePoolError> {
|
pub fn init(urls: Vec<String>) -> Result<Pool, CreatePoolError> {
|
||||||
Config::from_urls(urls).create_pool(Some(Runtime::Tokio1))
|
Config::from_urls(urls).create_pool(Some(Runtime::Tokio1))
|
||||||
|
|||||||
@@ -133,3 +133,25 @@ pub fn split_at_nth_from_end<'a, 'b>(
|
|||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Formats a number with commas as thousands separators.
|
||||||
|
///
|
||||||
|
/// E.g. `123456789` becomes `123,456,789`.
|
||||||
|
///
|
||||||
|
/// Arguments:
|
||||||
|
/// * `num` - The number to format.
|
||||||
|
///
|
||||||
|
/// Returns:
|
||||||
|
/// [`String`] - The formatted number as a string.
|
||||||
|
pub fn format_thousands(num: u64) -> String {
|
||||||
|
let mut num_str = num.to_string();
|
||||||
|
let mut result = String::new();
|
||||||
|
|
||||||
|
while num_str.len() > 3 {
|
||||||
|
let chunk = &num_str[num_str.len() - 3..];
|
||||||
|
result = format!(",{chunk}{result}");
|
||||||
|
num_str.truncate(num_str.len() - 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
format!("{}{}", num_str, result)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user