Improvements to omnifilter
parent
5179d987e1
commit
c6cdaf705d
|
|
@ -723,13 +723,16 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
|
|||
*/
|
||||
|
||||
// <FS:Zi> Omnifilter support
|
||||
OmnifilterEngine::Haystack haystack;
|
||||
haystack.mContent = message;
|
||||
haystack.mSenderName = agentName;
|
||||
haystack.mOwnerID = from_id;
|
||||
|
||||
switch (dialog)
|
||||
static LLCachedControl<bool> 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;
|
||||
}
|
||||
}
|
||||
// </FS:Zi>
|
||||
|
||||
|
|
|
|||
|
|
@ -475,70 +475,74 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
|
|||
LLUUID object_id = notification_id_to_object_id(notification_id);
|
||||
|
||||
// <FS:Zi> 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<bool> 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<std::string> 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<std::string> 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;
|
||||
}
|
||||
}
|
||||
// </FS:Zi>
|
||||
|
||||
|
|
|
|||
|
|
@ -3253,13 +3253,16 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
|
|||
}
|
||||
|
||||
// <FS:Zi> 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<bool> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
// </FS:Zi>
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
|
@ -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<bool> use_omnifilter(*LLControlGroup::getInstance("Global"), "OmnifilterEnabled");
|
||||
static LLCachedControl<bool> 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<OmnifilterEngine::eType>((*aiter).asInteger()));
|
||||
new_needle.mTypes.insert(static_cast<OmnifilterEngine::eType>(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;
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ class OmnifilterEngine
|
|||
bool mContentCaseInsensitive = false;
|
||||
};
|
||||
|
||||
typedef std::map<std::string, OmnifilterEngine::OmnifilterEngine::Needle> needle_list_t;
|
||||
typedef std::map<std::string, OmnifilterEngine::OmnifilterEngine::Needle, std::less<>> needle_list_t;
|
||||
needle_list_t& getNeedleList();
|
||||
|
||||
Needle& newNeedle(const std::string& needle_name);
|
||||
|
|
@ -116,11 +116,11 @@ class OmnifilterEngine
|
|||
typedef boost::signals2::signal<void(time_t, const std::string&)> log_signal_t;
|
||||
log_signal_t mLogSignal;
|
||||
|
||||
std::list<std::pair<time_t, std::string>> mLog;
|
||||
std::vector<std::pair<time_t, std::string>> 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();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater name="omnifilter" title="Omni-Filter Regel-Editor">
|
||||
<floater.string name="OmnifilterNewNeedle">
|
||||
NEUE REGEL
|
||||
</floater.string>
|
||||
<layout_stack name="needle_list_stack">
|
||||
<layout_panel name="needle_list_layout">
|
||||
<check_box name="enable_omnifilter" label="Omnifilter aktivieren"/>
|
||||
|
|
|
|||
|
|
@ -7327,7 +7327,4 @@ Ihre aktuelle Position: [AVATAR_POS]
|
|||
<string name="Maximum">
|
||||
Maximum
|
||||
</string>
|
||||
<string name="OmnifilterNewNeedle">
|
||||
NEUE REGEL
|
||||
</string>
|
||||
</strings>
|
||||
|
|
|
|||
|
|
@ -16,153 +16,571 @@
|
|||
reuse_instance="true"
|
||||
title="Omnifilter Rules Editor"
|
||||
width="700">
|
||||
<floater.string name="OmnifilterNewNeedle">
|
||||
NEW RULE
|
||||
</floater.string>
|
||||
|
||||
<layout_stack name="needle_list_stack" layout="topleft" follows="left|top|bottom" height="374" top="20" left="8" width="190" orientation="vertical" show_drag_handle="true">
|
||||
<layout_panel name="needle_list_layout" layout="topleft" height="150" min_height="94" user_resize="true">
|
||||
<layout_stack
|
||||
name="needle_list_stack"
|
||||
layout="topleft"
|
||||
follows="left|top|bottom"
|
||||
height="374"
|
||||
top="20"
|
||||
left="8"
|
||||
width="190"
|
||||
orientation="vertical"
|
||||
show_drag_handle="true">
|
||||
<layout_panel
|
||||
name="needle_list_layout"
|
||||
layout="topleft"
|
||||
height="150"
|
||||
min_height="94"
|
||||
user_resize="true">
|
||||
<check_box
|
||||
name="enable_omnifilter"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
top="0"
|
||||
right="-1"
|
||||
label="Enable Omnifilter"
|
||||
control_name="OmnifilterEnabled"/>
|
||||
<fs_scroll_list
|
||||
name="needle_list"
|
||||
layout="topleft"
|
||||
follows="all"
|
||||
height="100"
|
||||
top_pad="4"
|
||||
draw_heading="true"
|
||||
draw_stripes="true"
|
||||
desired_line_height="18">
|
||||
<fs_scroll_list.columns
|
||||
name="enabled"
|
||||
label="On"
|
||||
width="24"/>
|
||||
<fs_scroll_list.columns
|
||||
name="needle_name"
|
||||
label="Rule"
|
||||
width="175"/>
|
||||
<!-- example entries for UI editing -->
|
||||
<row>
|
||||
<column
|
||||
name="enabled"
|
||||
column="enabled"
|
||||
type="checkbox"
|
||||
value="true"/>
|
||||
<column
|
||||
name="needle_name"
|
||||
column="needle_name">
|
||||
Example Rule 1
|
||||
</column>
|
||||
</row>
|
||||
<row>
|
||||
<column
|
||||
name="enabled"
|
||||
column="enabled"
|
||||
type="checkbox"/>
|
||||
<column
|
||||
name="needle_name"
|
||||
column="needle_name">
|
||||
Example Rule 2
|
||||
</column>
|
||||
</row>
|
||||
</fs_scroll_list>
|
||||
|
||||
<check_box name="enable_omnifilter" layout="topleft" follows="left|top" height="20" top="0" right="-1" label="Enable Omnifilter" control_name="OmnifilterEnabled" />
|
||||
<button
|
||||
name="add_needle"
|
||||
layout="topleft"
|
||||
follows="left|bottom"
|
||||
height="20"
|
||||
top_pad="4"
|
||||
width="96"
|
||||
label="Add"/>
|
||||
<button
|
||||
name="remove_needle"
|
||||
layout="topleft"
|
||||
follows="right|bottom"
|
||||
height="20"
|
||||
left_pad="0"
|
||||
width="96"
|
||||
label="Remove"/>
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
name="filter_log_layout"
|
||||
layout="topleft"
|
||||
height="130"
|
||||
min_height="50">
|
||||
<fs_scroll_list
|
||||
name="filter_log"
|
||||
layout="topleft"
|
||||
follows="all"
|
||||
height="150"
|
||||
top="0"
|
||||
draw_heading="true"
|
||||
draw_stripes="true"
|
||||
can_sort="false">
|
||||
<fs_scroll_list.columns
|
||||
name="timestamp"
|
||||
label="Time (SLT)"
|
||||
width="64"/>
|
||||
<fs_scroll_list.columns
|
||||
name="log_entry"
|
||||
label="Rule"/>
|
||||
<!-- example entries for UI editing -->
|
||||
<row>
|
||||
<column
|
||||
name="timestamp"
|
||||
column="timestamp"
|
||||
tool_tip="2015-11-24 00:01:02">
|
||||
00:01:02
|
||||
</column>
|
||||
<column
|
||||
name="log_entry"
|
||||
column="log_entry">
|
||||
Example Rule 1
|
||||
</column>
|
||||
</row>
|
||||
<row>
|
||||
<column
|
||||
name="timestamp"
|
||||
column="timestamp"
|
||||
tool_tip="2015-11-24 01:02:03">
|
||||
01:02:03
|
||||
</column>
|
||||
<column
|
||||
name="log_entry"
|
||||
column="log_entry">
|
||||
Example Rule 2
|
||||
</column>
|
||||
</row>
|
||||
</fs_scroll_list>
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
|
||||
<fs_scroll_list name="needle_list" layout="topleft" follows="all" height="100" top_pad="4" draw_heading="true" draw_stripes="true" desired_line_height="18">
|
||||
<fs_scroll_list.columns name="enabled" label="On" width="24" />
|
||||
<fs_scroll_list.columns name="needle_name" label="Rule" width="175" />
|
||||
<panel
|
||||
name="panel_details"
|
||||
layout="topleft"
|
||||
follows="all"
|
||||
height="374"
|
||||
left_pad="4"
|
||||
right="-4">
|
||||
<text
|
||||
name="needle_name_label"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
width="100"
|
||||
left="0"
|
||||
top_pad="0"
|
||||
valign="center"
|
||||
value="Rule Name:"/>
|
||||
<line_editor
|
||||
name="needle_name"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
height="20"
|
||||
left_pad="4"
|
||||
right="-4"/>
|
||||
<text
|
||||
name="sender_name_label"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
width="100"
|
||||
left="0"
|
||||
top_pad="2"
|
||||
valign="center"
|
||||
value="Sender Name:"/>
|
||||
<line_editor
|
||||
name="sender_name"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
height="20"
|
||||
left_pad="4"
|
||||
right="-110"/>
|
||||
<check_box
|
||||
name="sender_case"
|
||||
layout="topleft"
|
||||
follows="right|top"
|
||||
height="20"
|
||||
left_pad="4"
|
||||
width="30"
|
||||
label="Aa"/>
|
||||
<combo_box
|
||||
name="sender_match_type"
|
||||
layout="topleft"
|
||||
follows="right|top"
|
||||
height="20"
|
||||
left_pad="8"
|
||||
right="-4">
|
||||
<combo_item
|
||||
name="sender_exact"
|
||||
value="0">
|
||||
<column
|
||||
width="40"
|
||||
name="label"
|
||||
label="|Abc|"/>
|
||||
<column
|
||||
name="longtext"
|
||||
label="Match full text"/>
|
||||
</combo_item>
|
||||
<combo_item
|
||||
name="sender_substring"
|
||||
value="1">
|
||||
<column
|
||||
name="label"
|
||||
label="*Abc*"/>
|
||||
<column
|
||||
name="longtext"
|
||||
label="Match substring"/>
|
||||
</combo_item>
|
||||
<combo_item
|
||||
name="sender_regex"
|
||||
value="2">
|
||||
<column
|
||||
name="label"
|
||||
label="/ *. /"/>
|
||||
<column
|
||||
name="longtext"
|
||||
label="Match regular expression"
|
||||
width.width="400"
|
||||
width.pixel_width="300"/>
|
||||
</combo_item>
|
||||
</combo_box>
|
||||
<text
|
||||
name="content_label"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
left="0"
|
||||
width="100"
|
||||
top_pad="3"
|
||||
valign="center"
|
||||
value="Content:"/>
|
||||
<text_editor
|
||||
name="content"
|
||||
layout="topleft"
|
||||
follows="all"
|
||||
height="74"
|
||||
left_pad="4"
|
||||
right="-4"
|
||||
top_delta="0"/>
|
||||
<check_box
|
||||
name="content_case"
|
||||
layout="topleft"
|
||||
follows="right|bottom"
|
||||
height="20"
|
||||
width="30"
|
||||
right="-76"
|
||||
top_pad="4"
|
||||
label="Aa"/>
|
||||
<combo_box
|
||||
name="content_match_type"
|
||||
layout="topleft"
|
||||
follows="right|bottom"
|
||||
height="20"
|
||||
left_pad="8"
|
||||
right="-4">
|
||||
<combo_item
|
||||
name="content_exact"
|
||||
value="0">
|
||||
<column
|
||||
width="40"
|
||||
name="label"
|
||||
label="|Abc|"/>
|
||||
<column
|
||||
name="longtext"
|
||||
label="Match full text"/>
|
||||
</combo_item>
|
||||
<combo_item
|
||||
name="content_substring"
|
||||
value="1">
|
||||
<column
|
||||
name="label"
|
||||
label="*Abc*"/>
|
||||
<column
|
||||
name="longtext"
|
||||
label="Match substring"/>
|
||||
</combo_item>
|
||||
<combo_item
|
||||
name="content_regex"
|
||||
value="2">
|
||||
<column
|
||||
name="label"
|
||||
label="/ *. /"/>
|
||||
<column
|
||||
name="longtext"
|
||||
label="Match regular expression"/>
|
||||
</combo_item>
|
||||
</combo_box>
|
||||
|
||||
<!-- example entries for UI editing -->
|
||||
<row>
|
||||
<column name="enabled" column="enabled" type="checkbox" value="true" />
|
||||
<column name="needle_name" column="needle_name">Example Rule 1</column>
|
||||
</row>
|
||||
<row>
|
||||
<column name="enabled" column="enabled" type="checkbox" />
|
||||
<column name="needle_name" column="needle_name">Example Rule 2</column>
|
||||
</row>
|
||||
<text
|
||||
name="region_name_label"
|
||||
layout="topleft"
|
||||
follows="left|bottom"
|
||||
height="20"
|
||||
width="100"
|
||||
left="0"
|
||||
top_pad="2"
|
||||
valign="center"
|
||||
value="Region Name:"/>
|
||||
<line_editor
|
||||
name="region_name"
|
||||
layout="topleft"
|
||||
follows="left|right|bottom"
|
||||
height="20"
|
||||
left_pad="4"
|
||||
right="-4"/>
|
||||
<text
|
||||
name="owner_label"
|
||||
layout="topleft"
|
||||
follows="left|bottom"
|
||||
height="20"
|
||||
width="100"
|
||||
left="0"
|
||||
top_pad="2"
|
||||
valign="center"
|
||||
value="Owner:"/>
|
||||
<line_editor
|
||||
name="owner_uuid"
|
||||
layout="topleft"
|
||||
follows="left|right|bottom"
|
||||
height="20"
|
||||
left_pad="4"
|
||||
right="-4"/>
|
||||
<text
|
||||
name="match_source_label"
|
||||
layout="topleft"
|
||||
follows="left|bottom"
|
||||
width="100"
|
||||
height="20"
|
||||
top_pad="4"
|
||||
left="0"
|
||||
valign="center"
|
||||
value="Match Source:"/>
|
||||
<layout_stack
|
||||
name="buttons_stack"
|
||||
orientation="horizontal"
|
||||
left="104"
|
||||
top_delta="0"
|
||||
right="-4"
|
||||
height="68"
|
||||
follows="left|right|bottom"
|
||||
layout="topleft">
|
||||
<layout_panel
|
||||
width="72"
|
||||
layout="topleft"
|
||||
follows="all"
|
||||
name="buttons_group_1">
|
||||
<button
|
||||
name="type_nearby"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top_pad="0"
|
||||
label="Local Chat"
|
||||
tool_tip="Regular public avatar chat nearby."/>
|
||||
<button
|
||||
name="type_im"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top_pad="4"
|
||||
label="IM"
|
||||
tool_tip="Instant messages from residents."/>
|
||||
<button
|
||||
name="type_group_im"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top_pad="4"
|
||||
label="Group Chat"
|
||||
tool_tip="Group chat from residents."/>
|
||||
</layout_panel>
|
||||
<layout_panel name="buttons_group_2">
|
||||
<button
|
||||
name="type_group_notice"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top="0"
|
||||
label="Notice"
|
||||
tool_tip="Group notices."/>
|
||||
<button
|
||||
name="type_invite"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top_pad="4"
|
||||
label="Invite"
|
||||
tool_tip="Group invitations."/>
|
||||
<button
|
||||
name="type_object_chat"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top_pad="4"
|
||||
label="Object Chat"
|
||||
tool_tip="Nearby chat from objects."/>
|
||||
</layout_panel>
|
||||
<layout_panel name="buttons_group_3">
|
||||
<button
|
||||
name="type_object_im"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top="0"
|
||||
label="Object IM"
|
||||
tool_tip="Instant messages from objects."/>
|
||||
<button
|
||||
name="type_script_error"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72" height="20"
|
||||
is_toggle="true"
|
||||
top_pad="4"
|
||||
label="Error"
|
||||
tool_tip="Debug chat coming from scripts."/>
|
||||
<button
|
||||
name="type_dialog"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top_pad="4"
|
||||
label="Dialog"
|
||||
tool_tip="Matches fields in script dialogs."/>
|
||||
</layout_panel>
|
||||
<layout_panel name="buttons_group_4">
|
||||
<button
|
||||
name="type_inventory_offer"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top="0"
|
||||
label="Offer"
|
||||
tool_tip="Matches fields in inventory offers."/>
|
||||
<button
|
||||
name="type_friendship"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top_pad="4"
|
||||
label="Friendship"
|
||||
tool_tip="Friend requests from residents."/>
|
||||
<button
|
||||
name="type_lure"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top_pad="4"
|
||||
label="TP Lure"
|
||||
tool_tip="Teleport offers from residents."/>
|
||||
</layout_panel>
|
||||
<layout_panel name="buttons_group_5">
|
||||
<button
|
||||
name="type_tp_request"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top="0"
|
||||
label="TP Request"
|
||||
tool_tip="Requests from residents to send them a teleport offer."/>
|
||||
<button
|
||||
name="type_load_url"
|
||||
layout="topleft"
|
||||
follows="left|right|top"
|
||||
width= "72"
|
||||
height="20"
|
||||
is_toggle="true"
|
||||
top_pad="4"
|
||||
label="Load URL"
|
||||
tool_tip="Scripted requests to visit a website."/>
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
|
||||
</fs_scroll_list>
|
||||
|
||||
<button name="add_needle" layout="topleft" follows="left|bottom" height="20" top_pad="4" width="96" label="Add" />
|
||||
<button name="remove_needle" layout="topleft" follows="right|bottom" height="20" left_pad="0" width="96" label="Remove" />
|
||||
|
||||
</layout_panel>
|
||||
<layout_panel name="filter_log_layout" layout="topleft" height="130" min_height="50">
|
||||
|
||||
<fs_scroll_list name="filter_log" layout="topleft" follows="all" height="150" top="0" draw_heading="true" draw_stripes="true" can_sort="false">
|
||||
<fs_scroll_list.columns name="timestamp" label="Time (SLT)" width="64" />
|
||||
<fs_scroll_list.columns name="log_entry" label="Rule" />
|
||||
|
||||
<!-- example entries for UI editing -->
|
||||
<row>
|
||||
<column name="timestamp" column="timestamp" tool_tip="2015-11-24 00:01:02">00:01:02</column>
|
||||
<column name="log_entry" column="log_entry">Example Rule 1</column>
|
||||
</row>
|
||||
<row>
|
||||
<column name="timestamp" column="timestamp" tool_tip="2015-11-24 01:02:03">01:02:03</column>
|
||||
<column name="log_entry" column="log_entry">Example Rule 2</column>
|
||||
</row>
|
||||
|
||||
</fs_scroll_list>
|
||||
|
||||
</layout_panel>
|
||||
|
||||
</layout_stack>
|
||||
|
||||
<panel name="panel_details" layout="topleft" follows="all" height="374" left_pad="4" right="-4">
|
||||
|
||||
<text name="needle_name_label" layout="topleft" follows="left|top" height="20" width="100" left="0" top_pad="0" valign="center" value="Rule Name:" />
|
||||
<line_editor name="needle_name" layout="topleft" follows="left|right|top" height="20" left_pad="4" right="-4" />
|
||||
<text name="sender_name_label" layout="topleft" follows="left|top" height="20" width="100" left="0" top_pad="2" valign="center" value="Sender Name:" />
|
||||
<line_editor name="sender_name" layout="topleft" follows="left|right|top" height="20" left_pad="4" right="-110" />
|
||||
<check_box name="sender_case" layout="topleft" follows="right|top" height="20" left_pad="4" width="30" label="Aa" />
|
||||
|
||||
<combo_box name="sender_match_type" layout="topleft" follows="right|top" height="20" left_pad="8" right="-4" >
|
||||
|
||||
<combo_item name="sender_exact" value="0">
|
||||
<column width="40" name="label" label="|Abc|" />
|
||||
<column name="longtext" label="Match full text" />
|
||||
</combo_item>
|
||||
|
||||
<combo_item name="sender_substring" value="1">
|
||||
<column name="label" label="*Abc*" />
|
||||
<column name="longtext" label="Match substring" />
|
||||
</combo_item>
|
||||
|
||||
<combo_item name="sender_regex" value="2">
|
||||
<column name="label" label="/ *. /" />
|
||||
<column name="longtext" label="Match regular expression" width.width="400" width.pixel_width="300" />
|
||||
</combo_item>
|
||||
|
||||
</combo_box>
|
||||
|
||||
<text name="content_label" layout="topleft" follows="left|top" height="20" left="0" width="100" top_pad="3" valign="center" value="Content:" />
|
||||
<text_editor name="content" layout="topleft" follows="all" height="74" left_pad="4" right="-4" top_delta="0" />
|
||||
<check_box name="content_case" layout="topleft" follows="right|bottom" height="20" width="30" right="-76" top_pad="4" label="Aa" />
|
||||
|
||||
<combo_box name="content_match_type" layout="topleft" follows="right|bottom" height="20" left_pad="8" right="-4" >
|
||||
|
||||
<combo_item name="content_exact" value="0">
|
||||
<column width="40" name="label" label="|Abc|" />
|
||||
<column name="longtext" label="Match full text" />
|
||||
</combo_item>
|
||||
|
||||
<combo_item name="content_substring" value="1">
|
||||
<column name="label" label="*Abc*" />
|
||||
<column name="longtext" label="Match substring" />
|
||||
</combo_item>
|
||||
|
||||
<combo_item name="content_regex" value="2">
|
||||
<column name="label" label="/ *. /" />
|
||||
<column name="longtext" label="Match regular expression" />
|
||||
</combo_item>
|
||||
|
||||
</combo_box>
|
||||
|
||||
<text name="region_name_label" layout="topleft" follows="left|bottom" height="20" width="100" left="0" top_pad="2" valign="center" value="Region Name:" />
|
||||
<line_editor name="region_name" layout="topleft" follows="left|right|bottom" height="20" left_pad="4" right="-4" />
|
||||
<text name="owner_label" layout="topleft" follows="left|bottom" height="20" width="100" left="0" top_pad="2" valign="center" value="Owner:" />
|
||||
<line_editor name="owner_uuid" layout="topleft" follows="left|right|bottom" height="20" left_pad="4" right="-4" />
|
||||
|
||||
<text name="match_source_label" layout="topleft" follows="left|bottom" width="100" height="20" top_pad="4" left="0" valign="center" value="Match Source:" />
|
||||
|
||||
<layout_stack name="buttons_stack" orientation="horizontal" left="104" top_delta="0" right="-4" height="68" follows="left|right|bottom" layout="topleft">
|
||||
|
||||
<layout_panel width="72" layout="topleft" follows="all" name="buttons_group_1">
|
||||
<button name="type_nearby" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="0" label="Nearby Chat" tool_tip="Regular public avatar chat nearby." />
|
||||
<button name="type_im" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="IM" tool_tip="Instant messages from users." />
|
||||
<button name="type_group_im" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Group Chat" tool_tip="Group chat from users." />
|
||||
</layout_panel>
|
||||
|
||||
<layout_panel name="buttons_group_2">
|
||||
<button name="type_group_notice" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top="0" label="Notice" tool_tip="Group notices." />
|
||||
<button name="type_invite" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Invite" tool_tip="Group invitations." />
|
||||
<button name="type_object_chat" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Object Chat" tool_tip="Nearby chat from objects." />
|
||||
</layout_panel>
|
||||
|
||||
<layout_panel name="buttons_group_3">
|
||||
<button name="type_object_im" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top="0" label="Object IM" tool_tip="Instant messages from objects." />
|
||||
<button name="type_script_error" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Error" tool_tip="Debug chat coming from scripts." />
|
||||
<button name="type_dialog" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Dialog" tool_tip="Matches fields in script dialogs." />
|
||||
</layout_panel>
|
||||
|
||||
<layout_panel name="buttons_group_4">
|
||||
<button name="type_inventory_offer" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top="0" label="Offer" tool_tip="Matches fields in inventory offers." />
|
||||
<button name="type_friendship" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Friendship" tool_tip="Friend requests from users." />
|
||||
<button name="type_lure" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="TP Lure" tool_tip="Teleport offers from users." />
|
||||
</layout_panel>
|
||||
|
||||
<layout_panel name="buttons_group_5">
|
||||
<button name="type_tp_request" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top="0" label="TP Request" tool_tip="Requests from users to send them a teleport offer." />
|
||||
<button name="type_load_url" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Load URL" tool_tip="Scripted requests to visit a website." />
|
||||
</layout_panel>
|
||||
|
||||
</layout_stack>
|
||||
|
||||
<view_border layout="topleft" right="-4" follows="left|bottom|right" left="0" height="1" top_pad="4" />
|
||||
|
||||
<text name="chat_replace_label" layout="topleft" follows="left|bottom" left="0" height="20" width="100" top_pad="2" value="Chat Replace:" valign="center" />
|
||||
<line_editor name="chat_replace" layout="topleft" follows="left|right|bottom" left_pad="4" height="20" right="-4" />
|
||||
<text name="button_reply_label" layout="topleft" follows="left|bottom" left="0" height="20" width="100" top_pad="2" value="Button Reply:" valign="center" />
|
||||
<line_editor name="button_reply" layout="topleft" follows="left|right|bottom" left_pad="4" height="20" right="-4" />
|
||||
<text name="text_box_reply_label" layout="topleft" follows="left|bottom" left="0" height="20" width="100" top_pad="3" value="Text Box Reply:" valign="center" />
|
||||
<text_editor name="text_box_reply" layout="topleft" follows="left|right|bottom" left_pad="4" height="60" right="-4" top_delta="0" />
|
||||
|
||||
</panel>
|
||||
<view_border
|
||||
layout="topleft"
|
||||
right="-4"
|
||||
follows="left|bottom|right"
|
||||
left="0"
|
||||
height="1"
|
||||
top_pad="4"/>
|
||||
|
||||
<text
|
||||
name="chat_replace_label"
|
||||
layout="topleft"
|
||||
follows="left|bottom"
|
||||
left="0"
|
||||
height="20"
|
||||
width="100"
|
||||
top_pad="2"
|
||||
value="Chat Replace:"
|
||||
valign="center"/>
|
||||
<line_editor
|
||||
name="chat_replace"
|
||||
layout="topleft"
|
||||
follows="left|right|bottom"
|
||||
left_pad="4"
|
||||
height="20"
|
||||
right="-4"/>
|
||||
<text
|
||||
name="button_reply_label"
|
||||
layout="topleft"
|
||||
follows="left|bottom"
|
||||
left="0"
|
||||
height="20"
|
||||
width="100"
|
||||
top_pad="2"
|
||||
value="Button Reply:"
|
||||
valign="center"/>
|
||||
<line_editor
|
||||
name="button_reply"
|
||||
layout="topleft"
|
||||
follows="left|right|bottom"
|
||||
left_pad="4"
|
||||
height="20"
|
||||
right="-4"/>
|
||||
<text
|
||||
name="text_box_reply_label"
|
||||
layout="topleft"
|
||||
follows="left|bottom"
|
||||
left="0"
|
||||
height="20"
|
||||
width="100"
|
||||
top_pad="3"
|
||||
value="Text Box Reply:"
|
||||
valign="center"/>
|
||||
<text_editor
|
||||
name="text_box_reply"
|
||||
layout="topleft"
|
||||
follows="left|right|bottom"
|
||||
left_pad="4"
|
||||
height="60"
|
||||
right="-4"
|
||||
top_delta="0"/>
|
||||
</panel>
|
||||
</floater>
|
||||
|
|
|
|||
|
|
@ -3341,6 +3341,4 @@ Your current position: [AVATAR_POS]
|
|||
<string name="Very High">Very High</string>
|
||||
<string name="Ultra">Ultra</string>
|
||||
<string name="Maximum">Maximum</string>
|
||||
|
||||
<string name="OmnifilterNewNeedle">NEW RULE</string> <!-- <FS:Zi> Omnifilter -->
|
||||
</strings>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater name="omnifilter" title="Edytor reguł Omnifiltra">
|
||||
<floater.string name="OmnifilterNewNeedle">
|
||||
NOWA REGUŁA
|
||||
</floater.string>
|
||||
<layout_stack name="needle_list_stack">
|
||||
<layout_panel name="needle_list_layout">
|
||||
<check_box name="enable_omnifilter" label="Włącz Wszystkofiltr" />
|
||||
|
|
|
|||
|
|
@ -6700,7 +6700,4 @@ Twoja aktualna pozycja: [AVATAR_POS]
|
|||
<string name="Maximum">
|
||||
Maksymalnie
|
||||
</string>
|
||||
<string name="OmnifilterNewNeedle">
|
||||
NOWA REGUŁA
|
||||
</string>
|
||||
</strings>
|
||||
|
|
|
|||
Loading…
Reference in New Issue