Merged with RLVa refactoring tip

--HG--
branch : RLVa
master
Kitty Barnett 2016-05-21 11:40:19 +02:00
commit f5fa9d1b82
31 changed files with 603 additions and 399 deletions

View File

@ -156,17 +156,6 @@
<key>Value</key>
<boolean>1</boolean>
</map>
<key>RLVaExtendedCommands</key>
<map>
<key>Comment</key>
<string>Enables the extended command set</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<boolean>1</boolean>
</map>
<key>RLVaHideLockedLayers</key>
<map>
<key>Comment</key>

View File

@ -2455,15 +2455,11 @@ void LLAgent::onAnimStop(const LLUUID& id)
}
else if (id == ANIM_AGENT_AWAY)
{
// clearAFK();
// [RLVa:KB] - Checked: 2010-05-03 (RLVa-1.2.0g) | Added: RLVa-1.1.0g
#ifdef RLV_EXTENSION_CMD_ALLOWIDLE
if (!gRlvHandler.hasBehaviour(RLV_BHVR_ALLOWIDLE))
clearAFK();
#else
clearAFK();
#endif // RLV_EXTENSION_CMD_ALLOWIDLE
// [/RLVa:KB]
// clearAFK();
}
else if (id == ANIM_AGENT_STANDUP)
{

View File

@ -491,15 +491,11 @@ void idle_afk_check()
{
// check idle timers
F32 current_idle = gAwayTriggerTimer.getElapsedTimeF32();
// F32 afk_timeout = gSavedSettings.getS32("AFKTimeout");
// [RLVa:KB] - Checked: 2010-05-03 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g
#ifdef RLV_EXTENSION_CMD_ALLOWIDLE
// Enforce an idle time of 30 minutes if @allowidle=n restricted
F32 afk_timeout = (!gRlvHandler.hasBehaviour(RLV_BHVR_ALLOWIDLE)) ? gSavedSettings.getS32("AFKTimeout") : 60 * 30;
#else
F32 afk_timeout = gSavedSettings.getS32("AFKTimeout");
#endif // RLV_EXTENSION_CMD_ALLOWIDLE
// [/RLVa:KB]
// F32 afk_timeout = gSavedSettings.getS32("AFKTimeout");
if (afk_timeout && (current_idle > afk_timeout) && ! gAgent.getAFK())
{
LL_INFOS("IdleAway") << "Idle more than " << afk_timeout << " seconds: automatically changing to Away status" << LL_ENDL;

View File

@ -208,7 +208,7 @@ void LLAvatarActions::startIM(const LLUUID& id)
return;
// [RLVa:KB] - Checked: 2013-05-09 (RLVa-1.4.9)
if ( (!RlvActions::canStartIM(id)) && (!RlvActions::hasOpenP2PSession(id)) )
if (!RlvActions::canStartIM(id))
{
make_ui_sound("UISndInvalidOp");
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("agent", id, "completename").getSLURLString()));
@ -253,7 +253,7 @@ void LLAvatarActions::startCall(const LLUUID& id)
}
// [RLVa:KB] - Checked: 2013-05-09 (RLVa-1.4.9)
if ( (!RlvActions::canStartIM(id)) && (!RlvActions::hasOpenP2PSession(id)) )
if (!RlvActions::canStartIM(id))
{
make_ui_sound("UISndInvalidOp");
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("agent", id, "completename").getSLURLString()));
@ -460,6 +460,17 @@ void LLAvatarActions::teleport_request_callback(const LLSD& notification, const
{
LLMessageSystem* msg = gMessageSystem;
// [RLVa:KB] - Checked: RLVa-2.0.0
const LLUUID idRecipient = notification["substitutions"]["uuid"];
std::string strMessage = response["message"];
// Filter the request message if the recipients is IM-blocked
if ( (!RlvActions::isRlvEnabled()) || ((RlvActions::canStartIM(idRecipient)) && (RlvActions::canSendIM(idRecipient))) )
{
strMessage = RlvStrings::getString(RLV_STRING_HIDDEN);
}
// [/RLVa:KB]
msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
@ -477,7 +488,10 @@ void LLAvatarActions::teleport_request_callback(const LLSD& notification, const
LLAgentUI::buildFullname(name);
msg->addStringFast(_PREHASH_FromAgentName, name);
msg->addStringFast(_PREHASH_Message, response["message"]);
// [RLVa:KB] - Checked: RLVa-2.0.0
msg->addStringFast(_PREHASH_Message, strMessage);
// [/RLVa:KB]
// msg->addStringFast(_PREHASH_Message, response["message"]);
msg->addU32Fast(_PREHASH_ParentEstateID, 0);
msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());

View File

@ -212,7 +212,7 @@ void LLGroupActions::startCall(const LLUUID& group_id)
}
// [RLVa:KB] - Checked: 2013-05-09 (RLVa-1.4.9)
if ( (!RlvActions::canStartIM(group_id)) && (!RlvActions::hasOpenGroupSession(group_id)) )
if (!RlvActions::canStartIM(group_id))
{
make_ui_sound("UISndInvalidOp");
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("group", group_id, "about").getSLURLString()));
@ -452,7 +452,7 @@ LLUUID LLGroupActions::startIM(const LLUUID& group_id)
if (group_id.isNull()) return LLUUID::null;
// [RLVa:KB] - Checked: 2013-05-09 (RLVa-1.4.9)
if ( (!RlvActions::canStartIM(group_id)) && (!RlvActions::hasOpenGroupSession(group_id)) )
if (!RlvActions::canStartIM(group_id))
{
make_ui_sound("UISndInvalidOp");
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("group", group_id, "about").getSLURLString()));

View File

@ -5548,7 +5548,7 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act
}
// [RLVa:KB] - Checked: 2013-05-08 (RLVa-1.4.9)
if ( (!RlvActions::canStartIM(item->getCreatorUUID())) && (!RlvActions::hasOpenP2PSession(item->getCreatorUUID())) )
if (!RlvActions::canStartIM(item->getCreatorUUID()))
{
make_ui_sound("UISndInvalidOp");
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_STARTIM, LLSD().with("RECIPIENT", LLSLURL("agent", item->getCreatorUUID(), "completename").getSLURLString()));

View File

@ -97,7 +97,7 @@ bool LLAlertHandler::processNotification(const LLNotificationPtr& notification)
// - LLHandlerUtil::logToIMP2P() below will still be called with to_file_only == false
// - LLHandlerUtil::logToIM() will eventually be called as a result and without an open IM session it will log the
// same message as it would for an open session whereas to_file_only == true would take a different code path
if ( (RlvActions::hasOpenP2PSession(from_id)) || (RlvActions::canStartIM(from_id)) )
if (RlvActions::canStartIM(from_id))
{
// [/RLVa:KB]
// firstly create session...

View File

@ -113,7 +113,7 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
// [RLVa:KB] - Checked: 2013-05-09 (RLVa-1.4.9)
// Don't spawn an IM session for non-chat related events
if ( (RlvActions::hasOpenP2PSession(from_id)) || (RlvActions::canStartIM(from_id)) )
if (RlvActions::canStartIM(from_id))
{
// [/RLVa:KB]
LLHandlerUtil::spawnIMSession(name, from_id);

View File

@ -4305,7 +4305,7 @@ void LLSelectMgr::convertTransient()
void LLSelectMgr::deselectAllIfTooFar()
{
// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c
// [RLVa:KB] - Checked: RLVa-1.3.0
if ( (!mSelectedObjects->isEmpty()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ))) )
{
struct NotTransientOrFocusedMediaOrEditable : public LLSelectedNodeFunctor
@ -4313,8 +4313,7 @@ void LLSelectMgr::deselectAllIfTooFar()
bool apply(LLSelectNode* pNode)
{
const LLViewerObject* pObj = pNode->getObject();
return (!pNode->isTransient()) && (pObj) && (!gRlvHandler.canEdit(pObj)) &&
(pObj->getID() != LLViewerMediaFocus::getInstance()->getFocusedObjectID());
return (!pNode->isTransient()) && (pObj) && (!gRlvHandler.canEdit(pObj)) && (pObj->getID() != LLViewerMediaFocus::getInstance()->getFocusedObjectID());
}
} f;
if (mSelectedObjects->getFirstRootNode(&f, TRUE))
@ -4327,15 +4326,13 @@ void LLSelectMgr::deselectAllIfTooFar()
return;
}
// [RLVa:KB] - Checked: 2010-05-03 (RLVa-1.2.0g) | Modified: RLVa-1.1.0l
#ifdef RLV_EXTENSION_CMD_INTERACT
// [Fall-back code] Don't allow an active selection (except for HUD attachments - see above) when @interact=n restricted
// [RLVa:KB] - Checked: RLVa-1.2.0
// [Fall-back code] Don't allow an active selection (except for HUD attachments - see above) when @interact restricted
if (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT))
{
deselectAll();
return;
}
#endif // RLV_EXTENSION_CMD_INTERACT
// [/RLVa:KB]
// HACK: Don't deselect when we're navigating to rate an object's

View File

@ -1006,11 +1006,7 @@ bool idle_startup()
// All accounts have both a home and a last location, and we don't support
// more locations than that. Choose the appropriate one. JC
// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.2.0c) | Modified: RLVa-0.2.1d
#ifndef RLV_EXTENSION_STARTLOCATION
if (rlv_handler_t::isEnabled())
#else
if ( (rlv_handler_t::isEnabled()) && (RlvSettings::getLoginLastLocation()) )
#endif // RLV_EXTENSION_STARTLOCATION
{
// Force login at the last location
LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST));

View File

