diff --git a/blastmud_game/src/db.rs b/blastmud_game/src/db.rs index 05025dc..c84a251 100644 --- a/blastmud_game/src/db.rs +++ b/blastmud_game/src/db.rs @@ -286,7 +286,7 @@ impl DBTrans { // be reset on restart. for to_copy in ["display", "display_less_explicit", "details", "details_less_explicit", "total_xp", "total_stats", "total_skills", "pronouns", "flags", - "sex", "is_challenge_attack_only"] { + "sex", "is_challenge_attack_only", "aliases"] { det_ex = format!("jsonb_set({}, '{{{}}}', ${})", det_ex, to_copy, var_id); params.push(obj_map.get(to_copy).unwrap_or(&Value::Null)); var_id += 1; @@ -467,46 +467,47 @@ impl DBTrans { search.from_item.item_code); let (offset, query) = parse_offset(search.query); - let mut param_no: usize = 4; + let mut param_no: usize = 5; 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_json = serde_json::to_value(query.to_lowercase())?; let query_len = query.len() as i32; let mut params: Vec<&(dyn ToSql + Sync)> = vec!( &query_wildcard, - &offset_sql, &query_len); + &offset_sql, &query_len, &query_json); if search.include_contents { ctes.push(format!("contents AS (\ - SELECT details FROM items WHERE details->>'location' = ${}\ + SELECT details, details->'aliases' AS aliases FROM items WHERE details->>'location' = ${}\ )", param_no)); param_no += 1; params.push(&player_desig); - include_tables.push("SELECT details FROM contents"); + include_tables.push("SELECT details, aliases FROM contents"); } if search.include_loc_contents { ctes.push(format!("loc_contents AS (\ - SELECT details FROM items WHERE details->>'location' = ${}\ + SELECT details, details->'aliases' AS aliases FROM items WHERE details->>'location' = ${}\ )", param_no)); drop(param_no); // or increment if this is a problem. params.push(&player_loc); - include_tables.push("SELECT details FROM loc_contents"); + include_tables.push("SELECT details, aliases FROM loc_contents"); } if search.include_active_players { ctes.push("active_players AS (\ - SELECT details FROM items WHERE details->>'item_type' = 'player' \ + SELECT details, ('[]'::JSONB) AS aliases FROM items WHERE details->>'item_type' = 'player' \ AND current_session IS NOT NULL \ )".to_owned()); - include_tables.push("SELECT details FROM active_players"); + include_tables.push("SELECT details, aliases FROM active_players"); } if search.include_all_players { ctes.push("all_players AS (\ - SELECT details FROM items WHERE details->>'item_type' = 'player' + SELECT details, ('[]'::JSONB) AS aliases FROM items WHERE details->>'item_type' = 'player' )".to_owned()); - include_tables.push("SELECT details FROM all_players"); + include_tables.push("SELECT details, aliases FROM all_players"); } ctes.push(format!("relevant_items AS ({})", include_tables.join(" UNION "))); @@ -514,8 +515,9 @@ impl DBTrans { Ok(Arc::new(self.pg_trans()?.query( &format!( - "WITH {} SELECT details FROM relevant_items WHERE (lower(details->>'display') LIKE $1) \ + "WITH {} SELECT details, aliases FROM relevant_items WHERE (lower(details->>'display') LIKE $1) \ OR (lower(details ->>'display_less_explicit') LIKE $1) \ + OR aliases @> $4 \ ORDER BY ABS(length(details->>'display')-$3) ASC \ LIMIT 1 OFFSET $2", &cte_str), ¶ms diff --git a/blastmud_game/src/models/item.rs b/blastmud_game/src/models/item.rs index 9dbf2a7..0a62efb 100644 --- a/blastmud_game/src/models/item.rs +++ b/blastmud_game/src/models/item.rs @@ -279,6 +279,7 @@ pub struct Item { pub display_less_explicit: Option, pub details: Option, pub details_less_explicit: Option, + pub aliases: Vec, pub location: String, // Item reference as item_type/item_code. pub action_type: LocationActionType, pub presence_target: Option, // e.g. what are they sitting on. @@ -350,6 +351,7 @@ impl Default for Item { display_less_explicit: None, details: None, details_less_explicit: None, + aliases: vec!(), location: "room/storage".to_owned(), action_type: LocationActionType::Normal, presence_target: None, diff --git a/blastmud_game/src/static_content/npc.rs b/blastmud_game/src/static_content/npc.rs index d3c750f..4dd6532 100644 --- a/blastmud_game/src/static_content/npc.rs +++ b/blastmud_game/src/static_content/npc.rs @@ -52,6 +52,7 @@ pub struct NPC { pub description: &'static str, pub spawn_location: &'static str, pub message_handler: Option<&'static (dyn NPCMessageHandler + Sync + Send)>, + pub aliases: Vec<&'static str>, pub says: Vec, pub attackable: bool } @@ -65,6 +66,7 @@ impl Default for NPC { description: "default", spawn_location: "default", message_handler: None, + aliases: vec!(), says: vec!(), attackable: false } @@ -124,6 +126,7 @@ pub fn npc_static_items() -> Box> { is_static: true, pronouns: c.pronouns.clone(), is_challenge_attack_only: !c.attackable, + aliases: c.aliases.iter().map(|a| (*a).to_owned()).collect::>(), ..Item::default() }) })) diff --git a/blastmud_game/src/static_content/npc/melbs_dog.rs b/blastmud_game/src/static_content/npc/melbs_dog.rs index dd1eb33..8da7630 100644 --- a/blastmud_game/src/static_content/npc/melbs_dog.rs +++ b/blastmud_game/src/static_content/npc/melbs_dog.rs @@ -9,6 +9,7 @@ macro_rules! dog { pronouns: Pronouns { is_proper: false, ..Pronouns::default_inanimate() }, attackable: true, description: "A malnourished looking dog. Its skeleton is visible through its thin and patchy fur. It smells terrible, and certainly doesn't look tame.", + aliases: vec!("dog"), spawn_location: concat!("room/", $spawn), ..Default::default() }