diff --git a/cpp/include/loot/database_interface.h b/cpp/include/loot/database_interface.h index 05502b9f..3a8810ca 100644 --- a/cpp/include/loot/database_interface.h +++ b/cpp/include/loot/database_interface.h @@ -167,6 +167,10 @@ public: /** * @brief Get all general messages listed in the loaded metadata lists. + * @param includeUserMetadata + * If true, any general messages present in the userlist are included + * in the returned metadata, otherwise the metadata returned only + * includes metadata from the masterlist. * @param evaluateConditions * If true, any metadata conditions are evaluated before the metadata * is returned, otherwise unevaluated metadata is returned. Evaluating @@ -176,6 +180,7 @@ public: * to any particular plugin. */ virtual std::vector GetGeneralMessages( + bool includeUserMetadata = true, bool evaluateConditions = false) const = 0; /** diff --git a/cpp/src/api/database.cpp b/cpp/src/api/database.cpp index c930d2b7..34f379c1 100644 --- a/cpp/src/api/database.cpp +++ b/cpp/src/api/database.cpp @@ -87,9 +87,11 @@ void Database::SetUserKnownBashTags(const std::vector& bashTags) { } std::vector Database::GetGeneralMessages( + bool includeUserMetadata, bool evaluateConditions) const { try { - return convert(database_->general_messages(evaluateConditions)); + return convert( + database_->general_messages(includeUserMetadata, evaluateConditions)); } catch (const ::rust::Error& e) { std::rethrow_exception(mapError(e)); } diff --git a/cpp/src/api/database.h b/cpp/src/api/database.h index 37d3229c..9ca97f48 100644 --- a/cpp/src/api/database.h +++ b/cpp/src/api/database.h @@ -36,6 +36,7 @@ public: void SetUserKnownBashTags(const std::vector& bashTags) override; std::vector GetGeneralMessages( + bool includeUserMetadata = true, bool evaluateConditions = false) const override; std::vector GetUserGeneralMessages( diff --git a/cpp/src/database.rs b/cpp/src/database.rs index 3825048b..0bffed41 100644 --- a/cpp/src/database.rs +++ b/cpp/src/database.rs @@ -134,12 +134,16 @@ impl Database { pub fn general_messages( &self, + include_user_metadata: bool, evaluate_conditions: bool, ) -> Result, VerboseError> { self.0 .read() .map_err(DatabaseLockPoisonError::from)? - .general_messages(to_eval_mode(evaluate_conditions)) + .general_messages( + to_merge_mode(include_user_metadata), + to_eval_mode(evaluate_conditions), + ) .map(|v| v.into_iter().map(Into::into).collect()) .map_err(Into::into) } diff --git a/cpp/src/lib.rs b/cpp/src/lib.rs index 5baa8aa4..88859e66 100644 --- a/cpp/src/lib.rs +++ b/cpp/src/lib.rs @@ -274,7 +274,11 @@ mod ffi { pub fn set_user_known_bash_tags(&self, bash_tags: Vec) -> Result<()>; - pub fn general_messages(&self, evaluate_conditions: bool) -> Result>; + pub fn general_messages( + &self, + include_user_metadata: bool, + evaluate_conditions: bool, + ) -> Result>; pub fn user_general_messages(&self, evaluate_conditions: bool) -> Result>; diff --git a/cpp/src/tests/api/interface/database_interface_test.h b/cpp/src/tests/api/interface/database_interface_test.h index 95a14863..2cadb6ae 100644 --- a/cpp/src/tests/api/interface/database_interface_test.h +++ b/cpp/src/tests/api/interface/database_interface_test.h @@ -555,13 +555,31 @@ TEST_P(DatabaseInterfaceTest, EXPECT_EQ(expectedMessages, messages); } +TEST_P( + DatabaseInterfaceTest, + getGeneralMessagesShouldGetGeneralMessagesFromTheMasterlistOnlyWhenFirstParamIsFalse) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + ASSERT_NO_THROW(handle_->GetDatabase().LoadMasterlist(masterlistPath)); + ASSERT_NO_THROW(handle_->GetDatabase().LoadUserlist(userlistPath_)); + + auto messages = handle_->GetDatabase().GetGeneralMessages(false); + + std::vector expectedMessages({ + Message(MessageType::say, + generalMasterlistMessage, + "file(\"" + missingEsp + "\")"), + }); + EXPECT_EQ(expectedMessages, messages); +} + TEST_P( DatabaseInterfaceTest, getGeneralMessagesShouldReturnOnlyValidMessagesIfConditionsAreEvaluated) { ASSERT_NO_THROW(GenerateMasterlist()); ASSERT_NO_THROW(handle_->GetDatabase().LoadMasterlist(masterlistPath)); - auto messages = handle_->GetDatabase().GetGeneralMessages(true); + auto messages = handle_->GetDatabase().GetGeneralMessages(true, true); EXPECT_TRUE(messages.empty()); } diff --git a/nodejs/src/database.rs b/nodejs/src/database.rs index 2c43f7bc..f7993914 100644 --- a/nodejs/src/database.rs +++ b/nodejs/src/database.rs @@ -173,12 +173,13 @@ impl Database { #[napi] pub fn general_messages( &self, + include_user_metadata: MergeMode, evaluate_conditions: EvalMode, ) -> Result, VerboseError> { self.0 .read() .map_err(DatabaseLockPoisonError::from)? - .general_messages(evaluate_conditions.into()) + .general_messages(include_user_metadata.into(), evaluate_conditions.into()) .map(|v| v.into_iter().map(Into::into).collect()) .map_err(Into::into) } diff --git a/python/src/database.rs b/python/src/database.rs index 5e3ce5a3..41495635 100644 --- a/python/src/database.rs +++ b/python/src/database.rs @@ -138,12 +138,16 @@ impl Database { pub fn general_messages( &self, + include_user_metadata: bool, evaluate_conditions: bool, ) -> Result, VerboseError> { self.0 .read() .map_err(DatabaseLockPoisonError::from)? - .general_messages(to_eval_mode(evaluate_conditions)) + .general_messages( + to_merge_mode(include_user_metadata), + to_eval_mode(evaluate_conditions), + ) .map(|v| v.into_iter().map(Into::into).collect()) .map_err(Into::into) } diff --git a/src/database/mod.rs b/src/database/mod.rs index d7db1c1f..5641ffff 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -192,16 +192,24 @@ impl Database { /// Get all general messages listed in the loaded metadata lists. pub fn general_messages( &self, + include_user_metadata: MergeMode, evaluate_conditions: EvalMode, ) -> Result, ConditionEvaluationError> { - process_messages( - self.masterlist - .messages() - .iter() - .chain(self.userlist.messages()), - &self.condition_evaluator_state, - evaluate_conditions, - ) + let messages_iter = self.masterlist.messages().iter(); + + if include_user_metadata == MergeMode::WithUserMetadata { + process_messages( + messages_iter.chain(self.userlist.messages()), + &self.condition_evaluator_state, + evaluate_conditions, + ) + } else { + process_messages( + messages_iter, + &self.condition_evaluator_state, + evaluate_conditions, + ) + } } /// Get all general messages listed in the loaded userlist. @@ -1010,7 +1018,35 @@ plugins: use super::*; #[test] - fn should_append_userlist_messages_to_masterlist_messages() { + fn should_not_append_userlist_messages_to_masterlist_messages_if_merge_mode_is_without_user_metadata() + { + let fixture = Fixture::new(GameType::Oblivion); + let mut database = fixture.database(); + + database.load_masterlist(&fixture.metadata_path).unwrap(); + + let userlist_path = fixture.inner.local_path.join("userlist.yaml"); + std::fs::write( + &userlist_path, + "globals: [{type: say, content: 'A user message'}]", + ) + .unwrap(); + + database.load_userlist(&userlist_path).unwrap(); + + assert_eq!( + &[Message::new(MessageType::Say, "A general message".into()) + .with_condition("file(\"missing.esp\")".into()),], + database + .general_messages(MergeMode::WithoutUserMetadata, EvalMode::DoNotEvaluate) + .unwrap() + .as_slice() + ); + } + + #[test] + fn should_append_userlist_messages_to_masterlist_messages_if_merge_mode_is_with_user_metadata() + { let fixture = Fixture::new(GameType::Oblivion); let mut database = fixture.database(); @@ -1032,7 +1068,7 @@ plugins: Message::new(MessageType::Say, "A user message".into()) ], database - .general_messages(EvalMode::DoNotEvaluate) + .general_messages(MergeMode::WithUserMetadata, EvalMode::DoNotEvaluate) .unwrap() .as_slice() ); @@ -1057,7 +1093,7 @@ plugins: assert_eq!( &[Message::new(MessageType::Say, "A user message".into())], database - .general_messages(EvalMode::Evaluate) + .general_messages(MergeMode::WithUserMetadata, EvalMode::Evaluate) .unwrap() .as_slice() );