@ -1271,14 +1271,17 @@ BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
{
if (!LLUI::sSettingGroups["config"]->getBOOL("ShowHoverTips")) return TRUE;
if (!mHoverPick.isValid()) return TRUE;
// [RLVa:KB] - Checked: 2010-05-03 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g
#ifdef RLV_EXTENSION_CMD_INTERACT
if (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) return TRUE;
#endif // RLV_EXTENSION_CMD_INTERACT
// [/RLVa:KB]
LLViewerObject* hover_object = mHoverPick.getObject();
// [RLVa:KB] - Checked: RLVa-1.2.0
// NOTE: handleTooltipObject() will block HUD tooltips anyway but technically interact should only interfere with world interaction
if ( (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) && (hover_object) && (!hover_object->isHUDAttachment()) )
{
return TRUE;
}
// [/RLVa:KB]
// update hover object and hover parcel
LLSelectMgr::getInstance()->setHoverObject(hover_object, mHoverPick.mObjectFace);

View File

@ -323,6 +323,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("region_restarting", "floater_region_restarting.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRegionRestarting>);
// [RLVa:KB] - Checked: 2010-03-11 (RLVa-1.2.0e) | Added: RLVa-1.2.0a
LLFloaterReg::add("rlv_behaviours", "floater_rlv_behaviours.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<RlvFloaterBehaviours>);
LLFloaterReg::add("rlv_console", "floater_rlv_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<RlvFloaterConsole>);
LLFloaterReg::add("rlv_locks", "floater_rlv_locks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<RlvFloaterLocks>);
LLFloaterReg::add("rlv_strings", "floater_rlv_strings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<RlvFloaterStrings>);
// [/RLVa:KB]

View File

@ -3244,7 +3244,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
case IM_LURE_USER:
case IM_TELEPORT_REQUEST:
{
// [RLVa:KB] - Checked: 2013-11-08 (RLVa-1.4.9)
// [RLVa:KB] - Checked: RLVa-1.4.9
// If we auto-accept the offer/request then this will override DnD status (but we'll still let the other party know later)
bool fRlvAutoAccept = (rlv_handler_t::isEnabled()) &&
( ((IM_LURE_USER == dialog) && (RlvActions::autoAcceptTeleportOffer(from_id))) ||
@ -3256,7 +3256,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
return;
}
// else if (is_do_not_disturb)
// [RLVa:KB] - Checked: 2013-11-08 (RLVa-1.4.9)
// [RLVa:KB] - Checked: RLVa-1.4.9
else if ( (is_do_not_disturb) && (!fRlvAutoAccept) )
// [/RLVa:KB]
{
@ -3321,7 +3321,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
}
}
// [RLVa:KB] - Checked: 2013-11-08 (RLVa-1.4.9)
// [RLVa:KB] - Checked: RLVa-1.4.9
if (rlv_handler_t::isEnabled())
{
if ( ((IM_LURE_USER == dialog) && (!RlvActions::canAcceptTpOffer(from_id))) ||
@ -3333,8 +3333,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
return;
}
// Censor lure message if: 1) restricted from receiving IMs from the sender, or 2) teleport offer and @showloc=n restricted
if ( (!RlvActions::canReceiveIM(from_id)) || ((IM_LURE_USER == dialog) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))) )
// Censor message if: 1) restricted from receiving IMs from the sender, or 2) teleport offer/request and @showloc=n restricted
if ( (!RlvActions::canReceiveIM(from_id)) ||
((gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) && (IM_LURE_USER == dialog || IM_TELEPORT_REQUEST == dialog)) )
{
message = RlvStrings::getString(RLV_STRING_HIDDEN);
}
@ -3390,8 +3391,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
params.substitutions = args;
params.payload = payload;
// [RLVa:KB] - Checked: 20103-11-08 (RLVa-1.4.9)
if ( (rlv_handler_t::isEnabled()) && (fRlvAutoAccept) )
// [RLVa:KB] - Checked: RLVa-1.4.9
if (fRlvAutoAccept)
{
if (IM_LURE_USER == dialog)
gRlvHandler.setCanCancelTp(false);
@ -7539,20 +7540,14 @@ void send_lures(const LLSD& notification, const LLSD& response)
LLAgentUI::buildSLURL(slurl);
text.append("\r\n").append(slurl.getSLURLString());
// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0)
if ( (RlvActions::hasBehaviour(RLV_BHVR_SENDIM)) || (RlvActions::hasBehaviour(RLV_BHVR_SENDIMTO)) )
{
// Filter the lure message if one of the recipients of the lure can't be sent an IM to
for (LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
it != notification["payload"]["ids"].endArray(); ++it)
{
if (!RlvActions::canSendIM(it->asUUID()))
{
text = RlvStrings::getString(RLV_STRING_HIDDEN);
break;
}
}
}
// [RLVa:KB] - Checked: RLVa-2.0.0
// Filter the lure message if any of the recipients are IM-blocked
const LLSD& sdRecipients = notification["payload"]["ids"];
if ( (gRlvHandler.isEnabled()) &&
(std::any_of(sdRecipients.beginArray(), sdRecipients.endArray(), [](const LLSD& id) { return !RlvActions::canStartIM(id.asUUID()) || !RlvActions::canSendIM(id.asUUID()); })) )
{
text = RlvStrings::getString(RLV_STRING_HIDDEN);
}
// [/RLVa:KB]
LLMessageSystem* msg = gMessageSystem;

View File

@ -4049,8 +4049,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
}
}
// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
#ifdef RLV_EXTENSION_CMD_INTERACT
// [RLVa:KB] - Checked: RLVa-1.2.0
if ( (rlv_handler_t::isEnabled()) && (found) && (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) )
{
// Allow picking if:
@ -4059,14 +4058,13 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
// - the pie tool is active *and* we picked our own avie (allows "mouse steering" and the self pie menu)
LLTool* pCurTool = LLToolMgr::getInstance()->getCurrentTool();
if ( (LLToolDragAndDrop::getInstance() != pCurTool) &&
(!LLToolCamera::getInstance()->hasMouseCapture()) &&
((LLToolPie::getInstance() != pCurTool) || (gAgent.getID() != found->getID())) )
(!LLToolCamera::getInstance()->hasMouseCapture()) &&
((LLToolPie::getInstance() != pCurTool) || (gAgent.getID() != found->getID())) )
{
found = NULL;
}
#endif // RLV_EXTENSION_CMD_INTERACT
// [/RLVa:KB]
}
// [/RLVa:KB]
}
return found;

View File

@ -55,41 +55,38 @@ bool RlvActions::canSendIM(const LLUUID& idRecipient)
( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) || (!gRlvHandler.isException(RLV_BHVR_SENDIMTO, idRecipient)) ) );
}
// Checked: 2011-04-12 (RLVa-1.3.0)
bool RlvActions::canStartIM(const LLUUID& idRecipient)
{
// User can start an IM session with "recipient" (could be an agent or a group) if:
// - not generally restricted from starting IM sessions (or the recipient is an exception)
// - not specifically restricted from starting an IM session with the recipient
// - the session already exists
return
(!rlv_handler_t::isEnabled()) ||
( ( (!gRlvHandler.hasBehaviour(RLV_BHVR_STARTIM)) || (gRlvHandler.isException(RLV_BHVR_STARTIM, idRecipient)) ) &&
( (!gRlvHandler.hasBehaviour(RLV_BHVR_STARTIMTO)) || (!gRlvHandler.isException(RLV_BHVR_STARTIMTO, idRecipient)) ) );
( (!gRlvHandler.hasBehaviour(RLV_BHVR_STARTIMTO)) || (!gRlvHandler.isException(RLV_BHVR_STARTIMTO, idRecipient)) ) ) ||
( (hasOpenP2PSession(idRecipient)) || (hasOpenGroupSession(idRecipient)) );
}
// ============================================================================
// Movement
//
// Checked: 2010-12-11 (RLVa-1.2.2)
bool RlvActions::canAcceptTpOffer(const LLUUID& idSender)
{
return ((!gRlvHandler.hasBehaviour(RLV_BHVR_TPLURE)) || (gRlvHandler.isException(RLV_BHVR_TPLURE, idSender))) && (canStand());
}
// Checked: 2013-11-08 (RLVa-1.4.9)
bool RlvActions::autoAcceptTeleportOffer(const LLUUID& idSender)
{
return ((idSender.notNull()) && (gRlvHandler.isException(RLV_BHVR_ACCEPTTP, idSender))) || (gRlvHandler.hasBehaviour(RLV_BHVR_ACCEPTTP));
}
// Checked: 2013-11-08 (RLVa-1.4.9)
bool RlvActions::canAcceptTpRequest(const LLUUID& idSender)
{
return (!gRlvHandler.hasBehaviour(RLV_BHVR_TPREQUEST)) || (gRlvHandler.isException(RLV_BHVR_TPREQUEST, idSender));
}
// Checked: 2013-11-08 (RLVa-1.4.9)
bool RlvActions::autoAcceptTeleportRequest(const LLUUID& idRequester)
{
return ((idRequester.notNull()) && (gRlvHandler.isException(RLV_BHVR_ACCEPTTPREQUEST, idRequester))) || (gRlvHandler.hasBehaviour(RLV_BHVR_ACCEPTTPREQUEST));

View File

@ -45,9 +45,9 @@ public:
static bool canSendIM(const LLUUID& idRecipient);
/*
* Returns true if the user is allowed to start a - P2P or group - conversation with the specified UUID.
* Returns true if the user is allowed to start a - P2P or group - conversation with the specified UUID (or if the session already exists)
*/
static bool canStartIM(const LLUUID& idRecipient); // @startim and @startimto
static bool canStartIM(const LLUUID& idRecipient);
/*
* Returns true if an avatar's name should be hidden for the requested operation/context

View File

@ -96,11 +96,9 @@ void RlvSettings::initClass()
if (gSavedSettings.controlExists(RLV_SETTING_SHOWNAMETAGS))
gSavedSettings.getControl(RLV_SETTING_SHOWNAMETAGS)->getSignal()->connect(boost::bind(&onChangedSettingBOOL, _2, &fShowNameTags));
#ifdef RLV_EXTENSION_STARTLOCATION
// Don't allow toggling RLVaLoginLastLocation from the debug settings floater
if (gSavedPerAccountSettings.controlExists(RLV_SETTING_LOGINLASTLOCATION))
gSavedPerAccountSettings.getControl(RLV_SETTING_LOGINLASTLOCATION)->setHiddenFromSettingsEditor(true);
#endif // RLV_EXTENSION_STARTLOCATION
if (gSavedSettings.controlExists(RLV_SETTING_TOPLEVELMENU))
gSavedSettings.getControl(RLV_SETTING_TOPLEVELMENU)->getSignal()->connect(boost::bind(&onChangedMenuLevel));
@ -109,21 +107,19 @@ void RlvSettings::initClass()
}
}
#ifdef RLV_EXTENSION_STARTLOCATION
// Checked: 2010-04-01 (RLVa-1.2.0c) | Modified: RLVa-0.2.1d
void RlvSettings::updateLoginLastLocation()
// 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::isQuitting()) && (gSavedPerAccountSettings.controlExists(RLV_SETTING_LOGINLASTLOCATION)) )
BOOL fValue = (gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)) || (!RlvActions::canStand());
if (gSavedPerAccountSettings.getBOOL(RLV_SETTING_LOGINLASTLOCATION) != fValue)
{
BOOL fValue = (gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)) || (!RlvActions::canStand());
if (gSavedPerAccountSettings.getBOOL(RLV_SETTING_LOGINLASTLOCATION) != fValue)
{
gSavedPerAccountSettings.setBOOL(RLV_SETTING_LOGINLASTLOCATION, fValue);
gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
}
gSavedPerAccountSettings.setBOOL(RLV_SETTING_LOGINLASTLOCATION, fValue);
gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
}
}
#endif // RLV_EXTENSION_STARTLOCATION
}
// Checked: 2011-08-16 (RLVa-1.4.0b) | Added: RLVa-1.4.0b
bool RlvSettings::onChangedMenuLevel()

View File

@ -98,10 +98,8 @@ public:
static bool getSharedInvAutoRename() { return rlvGetSetting<bool>(RLV_SETTING_SHAREDINVAUTORENAME, true); }
static bool getShowNameTags() { return fShowNameTags; }
#ifdef RLV_EXTENSION_STARTLOCATION
static bool getLoginLastLocation() { return rlvGetPerUserSetting<bool>(RLV_SETTING_LOGINLASTLOCATION, true); }
static void updateLoginLastLocation();
#endif // RLV_EXTENSION_STARTLOCATION
static void initClass();
static void onChangedSettingMain(const LLSD& sdValue);
@ -171,7 +169,7 @@ public:
static void notifyFailedAssertion(const std::string& strAssert, const std::string& strFile, int nLine);
static void sendBusyMessage(const LLUUID& idTo, const std::string& strMsg, const LLUUID& idSession = LLUUID::null);
static bool isValidReplyChannel(S32 nChannel);
static bool isValidReplyChannel(S32 nChannel, bool fLoopback = false);
static bool sendChatReply(S32 nChannel, const std::string& strUTF8Text);
static bool sendChatReply(const std::string& strChannel, const std::string& strUTF8Text);
@ -301,9 +299,9 @@ inline bool RlvUtil::isEmote(const std::string& strUTF8Text)
}
// Checked: 2010-03-09 (RLVa-1.2.0b) | Added: RLVa-1.0.2a
inline bool RlvUtil::isValidReplyChannel(S32 nChannel)
inline bool RlvUtil::isValidReplyChannel(S32 nChannel, bool fLoopback /*=false*/)
{
return (nChannel > 0) && (CHAT_CHANNEL_DEBUG != nChannel);
return (nChannel > ((!fLoopback) ? 0 : -1)) && (CHAT_CHANNEL_DEBUG != nChannel);
}
// Checked: 2009-08-05 (RLVa-1.0.1e) | Added: RLVa-1.0.0e

