Add hidden feature to not send messages when they're preceeded by an X

This commit is contained in:
2025-08-24 03:51:08 -03:00
parent bd09a55a74
commit 497d180669
4 changed files with 37 additions and 10 deletions
@@ -0,0 +1 @@
ALTER TABLE payphone.users ADD findings SET<TEXT>;
+13 -4
View File
@@ -1,3 +1,5 @@
use std::collections::HashSet;
use scylla::{ use scylla::{
DeserializeValue, SerializeValue, DeserializeValue, SerializeValue,
client::session::Session, client::session::Session,
@@ -102,6 +104,7 @@ pub struct User {
pub supporter_since: Option<UtcDateTime>, pub supporter_since: Option<UtcDateTime>,
pub supporter_until: Option<UtcDateTime>, pub supporter_until: Option<UtcDateTime>,
pub is_banned_from_leaderboard: Option<bool>, pub is_banned_from_leaderboard: Option<bool>,
pub findings: HashSet<String>,
} }
impl<'a> Object<'a> for User { impl<'a> Object<'a> for User {
@@ -116,6 +119,7 @@ impl<'a> Object<'a> for User {
Option<OffsetDateTime>, Option<OffsetDateTime>,
Option<OffsetDateTime>, Option<OffsetDateTime>,
Option<bool>, Option<bool>,
HashSet<String>,
); );
fn from_row(row: Self::Row) -> Self { fn from_row(row: Self::Row) -> Self {
@@ -130,6 +134,7 @@ impl<'a> Object<'a> for User {
supporter_since: row.7.map(|i| i.into()), supporter_since: row.7.map(|i| i.into()),
supporter_until: row.8.map(|i| i.into()), supporter_until: row.8.map(|i| i.into()),
is_banned_from_leaderboard: row.9, is_banned_from_leaderboard: row.9,
findings: row.10,
} }
} }
@@ -145,6 +150,7 @@ impl<'a> Object<'a> for User {
value.supporter_since.map(|i| i.into()), value.supporter_since.map(|i| i.into()),
value.supporter_until.map(|i| i.into()), value.supporter_until.map(|i| i.into()),
Some(value.is_banned_from_leaderboard.unwrap_or(false)), Some(value.is_banned_from_leaderboard.unwrap_or(false)),
value.findings,
) )
} }
} }
@@ -171,7 +177,8 @@ impl User {
last_seen_at, last_seen_at,
supporter_since, supporter_since,
supporter_until, supporter_until,
is_banned_from_leaderboard is_banned_from_leaderboard,
findings
FROM FROM
payphone.users payphone.users
WHERE WHERE
@@ -208,7 +215,7 @@ impl User {
/// Returns: /// Returns:
/// [`Result<User, DatabaseError>`] - The user from the database or a new user created from /// [`Result<User, DatabaseError>`] - The user from the database or a new user created from
/// Discord. /// Discord.
pub async fn get_or_create_and_set_last_seen( pub async fn create_or_update(
user: TwilightUser, user: TwilightUser,
session: &Session, session: &Session,
) -> Result<Self, DatabaseError> { ) -> Result<Self, DatabaseError> {
@@ -241,8 +248,9 @@ impl User {
last_seen_at, last_seen_at,
supporter_since, supporter_since,
supporter_until, supporter_until,
is_banned_from_leaderboard is_banned_from_leaderboard,
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?); findings
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
"#, "#,
Self::to_row(self.clone()), Self::to_row(self.clone()),
) )
@@ -329,6 +337,7 @@ impl From<TwilightUser> for User {
supporter_since: None, supporter_since: None,
supporter_until: None, supporter_until: None,
is_banned_from_leaderboard: None, is_banned_from_leaderboard: None,
findings: HashSet::new(),
} }
} }
} }
+22 -5
View File
@@ -160,8 +160,7 @@ impl OnMessageHandler<State, Extras> for CallMessageHandler {
return Ok(()); return Ok(());
}; };
let user = let mut user = User::create_or_update(event.author.clone(), &rt.state.db).await?;
User::get_or_create_and_set_last_seen(event.author.clone(), &rt.state.db).await?;
let user_incidents = UserIncident::get_for_user(event.author.id.get(), &rt.state.db) let user_incidents = UserIncident::get_for_user(event.author.id.get(), &rt.state.db)
.await? .await?
@@ -173,6 +172,26 @@ impl OnMessageHandler<State, Extras> for CallMessageHandler {
return Ok(()); return Ok(());
} }
if event.content.to_ascii_lowercase().starts_with("x ") {
if !user.findings.contains("feature:hide-message") {
user.findings.insert("feature:hide-message".into());
user.insert(&rt.state.db).await?;
rt
.http
.create_message(
event.channel_id
)
.content(
"✨ You found a hidden feature! Messages starting with `x` followed by a space will not be sent to the other party (nor moderated, i.e. you won't get banned for what you say in them)."
)
.reply(event.id)
.await?;
}
return Ok(());
}
let Some(mut opposite_channel) = Channel::get_by_id( let Some(mut opposite_channel) = Channel::get_by_id(
call.other_party_channel_id(event.channel_id.get()), call.other_party_channel_id(event.channel_id.get()),
&rt.state.db, &rt.state.db,
@@ -462,9 +481,7 @@ impl OnMessageEditHandler<State, Extras> for CallMessageEditHandler {
.reply(event.id) .reply(event.id)
.await?; .await?;
let user = let user = User::create_or_update(event.author.clone(), &rt.state.db).await?;
User::get_or_create_and_set_last_seen(event.author.clone(), &rt.state.db)
.await?;
penalize_user(user, message, rules, &rt).await?; penalize_user(user, message, rules, &rt).await?;
+1 -1
View File
@@ -241,7 +241,7 @@ impl ExtrasGetter<State> for PayphoneExtrasGetter {
) -> Result<Self::Extras, Box<dyn Error>> { ) -> Result<Self::Extras, Box<dyn Error>> {
log::trace!("Getting extras!"); log::trace!("Getting extras!");
let user = User::get_or_create_and_set_last_seen(user.clone(), &rt.state.db).await?; let user = User::create_or_update(user.clone(), &rt.state.db).await?;
Ok(Extras { user }) Ok(Extras { user })
} }