diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 98fe90df35..9cf3f6cab7 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1407,10 +1407,21 @@ Backup 0 + RLVaShowRedirectChatTyping + + Comment + Sends typing start messages (and optionally plays the typing animation) when @redirchat restricted + Persist + 1 + Type + Boolean + Value + 0 + RLVaSplitRedirectChat Comment - Splits long nearby chat lines across multiple messages when @redir* restricted. + Splits long nearby chat lines across multiple messages when @redir* restricted Persist 1 Type diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 4f32670c44..6120e6971a 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2381,6 +2381,13 @@ BOOL LLAgent::needsRenderHead() //----------------------------------------------------------------------------- void LLAgent::startTyping() { +// [RLVa:KB] - @redirchat + if (!RlvActions::canSendTypingStart()) + { + return; + } +// [/RLVa:KB] + mTypingTimer.reset(); if (getRenderState() & AGENT_STATE_TYPING) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3bccdc1bdf..daa72300a9 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -425,7 +425,10 @@ const std::string ERROR_MARKER_FILE_NAME(SAFE_FILE_NAME_PREFIX + ".error_marker" const std::string LLERROR_MARKER_FILE_NAME(SAFE_FILE_NAME_PREFIX + ".llerror_marker"); //FS orig modified LL const std::string LOGOUT_MARKER_FILE_NAME(SAFE_FILE_NAME_PREFIX + ".logout_marker"); //FS orig modified LL -static BOOL gDoDisconnect = FALSE; +//static BOOL gDoDisconnect = FALSE; +// [RLVa:KB] - Checked: RLVa-2.3 +BOOL gDoDisconnect = FALSE; +// [/RLVa:KB] static std::string gLaunchFileOnQuit; // Used on Win32 for other apps to identify our window (eg, win_setup) diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index a91322541d..bc6d8c28a6 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -68,6 +68,7 @@ #include "llviewercontrol.h" #include "llviewerobjectlist.h" // [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f) +#include "rlvactions.h" #include "rlvcommon.h" // [/RLVa:KB] @@ -488,6 +489,12 @@ public: { return canModerate(userdata); } +// [RLVa:KB] - @pay + else if (level == "can_pay") + { + return RlvActions::canPayAvatar(getAvatarId()); + } +// [/RLVa:KB] else if (level == "can_ban_member") { return canBanGroupMember(getAvatarId()); diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp index 7881681224..bf43e048fe 100644 --- a/indra/newview/llconversationloglist.cpp +++ b/indra/newview/llconversationloglist.cpp @@ -37,6 +37,9 @@ #include "llviewercontrol.h" // #include "llviewerwindow.h" #include "llwindow.h" +// [RLVa:KB] - @pay +#include "rlvactions.h" +// [/RLVa:KB] static LLDefaultChildRegistry::Register r("conversation_log_list"); @@ -397,6 +400,12 @@ bool LLConversationLogList::isActionEnabled(const LLSD& userdata) { return (is_p2p || is_group_member) && LLAvatarActions::canCall(); } +// [RLVa:KB] - @pay + else if ("can_pay" == command_name) + { + return is_p2p && RlvActions::canPayAvatar(selected_id); + } +// [/RLVa:KB] else if ("add_rem_friend" == command_name || "can_invite_to_group" == command_name || "can_share" == command_name || diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index c8e7d5210f..32c94973f3 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -56,6 +56,9 @@ #include "llworld.h" #include "llsdserialize.h" #include "llviewerobjectlist.h" +// [RLVa:KB] - @pay +#include "rlvactions.h" +// [/RLVa:KB] #include "boost/foreach.hpp" // @@ -1427,11 +1430,20 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v } // Handle all other options - if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item)) +// if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item)) +// [RLVa:KB] - @pay + if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item)) +// [/RLVa:KB] { // Those menu items are enable only if a single avatar is selected return is_single_select; } +// [RLVa:KB] - @pay + else if ("can_pay" == item) + { + return is_single_select && RlvActions::canPayAvatar(single_id); + } +// [/RLVa:KB] else if ("can_block" == item) { return (is_single_select ? LLAvatarActions::canBlock(single_id) : false); diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 3e117af817..5225473cf6 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -478,10 +478,7 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke() S32 length = raw_text.length(); -// if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences -// [RLVa:KB] - Checked: 2010-03-26 (RLVa-1.2.0b) | Modified: RLVa-1.0.0d - if ( (length > 0) && (raw_text[0] != '/') && (!RlvActions::hasBehaviour(RLV_BHVR_REDIRCHAT)) ) -// [/RLVa:KB] + if( (length > 0) && (raw_text[0] != '/') ) // forward slash is used for escape (eg. emote) sequences { gAgent.startTyping(); } diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index a516f14fb9..1e3d14b811 100644 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -290,6 +290,12 @@ bool PeopleContextMenu::enableContextMenuItem(const LLSD& userdata) { return LLLogChat::isTranscriptExist(mUUIDs.front()); } +// [RLVa:KB] - @pay + else if (item == std::string("can_pay")) + { + return RlvActions::canPayAvatar(mUUIDs.front()); + } +// [/RLVa:KB] else if (item == std::string("can_im") || item == std::string("can_invite") || item == std::string("can_share") || item == std::string("can_pay")) { diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index fc7658d48b..522f401e6c 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -308,14 +308,39 @@ BOOL LLToolPie::handleLeftClickPick() } // [/RLVa:KB] +// [RLVa:KB] - @buy + const std::function fnRlvCheck = [](const LLUUID& idObj, U8 clickAction) { + switch (clickAction) + { + case CLICK_ACTION_BUY: + return RlvActions::canBuyObject(idObj); + case CLICK_ACTION_PAY: + return RlvActions::canPayObject(idObj); + default: + return true; + } + }; +// [/RLVa:KB] mClickAction = 0; if (object && object->getClickAction()) { mClickAction = object->getClickAction(); +// [RLVa:KB] - @buy + if ( (RlvActions::isRlvEnabled()) && (!fnRlvCheck(object->getID(), mClickAction)) ) + { + mClickAction = CLICK_ACTION_NONE; + } +// [/RLVa:KB] } else if (parent && parent->getClickAction()) { mClickAction = parent->getClickAction(); +// [RLVa:KB] - @buy + if ((RlvActions::isRlvEnabled()) && (!fnRlvCheck(parent->getID(), mClickAction))) + { + mClickAction = CLICK_ACTION_NONE; + } +// [/RLVa:KB] } switch(mClickAction) @@ -563,7 +588,12 @@ ECursorType LLToolPie::cursorFromObject(LLViewerObject* object) LLSelectNode* node = LLSelectMgr::getInstance()->getHoverNode(); if (!node || node->mSaleInfo.isForSale()) { - cursor = UI_CURSOR_TOOLBUY; +// [RLVa:KB] - @buy + cursor = (!object || RlvActions::canBuyObject(parent ? parent->getID() : object->getID())) + ? UI_CURSOR_TOOLBUY + : ((object && object->flagHandleTouch()) || (parent && parent->flagHandleTouch())) ? UI_CURSOR_HAND : UI_CURSOR_ARROW; +// [/RLVa:KB] +// cursor = UI_CURSOR_TOOLBUY; } } break; @@ -581,7 +611,12 @@ ECursorType LLToolPie::cursorFromObject(LLViewerObject* object) || (parent && parent->flagTakesMoney())) { //cursor = UI_CURSOR_TOOLBUY; FIRESTORM - pay cursor is separate from buy cursor - cursor = UI_CURSOR_TOOLPAY; +// [RLVa:KB] - @buy + cursor = ((object && RlvActions::canPayObject(object->getID())) || (parent && RlvActions::canPayObject(parent->getID()))) + ? UI_CURSOR_TOOLPAY + : ((object && object->flagHandleTouch()) || (parent && parent->flagHandleTouch())) ? UI_CURSOR_HAND : UI_CURSOR_ARROW; +// [/RLVa:KB] +// cursor = UI_CURSOR_TOOLPAY; } } break; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index f18e75d948..debd897cc7 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -4395,6 +4395,11 @@ bool enable_buy_object() if( for_sale_selection(node) ) { +// [RLVa:KB] - @buy + if (!RlvActions::canBuyObject(obj->getID())) + return false; +// [/RLVa:KB] + // *NOTE: Is this needed? This checks to see if anyone owns the // object, dating back to when we had "public" objects owned by // no one. JC @@ -6164,6 +6169,11 @@ BOOL is_selection_buy_not_take() LLViewerObject* obj = node->getObject(); if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale())) { +// [RLVa:KB] - @buy + if (!RlvActions::canBuyObject(obj->getID())) + continue; +// [/RLVa:KB] + // you do not own the object and it is for sale, thus, // it's a buy return TRUE; @@ -7681,8 +7691,8 @@ bool enable_pay_avatar() LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); LLVOAvatar* avatar = find_avatar_from_object(obj); // return (avatar != NULL); -// [RLVa:KB] - Checked: RLVa-1.2.1 - return (avatar != NULL) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())); +// [RLVa:KB] - @shownames and @pay + return (avatar != NULL) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) && (RlvActions::canPayAvatar(avatar->getID())); // [/RLVa:KB] } @@ -7694,7 +7704,10 @@ bool enable_pay_object() LLViewerObject *parent = (LLViewerObject *)object->getParent(); if((object->flagTakesMoney()) || (parent && parent->flagTakesMoney())) { - return true; +// [RLVa:KB] - @buy + return RlvActions::canBuyObject(object->getID()); +// [/RLVa:KB] +// return true; } } return false; diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index 956a6c90c2..7d5e1c82b5 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2009-2016, Kitty Barnett + * Copyright (c) 2009-2020, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; @@ -188,6 +188,15 @@ bool RlvActions::canSendIM(const LLUUID& idRecipient) ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) || (!gRlvHandler.isException(RLV_BHVR_SENDIMTO, idRecipient)) ) ); } +// Handles: @redirchat +bool RlvActions::canSendTypingStart() +{ + // The CHAT_TYPE_START indicator can be sent if: + // - nearby chat isn't being redirected + // - the user specifically indicated that they want to show typing under @redirchat + return !RlvHandler::instance().hasBehaviour(RLV_BHVR_REDIRCHAT) || gSavedSettings.get(RLV_SETTING_SHOWREDIRECTCHATTYPING); +} + bool RlvActions::canStartIM(const LLUUID& idRecipient, bool fIgnoreOpen) { // User can start an IM session with "recipient" (could be an agent or a group) if: @@ -378,6 +387,14 @@ bool RlvActions::canBuild() (!gRlvHandler.hasBehaviour(RLV_BHVR_REZ)); } +// Handles: @buy +bool RlvActions::canBuyObject(const LLUUID& idObj) +{ + // User can buy an object set for sale if: + // - not restricted from buying objects + return (!RlvHandler::instance().hasBehaviour(RLV_BHVR_BUY)); +} + // Handles: @edit and @editobj bool RlvActions::canEdit(const LLViewerObject* pObj) { @@ -408,6 +425,22 @@ bool RlvActions::canInteract(const LLViewerObject* pObj, const LLVector3& posOff ( (!rlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) || (pObj->isHUDAttachment()) || (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) <= s_nFartouchDist * s_nFartouchDist)) ); } +// Handles: @pay +bool RlvActions::canPayAvatar(const LLUUID& idAvatar) +{ + // User can pay an avatar if: + // - not restricted from paying avatars + return (!RlvHandler::instance().hasBehaviour(RLV_BHVR_PAY)); +} + +// Handles: @buy +bool RlvActions::canPayObject(const LLUUID& idObj) +{ + // User can pay an object/vendor if: + // - not restricted from buying objects + return (!RlvHandler::instance().hasBehaviour(RLV_BHVR_BUY)); +} + bool RlvActions::canRez() { return (!gRlvHandler.hasBehaviour(RLV_BHVR_REZ)); diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h index be22f4ce6a..a0dfd85b50 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2009-2016, Kitty Barnett + * Copyright (c) 2009-2020, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; @@ -108,6 +108,11 @@ public: */ static bool canSendIM(const LLUUID& idRecipient); + /* + * Returns true if the viewer can inform the region about the user's (nearby chat) typing + */ + static bool canSendTypingStart(); + /* * Returns true if the user is allowed to start a - P2P or group - conversation with the specified UUID (or if the session already exists, unless 'ignore open' is specified) */ @@ -233,6 +238,11 @@ public: */ static bool canBuild(); + /* + * Returns true if the user can buy an object set for sale + */ + static bool canBuyObject(const LLUUID& idObj); + /* * Returns true if the user can edit the specified object (with an optional relative offset) */ @@ -249,6 +259,16 @@ public: */ static bool canInteract(const LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero); + /* + * Returns true if the user can pay an avatar + */ + static bool canPayAvatar(const LLUUID& idAvatar); + + /* + * Returns true if the user can pay an object (i.e. vendor) + */ + static bool canPayObject(const LLUUID& idObj); + /* * Returns true if the user can rez new objects (from inventory or through the create tool) */ diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index f61473b306..6f5f4f878c 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -138,7 +138,7 @@ void RlvSettings::initClass() // Checked: 2010-04-01 (RLVa-1.2.0c) | Modified: RLVa-0.2.1d void RlvSettings::updateLoginLastLocation() { - if ( (!LLApp::isQuitting()) && (gSavedPerAccountSettings.controlExists(RLV_SETTING_LOGINLASTLOCATION)) ) + if ( (!LLApp::isExiting()) && (gSavedPerAccountSettings.controlExists(RLV_SETTING_LOGINLASTLOCATION)) ) { BOOL fValue = (gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)) || (!RlvActions::canStand()); if (gSavedPerAccountSettings.getBOOL(RLV_SETTING_LOGINLASTLOCATION) != fValue) diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 9ce476ee5c..60d44e1480 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2009-2016, Kitty Barnett + * Copyright (c) 2009-2020, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; @@ -151,8 +151,10 @@ enum ERlvBehaviour { RLV_BHVR_ACCEPTTP, // "accepttp" RLV_BHVR_ACCEPTTPREQUEST, // "accepttprequest" RLV_BHVR_ALLOWIDLE, // "allowidle" + RLV_BHVR_BUY, // "buy" RLV_BHVR_EDIT, // "edit" RLV_BHVR_EDITOBJ, // "editobj" + RLV_BHVR_PAY, // "pay" RLV_BHVR_REZ, // "rez" RLV_BHVR_FARTOUCH, // "fartouch" RLV_BHVR_INTERACT, // "interact" @@ -380,6 +382,7 @@ enum ERlvAttachGroupType #define RLV_SETTING_HIDELOCKEDATTACH "RLVaHideLockedAttachments" #define RLV_SETTING_HIDELOCKEDINVENTORY "RLVaHideLockedInventory" #define RLV_SETTING_LOGINLASTLOCATION "RLVaLoginLastLocation" +#define RLV_SETTING_SHOWREDIRECTCHATTYPING "RLVaShowRedirectChatTyping" #define RLV_SETTING_SHAREDINVAUTORENAME "RLVaSharedInvAutoRename" #define RLV_SETTING_SHOWASSERTIONFAIL "RLVaShowAssertionFailures" #define RLV_SETTING_SPLITREDIRECTCHAT "RLVaSplitRedirectChat" diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index e26da09bac..7e0b6f7166 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -76,6 +76,9 @@ // Boost includes #include +// llappviewer.cpp +extern BOOL gDoDisconnect; + // ============================================================================ // Static variable initialization // @@ -164,7 +167,7 @@ void RlvHandler::cleanup() // // Clean up any restrictions that are still active // - RLV_ASSERT(LLApp::isQuitting()); // Several commands toggle debug settings but won't if they know the viewer is quitting + RLV_ASSERT(LLApp::isExiting() || gDoDisconnect); // Several commands toggle debug settings but won't if they know the viewer is quitting // Assume we have no way to predict how m_Objects will change so make a copy ahead of time uuid_vec_t idRlvObjects; @@ -512,6 +515,11 @@ ERlvCmdRet RlvHandler::processCommand(std::reference_wrapper r { RlvCommand rlvCmdRem(rlvCmd, RLV_TYPE_REMOVE); itObj->second.removeCommand(rlvCmdRem); + if (itObj->second.m_Commands.empty()) + { + RLV_DEBUGS << "\t- command list empty => removing " << idCurObj << RLV_ENDL; + m_Objects.erase(itObj); + } } // notifyBehaviourObservers(rlvCmd, !fFromObj); } @@ -1879,6 +1887,25 @@ ERlvCmdRet RlvBehaviourAddRemAttachHandler::onCommand(const RlvCommand& rlvCmd, return RLV_RET_SUCCESS; } +// Handles: @buy=n|y toggles +template<> template<> +void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) +{ + // Start or stop filtering opening the buy, buy contents and pay object floaters + if (fHasBhvr) + { + RLV_VERIFY(RlvUIEnabler::instance().addGenericFloaterFilter("buy_object", std::string(RLV_STRING_BLOCKED_GENERIC))); + RLV_VERIFY(RlvUIEnabler::instance().addGenericFloaterFilter("buy_object_contents", std::string(RLV_STRING_BLOCKED_GENERIC))); + RLV_VERIFY(RlvUIEnabler::instance().addGenericFloaterFilter("pay_object", std::string(RLV_STRING_BLOCKED_GENERIC))); + } + else + { + RLV_VERIFY(RlvUIEnabler::instance().removeGenericFloaterFilter("buy_object")); + RLV_VERIFY(RlvUIEnabler::instance().removeGenericFloaterFilter("buy_object_contents")); + RLV_VERIFY(RlvUIEnabler::instance().removeGenericFloaterFilter("pay_object")); + } +} + // Handles: @detach[:]=n|y template<> template<> ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) @@ -2012,9 +2039,28 @@ void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBh // Start or stop filtering opening the beacons floater if (fHasBhvr) - RlvUIEnabler::instance().addGenericFloaterFilter("beacons"); + { + RLV_VERIFY(RlvUIEnabler::instance().addGenericFloaterFilter("beacons")); + } else - RlvUIEnabler::instance().removeGenericFloaterFilter("beacons"); + { + RLV_VERIFY(RlvUIEnabler::instance().removeGenericFloaterFilter("beacons")); + } +} + +// Handles: @pay=n|y toggles +template<> template<> +void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) +{ + // Start or stop filtering opening the pay avatar floater + if (fHasBhvr) + { + RLV_VERIFY(RlvUIEnabler::instance().addGenericFloaterFilter("pay_resident", std::string(RLV_STRING_BLOCKED_GENERIC))); + } + else + { + RLV_VERIFY(RlvUIEnabler::instance().removeGenericFloaterFilter("pay_resident")); + } } // Handles: @setoverlay=n|y toggles @@ -2357,11 +2403,11 @@ void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour e LLFloaterReg::const_instance_list_t envFloaters = LLFloaterReg::getFloaterList(strEnvFloaters[idxFloater]); for (LLFloater* pFloater : envFloaters) pFloater->closeFloater(); - RlvUIEnabler::instance().addGenericFloaterFilter(strEnvFloaters[idxFloater]); + RLV_VERIFY(RlvUIEnabler::instance().addGenericFloaterFilter(strEnvFloaters[idxFloater])); } else { - RlvUIEnabler::instance().removeGenericFloaterFilter(strEnvFloaters[idxFloater]); + RLV_VERIFY(RlvUIEnabler::instance().removeGenericFloaterFilter(strEnvFloaters[idxFloater])); } } @@ -2414,7 +2460,7 @@ ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvComma template<> template<> void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) { - if (LLApp::isQuitting()) + if (LLApp::isExiting()) return; // Nothing to do if the viewer is shutting down // @@ -2466,13 +2512,13 @@ void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour // Modified for FIRE-8804 if (fHasBhvr) { - RlvUIEnabler::instance().addGenericFloaterFilter("inventory"); - RlvUIEnabler::instance().addGenericFloaterFilter("secondary_inventory"); + RLV_VERIFY(RlvUIEnabler::instance().addGenericFloaterFilter("inventory")); + RLV_VERIFY(RlvUIEnabler::instance().addGenericFloaterFilter("secondary_inventory")); } else { - RlvUIEnabler::instance().removeGenericFloaterFilter("inventory"); - RlvUIEnabler::instance().removeGenericFloaterFilter("secondary_inventory"); + RLV_VERIFY(RlvUIEnabler::instance().removeGenericFloaterFilter("inventory")); + RLV_VERIFY(RlvUIEnabler::instance().removeGenericFloaterFilter("secondary_inventory")); } } @@ -2480,7 +2526,7 @@ void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour template<> template<> void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) { - if (LLApp::isQuitting()) + if (LLApp::isExiting()) return; // Nothing to do if the viewer is shutting down // Update the shownames context @@ -2526,7 +2572,7 @@ template<> template<> ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) { ERlvCmdRet eRet = RlvBehaviourGenericHandler::onCommand(rlvCmd, fRefCount); - if ( (RLV_RET_SUCCESS == eRet) && (rlvCmd.hasOption()) && (!LLApp::isQuitting()) ) + if ( (RLV_RET_SUCCESS == eRet) && (rlvCmd.hasOption()) && (!LLApp::isExiting()) ) { const LLUUID idAgent = RlvCommandOptionHelper::parseOption(rlvCmd.getOption()); @@ -2564,7 +2610,7 @@ ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvCommand& template<> template<> void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) { - if (LLApp::isQuitting()) + if (LLApp::isExiting()) return; // Nothing to do if the viewer is shutting down // Update the shownames context @@ -2588,7 +2634,7 @@ ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvComman template<> template<> void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) { - if (LLApp::isQuitting()) + if (LLApp::isExiting()) return; // Nothing to do if the viewer is shutting down // Refresh the nearby people list diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 71c4bd3720..e333350d68 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2009-2016, Kitty Barnett + * Copyright (c) 2009-2020, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; @@ -93,6 +93,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourInfo("attachallthis", RLV_BHVR_ATTACHTHIS, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_SUBTREE)); addEntry(new RlvBehaviourInfo("attachthis_except", RLV_BHVR_ATTACHTHISEXCEPT, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_NODE)); addEntry(new RlvBehaviourInfo("attachallthis_except", RLV_BHVR_ATTACHTHISEXCEPT, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_SUBTREE)); + addEntry(new RlvBehaviourGenericToggleProcessor("buy")); addEntry(new RlvBehaviourGenericProcessor("chatwhisper", RLV_BHVR_CHATWHISPER)); addEntry(new RlvBehaviourGenericProcessor("chatnormal", RLV_BHVR_CHATNORMAL)); addEntry(new RlvBehaviourGenericProcessor("chatshout", RLV_BHVR_CHATSHOUT)); @@ -110,6 +111,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("interact", RLV_BHVR_INTERACT, RlvBehaviourInfo::BHVR_EXTENDED)); addEntry(new RlvBehaviourGenericProcessor("jump", RLV_BHVR_JUMP)); addEntry(new RlvBehaviourInfo("notify", RLV_BHVR_NOTIFY, RLV_TYPE_ADDREM)); + addEntry(new RlvBehaviourGenericToggleProcessor("pay")); addEntry(new RlvBehaviourGenericProcessor("permissive", RLV_BHVR_PERMISSIVE)); addEntry(new RlvBehaviourGenericProcessor("recvchat", RLV_BHVR_RECVCHAT, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor("recvchatfrom", RLV_BHVR_RECVCHATFROM, RlvBehaviourInfo::BHVR_STRICT)); diff --git a/indra/newview/rlvui.cpp b/indra/newview/rlvui.cpp index 575a32677e..ef01810cd2 100644 --- a/indra/newview/rlvui.cpp +++ b/indra/newview/rlvui.cpp @@ -76,7 +76,7 @@ RlvUIEnabler::RlvUIEnabler() // Checked: 2010-02-28 (RLVa-1.4.0a) | Added: RLVa-1.2.0a void RlvUIEnabler::onBehaviourToggle(ERlvBehaviour eBhvr, ERlvParamType eType) { - bool fQuitting = LLApp::isQuitting(); + bool fQuitting = LLApp::isExiting(); for (behaviour_handler_map_t::const_iterator itHandler = m_Handlers.lower_bound(eBhvr), endHandler = m_Handlers.upper_bound(eBhvr); itHandler != endHandler; ++itHandler) { @@ -181,9 +181,13 @@ void RlvUIEnabler::onToggleShowMinimap() // Start or stop filtering showing the mini-map floater if (!fEnable) - addGenericFloaterFilter("mini_map"); + { + RLV_VERIFY(addGenericFloaterFilter("mini_map")); + } else - removeGenericFloaterFilter("mini_map"); + { + RLV_VERIFY(removeGenericFloaterFilter("mini_map")); + } // Hide the mini-map floater if it's currently visible (or restore it if it was previously visible) static bool fPrevVisibile = false; @@ -228,9 +232,13 @@ void RlvUIEnabler::onToggleShowWorldMap() // Start or stop filtering opening the world map if (!fEnable) - addGenericFloaterFilter("world_map"); + { + RLV_VERIFY(addGenericFloaterFilter("world_map")); + } else - removeGenericFloaterFilter("world_map"); + { + RLV_VERIFY(removeGenericFloaterFilter("world_map")); + } } // Checked: 2010-08-22 (RLVa-1.2.1a) | Added: RLVa-1.2.1a @@ -285,31 +293,53 @@ void RlvUIEnabler::onUpdateLoginLastLocation(bool fQuitting) // ============================================================================ -// Checked: 2010-02-28 (RLVa-1.4.0a) | Added: RLVa-1.2.0a -void RlvUIEnabler::addGenericFloaterFilter(const std::string& strFloaterName) +bool RlvUIEnabler::addGenericFloaterFilter(const std::string& strFloaterName, const std::string& strRlvNotification) { - m_FilteredFloaters.insert(strFloaterName); + return addGenericFloaterFilter(strFloaterName, [strRlvNotification]() { RlvUtil::notifyBlocked(strRlvNotification); }); +} + +bool RlvUIEnabler::addGenericFloaterFilter(const std::string& strFloaterName, const std::function& fn) +{ + // NOTE: we don't currently support multiple filters for the same floater (due to the need to remove the correct one at the end of it all) + if (m_FilteredFloaterMap.end() != m_FilteredFloaterMap.find(strFloaterName)) + return false; + + m_FilteredFloaterMap.insert(std::make_pair(strFloaterName, fn)); if (!m_ConnFloaterGeneric.connected()) + { m_ConnFloaterGeneric = LLFloaterReg::setValidateCallback(boost::bind(&RlvUIEnabler::filterFloaterGeneric, this, _1, _2)); + } + + return true; } -// Checked: 2010-02-28 (RLVa-1.4.0a) | Added: RLVa-1.2.0a -void RlvUIEnabler::removeGenericFloaterFilter(const std::string& strFloaterName) +bool RlvUIEnabler::removeGenericFloaterFilter(const std::string& strFloaterName) { - std::multiset::iterator itFloater = m_FilteredFloaters.find(strFloaterName); - RLV_ASSERT_DBG(itFloater != m_FilteredFloaters.end()); - m_FilteredFloaters.erase(itFloater); + auto itFloater = m_FilteredFloaterMap.find(strFloaterName); + if (m_FilteredFloaterMap.end() == itFloater) + return false; + + m_FilteredFloaterMap.erase(itFloater); RLV_ASSERT_DBG(m_ConnFloaterGeneric.connected()); - if (m_FilteredFloaters.empty()) + if (m_FilteredFloaterMap.empty()) m_ConnFloaterGeneric.disconnect(); + + return true; } -// Checked: 2010-02-28 (RLVa-1.4.0a) | Added: RLVa-1.2.0a -bool RlvUIEnabler::filterFloaterGeneric(const std::string& strName, const LLSD&) +bool RlvUIEnabler::filterFloaterGeneric(const std::string& strFloaterName, const LLSD&) { - return m_FilteredFloaters.end() == m_FilteredFloaters.find(strName); + auto itFloater = m_FilteredFloaterMap.find(strFloaterName); + if (m_FilteredFloaterMap.end() != itFloater) + { + if (itFloater->second) + itFloater->second(); + return false; + } + return true; + } // Checked: 2010-04-22 (RLVa-1.4.5) | Added: RLVa-1.2.0 diff --git a/indra/newview/rlvui.h b/indra/newview/rlvui.h index fc6d0ce477..f8fab2d29f 100644 --- a/indra/newview/rlvui.h +++ b/indra/newview/rlvui.h @@ -57,8 +57,9 @@ protected: * Floater and sidebar validation callbacks */ public: - void addGenericFloaterFilter(const std::string& strFloaterName); - void removeGenericFloaterFilter(const std::string& strFloaterName); + bool addGenericFloaterFilter(const std::string& strFloaterName, const std::string& strRlvNotification); + bool addGenericFloaterFilter(const std::string& strFloaterName, const std::function& fn = nullptr); + bool removeGenericFloaterFilter(const std::string& strFloaterName); protected: bool filterFloaterGeneric(const std::string&, const LLSD&); @@ -88,7 +89,7 @@ protected: typedef std::multimap behaviour_handler_map_t; behaviour_handler_map_t m_Handlers; - std::multiset m_FilteredFloaters; + std::map> m_FilteredFloaterMap; }; // ============================================================================ diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml index 5d2be22297..edc8b22199 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml @@ -115,6 +115,7 @@ layout="topleft" name="Pay"> + + + + +