From c6cdaf705d0fa69e1811c28552dcbf2acef048bf Mon Sep 17 00:00:00 2001 From: Ansariel Date: Thu, 11 Dec 2025 14:59:52 +0100 Subject: [PATCH] Improvements to omnifilter --- indra/newview/llimprocessing.cpp | 34 +- indra/newview/llscriptfloater.cpp | 110 +-- indra/newview/llviewermessage.cpp | 46 +- indra/newview/omnifilter.cpp | 18 +- indra/newview/omnifilter.h | 63 +- indra/newview/omnifilterengine.cpp | 41 +- indra/newview/omnifilterengine.h | 6 +- .../default/xui/de/floater_omnifilter.xml | 3 + .../newview/skins/default/xui/de/strings.xml | 3 - .../default/xui/en/floater_omnifilter.xml | 704 ++++++++++++++---- .../newview/skins/default/xui/en/strings.xml | 2 - .../default/xui/pl/floater_omnifilter.xml | 3 + .../newview/skins/default/xui/pl/strings.xml | 3 - 13 files changed, 723 insertions(+), 313 deletions(-) diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 21d0da1e93..9746178a62 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -723,13 +723,16 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, */ // Omnifilter support - OmnifilterEngine::Haystack haystack; - haystack.mContent = message; - haystack.mSenderName = agentName; - haystack.mOwnerID = from_id; - - switch (dialog) + static LLCachedControl use_omnifilter(gSavedSettings, "OmnifilterEnabled"); + if (use_omnifilter) { + OmnifilterEngine::Haystack haystack; + haystack.mContent = message; + haystack.mSenderName = agentName; + haystack.mOwnerID = from_id; + + switch (dialog) + { case IM_NOTHING_SPECIAL: // this is the type for regular IMs { haystack.mType = OmnifilterEngine::eType::InstantMessage; @@ -802,17 +805,18 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, LL_DEBUGS("Omnifilter") << "unhandled IM type " << (U32)dialog << LL_ENDL; break; } - } - - const OmnifilterEngine::Needle* needle = OmnifilterEngine::getInstance()->match(haystack); - if (needle) - { - if (needle->mChatReplace.empty()) - { - return; } - message = needle->mChatReplace; + const OmnifilterEngine::Needle* needle = OmnifilterEngine::getInstance()->match(haystack); + if (needle) + { + if (needle->mChatReplace.empty()) + { + return; + } + + message = needle->mChatReplace; + } } // diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp index 679c068575..4bacd49811 100644 --- a/indra/newview/llscriptfloater.cpp +++ b/indra/newview/llscriptfloater.cpp @@ -475,70 +475,74 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id) LLUUID object_id = notification_id_to_object_id(notification_id); // Omnifilter support - LLNotificationPtr notification = LLNotifications::instance().find(notification_id); - - OmnifilterEngine::Haystack haystack; - haystack.mContent = notification->getMessage(); - - if(notification->getName() == "ScriptDialog") // ScriptDialogGroup seems not to be in use anymore? + static LLCachedControl use_omnifilter(gSavedSettings, "OmnifilterEnabled"); + if (use_omnifilter) { - haystack.mType = OmnifilterEngine::eType::ScriptDialog; - haystack.mSenderName = notification->getPayload()["object_name"].asString(); - haystack.mOwnerID = notification->getPayload()["owner_id"]; - } - else if(notification->getName() == "ObjectGiveItem") // what about OwnObjectGiveItem? - { - // "description":"\'Object Name\' ( http://slurl.com/secondlife/Region%20Name/x/y/z )" - std::vector params; - std::string description = notification->asLLSD()["responder_sd"]["description"].asString(); - if (!description.empty()) + LLNotificationPtr notification = LLNotifications::instance().find(notification_id); + + OmnifilterEngine::Haystack haystack; + haystack.mContent = notification->getMessage(); + + if (notification->getName() == "ScriptDialog") // ScriptDialogGroup seems not to be in use anymore? { - LLStringUtil::getTokens(description, params, "/"); - haystack.mRegionName = LLURI::unescape(params.at(params.size() - 4)); + haystack.mType = OmnifilterEngine::eType::ScriptDialog; + haystack.mSenderName = notification->getPayload()["object_name"].asString(); + haystack.mOwnerID = notification->getPayload()["owner_id"]; } - - haystack.mType = OmnifilterEngine::eType::URLRequest; - haystack.mSenderName = notification->asLLSD()["responder_sd"]["from_name"].asString(); - haystack.mOwnerID = notification->getPayload()["from_id"]; - } - else if(notification->getName() == "LoadWebPage") - { - haystack.mType = OmnifilterEngine::eType::ScriptDialog; - haystack.mSenderName = notification->getPayload()["object_name"].asString(); - haystack.mOwnerID = notification->getPayload()["owner_id"]; - } - else - { - LL_WARNS("Omnifilter") << "unknown notification name: " << notification->getName() << LL_ENDL; - } - - const OmnifilterEngine::Needle* needle = OmnifilterEngine::getInstance()->match(haystack); - if(needle) - { - LLSD response = notification->getResponseTemplate(); - - if(response.has(TEXTBOX_MAGIC_TOKEN)) + else if (notification->getName() == "ObjectGiveItem") // what about OwnObjectGiveItem? { - response[TEXTBOX_MAGIC_TOKEN] = needle->mTextBoxReply; - if (response[TEXTBOX_MAGIC_TOKEN].asString().empty()) + // "description":"\'Object Name\' ( http://slurl.com/secondlife/Region%20Name/x/y/z )" + std::vector params; + std::string description = notification->asLLSD()["responder_sd"]["description"].asString(); + if (!description.empty()) { - // so we can distinguish between a successfully - // submitted blank textbox, and an ignored toast - response[TEXTBOX_MAGIC_TOKEN] = true; + LLStringUtil::getTokens(description, params, "/"); + haystack.mRegionName = LLURI::unescape(params.at(params.size() - 4)); } + + haystack.mType = OmnifilterEngine::eType::URLRequest; + haystack.mSenderName = notification->asLLSD()["responder_sd"]["from_name"].asString(); + haystack.mOwnerID = notification->getPayload()["from_id"]; + } + else if (notification->getName() == "LoadWebPage") + { + haystack.mType = OmnifilterEngine::eType::ScriptDialog; + haystack.mSenderName = notification->getPayload()["object_name"].asString(); + haystack.mOwnerID = notification->getPayload()["owner_id"]; } else { - if (!needle->mButtonReply.empty()) - { - response[needle->mButtonReply] = true; - } + LL_WARNS("Omnifilter") << "unknown notification name: " << notification->getName() << LL_ENDL; } - // this will result in DialogStack complaining that there is no matching dialog to remove - // but that should not break anything - notification->respond(response); - return; + const OmnifilterEngine::Needle* needle = OmnifilterEngine::getInstance()->match(haystack); + if (needle) + { + LLSD response = notification->getResponseTemplate(); + + if (response.has(TEXTBOX_MAGIC_TOKEN)) + { + response[TEXTBOX_MAGIC_TOKEN] = needle->mTextBoxReply; + if (response[TEXTBOX_MAGIC_TOKEN].asString().empty()) + { + // so we can distinguish between a successfully + // submitted blank textbox, and an ignored toast + response[TEXTBOX_MAGIC_TOKEN] = true; + } + } + else + { + if (!needle->mButtonReply.empty()) + { + response[needle->mButtonReply] = true; + } + } + + // this will result in DialogStack complaining that there is no matching dialog to remove + // but that should not break anything + notification->respond(response); + return; + } } // diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index fef4b2582c..83631e77d1 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3253,13 +3253,16 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) } // Omnifilter support - OmnifilterEngine::Haystack haystack; - haystack.mContent = chat.mText; - haystack.mSenderName = from_name; // we don't use chat.mFromName here because that will include display names etc. - haystack.mOwnerID = chat.mFromID; - - switch (chat.mChatType) + static LLCachedControl use_omnifilter(gSavedSettings, "OmnifilterEnabled"); + if (use_omnifilter) { + OmnifilterEngine::Haystack haystack; + haystack.mContent = chat.mText; + haystack.mSenderName = from_name; // we don't use chat.mFromName here because that will include display names etc. + haystack.mOwnerID = chat.mFromID; + + switch (chat.mChatType) + { case CHAT_TYPE_WHISPER: case CHAT_TYPE_NORMAL: case CHAT_TYPE_SHOUT: @@ -3270,21 +3273,21 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) { switch (chat.mSourceType) { - case CHAT_SOURCE_AGENT: // this is the type for regular chat - { - haystack.mType = OmnifilterEngine::eType::NearbyChat; - break; - } - case CHAT_SOURCE_OBJECT: // this is the type for object chat - { - haystack.mType = OmnifilterEngine::eType::ObjectChat; - break; - } - default: - { - LL_DEBUGS("Omnifilter") << "unhandled source type " << (U32)chat.mSourceType << LL_ENDL; - break; - } + case CHAT_SOURCE_AGENT: // this is the type for regular chat + { + haystack.mType = OmnifilterEngine::eType::NearbyChat; + break; + } + case CHAT_SOURCE_OBJECT: // this is the type for object chat + { + haystack.mType = OmnifilterEngine::eType::ObjectChat; + break; + } + default: + { + LL_DEBUGS("Omnifilter") << "unhandled source type " << (U32)chat.mSourceType << LL_ENDL; + break; + } } const OmnifilterEngine::Needle* needle = OmnifilterEngine::getInstance()->match(haystack); @@ -3312,6 +3315,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) LL_DEBUGS("Omnifilter") << "unhandled chat type " << (U32)chat.mChatType << LL_ENDL; break; } + } } // diff --git a/indra/newview/omnifilter.cpp b/indra/newview/omnifilter.cpp index fac9b27b58..2ba9edda5b 100644 --- a/indra/newview/omnifilter.cpp +++ b/indra/newview/omnifilter.cpp @@ -29,7 +29,6 @@ #include "llcombobox.h" #include "lllineeditor.h" #include "lltexteditor.h" -#include "lltrans.h" #include "fsscrolllistctrl.h" @@ -44,10 +43,6 @@ Omnifilter::Omnifilter(const LLSD& key) : { } -Omnifilter::~Omnifilter() -{ -} - LLScrollListItem* Omnifilter::addNeedle(const std::string& needle_name, const OmnifilterEngine::Needle& needle) { LLSD row; @@ -194,7 +189,7 @@ void Omnifilter::onNeedleChanged() void Omnifilter::onAddNeedleClicked() { - std::string new_needle_string = LLTrans::getString("OmnifilterNewNeedle"); + std::string new_needle_string = getString("OmnifilterNewNeedle"); if (!mNeedleListCtrl->selectItemByLabel(new_needle_string, true, NEEDLE_NAME_COLUMN)) { OmnifilterEngine::Needle& new_needle = OmnifilterEngine::getInstance()->newNeedle(new_needle_string); @@ -336,19 +331,18 @@ bool Omnifilter::postBuild() mFilterLogCtrl->deleteAllItems(); - for (auto const& needle_entry : OmnifilterEngine::getInstance()->getNeedleList()) + auto& instance = OmnifilterEngine::instance(); + for (const auto& [needle_name, needle] : instance.getNeedleList()) { - const std::string& needle_name = needle_entry.first; - const OmnifilterEngine::Needle& needle = needle_entry.second; addNeedle(needle_name, needle); } - for (auto logLine : OmnifilterEngine::getInstance()->mLog) + for (const auto& [log_time, log_message] : instance.mLog) { - onLogLine(logLine.first, logLine.second); + onLogLine(log_time, log_message); } - OmnifilterEngine::getInstance()->mLogSignal.connect(boost::bind(&Omnifilter::onLogLine, this, _1, _2)); + instance.mLogSignal.connect(boost::bind(&Omnifilter::onLogLine, this, _1, _2)); if (mNeedleListCtrl->getItemCount()) { diff --git a/indra/newview/omnifilter.h b/indra/newview/omnifilter.h index a012b92b9d..a5b29f1eb0 100644 --- a/indra/newview/omnifilter.h +++ b/indra/newview/omnifilter.h @@ -44,7 +44,6 @@ class Omnifilter private: Omnifilter(const LLSD& key); - ~Omnifilter(); public: bool postBuild() override final; @@ -62,38 +61,38 @@ class Omnifilter void onLogLine(time_t time, const std::string& logLine); - FSScrollListCtrl* mNeedleListCtrl; - LLButton* mAddNeedleBtn; - LLButton* mRemoveNeedleBtn; - FSScrollListCtrl* mFilterLogCtrl; - LLPanel* mPanelDetails; - LLLineEditor* mNeedleNameCtrl; - LLLineEditor* mSenderNameCtrl; - LLCheckBoxCtrl* mSenderCaseSensitiveCheck; - LLComboBox* mSenderMatchTypeCombo; - LLTextEditor* mContentCtrl; - LLCheckBoxCtrl* mContentCaseSensitiveCheck; - LLComboBox* mContentMatchTypeCombo; - LLLineEditor* mRegionNameCtrl; - LLLineEditor* mOwnerCtrl; + FSScrollListCtrl* mNeedleListCtrl{ nullptr }; + LLButton* mAddNeedleBtn{ nullptr }; + LLButton* mRemoveNeedleBtn{ nullptr }; + FSScrollListCtrl* mFilterLogCtrl{ nullptr }; + LLPanel* mPanelDetails{ nullptr }; + LLLineEditor* mNeedleNameCtrl{ nullptr }; + LLLineEditor* mSenderNameCtrl{ nullptr }; + LLCheckBoxCtrl* mSenderCaseSensitiveCheck{ nullptr }; + LLComboBox* mSenderMatchTypeCombo{ nullptr }; + LLTextEditor* mContentCtrl{ nullptr }; + LLCheckBoxCtrl* mContentCaseSensitiveCheck{ nullptr }; + LLComboBox* mContentMatchTypeCombo{ nullptr }; + LLLineEditor* mRegionNameCtrl{ nullptr }; + LLLineEditor* mOwnerCtrl{ nullptr }; - LLButton* mTypeNearbyBtn; - LLButton* mTypeIMBtn; - LLButton* mTypeGroupIMBtn; - LLButton* mTypeObjectChatBtn; - LLButton* mTypeObjectIMBtn; - LLButton* mTypeScriptErrorBtn; - LLButton* mTypeDialogBtn; - LLButton* mTypeOfferBtn; - LLButton* mTypeInviteBtn; - LLButton* mTypeLureBtn; - LLButton* mTypeLoadURLBtn; - LLButton* mTypeFriendshipOfferBtn; - LLButton* mTypeTeleportRequestBtn; - LLButton* mTypeGroupNoticeBtn; + LLButton* mTypeNearbyBtn{ nullptr }; + LLButton* mTypeIMBtn{ nullptr }; + LLButton* mTypeGroupIMBtn{ nullptr }; + LLButton* mTypeObjectChatBtn{ nullptr }; + LLButton* mTypeObjectIMBtn{ nullptr }; + LLButton* mTypeScriptErrorBtn{ nullptr }; + LLButton* mTypeDialogBtn{ nullptr }; + LLButton* mTypeOfferBtn{ nullptr }; + LLButton* mTypeInviteBtn{ nullptr }; + LLButton* mTypeLureBtn{ nullptr }; + LLButton* mTypeLoadURLBtn{ nullptr }; + LLButton* mTypeFriendshipOfferBtn{ nullptr }; + LLButton* mTypeTeleportRequestBtn{ nullptr }; + LLButton* mTypeGroupNoticeBtn{ nullptr }; - LLLineEditor* mChatReplaceCtrl; - LLLineEditor* mButtonReplyCtrl; - LLTextEditor* mTextBoxReplyCtrl; + LLLineEditor* mChatReplaceCtrl{ nullptr }; + LLLineEditor* mButtonReplyCtrl{ nullptr }; + LLTextEditor* mTextBoxReplyCtrl{ nullptr }; }; #endif // OMNIFILTER_H diff --git a/indra/newview/omnifilterengine.cpp b/indra/newview/omnifilterengine.cpp index dc5c335d12..8d77a046f0 100644 --- a/indra/newview/omnifilterengine.cpp +++ b/indra/newview/omnifilterengine.cpp @@ -28,6 +28,7 @@ #include "llnotificationsutil.h" #include "llsdserialize.h" +#include "llviewercontrol.h" #include #include @@ -59,15 +60,15 @@ void OmnifilterEngine::init() const OmnifilterEngine::Needle* OmnifilterEngine::logMatch(const std::string& needle_name, const Needle& needle) { time_t now = (time_t)LLDate::now().secondsSinceEpoch(); - mLog.push_back(std::make_pair(now, needle_name)); + mLog.emplace_back(now, needle_name); mLogSignal(now, needle_name); return &needle; } -bool OmnifilterEngine::matchStrings(const std::string& needle_string, const std::string& haystack_string, eMatchType match_type, bool case_insensitive) +bool OmnifilterEngine::matchStrings(std::string_view needle_string, std::string_view haystack_string, eMatchType match_type, bool case_insensitive) { - static LLCachedControl use_omnifilter(*LLControlGroup::getInstance("Global"), "OmnifilterEnabled"); + static LLCachedControl use_omnifilter(gSavedSettings, "OmnifilterEnabled"); if (!use_omnifilter) { return false; @@ -98,8 +99,8 @@ bool OmnifilterEngine::matchStrings(const std::string& needle_string, const std: { re_flags |= boost::regex::icase; } - boost::regex re(needle_string, re_flags); - if (boost::regex_match(haystack_string, re)) + boost::regex re(std::string(needle_string), re_flags); + if (boost::regex_match(std::string(haystack_string), re)) { return true; } @@ -132,11 +133,8 @@ bool OmnifilterEngine::matchStrings(const std::string& needle_string, const std: const OmnifilterEngine::Needle* OmnifilterEngine::match(const Haystack& haystack) { - for (auto const& needle_entry : mNeedles) + for (const auto& [needle_name, needle]: mNeedles) { - const Needle& needle = needle_entry.second; - const std::string& needle_name = needle_entry.first; - if (!needle.mEnabled) { continue; @@ -166,7 +164,7 @@ const OmnifilterEngine::Needle* OmnifilterEngine::match(const Haystack& haystack } } - if (!needle.mTypes.empty() && needle.mTypes.find(haystack.mType) == needle.mTypes.end()) + if (!needle.mTypes.empty() && !needle.mTypes.contains(haystack.mType)) { continue; } @@ -182,7 +180,7 @@ const OmnifilterEngine::Needle* OmnifilterEngine::match(const Haystack& haystack OmnifilterEngine::Needle& OmnifilterEngine::newNeedle(const std::string& needle_name) { - if (mNeedles.find(needle_name) != mNeedles.end()) + if (mNeedles.contains(needle_name)) { Needle new_needle; new_needle.mEnabled = false; @@ -263,8 +261,7 @@ void OmnifilterEngine::loadNeedles() LL_DEBUGS("Omnifilter") << "Loading needles" << mNeedlesXMLPath << LL_ENDL; - std::ifstream file; - file.open(mNeedlesXMLPath.c_str()); + llifstream file(mNeedlesXMLPath.c_str()); if (file.fail()) { LL_DEBUGS("Omnifilter") << "Unable to open Omnifilter storage at '" << mNeedlesXMLPath << "' for reading." << LL_ENDL; @@ -294,11 +291,8 @@ void OmnifilterEngine::loadNeedles() return; } - for (LLSD::map_iterator iter = needles_llsd.beginMap(); iter != needles_llsd.endMap(); ++iter) + for (const auto& [new_needle_name, needle_data] : llsd::inMap(needles_llsd)) { - const std::string& new_needle_name = (*iter).first; - LLSD needle_data = (*iter).second; - Needle new_needle; new_needle.mSenderName = needle_data["sender_name"].asString(); new_needle.mContent = needle_data["content"].asString(); @@ -311,9 +305,9 @@ void OmnifilterEngine::loadNeedles() LLSD types_llsd = needle_data["types"]; - for (LLSD::array_iterator aiter = types_llsd.beginArray(); aiter != types_llsd.endArray(); ++aiter) + for (const auto& needle_type : llsd::inArray(types_llsd)) { - new_needle.mTypes.insert(static_cast((*aiter).asInteger())); + new_needle.mTypes.insert(static_cast(needle_type.asInteger())); } new_needle.mEnabled = needle_data["enabled"].asBoolean(); @@ -333,9 +327,7 @@ void OmnifilterEngine::saveNeedles() LL_DEBUGS("Omnifilter") << "Saving needles" << mNeedlesXMLPath << LL_ENDL; - std::ofstream file; - - file.open(mNeedlesXMLPath.c_str()); + llofstream file(mNeedlesXMLPath.c_str()); if (file.fail()) { LL_DEBUGS("Omnifilter") << "Unable to open Omnifilter storage at '" << mNeedlesXMLPath << "' for writing." << LL_ENDL; @@ -349,11 +341,8 @@ void OmnifilterEngine::saveNeedles() LLSD needles_llsd; - for (auto const& needle_entry : mNeedles) + for (const auto& [needle_name, needle] : mNeedles) { - const std::string& needle_name = needle_entry.first; - const Needle& needle = needle_entry.second; - needles_llsd[needle_name]["sender_name"] = needle.mSenderName; needles_llsd[needle_name]["content"] = needle.mContent; needles_llsd[needle_name]["region_name"] = needle.mRegionName; diff --git a/indra/newview/omnifilterengine.h b/indra/newview/omnifilterengine.h index de4d7efb81..1830058989 100644 --- a/indra/newview/omnifilterengine.h +++ b/indra/newview/omnifilterengine.h @@ -101,7 +101,7 @@ class OmnifilterEngine bool mContentCaseInsensitive = false; }; - typedef std::map needle_list_t; + typedef std::map> needle_list_t; needle_list_t& getNeedleList(); Needle& newNeedle(const std::string& needle_name); @@ -116,11 +116,11 @@ class OmnifilterEngine typedef boost::signals2::signal log_signal_t; log_signal_t mLogSignal; - std::list> mLog; + std::vector> mLog; protected: const Needle* logMatch(const std::string& needle_name, const Needle& needle); - bool matchStrings(const std::string& needle_string, const std::string& haystack_string, eMatchType match_type, bool case_insensitive); + bool matchStrings(std::string_view needle_string, std::string_view haystack_string, eMatchType match_type, bool case_insensitive); void loadNeedles(); void saveNeedles(); diff --git a/indra/newview/skins/default/xui/de/floater_omnifilter.xml b/indra/newview/skins/default/xui/de/floater_omnifilter.xml index 507b6eec1d..7b83c3e226 100644 --- a/indra/newview/skins/default/xui/de/floater_omnifilter.xml +++ b/indra/newview/skins/default/xui/de/floater_omnifilter.xml @@ -1,5 +1,8 @@ + + NEUE REGEL + diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 4fbc0bc197..77c04373ad 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -7327,7 +7327,4 @@ Ihre aktuelle Position: [AVATAR_POS] Maximum - - NEUE REGEL - diff --git a/indra/newview/skins/default/xui/en/floater_omnifilter.xml b/indra/newview/skins/default/xui/en/floater_omnifilter.xml index 54b640af7e..2410168874 100644 --- a/indra/newview/skins/default/xui/en/floater_omnifilter.xml +++ b/indra/newview/skins/default/xui/en/floater_omnifilter.xml @@ -16,153 +16,571 @@ reuse_instance="true" title="Omnifilter Rules Editor" width="700"> + + NEW RULE + - - + + + + + + + + + + + Example Rule 1 + + + + + + Example Rule 2 + + + - +