View File

@ -17,40 +17,6 @@
#ifndef RLV_DEFINES_H
#define RLV_DEFINES_H
// ============================================================================
// Extensions
//
// Extensions
#define RLV_EXTENSION_CMD_GETSETDEBUG_EX // Extends the debug variables accessible through @getdebug_xxx/@setdebug_xxx
#define RLV_EXTENSION_CMD_FINDFOLDERS // @findfolders:<option>=<channel> - @findfolder with multiple results
#define RLV_EXTENSION_FORCEWEAR_GESTURES // @attach*/detach* commands also (de)activate gestures
#define RLV_EXTENSION_STARTLOCATION // Reenables "Start Location" at login if not @tploc=n or @unsit=n restricted at last logoff
#define RLV_EXPERIMENTAL // Enables/disables experimental features en masse
#define RLV_EXPERIMENTAL_CMDS // Enables/disables experimental commands en masse
// Experimental features
#ifdef RLV_EXPERIMENTAL
// Stable (will mature to RLV_EXTENSION_XXX in next release if no bugs are found)
// Under testing (stable, but requires further testing - safe for public release but may be quirky)
#define RLV_EXTENSION_FORCEWEAR_FOLDERLINKS // @attach*/detach* commands will collect from folder links as well
// Under development (don't include in public release)
#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
// #define RLV_EXPERIMENTAL_COMPOSITEFOLDERS
#endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
#endif // RLV_EXPERIMENTAL
// Experimental commands (not part of the RLV API spec, disabled on public releases)
#ifdef RLV_EXPERIMENTAL_CMDS
#define RLV_EXTENSION_CMD_ALLOWIDLE // Forces "Away" status when idle (effect is the same as setting AllowIdleAFK to TRUE)
#define RLV_EXTENSION_CMD_GETCOMMAND // @getcommand:<option>=<channel>
#define RLV_EXTENSION_CMD_GETXXXNAMES // @get[add|rem]attachnames:<option>=<channel> and @get[add|rem]outfitnames=<channel>
#define RLV_EXTENSION_CMD_INTERACT // @interact=n
#define RLV_EXTENSION_CMD_TOUCHXXX // @touch:uuid=n|y, @touchworld[:<uuid>]=n|y, @touchattach[:<uuid>]=n|y, @touchud[:<uuid>]=n|y
#endif // RLV_EXPERIMENTAL_CMDS
// ============================================================================
// Defines
//
@ -100,6 +66,7 @@ const S32 RLVa_VERSION_BUILD = 0;
#define RLV_ROOT_FOLDER "#RLV"
#define RLV_CMD_PREFIX '@'
#define RLV_OPTION_SEPARATOR ";" // Default separator used in command options
#define RLV_PUTINV_PREFIX "#RLV/~"
#define RLV_PUTINV_SEPARATOR "/"
#define RLV_PUTINV_MAXDEPTH 4

View File

@ -385,11 +385,9 @@ RlvExtGetSet::RlvExtGetSet()
{
m_DbgAllowed.insert(std::pair<std::string, S16>("AvatarSex", DBG_READ | DBG_WRITE | DBG_PSEUDO));
m_DbgAllowed.insert(std::pair<std::string, S16>("RenderResolutionDivisor", DBG_READ | DBG_WRITE));
#ifdef RLV_EXTENSION_CMD_GETSETDEBUG_EX
m_DbgAllowed.insert(std::pair<std::string, S16>(RLV_SETTING_FORBIDGIVETORLV, DBG_READ));
m_DbgAllowed.insert(std::pair<std::string, S16>(RLV_SETTING_NOSETENV, DBG_READ));
m_DbgAllowed.insert(std::pair<std::string, S16>("WindLightUseAtmosShaders", DBG_READ));
#endif // RLV_EXTENSION_CMD_GETSETDEBUG_EX
m_DbgAllowed.insert(std::pair<std::string, S16>(RLV_SETTING_FORBIDGIVETORLV, DBG_READ));
m_DbgAllowed.insert(std::pair<std::string, S16>(RLV_SETTING_NOSETENV, DBG_READ));
m_DbgAllowed.insert(std::pair<std::string, S16>("WindLightUseAtmosShaders", DBG_READ));
// Cache persistance of every setting
LLControlVariable* pSetting;

View File

@ -16,6 +16,7 @@
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
#include "llappearancemgr.h"
#include "llavatarnamecache.h"
#include "llclipboard.h"
@ -672,3 +673,100 @@ void RlvFloaterStrings::refresh()
}
// ============================================================================
// RlvFloaterConsole
//
static const char s_strRlvConsolePrompt[] = "> ";
static const char s_strRlvConsoleDisabled[] = "RLVa is disabled";
static const char s_strRlvConsoleInvalid[] = "Invalid command";
RlvFloaterConsole::RlvFloaterConsole(const LLSD& sdKey)
: LLFloater(sdKey), m_pOutputText(nullptr)
{
}
RlvFloaterConsole::~RlvFloaterConsole()
{
}
BOOL RlvFloaterConsole::postBuild()
{
LLLineEditor* pInputEdit = getChild<LLLineEditor>("console_input");
pInputEdit->setEnableLineHistory(true);
pInputEdit->setCommitCallback(boost::bind(&RlvFloaterConsole::onInput, this, _1, _2));
pInputEdit->setFocus(true);
pInputEdit->setCommitOnFocusLost(false);
m_pOutputText = getChild<LLTextEditor>("console_output");
m_pOutputText->appendText(s_strRlvConsolePrompt, false);
return TRUE;
}
void RlvFloaterConsole::addCommandReply(const std::string& strCommand, const std::string& strReply)
{
m_pOutputText->appendText(llformat("%s: ", strCommand.c_str()), true);
m_pOutputText->appendText(strReply, false);
}
void RlvFloaterConsole::onInput(LLUICtrl* pCtrl, const LLSD& sdParam)
{
LLLineEditor* pInputEdit = static_cast<LLLineEditor*>(pCtrl);
std::string strInput = pInputEdit->getText();
m_pOutputText->appendText(strInput, false);
pInputEdit->clear();
if (!rlv_handler_t::isEnabled())
{
m_pOutputText->appendText(s_strRlvConsoleDisabled, true);
}
else if ( (strInput.length() <= 3) || (RLV_CMD_PREFIX != strInput[0]) )
{
m_pOutputText->appendText(s_strRlvConsoleInvalid, true);
}
else
{
strInput.erase(0, 1);
LLStringUtil::toLower(strInput);
std::string strExecuted, strFailed, strRetained, *pstr;
boost_tokenizer tokens(strInput, boost::char_separator<char>(",", "", boost::drop_empty_tokens));
for (std::string strCmd : tokens)
{
ERlvCmdRet eRet = gRlvHandler.processCommand(gAgent.getID(), strCmd, true);
if ( RLV_RET_SUCCESS == (eRet & RLV_RET_SUCCESS) )
pstr = &strExecuted;
else if ( RLV_RET_FAILED == (eRet & RLV_RET_FAILED) )
pstr = &strFailed;
else if (RLV_RET_RETAINED == eRet)
pstr = &strRetained;
else
{
RLV_ASSERT(false);
pstr = &strFailed;
}
if (const char* pstrSuffix = RlvStrings::getStringFromReturnCode(eRet))
strCmd.append(" (").append(pstrSuffix).append(")");
else if (RLV_RET_SUCCESS == (eRet & RLV_RET_SUCCESS))
strCmd.clear(); // Only show feedback on successful commands when there's an informational notice
if (!pstr->empty())
pstr->push_back(',');
pstr->append(strCmd);
}
if (!strExecuted.empty())
m_pOutputText->appendText("INFO: @" + strExecuted, true);
if (!strFailed.empty())
m_pOutputText->appendText("ERR: @" + strFailed, true);
if (!strRetained.empty())
m_pOutputText->appendText("RET: @" + strRetained, true);
}
m_pOutputText->appendText(s_strRlvConsolePrompt, true);
}
// ============================================================================

View File

@ -22,6 +22,12 @@
#include "rlvdefines.h"
#include "rlvcommon.h"
// ============================================================================
// Foward declarations
//
class LLComboBox;
class LLTextEditor;
// ============================================================================
// RlvFloaterLocks class declaration
//
@ -118,6 +124,39 @@ protected:
LLSD m_sdStringsInfo;
};
// ============================================================================
// RlvFloaterConsole - debug console to allow command execution without the need for a script
//
class RlvFloaterConsole : public LLFloater
{
friend class LLFloaterReg;
template<ERlvParamType> friend struct RlvCommandHandlerBaseImpl;
friend class RlvHandler;
private:
RlvFloaterConsole(const LLSD& sdKey);
~RlvFloaterConsole() override;
/*
* LLFloater overrides
*/
public:
BOOL postBuild() override;
/*
* Member functions
*/
protected:
void addCommandReply(const std::string& strCommand, const std::string& strReply);
void onInput(LLUICtrl* ctrl, const LLSD& param);
/*
* Member variables
*/
protected:
LLTextEditor* m_pOutputText;
};
// ============================================================================
#endif // RLV_FLOATERS_H

View File

