diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 26b36ac23d64f298fa7c52d9fa44bd403c56318c..0715f488629c8ceb941f45b8d9b0d16fb2f5fe26 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -65,191 +65,6 @@ bool RlvCommandOptionParser<int>::parseOption(const std::string& strOption, int& return LLStringUtil::convertToS32(strOption, nOption); } -// ============================================================================ -// Command processing template specialization implmentation -// - -ERlvCmdRet RlvBehaviourProcessorHelper::processBehaviourImpl(const RlvCommand& rlvCmd, RlvBhvrHandler* pHandlerFunc) -{ - bool fRefCount = false; - ERlvCmdRet eRet = (*pHandlerFunc)(rlvCmd, fRefCount); - - // If this command represents a restriction that's been added/removed then we need to do some additional processing - if ( (RLV_RET_SUCCESS == eRet) && (fRefCount) ) - { - ERlvBehaviour eBhvr = rlvCmd.getBehaviourType(); - S16& refBhvr = gRlvHandler.m_Behaviours[eBhvr]; - if (RLV_TYPE_ADD == rlvCmd.getParamType()) - { - if (rlvCmd.isStrict()) - gRlvHandler.addException(rlvCmd.getObjectID(), RLV_BHVR_PERMISSIVE, eBhvr); - refBhvr++; - } - else - { - if (rlvCmd.isStrict()) - gRlvHandler.removeException(rlvCmd.getObjectID(), RLV_BHVR_PERMISSIVE, eBhvr); - refBhvr--; - } - } - - return eRet; -} - -// Handles: @bhvr=n|y -ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_NONE>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) -{ - // There should be no option - if (rlvCmd.hasOption()) - return RLV_RET_FAILED_OPTION; - - fRefCount = true; - return RLV_RET_SUCCESS; -} - -// Handles: @bhvr:<uuid>=n|y -ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_EXCEPTION>::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)) - return RLV_RET_FAILED_OPTION; - - if (RLV_TYPE_ADD == rlvCmd.getParamType()) - gRlvHandler.addException(rlvCmd.getObjectID(), rlvCmd.getBehaviourType(), idException); - else - gRlvHandler.removeException(rlvCmd.getObjectID(), rlvCmd.getBehaviourType(), idException); - - fRefCount = true; - return RLV_RET_SUCCESS; -} - -// Handles: @bhvr[:<uuid>]=n|y -ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_NONE_OR_EXCEPTION>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) -{ - // If there is an option then it should specify a valid UUID (but don't reference count) - if (rlvCmd.hasOption()) - { - ERlvCmdRet eRet = RlvBehaviourGenericHandler<RLV_OPTION_EXCEPTION>::onCommand(rlvCmd, fRefCount); - fRefCount = false; - return eRet; - } - return RlvBehaviourGenericHandler<RLV_OPTION_NONE>::onCommand(rlvCmd, fRefCount); -} - -// Handles: @sendim=n|y toggles -void RlvBehaviourToggleHandler<RLV_BHVR_SENDIM>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) -{ - gSavedPerAccountSettings.getControl("DoNotDisturbModeResponse")->setHiddenFromSettingsEditor(fHasBhvr); -} - - -// Handles: @sendchannel[:<channel>]=n|y -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) ) - 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; - } - return RLV_RET_SUCCESS; -} - -// Handles: @showhovertext:<uuid>=n|y -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)) - return RLV_RET_FAILED_OPTION; - - if (RLV_TYPE_ADD == rlvCmd.getParamType()) - gRlvHandler.addException(rlvCmd.getObjectID(), rlvCmd.getBehaviourType(), idException); - else - gRlvHandler.removeException(rlvCmd.getObjectID(), rlvCmd.getBehaviourType(), idException); - - // Clear/restore the object's hover text as needed - LLViewerObject* pObj = gObjectList.findObject(idException); - if ( (pObj) && (pObj->mText.notNull()) && (!pObj->mText->getObjectText().empty()) ) - pObj->mText->setString( (RLV_TYPE_ADD == rlvCmd.getParamType()) ? "" : pObj->mText->getObjectText()); - - fRefCount = true; - return RLV_RET_SUCCESS; -} - -// Handles: @setgroup:<uuid>=force -ERlvCmdRet RlvCommandHandler<RLV_TYPE_FORCE, RLV_BHVR_SETGROUP>::onCommand(const RlvCommand& rlvCmd) -{ - if (gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETGROUP, rlvCmd.getObjectID())) - { - return RLV_RET_FAILED_LOCK; - } - - LLUUID idGroup; bool fValid = false; - if (idGroup.set(rlvCmd.getOption())) - { - fValid = (idGroup.isNull()) || (gAgent.isInGroup(idGroup, true)); - } - else - { - for (S32 idxGroup = 0, cntGroup = gAgent.mGroups.size(); (idxGroup < cntGroup) && (idGroup.isNull()); idxGroup++) - if (boost::iequals(gAgent.mGroups.at(idxGroup).mName, rlvCmd.getOption())) - idGroup = gAgent.mGroups.at(idxGroup).mID; - fValid = (idGroup.notNull()) || ("none" == rlvCmd.getOption()); - } - - if (fValid) - { - gRlvHandler.m_idAgentGroup = idGroup; - LLGroupActions::activate(idGroup); - } - - return (fValid) ? RLV_RET_SUCCESS : RLV_RET_FAILED_OPTION; -} - -// Handles: @sit:<uuid>=force -ERlvCmdRet RlvCommandHandler<RLV_TYPE_FORCE, 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 - if ( (idTarget.isNull()) || ((pObj = gObjectList.findObject(idTarget)) == NULL) || (LL_PCODE_VOLUME != pObj->getPCode()) ) - return RLV_RET_FAILED_OPTION; - - if (!gRlvHandler.canSit(pObj)) - return RLV_RET_FAILED_LOCK; - else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_STANDTP)) && (isAgentAvatarValid()) ) - { - if (gAgentAvatarp->isSitting()) - return RLV_RET_FAILED_LOCK; - gRlvHandler.m_posSitSource = gAgent.getPositionGlobal(); - } - - // Copy/paste from handle_sit_or_stand() [see http://wiki.secondlife.com/wiki/AgentRequestSit] - gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_TargetObject); - gMessageSystem->addUUIDFast(_PREHASH_TargetID, pObj->mID); - // Offset: "a rough position in local coordinates for the edge to sit on" - // (we might not even be looking at the object so I don't think we can supply the offset to an edge) - gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3::zero); - pObj->getRegion()->sendReliableMessage(); - - return RLV_RET_SUCCESS; -} - // ============================================================================ // Command specific helper functions // @@ -1353,13 +1168,6 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd) eRet = RLV_RET_SUCCESS; bool fRefCount = false; const std::string& strOption = rlvCmd.getOption(); switch (eBhvr) { - case RLV_BHVR_DETACH: // @detach[:<option>]=n|y - eRet = onAddRemDetach(rlvCmd, fRefCount); - break; - case RLV_BHVR_ADDATTACH: // @addattach[:<option>]=n|y - case RLV_BHVR_REMATTACH: // @addattach[:<option>]=n|y - eRet = onAddRemAttach(rlvCmd, fRefCount); - break; case RLV_BHVR_ATTACHTHIS: // @attachthis[:<option>]=n|y case RLV_BHVR_DETACHTHIS: // @detachthis[:<option>]=n|y eRet = onAddRemFolderLock(rlvCmd, fRefCount); @@ -1491,12 +1299,84 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd) return eRet; } -// Checked: 2010-03-03 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a -ERlvCmdRet RlvHandler::onAddRemAttach(const RlvCommand& rlvCmd, bool& fRefCount) +// 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) +{ + ERlvBehaviour eBhvr = rlvCmd.getBehaviourType(); + bool fRefCount = false, fHasBhvr = gRlvHandler.hasBehaviour(eBhvr); + + ERlvCmdRet eRet = (*pHandlerFunc)(rlvCmd, fRefCount); + + // If this command represents a restriction that's been added/removed then we need to do some additional processing + if ( (RLV_RET_SUCCESS == eRet) && (fRefCount) ) + { + if (RLV_TYPE_ADD == rlvCmd.getParamType()) + { + if (rlvCmd.isStrict()) + gRlvHandler.addException(rlvCmd.getObjectID(), RLV_BHVR_PERMISSIVE, eBhvr); + gRlvHandler.m_Behaviours[eBhvr]++; + } + else + { + if (rlvCmd.isStrict()) + gRlvHandler.removeException(rlvCmd.getObjectID(), RLV_BHVR_PERMISSIVE, eBhvr); + gRlvHandler.m_Behaviours[eBhvr]--; + } + + if (fHasBhvr != gRlvHandler.hasBehaviour(eBhvr)) + { + if (pToggleHandlerFunc) + (*pToggleHandlerFunc)(eBhvr, !fHasBhvr); + gRlvHandler.m_OnBehaviourToggle(eBhvr, rlvCmd.getParamType()); + } + } + + return eRet; +} + +// Handles: @bhvr=n|y +ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_NONE>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) +{ + // There should be no option + if (rlvCmd.hasOption()) + return RLV_RET_FAILED_OPTION; + + fRefCount = true; + return RLV_RET_SUCCESS; +} + +// Handles: @bhvr:<uuid>=n|y +ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_EXCEPTION>::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)) + return RLV_RET_FAILED_OPTION; + + if (RLV_TYPE_ADD == rlvCmd.getParamType()) + gRlvHandler.addException(rlvCmd.getObjectID(), rlvCmd.getBehaviourType(), idException); + else + gRlvHandler.removeException(rlvCmd.getObjectID(), rlvCmd.getBehaviourType(), idException); + + fRefCount = true; + return RLV_RET_SUCCESS; +} + +// Handles: @bhvr[:<uuid>]=n|y +ERlvCmdRet RlvBehaviourGenericHandler<RLV_OPTION_NONE_OR_EXCEPTION>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) { - RLV_ASSERT( (RLV_TYPE_ADD == rlvCmd.getParamType()) || (RLV_TYPE_REMOVE == rlvCmd.getParamType()) ); - RLV_ASSERT( (RLV_BHVR_ADDATTACH == rlvCmd.getBehaviourType()) || (RLV_BHVR_REMATTACH == rlvCmd.getBehaviourType()) ); + // If there is an option then it should specify a valid UUID (but don't reference count) + if (rlvCmd.hasOption()) + { + ERlvCmdRet eRet = RlvBehaviourGenericHandler<RLV_OPTION_EXCEPTION>::onCommand(rlvCmd, fRefCount); + fRefCount = false; + return eRet; + } + return RlvBehaviourGenericHandler<RLV_OPTION_NONE>::onCommand(rlvCmd, fRefCount); +} +ERlvCmdRet RlvBehaviourAddRemAttachHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) +{ // Sanity check - if there's an option it should specify a valid attachment point name S32 idxAttachPt = RlvAttachPtLookup::getAttachPointIndex(rlvCmd.getOption()); if ( (!idxAttachPt) && (!rlvCmd.getOption().empty()) ) @@ -1526,12 +1406,8 @@ ERlvCmdRet RlvHandler::onAddRemAttach(const RlvCommand& rlvCmd, bool& fRefCount) return RLV_RET_SUCCESS; } -// Checked: 2010-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a -ERlvCmdRet RlvHandler::onAddRemDetach(const RlvCommand& rlvCmd, bool& fRefCount) +ERlvCmdRet RlvBehaviourHandler<RLV_BHVR_DETACH>::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) { - RLV_ASSERT( (RLV_TYPE_ADD == rlvCmd.getParamType()) || (RLV_TYPE_REMOVE == rlvCmd.getParamType()) ); - RLV_ASSERT(RLV_BHVR_DETACH == rlvCmd.getBehaviourType()); - // We need to flush any queued force-wear commands before changing the restrictions if (RlvForceWear::instanceExists()) RlvForceWear::instance().done(); @@ -1543,13 +1419,13 @@ ERlvCmdRet RlvHandler::onAddRemDetach(const RlvCommand& rlvCmd, bool& fRefCount) // - if it hasn't rezzed yet then it's a @detach=n from a non-attachment and RlvHandler::onAttach() takes care of it // * @detach=y: - if it ever rezzed as an attachment we'll have cached the UUID of its root // - if it never rezzed as an attachment there won't be a lock to remove - rlv_object_map_t::const_iterator itObj = m_Objects.find(rlvCmd.getObjectID()); - if ( (itObj != m_Objects.end()) && (itObj->second.m_fLookup) && (itObj->second.m_idxAttachPt) ) + RlvHandler::rlv_object_map_t::const_iterator itObj = gRlvHandler.m_Objects.find(rlvCmd.getObjectID()); + if ( (itObj != gRlvHandler.m_Objects.end()) && (itObj->second.hasLookup()) && (itObj->second.getAttachPt()) ) { if (RLV_TYPE_ADD == rlvCmd.getParamType()) - gRlvAttachmentLocks.addAttachmentLock(itObj->second.m_idRoot, itObj->first); + gRlvAttachmentLocks.addAttachmentLock(itObj->second.getRootID(), itObj->first); else - gRlvAttachmentLocks.removeAttachmentLock(itObj->second.m_idRoot, itObj->first); + gRlvAttachmentLocks.removeAttachmentLock(itObj->second.getRootID(), itObj->first); } } else // @detach:<attachpt>=n|y - RLV_LOCK_ADD and RLV_LOCK_REMOVE locks an attachment *point* @@ -1640,6 +1516,56 @@ ERlvCmdRet RlvHandler::onAddRemFolderLockException(const RlvCommand& rlvCmd, boo return RLV_RET_SUCCESS; } +// Handles: @sendchannel[:<channel>]=n|y +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) ) + 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; + } + return RLV_RET_SUCCESS; +} + +// Handles: @sendim=n|y toggles +void RlvBehaviourToggleHandler<RLV_BHVR_SENDIM>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) +{ + gSavedPerAccountSettings.getControl("DoNotDisturbModeResponse")->setHiddenFromSettingsEditor(fHasBhvr); +} + +// Handles: @showhovertext:<uuid>=n|y +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)) + return RLV_RET_FAILED_OPTION; + + if (RLV_TYPE_ADD == rlvCmd.getParamType()) + gRlvHandler.addException(rlvCmd.getObjectID(), rlvCmd.getBehaviourType(), idException); + else + gRlvHandler.removeException(rlvCmd.getObjectID(), rlvCmd.getBehaviourType(), idException); + + // Clear/restore the object's hover text as needed + LLViewerObject* pObj = gObjectList.findObject(idException); + if ( (pObj) && (pObj->mText.notNull()) && (!pObj->mText->getObjectText().empty()) ) + pObj->mText->setString( (RLV_TYPE_ADD == rlvCmd.getParamType()) ? "" : pObj->mText->getObjectText()); + + fRefCount = true; + return RLV_RET_SUCCESS; +} + // ============================================================================ // Command handlers (RLV_TYPE_FORCE) // @@ -1834,6 +1760,66 @@ 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) +{ + if (gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETGROUP, rlvCmd.getObjectID())) + { + return RLV_RET_FAILED_LOCK; + } + + LLUUID idGroup; bool fValid = false; + if (idGroup.set(rlvCmd.getOption())) + { + fValid = (idGroup.isNull()) || (gAgent.isInGroup(idGroup, true)); + } + else + { + for (S32 idxGroup = 0, cntGroup = gAgent.mGroups.size(); (idxGroup < cntGroup) && (idGroup.isNull()); idxGroup++) + if (boost::iequals(gAgent.mGroups.at(idxGroup).mName, rlvCmd.getOption())) + idGroup = gAgent.mGroups.at(idxGroup).mID; + fValid = (idGroup.notNull()) || ("none" == rlvCmd.getOption()); + } + + if (fValid) + { + gRlvHandler.m_idAgentGroup = idGroup; + LLGroupActions::activate(idGroup); + } + + return (fValid) ? RLV_RET_SUCCESS : RLV_RET_FAILED_OPTION; +} + +// Handles: @sit:<uuid>=force +ERlvCmdRet RlvCommandHandler<RLV_TYPE_FORCE, 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 + if ( (idTarget.isNull()) || ((pObj = gObjectList.findObject(idTarget)) == NULL) || (LL_PCODE_VOLUME != pObj->getPCode()) ) + return RLV_RET_FAILED_OPTION; + + if (!gRlvHandler.canSit(pObj)) + return RLV_RET_FAILED_LOCK; + else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_STANDTP)) && (isAgentAvatarValid()) ) + { + if (gAgentAvatarp->isSitting()) + return RLV_RET_FAILED_LOCK; + gRlvHandler.m_posSitSource = gAgent.getPositionGlobal(); + } + + // Copy/paste from handle_sit_or_stand() + gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_TargetObject); + gMessageSystem->addUUIDFast(_PREHASH_TargetID, pObj->mID); + gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3::zero); + pObj->getRegion()->sendReliableMessage(); + + return RLV_RET_SUCCESS; +} + // ============================================================================ // Command handlers (RLV_TYPE_REPLY) // diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h index ac5f3c10cfc9315ec66783a249c6913b7938f5ea..9a438970bb0180e8d7ed112238dcc76ac8bdfedf 100644 --- a/indra/newview/rlvhandler.h +++ b/indra/newview/rlvhandler.h @@ -158,8 +158,6 @@ class RlvHandler : public LLOldEvents::LLSimpleListener // Command handlers (RLV_TYPE_ADD and RLV_TYPE_CLEAR) ERlvCmdRet processAddRemCommand(const RlvCommand& rlvCmd); - ERlvCmdRet onAddRemAttach(const RlvCommand& rlvCmd, bool& fRefCount); - ERlvCmdRet onAddRemDetach(const RlvCommand& rlvCmd, bool& fRefCount); ERlvCmdRet onAddRemFolderLock(const RlvCommand& rlvCmd, bool& fRefCount); ERlvCmdRet onAddRemFolderLockException(const RlvCommand& rlvCmd, bool& fRefCount); // Command handlers (RLV_TYPE_FORCE) diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 4eb85c8920deff45670437f9958a9c47e24a8270..ff05df400cb9834f0838ee466ef700d0e9313cd7 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -40,7 +40,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("acceptpermission", RLV_BHVR_ACCEPTPERMISSION)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("accepttp", RLV_BHVR_ACCEPTTP, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("accepttprequest", RLV_BHVR_ACCEPTTPREQUEST, RlvBehaviourInfo::BHVR_STRICT | RlvBehaviourInfo::BHVR_EXTENDED)); - addEntry(new RlvBehaviourInfo("addattach", RLV_BHVR_ADDATTACH, RLV_TYPE_ADDREM)); + addEntry(new RlvBehaviourProcessor<RLV_BHVR_ADDATTACH, RlvBehaviourAddRemAttachHandler>("addattach")); addEntry(new RlvBehaviourInfo("addoutfit", RLV_BHVR_ADDOUTFIT, RLV_TYPE_ADDREM)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("allowidle", RLV_BHVR_ALLOWIDLE, RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("alwaysrun", RLV_BHVR_ALWAYSRUN)); @@ -51,7 +51,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("chatwhisper", RLV_BHVR_CHATWHISPER)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("chatnormal", RLV_BHVR_CHATNORMAL)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("chatshout", RLV_BHVR_CHATSHOUT)); - addEntry(new RlvBehaviourInfo("detach", RLV_BHVR_DETACH, RLV_TYPE_ADDREM)); + addEntry(new RlvBehaviourProcessor<RLV_BHVR_DETACH>("detach")); addEntry(new RlvBehaviourInfo("detachthis", RLV_BHVR_DETACHTHIS, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_NODE)); 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)); @@ -72,7 +72,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_EXCEPTION>("recvimfrom", RLV_BHVR_RECVIMFROM, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourInfo("redirchat", RLV_BHVR_REDIRCHAT, RLV_TYPE_ADDREM)); addEntry(new RlvBehaviourInfo("rediremote", RLV_BHVR_REDIREMOTE, RLV_TYPE_ADDREM)); - addEntry(new RlvBehaviourInfo("remattach", RLV_BHVR_REMATTACH, RLV_TYPE_ADDREM)); + addEntry(new RlvBehaviourProcessor<RLV_BHVR_REMATTACH, RlvBehaviourAddRemAttachHandler>("remattach")); addEntry(new RlvBehaviourInfo("remoutfit", RLV_BHVR_REMOUTFIT, RLV_TYPE_ADDREM)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("rez", RLV_BHVR_REZ)); addEntry(new RlvBehaviourProcessor<RLV_BHVR_SENDCHANNEL>("sendchannel", RlvBehaviourInfo::BHVR_STRICT)); diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index 5811b9f263f39931a8dc97f5f3f0cff7c194f6e4..78b22e2ae54a715a3c538643b973f9dacc1ce957 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -85,7 +85,8 @@ class RlvBehaviourProcessorHelper { public: typedef ERlvCmdRet(RlvBhvrHandler)(const RlvCommand& rlvCmd, bool& fRefCount); - static ERlvCmdRet processBehaviourImpl(const RlvCommand& rlvCmd, RlvBhvrHandler* pHandlerFunc); + 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); }; @@ -109,17 +110,11 @@ template <ERlvBehaviour eBhvr, RlvBehaviourOptionType optionType, typename bhvrT { public: RlvBehaviourToggleProcessor(const std::string& strBhvr, U32 nBhvrFlags = 0) : RlvBehaviourInfo(strBhvr, eBhvr, RLV_TYPE_ADDREM, nBhvrFlags) {} - /*virtual*/ ERlvCmdRet processCommand(const RlvCommand& rlvCmd) const - { - bool fHasBhvr = gRlvHandler.hasBehaviour(eBhvr); - - ERlvCmdRet eRet = RlvBehaviourProcessorHelper::processBehaviourImpl(rlvCmd, &RlvBehaviourGenericHandler<optionType>::onCommand); - if (fHasBhvr != gRlvHandler.hasBehaviour(eBhvr)) - bhvrToggleHandler::onCommandToggle(eBhvr, !fHasBhvr); - return eRet; - } + /*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 // @@ -327,10 +322,16 @@ class RlvObject bool hasBehaviour(ERlvBehaviour eBehaviour, bool fStrictOnly) const; bool hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption, bool fStrictOnly) const; - const rlv_command_list_t* getCommandList() const { return &m_Commands; } - const LLUUID& getObjectID() const { return m_idObj; } - const LLUUID& getRootID() const { return m_idRoot; } + /* + * Accessors + */ +public: + S32 getAttachPt() const { return m_idxAttachPt; } + const LLUUID& getObjectID() const { return m_idObj; } + const LLUUID& getRootID() const { return m_idRoot; } + bool hasLookup() const { return m_fLookup; } + const rlv_command_list_t* getCommandList() const { return &m_Commands; } /* * Member variables