Support paging.

This commit is contained in:
Condorra 2023-02-26 17:01:05 +11:00
parent 863ba692f4
commit 369b07474a
5 changed files with 101 additions and 4 deletions

View File

@ -590,8 +590,10 @@ impl DBTrans {
} }
if search.include_active_players { if search.include_active_players {
ctes.push("active_players AS (\ ctes.push("active_players AS (\
SELECT details, ('[]'::JSONB) AS aliases FROM items WHERE details->>'item_type' = 'player' \ SELECT i.details, ('[]'::JSONB) AS aliases FROM items i \
AND current_session IS NOT NULL \ JOIN users u ON u.username = i.details->>'item_code' \
WHERE i.details->>'item_type' = 'player' \
AND u.current_session IS NOT NULL \
)".to_owned()); )".to_owned());
include_tables.push("SELECT details, aliases FROM active_players"); include_tables.push("SELECT details, aliases FROM active_players");
} }

View File

@ -26,6 +26,7 @@ mod login;
mod look; mod look;
mod map; mod map;
pub mod movement; pub mod movement;
mod page;
pub mod parsing; pub mod parsing;
mod quit; mod quit;
mod register; mod register;
@ -125,6 +126,13 @@ static REGISTERED_COMMANDS: UserVerbRegistry = phf_map! {
"list" => list::VERB, "list" => list::VERB,
"lmap" => map::VERB, "lmap" => map::VERB,
"p" => page::VERB,
"page" => page::VERB,
"pg" => page::VERB,
"rep" => page::VERB,
"repl" => page::VERB,
"reply" => page::VERB,
"\'" => say::VERB, "\'" => say::VERB,
"say" => say::VERB, "say" => say::VERB,

View File

@ -0,0 +1,82 @@
use super::{VerbContext, UserVerb, UserVerbRef, UResult,
ItemSearchParams, user_error,
get_player_item_or_fail, is_likely_explicit,
search_item_for_user,
parsing::parse_to_space};
use async_trait::async_trait;
use ansi::{ignore_special_characters, ansi};
pub struct Verb;
#[async_trait]
impl UserVerb for Verb {
async fn handle(self: &Self, ctx: &mut VerbContext, verb: &str, remaining: &str) -> UResult<()> {
let (to_whom_name, say_what_raw) = if verb.starts_with("r") {
let last_page_from = match ctx.user_dat.as_ref().and_then(|u| u.last_page_from.as_ref()) {
None => user_error("No one has paged you, so you can't reply.".to_owned())?,
Some(m) => (*m).clone()
};
(last_page_from, remaining)
} else {
let (to_whom, say_what) = parse_to_space(remaining);
(to_whom.to_owned(), say_what)
};
let say_what = ignore_special_characters(&say_what_raw);
if say_what == "" {
user_error("You need to provide a message to send.".to_owned())?;
}
let player_item = get_player_item_or_fail(ctx).await?;
if player_item.is_dead {
user_error("Shush, the dead can't talk!".to_string())?;
}
let to_whom = search_item_for_user(ctx, &ItemSearchParams {
include_active_players: true,
limit: 1,
..ItemSearchParams::base(&player_item, &to_whom_name)
}).await?;
match to_whom.item_type.as_str() {
"player" => {},
_ => user_error("Only players accept pages".to_string())?
}
ctx.trans.queue_for_session(ctx.session, Some(&format!(
ansi!("<blue>You page {} on your wristpad: \"{}\"<reset>\n"),
to_whom.display_for_session(&ctx.session_dat),
say_what
))).await?;
if player_item == to_whom {
return Ok(());
}
match to_whom.item_type.as_str() {
"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 {
if let Some(mut user) = ctx.trans.find_by_username(&to_whom.item_code).await? {
user.last_page_from = Some(player_item.item_code.clone());
ctx.trans.save_user_model(&user).await?;
}
ctx.trans.queue_for_session(&other_session, Some(&format!(
ansi!("<blue>Your wristpad beeps with page from {}: \"{}\"<reset>\n"),
player_item.display_for_session(&ctx.session_dat),
say_what
))).await?;
}
}
}
},
_ => {}
}
Ok(())
}
}
static VERB_INT: Verb = Verb;
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;

View File

@ -35,6 +35,7 @@ pub struct User {
pub raw_skills: BTreeMap<SkillType, f64>, pub raw_skills: BTreeMap<SkillType, f64>,
pub raw_stats: BTreeMap<StatType, f64>, pub raw_stats: BTreeMap<StatType, f64>,
pub last_skill_improve: BTreeMap<SkillType, DateTime<Utc>>, pub last_skill_improve: BTreeMap<SkillType, DateTime<Utc>>,
pub last_page_from: Option<String>,
pub credits: u64, pub credits: u64,
// Reminder: Consider backwards compatibility when updating this. // Reminder: Consider backwards compatibility when updating this.
} }
@ -77,6 +78,7 @@ impl Default for User {
raw_skills: BTreeMap::new(), raw_skills: BTreeMap::new(),
raw_stats: BTreeMap::new(), raw_stats: BTreeMap::new(),
last_skill_improve: BTreeMap::new(), last_skill_improve: BTreeMap::new(),
last_page_from: None,
credits: 500 credits: 500
} }
} }

View File

@ -10,7 +10,8 @@ pub struct FixedItem {
pub description: &'static str, pub description: &'static str,
pub description_less_explicit: Option<&'static str>, pub description_less_explicit: Option<&'static str>,
pub location: &'static str, pub location: &'static str,
pub proper_noun: bool pub proper_noun: bool,
pub aliases: Vec<&'static str>
} }
fn fixed_item_list() -> &'static Vec<FixedItem> { fn fixed_item_list() -> &'static Vec<FixedItem> {
@ -34,7 +35,8 @@ fn fixed_item_list() -> &'static Vec<FixedItem> {
further out, outside my realm, is a dangerous and radioactive place.\"", further out, outside my realm, is a dangerous and radioactive place.\"",
description_less_explicit: None, description_less_explicit: None,
location: "room/repro_xv_updates", location: "room/repro_xv_updates",
proper_noun: false proper_noun: false,
aliases: vec!("poster")
} }
)) ))
} }
@ -50,6 +52,7 @@ pub fn static_items() -> Box<dyn Iterator<Item = StaticItem>> {
details_less_explicit: r.description_less_explicit.map(|d|d.to_owned()), details_less_explicit: r.description_less_explicit.map(|d|d.to_owned()),
location: r.location.to_owned(), location: r.location.to_owned(),
is_static: true, is_static: true,
aliases: r.aliases.iter().map(|s| (*s).to_owned()).collect(),
pronouns: Pronouns { pronouns: Pronouns {
is_proper: r.proper_noun, is_proper: r.proper_noun,
..Pronouns::default_inanimate() ..Pronouns::default_inanimate()