@ -14,6 +14,7 @@
*
*/
// Generic includes
#include "llviewerprecompiledheaders.h"
#include "llagent.h"
#include "llappearancemgr.h"
@ -27,6 +28,17 @@
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
// Command specific includes
#include "llenvmanager.h" // @setenv
#include "lloutfitslist.h" // @showinv - "Appearance / My Outfits" panel
#include "llpaneloutfitsinventory.h" // @showinv - "Appearance" floater
#include "llpanelwearing.h" // @showinv - "Appearance / Current Outfit" panel
#include "llsidepanelappearance.h" // @showinv - "Appearance / Edit appearance" panel
#include "lltabcontainer.h" // @showinv - Tab container control for inventory tabs
#include "lltoolmgr.h" // @edit
// RLVa includes
#include "rlvfloaters.h"
#include "rlvhandler.h"
#include "rlvhelper.h"
#include "rlvinventory.h"
@ -34,6 +46,7 @@
#include "rlvui.h"
#include "rlvextensions.h"
// Boost includes
#include <boost/algorithm/string.hpp>
// ============================================================================
@ -48,23 +61,33 @@ rlv_handler_t gRlvHandler;
// Option parsing template specialization implmentation
//
template <class optionType>
struct RlvCommandOptionParser
struct RlvCommandOptionHelper
{
template <typename optionType>
static bool parseOption(const std::string& strOption, optionType& valueOption);
static bool parseStringList(const std::string& strOption, std::vector<std::string>& optionList);
};
bool RlvCommandOptionParser<LLUUID>::parseOption(const std::string& strOption, LLUUID& idOption)
template<>
bool RlvCommandOptionHelper::parseOption<LLUUID>(const std::string& strOption, LLUUID& idOption)
{
idOption.set(strOption);
return idOption.notNull();
}
bool RlvCommandOptionParser<int>::parseOption(const std::string& strOption, int& nOption)
template<>
bool RlvCommandOptionHelper::parseOption<int>(const std::string& strOption, int& nOption)
{
return LLStringUtil::convertToS32(strOption, nOption);
}
bool RlvCommandOptionHelper::parseStringList(const std::string& strOption, std::vector<std::string>& optionList)
{
if (!strOption.empty())
boost::split(optionList, strOption, boost::is_any_of(std::string(RLV_OPTION_SEPARATOR)));
return !optionList.empty();
}
// ============================================================================
// Command specific helper functions
//
@ -474,12 +497,10 @@ bool RlvHandler::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD&
// Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c
void RlvHandler::onSitOrStand(bool fSitting)
{
#ifdef RLV_EXTENSION_STARTLOCATION
if (rlv_handler_t::isEnabled())
{
RlvSettings::updateLoginLastLocation();
}
#endif // RLV_EXTENSION_STARTLOCATION
if ( (hasBehaviour(RLV_BHVR_STANDTP)) && (!fSitting) && (!m_posSitSource.isExactlyZero()) )
{
@ -668,10 +689,7 @@ void RlvHandler::onLoginComplete()
{
RlvInventory::instance().fetchWornItems();
RlvInventory::instance().fetchSharedInventory();
#ifdef RLV_EXTENSION_STARTLOCATION
RlvSettings::updateLoginLastLocation();
#endif // RLV_EXTENSION_STARTLOCATION
LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&RlvHandler::onTeleportFailed, this));
LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&RlvHandler::onTeleportFinished, this, _1));
@ -739,13 +757,11 @@ bool RlvHandler::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset
((!hasBehaviour(RLV_BHVR_TOUCHATTACH)) || (isException(RLV_BHVR_TOUCHATTACH, idRoot, RLV_CHECK_PERMISSIVE))) &&
((!hasBehaviour(RLV_BHVR_TOUCHATTACHSELF)) || (isException(RLV_BHVR_TOUCHATTACH, idRoot, RLV_CHECK_PERMISSIVE)));
}
#ifdef RLV_EXTENSION_CMD_TOUCHXXX
else
{
// HUD attachment
fCanTouch = (!hasBehaviour(RLV_BHVR_TOUCHHUD)) || (isException(RLV_BHVR_TOUCHHUD, idRoot, RLV_CHECK_PERMISSIVE));
}
#endif // RLV_EXTENSION_CMD_TOUCHXXX
}
if ( (!fCanTouch) && (hasBehaviour(RLV_BHVR_TOUCHME)) )
fCanTouch = hasBehaviourRoot(idRoot, RLV_BHVR_TOUCHME);
@ -1300,7 +1316,7 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
}
// Handles reference counting of behaviours and tracks strict exceptions for @permissive (all restriction handlers should call this function)
ERlvCmdRet RlvBehaviourProcessorHelper::processBehaviourImpl(const RlvCommand& rlvCmd, RlvBhvrHandler* pHandlerFunc, RlvBhvrToggleHandler* pToggleHandlerFunc)
ERlvCmdRet RlvCommandHandlerBaseImpl<RLV_TYPE_ADDREM>::processCommand(const RlvCommand& rlvCmd, RlvBhvrHandlerFunc* pHandlerFunc, RlvBhvrToggleHandlerFunc* pToggleHandlerFunc)
{
ERlvBehaviour eBhvr = rlvCmd.getBehaviourType();
bool fRefCount = false, fHasBhvr = gRlvHandler.hasBehaviour(eBhvr);
@ -1350,7 +1366,7 @@ ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_EXCEPTION>::onCommand(const Rlv
{
// There should be an option and it should specify a valid UUID
LLUUID idException;
if (!RlvCommandOptionParser<LLUUID>::parseOption(rlvCmd.getOption(), idException))
if (!RlvCommandOptionHelper::parseOption(rlvCmd.getOption(), idException))
return RLV_RET_FAILED_OPTION;
if (RLV_TYPE_ADD == rlvCmd.getParamType())
@ -1375,6 +1391,8 @@ ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_NONE_OR_EXCEPTION>::onCommand(c
return RlvBehaviourGenericHandler<RLV_OPTION_NONE>::onCommand(rlvCmd, fRefCount);
}
// Handles: @addattach[:<attachpt>]=n|y and @remattach[:<attachpt>]=n|y
template<> template<>
ERlvCmdRet RlvBehaviourAddRemAttachHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount)
{
// Sanity check - if there's an option it should specify a valid attachment point name
@ -1406,6 +1424,8 @@ ERlvCmdRet RlvBehaviourAddRemAttachHandler::onCommand(const RlvCommand& rlvCmd,
return RLV_RET_SUCCESS;
}
// Handles: @detach[:<attachpt>]=n|y
template<> template<>
ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_DETACH>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount)
{
// We need to flush any queued force-wear commands before changing the restrictions
@ -1516,21 +1536,47 @@ ERlvCmdRet RlvHandler::onAddRemFolderLockException(const RlvCommand& rlvCmd, boo
return RLV_RET_SUCCESS;
}
// Handles: @edit=n|y toggles
template<> template<>
void RlvBehaviourToggleHandler<RLV_BHVR_EDIT>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
{
if (fHasBhvr)
{
// Turn off "View / Highlight Transparent"
LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
// Hide the beacons floater if it's currently visible
if (LLFloaterReg::instanceVisible("beacons"))
LLFloaterReg::hideInstance("beacons");
// Hide the build floater if it's currently visible
if (LLFloaterReg::instanceVisible("build"))
LLToolMgr::instance().toggleBuildMode();
}
// Start or stop filtering opening the beacons floater
if (fHasBhvr)
RlvUIEnabler::instance().addGenericFloaterFilter("beacons");
else
RlvUIEnabler::instance().removeGenericFloaterFilter("beacons");
}
// Handles: @sendchannel[:<channel>]=n|y
template<> template<>
ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SENDCHANNEL>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount)
{
// If there's an option then it should be a valid (= positive and non-zero) chat channel
if (rlvCmd.hasOption())
{
S32 nChannel = 0;
if ( (!RlvCommandOptionParser<int>::parseOption(rlvCmd.getOption(), nChannel)) || (nChannel <= 0) )
if ( (!RlvCommandOptionHelper::parseOption(rlvCmd.getOption(), nChannel)) || (nChannel <= 0) )
return RLV_RET_FAILED_OPTION;
if (RLV_TYPE_ADD == rlvCmd.getParamType())
gRlvHandler.addException(rlvCmd.getObjectID(), rlvCmd.getBehaviourType(), nChannel);
else
gRlvHandler.removeException(rlvCmd.getObjectID(), rlvCmd.getBehaviourType(), nChannel);
}
}
else
{
fRefCount = true;
@ -1539,17 +1585,60 @@ ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SENDCHANNEL>::onCommand(const RlvCommand
}
// Handles: @sendim=n|y toggles
template<> template<>
void RlvBehaviourToggleHandler<RLV_BHVR_SENDIM>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
{
gSavedPerAccountSettings.getControl("DoNotDisturbModeResponse")->setHiddenFromSettingsEditor(fHasBhvr);
}
// Handles: @edit=n|y toggles
template<> template<>
void RlvBehaviourToggleHandler<RLV_BHVR_SETDEBUG>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
{
for (const auto& dbgSetting : RlvExtGetSet::m_DbgAllowed)
{
if (dbgSetting.second & RlvExtGetSet::DBG_WRITE)
gSavedSettings.getControl(dbgSetting.first)->setHiddenFromSettingsEditor(fHasBhvr);
}
}
// Handles: @edit=n|y toggles
template<> template<>
void RlvBehaviourToggleHandler<RLV_BHVR_SETENV>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
{
const std::string strEnvFloaters[] = { "env_post_process", "env_settings", "env_delete_preset", "env_edit_sky", "env_edit_water", "env_edit_day_cycle" };
for (int idxFloater = 0, cntFloater = sizeof(strEnvFloaters) / sizeof(std::string); idxFloater < cntFloater; idxFloater++)
{
if (fHasBhvr)
{
// Hide the floater if it's currently visible
LLFloaterReg::const_instance_list_t envFloaters = LLFloaterReg::getFloaterList(strEnvFloaters[idxFloater]);
for (LLFloater* pFloater : envFloaters)
pFloater->closeFloater();
RlvUIEnabler::instance().addGenericFloaterFilter(strEnvFloaters[idxFloater]);
}
else
{
RlvUIEnabler::instance().removeGenericFloaterFilter(strEnvFloaters[idxFloater]);
}
}
// Don't allow toggling "Basic Shaders" and/or "Atmopsheric Shaders" through the debug settings under @setenv=n
gSavedSettings.getControl("VertexShaderEnable")->setHiddenFromSettingsEditor(fHasBhvr);
gSavedSettings.getControl("WindLightUseAtmosShaders")->setHiddenFromSettingsEditor(fHasBhvr);
// Restore the user's WindLight preferences when releasing
if (!fHasBhvr)
LLEnvManagerNew::instance().usePrefs();
}
// Handles: @showhovertext:<uuid>=n|y
template<> template<>
ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SHOWHOVERTEXT>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount)
{
// There should be an option and it should specify a valid UUID
LLUUID idException;
if (!RlvCommandOptionParser<LLUUID>::parseOption(rlvCmd.getOption(), idException))
if (!RlvCommandOptionHelper::parseOption(rlvCmd.getOption(), idException))
return RLV_RET_FAILED_OPTION;
if (RLV_TYPE_ADD == rlvCmd.getParamType())
@ -1566,10 +1655,70 @@ ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_SHOWHOVERTEXT>::onCommand(const RlvComma
return RLV_RET_SUCCESS;
}
// Handles: @edit=n|y toggles
template<> template<>
void RlvBehaviourToggleHandler<RLV_BHVR_SHOWINV>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
{
if (LLApp::isQuitting())
return; // Nothing to do if the viewer is shutting down
//
// When disabling, close any inventory floaters that may be open
//
if (fHasBhvr)
{
LLFloaterReg::const_instance_list_t invFloaters = LLFloaterReg::getFloaterList("inventory");
for (LLFloater* pFloater : invFloaters)
pFloater->closeFloater();
}
//
// Enable/disable the "My Outfits" panel on the "My Appearance" sidebar tab
//
LLPanelOutfitsInventory* pAppearancePanel = LLPanelOutfitsInventory::findInstance();
RLV_ASSERT(pAppearancePanel);
if (pAppearancePanel)
{
LLTabContainer* pAppearanceTabs = pAppearancePanel->getAppearanceTabs();
LLOutfitsList* pMyOutfitsPanel = pAppearancePanel->getMyOutfitsPanel();
if ( (pAppearanceTabs) && (pMyOutfitsPanel) )
{
S32 idxTab = pAppearanceTabs->getIndexForPanel(pMyOutfitsPanel);
RLV_ASSERT(-1 != idxTab);
pAppearanceTabs->enableTabButton(idxTab, !fHasBhvr);
// When disabling, switch to the COF tab if "My Outfits" is currently active
if ( (fHasBhvr) && (pAppearanceTabs->getCurrentPanelIndex() == idxTab) )
pAppearanceTabs->selectTabPanel(pAppearancePanel->getCurrentOutfitPanel());
}
LLSidepanelAppearance* pCOFPanel = pAppearancePanel->getAppearanceSP();
RLV_ASSERT(pCOFPanel);
if ( (fHasBhvr) && (pCOFPanel) && (pCOFPanel->isOutfitEditPanelVisible()) )
{
// TODO-RLVa: we should really just be collapsing the "Add more..." inventory panel (and disable the button)
pCOFPanel->showOutfitsInventoryPanel();
}
}
//
// Filter (or stop filtering) opening new inventory floaters
//
if (fHasBhvr)
RlvUIEnabler::instance().addGenericFloaterFilter("inventory");
else
RlvUIEnabler::instance().removeGenericFloaterFilter("inventory");
}
// ============================================================================
// Command handlers (RLV_TYPE_FORCE)
//
ERlvCmdRet RlvCommandHandlerBaseImpl<RLV_TYPE_FORCE>::processCommand(const RlvCommand& rlvCmd, RlvForceHandlerFunc* pHandler)
{
return (*pHandler)(rlvCmd);
}
// Checked: 2010-04-07 (RLVa-1.2.0d) | Modified: RLVa-1.1.0j
ERlvCmdRet RlvHandler::processForceCommand(const RlvCommand& rlvCmd) const
{
@ -1761,7 +1910,8 @@ void RlvHandler::onForceWearCallback(const uuid_vec_t& idItems, U32 nFlags) cons
}
// Handles: @setgroup:<uuid|name>=force
ERlvCmdRet RlvCommandHandler<RLV_TYPE_FORCE, RLV_BHVR_SETGROUP>::onCommand(const RlvCommand& rlvCmd)
template<> template<>
ERlvCmdRet RlvForceHandler<RLV_BHVR_SETGROUP>::onCommand(const RlvCommand& rlvCmd)
{
if (gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETGROUP, rlvCmd.getObjectID()))
{
@ -1791,7 +1941,8 @@ ERlvCmdRet RlvCommandHandler<RLV_TYPE_FORCE, RLV_BHVR_SETGROUP>::onCommand(const
}
// Handles: @sit:<uuid>=force
ERlvCmdRet RlvCommandHandler<RLV_TYPE_FORCE, RLV_BHVR_SIT>::onCommand(const RlvCommand& rlvCmd)
template<> template<>
ERlvCmdRet RlvForceHandler<RLV_BHVR_SIT>::onCommand(const RlvCommand& rlvCmd)
{
LLViewerObject* pObj = NULL; LLUUID idTarget(rlvCmd.getOption());
// Sanity checking - we need to know about the object and it should identify a prim/linkset
@ -1824,17 +1975,49 @@ ERlvCmdRet RlvCommandHandler<RLV_TYPE_FORCE, RLV_BHVR_SIT>::onCommand(const RlvC
// Command handlers (RLV_TYPE_REPLY)
//
ERlvCmdRet RlvCommandHandlerBaseImpl<RLV_TYPE_REPLY>::processCommand(const RlvCommand& rlvCmd, RlvReplyHandlerFunc* pHandler)
{
// Sanity check - <param> should specify a - valid - reply channel
S32 nChannel;
if ( (!LLStringUtil::convertToS32(rlvCmd.getParam(), nChannel)) || (!RlvUtil::isValidReplyChannel(nChannel, rlvCmd.getObjectID() == gAgent.getID())) )
return RLV_RET_FAILED_PARAM;
std::string strReply;
ERlvCmdRet eRet = (*pHandler)(rlvCmd, strReply);
// If we made it this far then:
// - the command was handled successfully so we send off the response
// - the command failed but we still send off an - empty - response to keep the issuing script from blocking
if (nChannel != 0)
RlvUtil::sendChatReply(nChannel, strReply);
else
{
if (RlvFloaterConsole* pConsole = LLFloaterReg::findTypedInstance<RlvFloaterConsole>("rlv_console"))
pConsole->addCommandReply(rlvCmd.getBehaviour(), strReply);
}
return eRet;
}
// Checked: 2010-04-07 (RLVa-1.2.0d) | Modified: RLVa-1.1.0f
ERlvCmdRet RlvHandler::processReplyCommand(const RlvCommand& rlvCmd) const
{
RLV_ASSERT(RLV_TYPE_REPLY == rlvCmd.getParamType());
// Try a command processor first
ERlvCmdRet eRet = rlvCmd.processCommand();
if (RLV_RET_NO_PROCESSOR != eRet)
{
return eRet;
}
// Sanity check - <param> should specify a - valid - reply channel
S32 nChannel;
if ( (!LLStringUtil::convertToS32(rlvCmd.getParam(), nChannel)) || (!RlvUtil::isValidReplyChannel(nChannel)) )
if ( (!LLStringUtil::convertToS32(rlvCmd.getParam(), nChannel)) || (!RlvUtil::isValidReplyChannel(nChannel, rlvCmd.getObjectID() == gAgent.getID())) )
return RLV_RET_FAILED_PARAM;
ERlvCmdRet eRet = RLV_RET_SUCCESS; std::string strReply;
// Process the command the legacy way
eRet = RLV_RET_SUCCESS; std::string strReply;
switch (rlvCmd.getBehaviourType())
{
case RLV_BHVR_VERSION: // @version=<channel> - Checked: 2010-03-27 (RLVa-1.4.0a)
@ -1849,27 +2032,21 @@ ERlvCmdRet RlvHandler::processReplyCommand(const RlvCommand& rlvCmd) const
case RLV_BHVR_GETATTACH: // @getattach[:<layer>]=<channel>
eRet = onGetAttach(rlvCmd, strReply);
break;
#ifdef RLV_EXTENSION_CMD_GETXXXNAMES
case RLV_BHVR_GETATTACHNAMES: // @getattachnames[:<grp>]=<channel>
case RLV_BHVR_GETADDATTACHNAMES:// @getaddattachnames[:<grp>]=<channel>
case RLV_BHVR_GETREMATTACHNAMES:// @getremattachnames[:<grp>]=<channel>
eRet = onGetAttachNames(rlvCmd, strReply);
break;
#endif // RLV_EXTENSION_CMD_GETXXXNAMES
case RLV_BHVR_GETOUTFIT: // @getoutfit[:<layer>]=<channel>
eRet = onGetOutfit(rlvCmd, strReply);
break;
#ifdef RLV_EXTENSION_CMD_GETXXXNAMES
case RLV_BHVR_GETOUTFITNAMES: // @getoutfitnames=<channel>
case RLV_BHVR_GETADDOUTFITNAMES:// @getaddoutfitnames=<channel>
case RLV_BHVR_GETREMOUTFITNAMES:// @getremoutfitnames=<channel>
eRet = onGetOutfitNames(rlvCmd, strReply);
break;
#endif // RLV_EXTENSION_CMD_GETXXXNAMES
case RLV_BHVR_FINDFOLDER: // @findfolder:<criteria>=<channel>
#ifdef RLV_EXTENSION_CMD_FINDFOLDERS
case RLV_BHVR_FINDFOLDERS: // @findfolders:<criteria>=<channel>
#endif // RLV_EXTENSION_CMD_FINDFOLDERS
eRet = onFindFolder(rlvCmd, strReply);
break;
case RLV_BHVR_GETPATH: // @getpath[:<option>]=<channel>
@ -1898,16 +2075,6 @@ ERlvCmdRet RlvHandler::processReplyCommand(const RlvCommand& rlvCmd) const
strReply = idSitObj.asString();
}
break;
#ifdef RLV_EXTENSION_CMD_GETCOMMAND
case RLV_BHVR_GETCOMMAND: // @getcommand:<option>=<channel> - Checked: 2010-12-11 (RLVa-1.2.2c) | Added: RLVa-1.2.2c
{
std::list<std::string> cmdList;
if (RlvBehaviourDictionary::instance().getCommands(rlvCmd.getOption(), RLV_TYPE_UNKNOWN, cmdList))
for (std::list<std::string>::const_iterator itCmd = cmdList.begin(); itCmd != cmdList.end(); ++itCmd)
strReply.append("/").append(*itCmd);
}
break;
#endif // RLV_EXTENSION_CMD_GETCOMMAND
case RLV_BHVR_GETSTATUS: // @getstatus - Checked: 2010-04-07 (RLVa-1.2.0d) | Modified: RLVa-1.1.0f
{
std::string strFilter, strSeparator;
@ -1942,7 +2109,13 @@ ERlvCmdRet RlvHandler::processReplyCommand(const RlvCommand& rlvCmd) const
// If we made it this far then:
// - the command was handled successfully so we send off the response
// - the command failed but we still send off an - empty - response to keep the issuing script from blocking
RlvUtil::sendChatReply(nChannel, strReply);
if (nChannel > 0)
RlvUtil::sendChatReply(nChannel, strReply);
else
{
if (RlvFloaterConsole* pConsole = LLFloaterReg::findTypedInstance<RlvFloaterConsole>("rlv_console"))
pConsole->addCommandReply(rlvCmd.getBehaviour(), strReply);
}
return eRet;
}
@ -2066,6 +2239,35 @@ ERlvCmdRet RlvHandler::onGetAttachNames(const RlvCommand& rlvCmd, std::string& s
return RLV_RET_SUCCESS;
}
// Handles: @getcommand[:<behaviour>[;<type>[;<separator>]]]=<channel>
template<> template<>
ERlvCmdRet RlvReplyHandler<RLV_BHVR_GETCOMMAND>::onCommand(const RlvCommand& rlvCmd, std::string& strReply)
{
std::vector<std::string> optionList;
RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList);
// If a second parameter is present it'll specify the command type
ERlvParamType eType = RLV_TYPE_UNKNOWN;
if (optionList.size() >= 2)
{
if ( (optionList[1] == "any") || (optionList[1].empty()) )
eType = RLV_TYPE_UNKNOWN;
else if (optionList[1] == "add")
eType = RLV_TYPE_ADDREM;
else if (optionList[1] == "force")
eType = RLV_TYPE_FORCE;
else if (optionList[1] == "reply")
eType = RLV_TYPE_REPLY;
else
return RLV_RET_FAILED_OPTION;
}
std::list<std::string> cmdList;
if (RlvBehaviourDictionary::instance().getCommands((optionList.size() >= 1) ? optionList[0] : LLStringUtil::null, eType, cmdList))
strReply = boost::algorithm::join(cmdList, (optionList.size() >= 3) ? optionList[2] : std::string(RLV_OPTION_SEPARATOR) );
return RLV_RET_SUCCESS;
}
// Checked: 2010-03-09 (RLVa-1.2.0a) | Modified: RLVa-1.1.0f
ERlvCmdRet RlvHandler::onGetInv(const RlvCommand& rlvCmd, std::string& strReply) const
{

View File

@ -209,11 +209,8 @@ protected:
friend class RlvSharedRootFetcher; // Fetcher needs access to m_fFetchComplete
friend class RlvGCTimer; // Timer clear its own point at destruction
friend class RlvBehaviourProcessorHelper;
template <RlvBehaviourOptionType> friend struct RlvBehaviourGenericHandler;
template <ERlvBehaviour> friend struct RlvBehaviourHandler;
template <ERlvBehaviour> friend struct RlvBehaviourToggleHandler;
template <ERlvParamType, ERlvBehaviour> friend struct RlvCommandHandler;
template<ERlvParamType> friend struct RlvCommandHandlerBaseImpl;
template<ERlvParamType, ERlvBehaviour> friend struct RlvCommandHandler;
// --------------------------------

View File

@ -56,7 +56,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
addEntry(new RlvBehaviourInfo("detachallthis", RLV_BHVR_DETACHTHIS, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_SUBTREE));
addEntry(new RlvBehaviourInfo("detachthis_except", RLV_BHVR_DETACHTHISEXCEPT, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_NODE));
addEntry(new RlvBehaviourInfo("detachallthis_except", RLV_BHVR_DETACHTHISEXCEPT, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_SUBTREE));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("edit", RLV_BHVR_EDIT));
addEntry(new RlvBehaviourToggleProcessor<RLV_BHVR_EDIT, RLV_OPTION_NONE_OR_EXCEPTION>("edit"));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_EXCEPTION>("editobj", RLV_BHVR_EDITOBJ));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("emote", RLV_BHVR_EMOTE));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("fartouch", RLV_BHVR_FARTOUCH));
@ -80,8 +80,8 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
addEntry(new RlvBehaviourToggleProcessor<RLV_BHVR_SENDIM, RLV_OPTION_NONE_OR_EXCEPTION>("sendim", RlvBehaviourInfo::BHVR_STRICT));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_EXCEPTION>("sendimto", RLV_BHVR_SENDIMTO, RlvBehaviourInfo::BHVR_STRICT));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("sendgesture", RLV_BHVR_SENDGESTURE, RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("setdebug", RLV_BHVR_SETDEBUG));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("setenv", RLV_BHVR_SETENV));
addEntry(new RlvBehaviourToggleProcessor<RLV_BHVR_SETDEBUG, RLV_OPTION_NONE>("setdebug"));
addEntry(new RlvBehaviourToggleProcessor<RLV_BHVR_SETENV, RLV_OPTION_NONE>("setenv"));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("setgroup", RLV_BHVR_SETGROUP));
addEntry(new RlvBehaviourInfo("sharedunwear", RLV_BHVR_SHAREDUNWEAR, RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_EXTENDED));
addEntry(new RlvBehaviourInfo("sharedwear", RLV_BHVR_SHAREDWEAR, RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_EXTENDED));
@ -89,7 +89,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("showhovertextall", RLV_BHVR_SHOWHOVERTEXTALL));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("showhovertexthud", RLV_BHVR_SHOWHOVERTEXTHUD));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("showhovertextworld", RLV_BHVR_SHOWHOVERTEXTWORLD));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("showinv", RLV_BHVR_SHOWINV));
addEntry(new RlvBehaviourToggleProcessor<RLV_BHVR_SHOWINV, RLV_OPTION_NONE>("showinv"));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("showloc", RLV_BHVR_SHOWLOC));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("showminimap", RLV_BHVR_SHOWMINIMAP));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("shownames", RLV_BHVR_SHOWNAMES));
@ -157,8 +157,8 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
//
addEntry(new RlvBehaviourInfo("adjustheight", RLV_BHVR_ADJUSTHEIGHT, RLV_TYPE_FORCE));
addEntry(new RlvBehaviourInfo("detachme", RLV_BHVR_DETACHME, RLV_TYPE_FORCE));
addEntry(new RlvCommandProcessor<RLV_TYPE_FORCE, RLV_BHVR_SETGROUP>("setgroup"));
addEntry(new RlvCommandProcessor<RLV_TYPE_FORCE, RLV_BHVR_SIT>("sit"));
addEntry(new RlvForceProcessor<RLV_BHVR_SETGROUP>("setgroup"));
addEntry(new RlvForceProcessor<RLV_BHVR_SIT>("sit"));
addEntry(new RlvBehaviourInfo("tpto", RLV_BHVR_TPTO, RLV_TYPE_FORCE));
addEntry(new RlvBehaviourInfo("unsit", RLV_BHVR_UNSIT, RLV_TYPE_FORCE));
@ -171,7 +171,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
addEntry(new RlvBehaviourInfo("getaddoutfitnames", RLV_BHVR_GETADDOUTFITNAMES, RLV_TYPE_REPLY, RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvBehaviourInfo("getattach", RLV_BHVR_GETATTACH, RLV_TYPE_REPLY));
addEntry(new RlvBehaviourInfo("getattachnames", RLV_BHVR_GETATTACHNAMES, RLV_TYPE_REPLY, RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvBehaviourInfo("getcommand", RLV_BHVR_GETCOMMAND, RLV_TYPE_REPLY, RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvReplyProcessor<RLV_BHVR_GETCOMMAND>("getcommand", RlvBehaviourInfo::BHVR_EXTENDED));
addEntry(new RlvBehaviourInfo("getgroup", RLV_BHVR_GETGROUP, RLV_TYPE_REPLY));
addEntry(new RlvBehaviourInfo("getinv", RLV_BHVR_GETINV, RLV_TYPE_REPLY));
addEntry(new RlvBehaviourInfo("getinvworn", RLV_BHVR_GETINVWORN, RLV_TYPE_REPLY));
@ -205,7 +205,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
RLV_ASSERT( (itBhvr.first != pBhvrInfo->getBehaviourType()) || (itBhvr.second->getBehaviourFlags() != pBhvrInfo->getBehaviourFlags()) );
}
#endif // RLV_DEBUG
m_Bhvr2InfoMap.insert(std::pair<ERlvBehaviour, const RlvBehaviourInfo*>(pBhvrInfo->getBehaviourType(), pBhvrInfo));
m_Bhvr2InfoMap.insert(std::pair<ERlvBehaviour, const RlvBehaviourInfo*>(pBhvrInfo->getBehaviourType(), pBhvrInfo));
}
}
@ -223,6 +223,13 @@ RlvBehaviourDictionary::~RlvBehaviourDictionary()
void RlvBehaviourDictionary::addEntry(const RlvBehaviourInfo* pEntry)
{
// Filter experimental commands (if disabled)
static LLCachedControl<bool> sEnableExperimental(gSavedSettings, "RLVaExperimentalCommands");
if ( (!pEntry) || ((!sEnableExperimental) && (pEntry->isExperimental())) )
{
return;
}
// Sanity check for duplicate entries
#ifndef LL_RELEASE_FOR_DOWNLOAD
std::for_each(m_BhvrInfoList.begin(), m_BhvrInfoList.end(),
@ -253,17 +260,14 @@ ERlvBehaviour RlvBehaviourDictionary::getBehaviourFromString(const std::string&
bool RlvBehaviourDictionary::getCommands(const std::string& strMatch, ERlvParamType eParamType, std::list<std::string>& cmdList) const
{
cmdList.clear();
if (strMatch.empty())
return false;
for (const RlvBehaviourInfo* pBhvrInfo : m_BhvrInfoList)
{
if ( (pBhvrInfo->getParamTypeMask() & eParamType) || (RLV_TYPE_UNKNOWN == eParamType) )
{
std::string strCmd = pBhvrInfo->getBehaviour();
if (std::string::npos != strCmd.find(strMatch))
if ( (std::string::npos != strCmd.find(strMatch)) || (strMatch.empty()) )
cmdList.push_back(strCmd);
if ( (pBhvrInfo->hasStrict()) && (std::string::npos != strCmd.append("_sec").find(strMatch)) )
if ( (pBhvrInfo->hasStrict()) && ((std::string::npos != strCmd.append("_sec").find(strMatch)) || (strMatch.empty())) )
cmdList.push_back(strCmd);
}
}
@ -326,16 +330,7 @@ RlvCommand::RlvCommand(const LLUUID& idObj, const std::string& strCommand)
return;
}
if (m_pBhvrInfo = RlvBehaviourDictionary::instance().getBehaviourInfo(strBehaviour, m_eParamType, &m_fStrict))
{
// Filter experimental and/or extended commands (if disabled)
static LLCachedControl<bool> sEnableExperimental(gSavedSettings, "RLVaExperimentalCommands");
static LLCachedControl<bool> sEnableExtended(gSavedSettings, "RLVaExtendedCommands");
if ( ((!sEnableExperimental) && (m_pBhvrInfo->isExperimental())) || ((!sEnableExtended) && (m_pBhvrInfo->isExtended())) )
{
m_pBhvrInfo = NULL;
}
}
m_pBhvrInfo = RlvBehaviourDictionary::instance().getBehaviourInfo(strBehaviour, m_eParamType, &m_fStrict);
}
bool RlvCommand::parseCommand(const std::string& strCommand, std::string& strBehaviour, std::string& strOption, std::string& strParam)
@ -779,7 +774,6 @@ void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAc
}
break;
#ifdef RLV_EXTENSION_FORCEWEAR_GESTURES
case LLAssetType::AT_GESTURE:
if (isWearAction(eAction))
{
@ -792,7 +786,6 @@ void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAc
m_remGestures.push_back(pRlvItem);
}
break;
#endif // RLV_EXTENSION_FORCEWEAR_GESTURES
default:
break;
@ -812,13 +805,13 @@ bool RlvForceWear::isForceDetachable(const LLViewerObject* pAttachObj, bool fChe
#endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
return
(
(pAttachObj) && (pAttachObj->isAttachment())
(pAttachObj) && (pAttachObj->isAttachment())
&& ( (idExcept.isNull()) ? (!gRlvAttachmentLocks.isLockedAttachment(pAttachObj))
: (!gRlvAttachmentLocks.isLockedAttachmentExcept(pAttachObj, idExcept)) )
: (!gRlvAttachmentLocks.isLockedAttachmentExcept(pAttachObj, idExcept)) )
&& (isStrippable(pAttachObj->getAttachmentItemID()))
#ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
&& ( (!fCheckComposite) || (!RlvSettings::getEnableComposites()) ||
(!gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pFolder)) || (gRlvHandler.canTakeOffComposite(pFolder)) )
(!gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pFolder)) || (gRlvHandler.canTakeOffComposite(pFolder)) )
#endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
);
}

