From 92814a41750f2b04940945f3fc2c462592e65169 Mon Sep 17 00:00:00 2001 From: Shagnor Date: Sat, 31 Dec 2022 19:33:31 +1100 Subject: [PATCH] Add player-to-player whispering. --- blastmud_game/src/db.rs | 24 +++++++++++++++---- .../message_handler/user_commands/whisper.rs | 21 ++++++++++++++++ blastmud_game/src/models/item.rs | 10 ++++---- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/blastmud_game/src/db.rs b/blastmud_game/src/db.rs index 0c81ad2..7e636a1 100644 --- a/blastmud_game/src/db.rs +++ b/blastmud_game/src/db.rs @@ -370,6 +370,21 @@ impl DBTrans { Ok(()) } + pub async fn find_session_for_player(self: &Self, item_code: &str) -> DResult> { + Ok(self.pg_trans()? + .query_opt("SELECT u.current_listener, u.current_session, s.details \ + FROM users u JOIN sessions s ON s.session = u.current_session \ + WHERE u.username=$1", &[&item_code]) + .await? + .and_then(|r| match (r.get("current_listener"), r.get("current_session"), + r.get("details")) { + (Some(listener), Some(session), details) => + Some((ListenerSession { listener, session }, + serde_json::from_value(details).ok()?)), + _ => None + })) + } + pub async fn resolve_items_by_display_name_for_player<'l>( self: &Self, search: &'l ItemSearchParams<'l> @@ -382,15 +397,16 @@ impl DBTrans { search.from_item.item_code); let (offset, query) = parse_offset(search.query); - let mut param_no: usize = 3; + let mut param_no: usize = 4; let query_wildcard = query.replace("\\", "\\\\") .replace("_", "\\_") .replace("%", "") .to_lowercase() + "%"; let offset_sql = offset.map(|x| (if x >= 1 { x - 1 } else { x}) as i64).unwrap_or(0); + let query_len = query.len() as i32; let mut params: Vec<&(dyn ToSql + Sync)> = vec!( &query_wildcard, - &offset_sql); + &offset_sql, &query_len); if search.include_contents { @@ -430,8 +446,8 @@ impl DBTrans { &format!( "WITH {} SELECT details FROM relevant_items WHERE (lower(details->>'display') LIKE $1) \ OR (lower(details ->>'display_less_explicit') LIKE $1) \ - ORDER BY length(details->>'display') DESC \ - LIMIT 2 OFFSET $2", &cte_str), + ORDER BY ABS(length(details->>'display')-$3) ASC \ + LIMIT 1 OFFSET $2", &cte_str), ¶ms ).await?.into_iter() .filter_map(|i| serde_json::from_value(i.get("details")).ok()) diff --git a/blastmud_game/src/message_handler/user_commands/whisper.rs b/blastmud_game/src/message_handler/user_commands/whisper.rs index c673cdd..ec6f775 100644 --- a/blastmud_game/src/message_handler/user_commands/whisper.rs +++ b/blastmud_game/src/message_handler/user_commands/whisper.rs @@ -35,6 +35,10 @@ impl UserVerb for Verb { say_what ))).await?; + if player_item == to_whom { + return Ok(()); + } + match to_whom.item_type.as_str() { "npc" => { let npc = npc_by_code().get(to_whom.item_code.as_str()) @@ -45,6 +49,23 @@ impl UserVerb for Verb { } } "player" => { + match ctx.trans.find_session_for_player(&to_whom.item_code).await? { + None => user_error("That character is asleep.".to_string())?, + Some((other_session, other_session_dets)) => { + if other_session_dets.less_explicit_mode && is_likely_explicit(&say_what) { + user_error("That player is on a client that doesn't allow explicit \ + content, and your message looked explicit, so it wasn't sent." + .to_owned())? + } else { + ctx.trans.queue_for_session(&other_session, Some(&format!( + ansi!("{} whispers to {}: \"{}\"\n"), + player_item.display_for_session(&ctx.session_dat), + to_whom.display_for_session(&ctx.session_dat), + say_what + ))).await?; + } + } + } }, _ => {} } diff --git a/blastmud_game/src/models/item.rs b/blastmud_game/src/models/item.rs index cad9c94..a5492cb 100644 --- a/blastmud_game/src/models/item.rs +++ b/blastmud_game/src/models/item.rs @@ -2,7 +2,7 @@ use serde::{Serialize, Deserialize}; use std::collections::BTreeMap; use super::{user::{SkillType, StatType}, session::Session}; -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub enum BuffCause { WaitingTask { task_code: String, task_type: String }, ByItem { item_code: String, item_type: String } @@ -14,7 +14,7 @@ pub enum BuffImpact { ChangeSkill { stat: StatType, magnitude: i16 } } -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub struct Buff { description: String, cause: BuffCause, @@ -90,7 +90,7 @@ pub enum Subattack { Wrestling } -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub enum LocationActionType { Normal, Sitting, @@ -100,13 +100,13 @@ pub enum LocationActionType { Attacking(Subattack), } -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub enum Sex { Male, Female, } -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub struct Item { pub item_code: String, pub item_type: String,