Add player-to-player whispering.

This commit is contained in:
Condorra 2022-12-31 19:33:31 +11:00
parent d15558a728
commit 92814a4175
3 changed files with 46 additions and 9 deletions

View File

@ -370,6 +370,21 @@ impl DBTrans {
Ok(()) Ok(())
} }
pub async fn find_session_for_player(self: &Self, item_code: &str) -> DResult<Option<(ListenerSession, Session)>> {
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>( pub async fn resolve_items_by_display_name_for_player<'l>(
self: &Self, self: &Self,
search: &'l ItemSearchParams<'l> search: &'l ItemSearchParams<'l>
@ -382,15 +397,16 @@ impl DBTrans {
search.from_item.item_code); search.from_item.item_code);
let (offset, query) = parse_offset(search.query); let (offset, query) = parse_offset(search.query);
let mut param_no: usize = 3; let mut param_no: usize = 4;
let query_wildcard = query.replace("\\", "\\\\") let query_wildcard = query.replace("\\", "\\\\")
.replace("_", "\\_") .replace("_", "\\_")
.replace("%", "") .replace("%", "")
.to_lowercase() + "%"; .to_lowercase() + "%";
let offset_sql = offset.map(|x| (if x >= 1 { x - 1 } else { x}) as i64).unwrap_or(0); 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!( let mut params: Vec<&(dyn ToSql + Sync)> = vec!(
&query_wildcard, &query_wildcard,
&offset_sql); &offset_sql, &query_len);
if search.include_contents { if search.include_contents {
@ -430,8 +446,8 @@ impl DBTrans {
&format!( &format!(
"WITH {} SELECT details FROM relevant_items WHERE (lower(details->>'display') LIKE $1) \ "WITH {} SELECT details FROM relevant_items WHERE (lower(details->>'display') LIKE $1) \
OR (lower(details ->>'display_less_explicit') LIKE $1) \ OR (lower(details ->>'display_less_explicit') LIKE $1) \
ORDER BY length(details->>'display') DESC \ ORDER BY ABS(length(details->>'display')-$3) ASC \
LIMIT 2 OFFSET $2", &cte_str), LIMIT 1 OFFSET $2", &cte_str),
&params &params
).await?.into_iter() ).await?.into_iter()
.filter_map(|i| serde_json::from_value(i.get("details")).ok()) .filter_map(|i| serde_json::from_value(i.get("details")).ok())

View File

@ -35,6 +35,10 @@ impl UserVerb for Verb {
say_what say_what
))).await?; ))).await?;
if player_item == to_whom {
return Ok(());
}
match to_whom.item_type.as_str() { match to_whom.item_type.as_str() {
"npc" => { "npc" => {
let npc = npc_by_code().get(to_whom.item_code.as_str()) let npc = npc_by_code().get(to_whom.item_code.as_str())
@ -45,6 +49,23 @@ impl UserVerb for Verb {
} }
} }
"player" => { "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!("<blue>{} whispers to {}: \"{}\"<reset>\n"),
player_item.display_for_session(&ctx.session_dat),
to_whom.display_for_session(&ctx.session_dat),
say_what
))).await?;
}
}
}
}, },
_ => {} _ => {}
} }

View File

@ -2,7 +2,7 @@ use serde::{Serialize, Deserialize};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use super::{user::{SkillType, StatType}, session::Session}; use super::{user::{SkillType, StatType}, session::Session};
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum BuffCause { pub enum BuffCause {
WaitingTask { task_code: String, task_type: String }, WaitingTask { task_code: String, task_type: String },
ByItem { item_code: String, item_type: String } ByItem { item_code: String, item_type: String }
@ -14,7 +14,7 @@ pub enum BuffImpact {
ChangeSkill { stat: StatType, magnitude: i16 } ChangeSkill { stat: StatType, magnitude: i16 }
} }
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct Buff { pub struct Buff {
description: String, description: String,
cause: BuffCause, cause: BuffCause,
@ -90,7 +90,7 @@ pub enum Subattack {
Wrestling Wrestling
} }
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum LocationActionType { pub enum LocationActionType {
Normal, Normal,
Sitting, Sitting,
@ -100,13 +100,13 @@ pub enum LocationActionType {
Attacking(Subattack), Attacking(Subattack),
} }
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum Sex { pub enum Sex {
Male, Male,
Female, Female,
} }
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct Item { pub struct Item {
pub item_code: String, pub item_code: String,
pub item_type: String, pub item_type: String,