View File

@ -77,55 +77,82 @@ protected:
U32 m_maskParamType;
};
// ============================================================================
// RlvCommandHandler and related classes
//
typedef ERlvCmdRet(RlvBhvrHandlerFunc)(const RlvCommand&, bool&);
typedef void(RlvBhvrToggleHandlerFunc)(ERlvBehaviour, bool);
typedef ERlvCmdRet(RlvForceHandlerFunc)(const RlvCommand&);
typedef ERlvCmdRet(RlvReplyHandlerFunc)(const RlvCommand&, std::string&);
//
// RlvCommandHandlerBaseImpl - Base implementation for each command type (the old process(AddRem|Force|Reply)Command functions)
//
template<ERlvParamType paramType> struct RlvCommandHandlerBaseImpl;
template<> struct RlvCommandHandlerBaseImpl<RLV_TYPE_ADDREM> { static ERlvCmdRet processCommand(const RlvCommand&, RlvBhvrHandlerFunc*, RlvBhvrToggleHandlerFunc* = nullptr); };
template<> struct RlvCommandHandlerBaseImpl<RLV_TYPE_FORCE> { static ERlvCmdRet processCommand(const RlvCommand&, RlvForceHandlerFunc*); };
template<> struct RlvCommandHandlerBaseImpl<RLV_TYPE_REPLY> { static ERlvCmdRet processCommand(const RlvCommand&, RlvReplyHandlerFunc*);
};
//
// RlvCommandHandler - The actual command handler (Note that a handler is more general than a processor; a handler can - for instance - be used by multiple processors)
//
template <ERlvParamType paramType, ERlvBehaviour eBhvr>
struct RlvCommandHandler
{
template<typename = typename std::enable_if<paramType == RLV_TYPE_ADDREM>::type> static ERlvCmdRet onCommand(const RlvCommand&, bool&);
template<typename = typename std::enable_if<paramType == RLV_TYPE_ADDREM>::type> static void onCommandToggle(ERlvBehaviour, bool);
template<typename = typename std::enable_if<paramType == RLV_TYPE_FORCE>::type> static ERlvCmdRet onCommand(const RlvCommand&);
template<typename = typename std::enable_if<paramType == RLV_TYPE_REPLY>::type> static ERlvCmdRet onCommand(const RlvCommand&, std::string&);
};
// Aliases to improve readability in definitions
template<ERlvBehaviour eBhvr> using RlvBehaviourHandler = RlvCommandHandler<RLV_TYPE_ADDREM, eBhvr>;
template<ERlvBehaviour eBhvr> using RlvBehaviourToggleHandler = RlvBehaviourHandler<eBhvr>;
template<ERlvBehaviour eBhvr> using RlvForceHandler = RlvCommandHandler<RLV_TYPE_FORCE, eBhvr>;
template<ERlvBehaviour eBhvr> using RlvReplyHandler = RlvCommandHandler<RLV_TYPE_REPLY, eBhvr>;
// List of shared handlers
typedef RlvBehaviourHandler<RLV_BHVR_REMATTACH> RlvBehaviourAddRemAttachHandler; // Shared between @addattach and @remattach
//
// RlvCommandProcessor - Templated glue class that brings RlvBehaviourInfo, RlvCommandHandlerBaseImpl and RlvCommandHandler together
//
template <ERlvParamType paramType, ERlvBehaviour eBhvr, typename handlerImpl = RlvCommandHandler<paramType, eBhvr>, typename baseImpl = RlvCommandHandlerBaseImpl<paramType>>
class RlvCommandProcessor : public RlvBehaviourInfo
{
public:
// Default constructor used by behaviour specializations
template<typename = typename std::enable_if<eBhvr != RLV_BHVR_UNKNOWN>::type>
RlvCommandProcessor(const std::string& strBhvr, U32 nBhvrFlags = 0) : RlvBehaviourInfo(strBhvr, eBhvr, paramType, nBhvrFlags) {}
// Constructor used when we don't want to specialize on behaviour (see RlvBehaviourGenericProcessor)
template<typename = typename std::enable_if<eBhvr == RLV_BHVR_UNKNOWN>::type>
RlvCommandProcessor(const std::string& strBhvr, ERlvBehaviour eBhvr, U32 nBhvrFlags = 0) : RlvBehaviourInfo(strBhvr, eBhvr, paramType, nBhvrFlags) {}
ERlvCmdRet processCommand(const RlvCommand& rlvCmd) const override { return baseImpl::processCommand(rlvCmd, &handlerImpl::onCommand); }
};
// Aliases to improve readability in definitions
template<ERlvBehaviour eBhvr, typename handlerImpl = RlvCommandHandler<RLV_TYPE_ADDREM, eBhvr>> using RlvBehaviourProcessor = RlvCommandProcessor<RLV_TYPE_ADDREM, eBhvr, handlerImpl>;
template<ERlvBehaviour eBhvr, typename handlerImpl = RlvCommandHandler<RLV_TYPE_FORCE, eBhvr>> using RlvForceProcessor = RlvCommandProcessor<RLV_TYPE_FORCE, eBhvr, handlerImpl>;
template<ERlvBehaviour eBhvr, typename handlerImpl = RlvCommandHandler<RLV_TYPE_REPLY, eBhvr>> using RlvReplyProcessor = RlvCommandProcessor<RLV_TYPE_REPLY, eBhvr, handlerImpl>;
// Provides pre-defined generic implementations of basic behaviours (template voodoo - see original commit for something that still made sense)
template<RlvBehaviourOptionType optionType> struct RlvBehaviourGenericHandler { static ERlvCmdRet onCommand(const RlvCommand& rlvCmd, bool& fRefCount); };
template<RlvBehaviourOptionType optionType> using RlvBehaviourGenericProcessor = RlvBehaviourProcessor<RLV_BHVR_UNKNOWN, RlvBehaviourGenericHandler<optionType>>;
// ============================================================================
// RlvBehaviourProcessor and related classes - Handles add/rem comamnds aka "restrictions)
//
class RlvBehaviourProcessorHelper
{
public:
typedef ERlvCmdRet(RlvBhvrHandler)(const RlvCommand& rlvCmd, bool& fRefCount);
typedef void(RlvBhvrToggleHandler)(ERlvBehaviour eBhvr, bool fHasBhvr);
static ERlvCmdRet processBehaviourImpl(const RlvCommand& rlvCmd, RlvBhvrHandler* pHandlerFunc, RlvBhvrToggleHandler* pToggleHandlerFunc = nullptr);
};
template <RlvBehaviourOptionType optionType> struct RlvBehaviourGenericHandler { static ERlvCmdRet onCommand(const RlvCommand& rlvCmd, bool& fRefCount); };
template <RlvBehaviourOptionType optionType> class RlvBehaviourGenericProcessor : public RlvBehaviourInfo
{
public:
RlvBehaviourGenericProcessor(const std::string& strBhvr, ERlvBehaviour eBhvr, U32 nBhvrFlags = 0) : RlvBehaviourInfo(strBhvr, eBhvr, RLV_TYPE_ADDREM, nBhvrFlags) {}
/*virtual*/ ERlvCmdRet processCommand(const RlvCommand& rlvCmd) const { return RlvBehaviourProcessorHelper::processBehaviourImpl(rlvCmd, &RlvBehaviourGenericHandler<optionType>::onCommand); }
};
template <ERlvBehaviour eBhvr> struct RlvBehaviourHandler { static ERlvCmdRet onCommand(const RlvCommand& rlvCmd, bool& fRefCount); };
template <ERlvBehaviour eBhvr, typename bhvrHandler = RlvBehaviourHandler<eBhvr>> class RlvBehaviourProcessor : public RlvBehaviourInfo
{
public:
RlvBehaviourProcessor(const std::string& strBhvr, U32 nBhvrFlags = 0) : RlvBehaviourInfo(strBhvr, eBhvr, RLV_TYPE_ADDREM, nBhvrFlags) {}
/*virtual*/ ERlvCmdRet processCommand(const RlvCommand& rlvCmd) const { return RlvBehaviourProcessorHelper::processBehaviourImpl(rlvCmd, &bhvrHandler::onCommand); }
};
template <ERlvBehaviour> struct RlvBehaviourToggleHandler { static void onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr); };
template <ERlvBehaviour eBhvr, RlvBehaviourOptionType optionType, typename bhvrToggleHandler = RlvBehaviourToggleHandler<eBhvr>> class RlvBehaviourToggleProcessor : public RlvBehaviourInfo
template <ERlvBehaviour eBhvr, RlvBehaviourOptionType optionType, typename toggleHandlerImpl = RlvBehaviourToggleHandler<eBhvr>>
class RlvBehaviourToggleProcessor : public RlvBehaviourInfo
{
public:
RlvBehaviourToggleProcessor(const std::string& strBhvr, U32 nBhvrFlags = 0) : RlvBehaviourInfo(strBhvr, eBhvr, RLV_TYPE_ADDREM, nBhvrFlags) {}
/*virtual*/ ERlvCmdRet processCommand(const RlvCommand& rlvCmd) const { return RlvBehaviourProcessorHelper::processBehaviourImpl(rlvCmd, &RlvBehaviourGenericHandler<optionType>::onCommand, &bhvrToggleHandler::onCommandToggle); }
};
typedef RlvBehaviourHandler<RLV_BHVR_REMATTACH> RlvBehaviourAddRemAttachHandler; // Shared between @addattach and @remattach
// ============================================================================
// RlvCommandHandler and related classes - Handles force/reply commands
//
template <ERlvParamType paramType, ERlvBehaviour eBhvr> struct RlvCommandHandler { static ERlvCmdRet onCommand(const RlvCommand& rlvCmd); };
template <ERlvParamType paramType, ERlvBehaviour eBhvr> class RlvCommandProcessor : public RlvBehaviourInfo
{
public:
RlvCommandProcessor(const std::string& strBhvr, U32 nBhvrFlags = 0) : RlvBehaviourInfo(strBhvr, eBhvr, paramType, nBhvrFlags) {}
public:
/*virtual*/ ERlvCmdRet processCommand(const RlvCommand& rlvCmd) const { return RlvCommandHandler<paramType, eBhvr>::onCommand(rlvCmd); }
ERlvCmdRet processCommand(const RlvCommand& rlvCmd) const override { return RlvCommandHandlerBaseImpl<RLV_TYPE_ADDREM>::processCommand(rlvCmd, &RlvBehaviourGenericHandler<optionType>::onCommand, &toggleHandlerImpl::onCommandToggle); }
};
// ============================================================================
@ -191,7 +218,7 @@ public:
bool isBlocked() const { return (m_pBhvrInfo) ? m_pBhvrInfo->isBlocked() : false; }
bool isStrict() const { return m_fStrict; }
bool isValid() const { return m_fValid; }
ERlvCmdRet processCommand() const { return (m_pBhvrInfo) ? m_pBhvrInfo->processCommand(*this) : RLV_RET_UNKNOWN; }
ERlvCmdRet processCommand() const { return (m_pBhvrInfo) ? m_pBhvrInfo->processCommand(*this) : RLV_RET_FAILED_UNKNOWN; }
protected:
static bool parseCommand(const std::string& strCommand, std::string& strBehaviour, std::string& strOption, std::string& strParam);

