use crate::{ DResult, models::item::Item, models::consent::{Consent, ConsentType, ConsentStatus}, static_content::npc::npc_by_code, }; use mockall_double::double; #[double] use crate::db::DBTrans; pub mod skills; pub mod combat; pub mod capacity; pub mod effect; pub async fn broadcast_to_room(trans: &DBTrans, location: &str, from_item: Option<&Item>, message_explicit_ok: &str, message_nonexplicit: Option<&str>) -> DResult<()> { for item in trans.find_items_by_location(location).await? { if item.item_type != "player" || item.is_dead { continue; } if let Some((session, session_dat)) = trans.find_session_for_player(&item.item_code).await? { if session_dat.less_explicit_mode && Some(&item.item_code) != from_item.map(|i| &i.item_code) { if let Some(msg) = message_nonexplicit { trans.queue_for_session(&session, Some(msg)).await?; } return Ok(()); } trans.queue_for_session(&session, Some(message_explicit_ok)).await?; } } Ok(()) } fn check_one_consent(consent: &Consent, action: &str, target: &Item) -> bool { if let Some((loctype, loccode)) = target.location.split_once("/") { if !consent.only_in.is_empty() { if loctype != "room" || !consent.only_in.iter().any(|v| v == loccode) { return false; } } if !consent.allow_private && loctype != "room" { return false; } } else { if !consent.only_in.is_empty() || !consent.allow_private { return false; } } if let Some(fight_consent) = consent.fight_consent.as_ref() { if fight_consent.status == ConsentStatus::PendingAdd { return false; } if !fight_consent.allow_pick && action == "pick" { return false; } } true } pub async fn check_consent(trans: &DBTrans, action: &str, consent_type: &ConsentType, by: &Item, target: &Item) -> DResult { // Consent is only a factor on actions by players towards other players or npcs. if by.item_type != "player" || (target.item_type != "player" && target.item_type != "npc") { return Ok(true); } if target.item_type == "npc" { return Ok(match npc_by_code().get(target.item_code.as_str()) { None => false, Some(npc) => npc.player_consents.contains(consent_type) }); } if target.item_code == by.item_code { return Ok(true) } trans.delete_expired_user_consent().await?; if let Some(consent) = trans.find_user_consent_by_parties_type( &target.item_code, &by.item_code, consent_type).await? { if check_one_consent(&consent, action, &target) { return Ok(true); } } Ok(false) }