Restrict accounts to min 30 days to be able to call and start working on masks
This commit is contained in:
Generated
+1
-1
@@ -1437,7 +1437,7 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "payphone"
|
name = "payphone"
|
||||||
version = "4.2.21"
|
version = "4.2.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "payphone"
|
name = "payphone"
|
||||||
version = "4.2.21"
|
version = "4.2.24"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
default-run = "payphone"
|
default-run = "payphone"
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ twilight-cache-inmemory = { version = "0.16.0", features = ["permission-calculat
|
|||||||
twilight-gateway = "0.16.0"
|
twilight-gateway = "0.16.0"
|
||||||
twilight-http = { version = "0.16.0", features = ["simd-json"] }
|
twilight-http = { version = "0.16.0", features = ["simd-json"] }
|
||||||
twilight-model = "0.16.0"
|
twilight-model = "0.16.0"
|
||||||
twilight-util = { version = "0.16.0", features = ["builder", "permission-calculator"] }
|
twilight-util = { version = "0.16.0", features = ["builder", "permission-calculator", "snowflake"] }
|
||||||
twilight-validate = "0.16.0"
|
twilight-validate = "0.16.0"
|
||||||
unicode-segmentation = "1.12.0"
|
unicode-segmentation = "1.12.0"
|
||||||
unidecode = "0.3.0"
|
unidecode = "0.3.0"
|
||||||
|
|||||||
+132
-1
@@ -21,7 +21,7 @@ use twilight_model::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
constants::DEFAULT_PREFIX,
|
constants::DEFAULT_PREFIX,
|
||||||
groups::calls::DisplayProfile,
|
groups::calls::{DisplayProfile, masks::get_random_mask},
|
||||||
utils::{get_random_u64, i64_to_u64, u64_to_i64},
|
utils::{get_random_u64, i64_to_u64, u64_to_i64},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,6 +47,9 @@ pub enum DatabaseError {
|
|||||||
|
|
||||||
#[error("The resulting row could not be deserialized into an object")]
|
#[error("The resulting row could not be deserialized into an object")]
|
||||||
DeserializationFailed,
|
DeserializationFailed,
|
||||||
|
|
||||||
|
#[error("An unknown error occurred")]
|
||||||
|
Unknown(&'static str),
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Object<'a> {
|
trait Object<'a> {
|
||||||
@@ -1744,3 +1747,131 @@ impl UserIncident {
|
|||||||
incident.insert(session).await
|
incident.insert(session).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Participant {
|
||||||
|
pub call_id: u64,
|
||||||
|
pub user_id: u64,
|
||||||
|
pub channel_id: u64,
|
||||||
|
|
||||||
|
pub user_name: String,
|
||||||
|
pub user_avatar_url: String,
|
||||||
|
pub user_mask: String,
|
||||||
|
|
||||||
|
pub is_masked: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Object<'a> for Participant {
|
||||||
|
type Row = (i64, i64, i64, String, String, String, bool);
|
||||||
|
|
||||||
|
fn from_row(row: Self::Row) -> Self {
|
||||||
|
Self {
|
||||||
|
call_id: i64_to_u64(row.0),
|
||||||
|
user_id: i64_to_u64(row.1),
|
||||||
|
channel_id: i64_to_u64(row.2),
|
||||||
|
user_name: row.3,
|
||||||
|
user_avatar_url: row.4,
|
||||||
|
user_mask: row.5,
|
||||||
|
is_masked: row.6,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_row(value: Self) -> Self::Row {
|
||||||
|
(
|
||||||
|
u64_to_i64(value.call_id),
|
||||||
|
u64_to_i64(value.user_id),
|
||||||
|
u64_to_i64(value.channel_id),
|
||||||
|
value.user_name,
|
||||||
|
value.user_avatar_url,
|
||||||
|
value.user_mask,
|
||||||
|
value.is_masked,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Participant {
|
||||||
|
pub async fn get_for_call(call_id: u64, session: &Session) -> Result<Vec<Self>, DatabaseError> {
|
||||||
|
let call_id = u64_to_i64(call_id);
|
||||||
|
|
||||||
|
let rows = session
|
||||||
|
.query_unpaged(
|
||||||
|
r#"
|
||||||
|
SELECT * FROM payphone.participants
|
||||||
|
WHERE call_id = ?;
|
||||||
|
"#,
|
||||||
|
(call_id,),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(DatabaseError::QueryError)?;
|
||||||
|
|
||||||
|
Ok(rows
|
||||||
|
.into_rows_result()
|
||||||
|
.map_err(|_| DatabaseError::ResultNotRows)?
|
||||||
|
.rows()
|
||||||
|
.map_err(|_| DatabaseError::ResultNotRows)?
|
||||||
|
.collect::<Result<Vec<_>, _>>()
|
||||||
|
.map_err(|_| DatabaseError::DeserializationFailed)?
|
||||||
|
.into_iter()
|
||||||
|
.map(Self::from_row)
|
||||||
|
.collect::<Vec<_>>())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create(
|
||||||
|
user_id: u64,
|
||||||
|
channel_id: u64,
|
||||||
|
call_id: u64,
|
||||||
|
profile: DisplayProfile,
|
||||||
|
is_masked: bool,
|
||||||
|
session: &Session,
|
||||||
|
) -> Result<(), DatabaseError> {
|
||||||
|
let masks_in_use = Self::get_for_call(call_id, session)
|
||||||
|
.await?
|
||||||
|
.iter()
|
||||||
|
.filter_map(|p| {
|
||||||
|
if p.channel_id == channel_id {
|
||||||
|
Some(p.user_mask.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let (mask, _) = get_random_mask(&masks_in_use).ok_or(DatabaseError::Unknown(
|
||||||
|
"No remaining masks available for the channel",
|
||||||
|
))?;
|
||||||
|
|
||||||
|
let participant = Participant {
|
||||||
|
call_id,
|
||||||
|
user_id,
|
||||||
|
channel_id,
|
||||||
|
user_name: profile.name,
|
||||||
|
user_avatar_url: profile.avatar_url,
|
||||||
|
user_mask: mask,
|
||||||
|
is_masked,
|
||||||
|
};
|
||||||
|
|
||||||
|
participant.insert(session).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn insert(&self, session: &Session) -> Result<(), DatabaseError> {
|
||||||
|
session
|
||||||
|
.query_unpaged(
|
||||||
|
r#"
|
||||||
|
INSERT INTO payphone.participants (
|
||||||
|
call_id,
|
||||||
|
user_id,
|
||||||
|
channel_id,
|
||||||
|
user_name,
|
||||||
|
user_avatar_url,
|
||||||
|
user_mask,
|
||||||
|
is_masked
|
||||||
|
) IF NOT EXISTS VALUES (?, ?, ?, ?, ?, ?, ?);
|
||||||
|
"#,
|
||||||
|
Self::to_row(self.clone()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(DatabaseError::QueryError)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
groups::calls::{
|
groups::calls::{
|
||||||
get_display_profile,
|
get_display_profile,
|
||||||
permissions::NotBannedPermission,
|
permissions::{NonNewAccountPermission, NotBannedPermission},
|
||||||
strings::{
|
strings::{
|
||||||
get_string_call_answered, get_string_call_hangup_other_party,
|
get_string_call_answered, get_string_call_hangup_other_party,
|
||||||
get_string_call_hangup_this_party, get_string_call_no_answer,
|
get_string_call_hangup_this_party, get_string_call_no_answer,
|
||||||
@@ -53,7 +53,10 @@ impl Command<State, Extras> for CallCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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![Box::new(NotBannedPermission)]
|
vec![
|
||||||
|
Box::new(NotBannedPermission),
|
||||||
|
Box::new(NonNewAccountPermission),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn execute(
|
async fn execute(
|
||||||
@@ -146,7 +149,10 @@ 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![Box::new(NotBannedPermission)]
|
vec![
|
||||||
|
Box::new(NotBannedPermission),
|
||||||
|
Box::new(NonNewAccountPermission),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn execute(
|
async fn execute(
|
||||||
@@ -254,7 +260,10 @@ 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![Box::new(NotBannedPermission)]
|
vec![
|
||||||
|
Box::new(NotBannedPermission),
|
||||||
|
Box::new(NonNewAccountPermission),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn execute(
|
async fn execute(
|
||||||
@@ -354,7 +363,10 @@ 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![Box::new(NotBannedPermission)]
|
vec![
|
||||||
|
Box::new(NotBannedPermission),
|
||||||
|
Box::new(NonNewAccountPermission),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn execute(
|
async fn execute(
|
||||||
@@ -494,7 +506,6 @@ impl Command<State, Extras> for MaskCommand {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(call_id) = channel.call_id {
|
if let Some(call_id) = channel.call_id {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ctx
|
ctx
|
||||||
.send()
|
.send()
|
||||||
|
|||||||
@@ -2,12 +2,16 @@ use std::{error::Error, sync::Arc};
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use time::{Duration, UtcDateTime};
|
||||||
use twilight_http::{api_error::ApiError, error::ErrorType};
|
use twilight_http::{api_error::ApiError, error::ErrorType};
|
||||||
use twilight_model::{
|
use twilight_model::{
|
||||||
gateway::payload::incoming::{MessageCreate, MessageDelete, MessageUpdate},
|
gateway::payload::incoming::{MessageCreate, MessageDelete, MessageUpdate},
|
||||||
id::Id,
|
id::Id,
|
||||||
};
|
};
|
||||||
use twilight_util::builder::embed::{EmbedAuthorBuilder, EmbedBuilder, ImageSource};
|
use twilight_util::{
|
||||||
|
builder::embed::{EmbedAuthorBuilder, EmbedBuilder, ImageSource},
|
||||||
|
snowflake::Snowflake,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
constants::COLOR_WHITE,
|
constants::COLOR_WHITE,
|
||||||
@@ -15,14 +19,18 @@ use crate::{
|
|||||||
discord::sanitizing::SanitizeDiscordMarkdown,
|
discord::sanitizing::SanitizeDiscordMarkdown,
|
||||||
extras::Extras,
|
extras::Extras,
|
||||||
framework::{
|
framework::{
|
||||||
commands::extras::ExtrasGetter, events::traits::{
|
commands::{extras::ExtrasGetter, permissions::Permission},
|
||||||
|
events::traits::{
|
||||||
EventResult, OnMessageDeleteHandler, OnMessageEditHandler, OnMessageHandler,
|
EventResult, OnMessageDeleteHandler, OnMessageEditHandler, OnMessageHandler,
|
||||||
}, interactions::components::ActionRow, runtime::Runtime
|
},
|
||||||
|
interactions::components::ActionRow,
|
||||||
|
runtime::Runtime,
|
||||||
},
|
},
|
||||||
groups::calls::{
|
groups::calls::{
|
||||||
components::{CodeOfConductButton, NeedHelpButton},
|
components::{CodeOfConductButton, NeedHelpButton},
|
||||||
embeds, get_display_profile,
|
embeds, get_display_profile,
|
||||||
moderation::{escape_message, Action, Rule},
|
moderation::{Action, Rule, escape_message},
|
||||||
|
permissions::NonNewAccountPermission,
|
||||||
},
|
},
|
||||||
state::State,
|
state::State,
|
||||||
utils::{ellipse, i64_to_u64},
|
utils::{ellipse, i64_to_u64},
|
||||||
@@ -96,6 +104,12 @@ impl OnMessageHandler<State, Extras> for CallMessageHandler {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if UtcDateTime::from_unix_timestamp(event.author.id.timestamp() / 1000).unwrap()
|
||||||
|
> UtcDateTime::now() - Duration::days(30)
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let prefixes = rt
|
let prefixes = rt
|
||||||
.get_prefixes(event.guild_id.map(|i| i.get()), Some(event.author.id.get()))
|
.get_prefixes(event.guild_id.map(|i| i.get()), Some(event.author.id.get()))
|
||||||
.await;
|
.await;
|
||||||
@@ -239,7 +253,11 @@ impl OnMessageHandler<State, Extras> for CallMessageHandler {
|
|||||||
embeds.push(
|
embeds.push(
|
||||||
EmbedBuilder::new()
|
EmbedBuilder::new()
|
||||||
.author(
|
.author(
|
||||||
EmbedAuthorBuilder::new(format!("Replying to {}", replying_to.data.author_name)).icon_url(
|
EmbedAuthorBuilder::new(format!(
|
||||||
|
"Replying to {}",
|
||||||
|
replying_to.data.author_name
|
||||||
|
))
|
||||||
|
.icon_url(
|
||||||
ImageSource::url(replying_to.data.author_avatar_url).unwrap(),
|
ImageSource::url(replying_to.data.author_avatar_url).unwrap(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -323,6 +341,10 @@ impl OnMessageEditHandler<State, Extras> for CallMessageEditHandler {
|
|||||||
event: &MessageUpdate,
|
event: &MessageUpdate,
|
||||||
rt: Arc<Runtime<State, Extras>>,
|
rt: Arc<Runtime<State, Extras>>,
|
||||||
) -> EventResult {
|
) -> EventResult {
|
||||||
|
if event.edited_timestamp.is_none() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
log::trace!(
|
log::trace!(
|
||||||
"Edited message was '{}' sent by {} (bot? {:?})",
|
"Edited message was '{}' sent by {} (bot? {:?})",
|
||||||
event.content,
|
event.content,
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
scum
|
scum
|
||||||
idiot
|
idiot
|
||||||
stupid
|
|
||||||
dumb
|
|
||||||
moron
|
moron
|
||||||
fool
|
fool
|
||||||
stfu
|
stfu
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"dinosaur": 1278255435652010014,
|
||||||
|
"shleepy cat": 1278255475066146816,
|
||||||
|
"cozy cat": 1278255420124696663,
|
||||||
|
"coquette cat": 1278255408254816300,
|
||||||
|
"panic cat": 1278255451993145345
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"ferret": 1278176917123760139,
|
||||||
|
"octopus": 1278176904410697880,
|
||||||
|
"cat": 1278176891290783824,
|
||||||
|
"monkey": 1278176881195094049,
|
||||||
|
"panda": 1278176868767629455,
|
||||||
|
"sheep": 1278176856910073946,
|
||||||
|
"horse": 1278176842116894760,
|
||||||
|
"bee": 1278176823846506577,
|
||||||
|
"wild boar": 1278176806498996235,
|
||||||
|
"duck": 1278176794591232102,
|
||||||
|
"chicken": 1278176781790216233,
|
||||||
|
"elephant": 1278176771413512213,
|
||||||
|
"cow": 1278176761565413483,
|
||||||
|
"deer": 1278176744691597312,
|
||||||
|
"turkey": 1278176730619576321,
|
||||||
|
"dog": 1278176719932751903,
|
||||||
|
"beaver": 1278176709530882091,
|
||||||
|
"camel": 1278176699921465394,
|
||||||
|
"koala": 1278176687493746709,
|
||||||
|
"hippo": 1278176675846295603,
|
||||||
|
"ostrich": 1278176661317095494,
|
||||||
|
"rhino": 1278176650340864000,
|
||||||
|
"squirrel": 1278176637627924570,
|
||||||
|
"chamaleon": 1278176625392877648,
|
||||||
|
"frog": 1278176614512857088,
|
||||||
|
"skunk": 1278176604509442079,
|
||||||
|
"walrus": 1278176554723311678,
|
||||||
|
"hedgehog": 1278176541750067252,
|
||||||
|
"pig": 1278176531415564332,
|
||||||
|
"hen": 1278176518643646485,
|
||||||
|
"turtle": 1278176507428343891,
|
||||||
|
"mouse": 1278175957047578696,
|
||||||
|
"rabbit": 1278175944007487489,
|
||||||
|
"goat": 1278175933915856938,
|
||||||
|
"lion": 1278175922964664382,
|
||||||
|
"wolf": 1278175902047535165,
|
||||||
|
"snake": 1278175869331968061,
|
||||||
|
"llama": 1278175850008674325,
|
||||||
|
"crab": 1278175835634925620,
|
||||||
|
"owl": 1278175822947029152,
|
||||||
|
"bat": 1278175813572886550,
|
||||||
|
"zebra": 1278175799962505216,
|
||||||
|
"fox": 1278175788818104474,
|
||||||
|
"gorilla": 1278175775891259456,
|
||||||
|
"sloth": 1278175765661356175,
|
||||||
|
"puffer fish": 1278175753497743360,
|
||||||
|
"bear": 1278175741569142867,
|
||||||
|
"giraffe": 1278175732601983006,
|
||||||
|
"penguin": 1278175721956573236,
|
||||||
|
"parrot": 1278175706798489642
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use rand::{SeedableRng, seq::IndexedRandom};
|
||||||
|
use rand_chacha::ChaCha20Rng;
|
||||||
|
|
||||||
|
static MASKS_COMMON: Lazy<HashMap<String, u64>> = Lazy::new(|| {
|
||||||
|
let (file_name, json) = if cfg!(debug_assertions) {
|
||||||
|
("dev/common.json", include_str!("dev/common.json"))
|
||||||
|
} else {
|
||||||
|
("prod/common.json", include_str!("prod/common.json"))
|
||||||
|
};
|
||||||
|
|
||||||
|
let masks: HashMap<String, u64> =
|
||||||
|
serde_json::from_str(json).expect(&format!("Failed to parse masks/{file_name} masks"));
|
||||||
|
|
||||||
|
assert_ne!(masks.len(), 0, "No masks found in masks/{file_name}");
|
||||||
|
|
||||||
|
masks
|
||||||
|
});
|
||||||
|
|
||||||
|
pub fn get_random_mask(not_in: &[String]) -> Option<(String, u64)> {
|
||||||
|
let mask_names = MASKS_COMMON
|
||||||
|
.iter()
|
||||||
|
.filter(|(name, _)| !not_in.contains(name))
|
||||||
|
.map(|(name, value)| (name.clone(), *value))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut rng = ChaCha20Rng::from_os_rng();
|
||||||
|
|
||||||
|
mask_names.choose(&mut rng).cloned()
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"dinosaur": 1278254725833297965,
|
||||||
|
"shleepy cat": 1278254779767984181,
|
||||||
|
"cozy cat": 1278254704324771893,
|
||||||
|
"coquette cat": 1278254684200636428,
|
||||||
|
"panic cat": 1278254760700674098
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"ferret": 1278173356423909448,
|
||||||
|
"octopus": 1278173331421397072,
|
||||||
|
"cat": 1278173317034934282,
|
||||||
|
"monkey": 1278173297456185344,
|
||||||
|
"panda": 1278173272390762538,
|
||||||
|
"sheep": 1278173251914432563,
|
||||||
|
"horse": 1278173237582237708,
|
||||||
|
"bee": 1278173216652787826,
|
||||||
|
"wild boar": 1278173196658413649,
|
||||||
|
"duck": 1278173181483679918,
|
||||||
|
"chicken": 1278173167218589726,
|
||||||
|
"elephant": 1278173150063886346,
|
||||||
|
"cow": 1278173125024153733,
|
||||||
|
"deer": 1278173110105014406,
|
||||||
|
"turkey": 1278173091796877363,
|
||||||
|
"dog": 1278173070846201856,
|
||||||
|
"beaver": 1278173051485425705,
|
||||||
|
"camel": 1278173035018584086,
|
||||||
|
"koala": 1278173021345021952,
|
||||||
|
"hippo": 1278173007419932804,
|
||||||
|
"ostrich": 1278172994669248523,
|
||||||
|
"rhino": 1278172980848885832,
|
||||||
|
"squirrel": 1278172965590274088,
|
||||||
|
"chamaleon": 1278172953305022496,
|
||||||
|
"frog": 1278172937043710094,
|
||||||
|
"skunk": 1278172923495976981,
|
||||||
|
"walrus": 1278172912368619603,
|
||||||
|
"hedgehog": 1278172899911405678,
|
||||||
|
"pig": 1278172885239861338,
|
||||||
|
"hen": 1278172871302184994,
|
||||||
|
"turtle": 1278172858199314455,
|
||||||
|
"mouse": 1278172846442414081,
|
||||||
|
"rabbit": 1278172831921999945,
|
||||||
|
"goat": 1278172815421472808,
|
||||||
|
"lion": 1278172803534684235,
|
||||||
|
"wolf": 1278172791052570687,
|
||||||
|
"snake": 1278172776259260547,
|
||||||
|
"llama": 1278172764913799168,
|
||||||
|
"crab": 1278172752322232330,
|
||||||
|
"owl": 1278172738309193749,
|
||||||
|
"bat": 1278172726426865724,
|
||||||
|
"zebra": 1278172715114565753,
|
||||||
|
"fox": 1278172702955274292,
|
||||||
|
"gorilla": 1278172687797194824,
|
||||||
|
"sloth": 1278172676837343242,
|
||||||
|
"puffer fish": 1278172665093558294,
|
||||||
|
"bear": 1278172653076746301,
|
||||||
|
"giraffe": 1278172640296702073,
|
||||||
|
"penguin": 1278172627629899808,
|
||||||
|
"parrot": 1278172600702337074
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ pub mod commands;
|
|||||||
pub(super) mod components;
|
pub(super) mod components;
|
||||||
pub(super) mod embeds;
|
pub(super) mod embeds;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
|
pub mod masks;
|
||||||
pub(super) mod moderation;
|
pub(super) mod moderation;
|
||||||
pub(super) mod permissions;
|
pub(super) mod permissions;
|
||||||
pub(super) mod strings;
|
pub(super) mod strings;
|
||||||
@@ -34,7 +35,10 @@ fn make_name_valid(name: String) -> String {
|
|||||||
fn get_display_profile(event: &MessageCreate) -> DisplayProfile {
|
fn get_display_profile(event: &MessageCreate) -> DisplayProfile {
|
||||||
let member = event.member.clone();
|
let member = event.member.clone();
|
||||||
|
|
||||||
let name = if let Some(nick) = &member.clone().and_then(|member| member.nick.map(make_name_valid)) {
|
let name = if let Some(nick) = &member
|
||||||
|
.clone()
|
||||||
|
.and_then(|member| member.nick.map(make_name_valid))
|
||||||
|
{
|
||||||
if webhook_username(nick).is_err() {
|
if webhook_username(nick).is_err() {
|
||||||
"Invalid Nickname".to_string()
|
"Invalid Nickname".to_string()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use time::{Duration, UtcDateTime};
|
||||||
|
use twilight_util::snowflake::{self, Snowflake};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
database::models::UserIncident,
|
database::models::UserIncident,
|
||||||
@@ -41,3 +43,32 @@ impl Permission<State, Extras> for NotBannedPermission {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct NonNewAccountPermission;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Permission<State, Extras> for NonNewAccountPermission {
|
||||||
|
async fn check(&self, ctx: &CommandContext<State, Extras>) -> Result<bool, CommandError> {
|
||||||
|
Ok(
|
||||||
|
UtcDateTime::from_unix_timestamp(ctx.event.author.id.timestamp() / 1000).unwrap()
|
||||||
|
< UtcDateTime::now() - Duration::days(30),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn on_handle_denied(
|
||||||
|
&self,
|
||||||
|
ctx: &CommandContext<State, Extras>,
|
||||||
|
) -> Result<(), CommandError> {
|
||||||
|
ctx.send()
|
||||||
|
.content("❌ Your account must be at least 30 days old to use Payphone.")
|
||||||
|
.component(CodeOfConductButton, 1)
|
||||||
|
.component(NeedHelpButton, 1)
|
||||||
|
.await
|
||||||
|
.inspect_err(|e| {
|
||||||
|
log::error!("Failed to send message: {e}");
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+3
-2
@@ -137,7 +137,7 @@ use crate::{
|
|||||||
groups::{
|
groups::{
|
||||||
about::{commands::HelpCommand, components::HelpGoBackButton},
|
about::{commands::HelpCommand, components::HelpGoBackButton},
|
||||||
calls::{
|
calls::{
|
||||||
commands::{CallCommand, FriendRequestCommand, HangupCommand, SkipCommand},
|
commands::{CallCommand, FriendRequestCommand, HangupCommand, MaskCommand, SkipCommand},
|
||||||
events::{CallMessageDeleteHandler, CallMessageEditHandler, CallMessageHandler},
|
events::{CallMessageDeleteHandler, CallMessageEditHandler, CallMessageHandler},
|
||||||
},
|
},
|
||||||
gateway::events::{ReadyHandler, ReconnectHandler},
|
gateway::events::{ReadyHandler, ReconnectHandler},
|
||||||
@@ -289,8 +289,9 @@ async fn start(
|
|||||||
.command(SkipCommand)
|
.command(SkipCommand)
|
||||||
.command(HangupCommand)
|
.command(HangupCommand)
|
||||||
.command(FriendRequestCommand)
|
.command(FriendRequestCommand)
|
||||||
.command(PrefixCommand)
|
.command(MaskCommand)
|
||||||
.command(LeaderboardCommand)
|
.command(LeaderboardCommand)
|
||||||
|
.command(PrefixCommand)
|
||||||
.command(ModeratorCommand)
|
.command(ModeratorCommand)
|
||||||
.command(IncidentsCommand)
|
.command(IncidentsCommand)
|
||||||
.command(StatsCommand)
|
.command(StatsCommand)
|
||||||
|
|||||||
Reference in New Issue
Block a user