View File

@ -809,12 +809,9 @@ bool RlvWearableItemCollector::onCollectItem(const LLInventoryItem* pItem)
(m_Folded.end() != std::find(m_Folded.begin(), m_Folded.end(), idParent)) ) &&
( (!fAttach) || (RlvAttachPtLookup::hasAttachPointName(pItem)) || (RlvSettings::getEnableSharedWear()) );
break;
#ifdef RLV_EXTENSION_FORCEWEAR_GESTURES
case LLAssetType::AT_GESTURE:
fRet = (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent));
break;
#endif // RLV_EXTENSION_FORCEWEAR_GESTURES
#ifdef RLV_EXTENSION_FORCEWEAR_FOLDERLINKS
case LLAssetType::AT_CATEGORY:
if (LLAssetType::AT_LINK_FOLDER == pItem->getActualType())
{
@ -831,7 +828,6 @@ bool RlvWearableItemCollector::onCollectItem(const LLInventoryItem* pItem)
}
}
break;
#endif // RLV_EXTENSION_FORCEWEAR_FOLDERLINKS
default:
break;
}

View File

@ -19,22 +19,15 @@
#include "llavataractions.h" // LLAvatarActions::profileVisible()
#include "llavatarlist.h" // Avatar list control used by the "Nearby" tab in the "People" sidebar panel
#include "llavatarnamecache.h"
#include "llenvmanager.h"
#include "llfloatersidepanelcontainer.h"
#include "llhudtext.h" // LLHUDText::refreshAllObjectText()
#include "llimview.h" // LLIMMgr::computeSessionID()
#include "llmoveview.h" // Movement panel (contains "Stand" and "Stop Flying" buttons)
#include "llnavigationbar.h" // Navigation bar
#include "lloutfitslist.h" // "My Outfits" sidebar panel
#include "llpaneloutfitsinventory.h" // "My Appearance" sidebar panel
#include "llpanelpeople.h" // "People" sidebar panel
#include "llpanelwearing.h" // "Current Outfit" sidebar panel
#include "llparcel.h"
#include "llpaneltopinfobar.h"
#include "llsidepanelappearance.h"
#include "lltabcontainer.h"
#include "llteleporthistory.h"
#include "lltoolmgr.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "llvoavatar.h"
@ -70,10 +63,6 @@ RlvUIEnabler::RlvUIEnabler()
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_VIEWTEXTURE, boost::bind(&RlvUIEnabler::onToggleViewXXX, this)));
// onToggleXXX
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_EDIT, boost::bind(&RlvUIEnabler::onToggleEdit, this)));
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_SETDEBUG, boost::bind(&RlvUIEnabler::onToggleSetDebug, this)));
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_SETENV, boost::bind(&RlvUIEnabler::onToggleSetEnv, this)));
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_SHOWINV, boost::bind(&RlvUIEnabler::onToggleShowInv, this, _1)));
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_SHOWLOC, boost::bind(&RlvUIEnabler::onToggleShowLoc, this)));
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_SHOWMINIMAP, boost::bind(&RlvUIEnabler::onToggleShowMinimap, this)));
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_SHOWNAMES, boost::bind(&RlvUIEnabler::onToggleShowNames, this, _1)));
@ -85,10 +74,8 @@ RlvUIEnabler::RlvUIEnabler()
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_TPLM, boost::bind(&RlvUIEnabler::onToggleTp, this)));
// onUpdateLoginLastLocation
#ifdef RLV_EXTENSION_STARTLOCATION
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_TPLOC, boost::bind(&RlvUIEnabler::onUpdateLoginLastLocation, this, _1)));
m_Handlers.insert(std::pair<ERlvBehaviour, behaviour_handler_t>(RLV_BHVR_UNSIT, boost::bind(&RlvUIEnabler::onUpdateLoginLastLocation, this, _1)));
#endif // RLV_EXTENSION_STARTLOCATION
}
// Checked: 2010-02-28 (RLVa-1.4.0a) | Added: RLVa-1.2.0a
@ -111,32 +98,6 @@ void RlvUIEnabler::onRefreshHoverText()
LLHUDText::refreshAllObjectText();
}
// Checked: 2010-03-17 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
void RlvUIEnabler::onToggleEdit()
{
bool fEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_EDIT);
if (!fEnable)
{
// Turn off "View / Highlight Transparent"
LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
// Hide the beacons floater if it's currently visible
if (LLFloaterReg::instanceVisible("beacons"))
LLFloaterReg::hideInstance("beacons");
// Hide the build floater if it's currently visible
if (LLFloaterReg::instanceVisible("build"))
LLToolMgr::instance().toggleBuildMode();
}
// Start or stop filtering opening the beacons floater
if (!fEnable)
addGenericFloaterFilter("beacons");
else
removeGenericFloaterFilter("beacons");
}
// Checked: 2010-03-02 (RLVa-1.4.0a) | Modified: RLVa-1.4.0a
void RlvUIEnabler::onToggleMovement()
{
@ -151,106 +112,6 @@ void RlvUIEnabler::onToggleMovement()
LLFloaterMove::sUpdateMovementStatus();
}
// Checked: 2011-05-28 (RLVa-1.4.0a) | Added: RLVa-1.4.0a
void RlvUIEnabler::onToggleSetDebug()
{
bool fEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_SETDEBUG);
for (std::map<std::string, S16>::const_iterator itSetting = RlvExtGetSet::m_DbgAllowed.begin();
itSetting != RlvExtGetSet::m_DbgAllowed.end(); ++itSetting)
{
if (itSetting->second & RlvExtGetSet::DBG_WRITE)
gSavedSettings.getControl(itSetting->first)->setHiddenFromSettingsEditor(!fEnable);
}
}
// Checked: 2011-09-04 (RLVa-1.4.1a) | Modified: RLVa-1.4.1a
void RlvUIEnabler::onToggleSetEnv()
{
bool fEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV);
const std::string strEnvFloaters[] =
{ "env_post_process", "env_settings", "env_delete_preset", "env_edit_sky", "env_edit_water", "env_edit_day_cycle" };
for (int idxFloater = 0, cntFloater = sizeof(strEnvFloaters) / sizeof(std::string); idxFloater < cntFloater; idxFloater++)
{
if (!fEnable)
{
// Hide the floater if it's currently visible
if (LLFloaterReg::instanceVisible(strEnvFloaters[idxFloater]))
LLFloaterReg::hideInstance(strEnvFloaters[idxFloater]);
addGenericFloaterFilter(strEnvFloaters[idxFloater]);
}
else
{
removeGenericFloaterFilter(strEnvFloaters[idxFloater]);
}
}
// Don't allow toggling "Basic Shaders" and/or "Atmopsheric Shaders" through the debug settings under @setenv=n
gSavedSettings.getControl("VertexShaderEnable")->setHiddenFromSettingsEditor(!fEnable);
gSavedSettings.getControl("WindLightUseAtmosShaders")->setHiddenFromSettingsEditor(!fEnable);
// Restore the user's WindLight preferences when releasing
if (fEnable)
LLEnvManagerNew::instance().usePrefs();
}
// Checked: 2011-11-04 (RLVa-1.4.4a) | Modified: RLVa-1.4.4a
void RlvUIEnabler::onToggleShowInv(bool fQuitting)
{
if (fQuitting)
return; // Nothing to do if the viewer is shutting down
bool fEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWINV);
//
// When disabling, close any inventory floaters that may be open
//
if (!fEnable)
{
LLFloaterReg::const_instance_list_t lFloaters = LLFloaterReg::getFloaterList("inventory");
for (LLFloaterReg::const_instance_list_t::const_iterator itFloater = lFloaters.begin(); itFloater != lFloaters.end(); ++itFloater)
(*itFloater)->closeFloater();
}
//
// Enable/disable the "My Outfits" panel on the "My Appearance" sidebar tab
//
LLPanelOutfitsInventory* pAppearancePanel = LLPanelOutfitsInventory::findInstance();
RLV_ASSERT(pAppearancePanel);
if (pAppearancePanel)
{
LLTabContainer* pAppearanceTabs = pAppearancePanel->getAppearanceTabs();
LLOutfitsList* pMyOutfitsPanel = pAppearancePanel->getMyOutfitsPanel();
if ( (pAppearanceTabs) && (pMyOutfitsPanel) )
{
S32 idxTab = pAppearanceTabs->getIndexForPanel(pMyOutfitsPanel);
RLV_ASSERT(-1 != idxTab);
pAppearanceTabs->enableTabButton(idxTab, fEnable);
// When disabling, switch to the COF tab if "My Outfits" is currently active
if ( (!fEnable) && (pAppearanceTabs->getCurrentPanelIndex() == idxTab) )
pAppearanceTabs->selectTabPanel(pAppearancePanel->getCurrentOutfitPanel());
}
LLSidepanelAppearance* pCOFPanel = pAppearancePanel->getAppearanceSP();
RLV_ASSERT(pCOFPanel);
if ( (!fEnable) && (pCOFPanel) && (pCOFPanel->isOutfitEditPanelVisible()) )
{
// TODO-RLVa: we should really just be collapsing the "Add more..." inventory panel (and disable the button)
pCOFPanel->showOutfitsInventoryPanel();
}
}
//
// Filter (or stop filtering) opening new inventory floaters
//
if (!fEnable)
addGenericFloaterFilter("inventory");
else
removeGenericFloaterFilter("inventory");
}
// Checked: 2010-04-22 (RLVa-1.2.0f) | Modified: RLVa-1.2.0f
void RlvUIEnabler::onToggleShowLoc()
{

View File

@ -44,11 +44,7 @@ public:
*/
protected:
void onRefreshHoverText(); // showloc, shownames, showhovertext(all|world|hud)
void onToggleEdit(); // edit
void onToggleMovement(); // fly, alwaysrun and temprun
void onToggleSetDebug(); // setdebug
void onToggleSetEnv(); // setenv
void onToggleShowInv(bool fQuitting); // showinv
void onToggleShowLoc(); // showloc
void onToggleShowMinimap(); // showminimap
void onToggleShowNames(bool fQuitting); // shownames
@ -61,10 +57,11 @@ protected:
/*
* Floater and sidebar validation callbacks
*/
protected:
public:
void addGenericFloaterFilter(const std::string& strFloaterName);
void removeGenericFloaterFilter(const std::string& strFloaterName);
protected:
bool filterFloaterGeneric(const std::string&, const LLSD&);
boost::signals2::connection m_ConnFloaterGeneric;
bool filterFloaterShowLoc(const std::string&, const LLSD& );

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
can_resize="true"
height="400"
layout="topleft"
min_height="300"
min_width="300"
name="rlv_console"
title="RLVa console"
width="600"
>
<text_editor
follows="all"
left="10"
length="1"
font="Monospace"
height="366"
ignore_tab="false"
layout="topleft"
max_length="65536"
name="console_output"
read_only="true"
track_end="true"
type="string"
width="576"
word_wrap="true"
>
</text_editor>
<line_editor
border_style="line"
border_thickness="1"
bottom_delta="20"
follows="left|right|bottom"
font="SansSerif"
height="19"
layout="topleft"
max_length="127"
name="console_input"
top_delta="0"
width="576"
>
</line_editor>
</floater>

View File

@ -1664,6 +1664,16 @@
parameter="RLVaWearReplaceUnlocked" />
</menu_item_check>
<menu_item_separator />
<menu_item_check
label="Console..."
name="Console">
<menu_item_check.on_check
function="Floater.Visible"
parameter="rlv_console" />
<menu_item_check.on_click
function="Floater.Toggle"
parameter="rlv_console" />
</menu_item_check>
<menu_item_check
label="Restrictions..."
name="Restrictions">