diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 5da6322b3068e107ba1133f29da47edd8cd955ad..277d3b1c45a256cfaa86b3ac2c68a51dd07f3619 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -37,46 +37,6 @@ BOOL RlvHandler::m_fEnabled = FALSE; rlv_handler_t gRlvHandler; -// ============================================================================ -// Attachment group helper functions -// - -// Has to match the order of ERlvAttachGroupType -const std::string cstrAttachGroups[RLV_ATTACHGROUP_COUNT] = { "head", "torso", "arms", "legs", "hud" }; - -// Checked: 2009-10-19 (RLVa-1.1.0e) | Added: RLVa-1.1.0e -inline ERlvAttachGroupType rlvGetAttachGroupTypeFromIndex(S32 idxGroup) -{ - switch (idxGroup) - { - case 0: // Right Hand - case 1: // Right Arm - case 3: // Left Arm - case 4: // Left Hand - return RLV_ATTACHGROUP_ARMS; - case 2: // Head - return RLV_ATTACHGROUP_HEAD; - case 5: // Left Leg - case 7: // Right Leg - return RLV_ATTACHGROUP_LEGS; - case 6: // Torso - return RLV_ATTACHGROUP_TORSO; - case 8: // HUD - return RLV_ATTACHGROUP_HUD; - default: - return RLV_ATTACHGROUP_INVALID; - } -} - -// Checked: 2009-10-19 (RLVa-1.1.0e) | Added: RLVa-1.1.0e -inline ERlvAttachGroupType rlvGetAttachGroupTypeFromString(const std::string& strGroup) -{ - for (int idx = 0; idx < RLV_ATTACHGROUP_COUNT; idx++) - if (cstrAttachGroups[idx] == strGroup) - return (ERlvAttachGroupType)idx; - return RLV_ATTACHGROUP_INVALID; -} - // ============================================================================ // Command specific helper functions // @@ -1011,17 +971,17 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const LLUUID& idObj, const RlvComman case RLV_BHVR_SETENV: // @setenv=n|y eRet = onAddRemSetEnv(idObj, rlvCmd, fRefCount); break; - case RLV_BHVR_ADDOUTFIT: // @addoutfit[:<layer>]=n|y - Checked: 2010-03-18 (RLVa-1.2.0g) | Modified: RLVa-1.2.0a - case RLV_BHVR_REMOUTFIT: // @remoutfit[:<layer>]=n|y - Checked: 2010-03-18 (RLVa-1.2.0g) | Modified: RLVa-1.2.0a + case RLV_BHVR_ADDOUTFIT: // @addoutfit[:<layer>]=n|y - Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c + case RLV_BHVR_REMOUTFIT: // @remoutfit[:<layer>]=n|y - Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c { - // If there's an option it should specify a wearable type name (reference count on no option *and* a valid option) - LLWearableType::EType wtType = LLWearableType::typeNameToType(strOption); - VERIFY_OPTION_REF( (strOption.empty()) || (LLWearableType::WT_INVALID != wtType) ); + // If there's an option it should specify a wearable type name (reference count on no option *and* a valid option) + RlvCommandOptionGeneric rlvCmdOption(rlvCmd.getOption()); + VERIFY_OPTION_REF( (rlvCmdOption.isEmpty()) || (rlvCmdOption.isWearableType()) ); ERlvLockMask eLock = (RLV_BHVR_ADDOUTFIT == eBhvr) ? RLV_LOCK_ADD : RLV_LOCK_REMOVE; for (int idxType = 0; idxType < LLWearableType::WT_COUNT; idxType++) { - if ( ((LLWearableType::EType)idxType == wtType) || (LLWearableType::WT_INVALID == wtType) ) + if ( (rlvCmdOption.isEmpty()) || ((LLWearableType::EType)idxType == rlvCmdOption.getWearableType()) ) { if (RLV_TYPE_ADD == eType) gRlvWearableLocks.addWearableTypeLock((LLWearableType::EType)idxType, idObj, eLock); @@ -1417,7 +1377,7 @@ ERlvCmdRet RlvHandler::processForceCommand(const LLUUID& idObj, const RlvCommand return eRet; } -// Checked: 2010-03-19 (RLVa-1.2.0c) | Modified: RLVa-1.1.0i +// Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c ERlvCmdRet RlvHandler::onForceRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd) const { RLV_ASSERT(RLV_TYPE_FORCE == rlvCmd.getParamType()); @@ -1426,27 +1386,23 @@ ERlvCmdRet RlvHandler::onForceRemAttach(const LLUUID& idObj, const RlvCommand& r if (!isAgentAvatarValid()) return RLV_RET_FAILED; - S32 idxAttachPt = 0; ERlvAttachGroupType eAttachGroup = RLV_ATTACHGROUP_INVALID; + RlvCommandOptionGeneric rlvCmdOption(rlvCmd.getOption()); // @remattach:<attachpt>=force - force detach single attachment point - if ((idxAttachPt = RlvAttachPtLookup::getAttachPointIndex(rlvCmd.getOption())) != 0) + if (rlvCmdOption.isAttachmentPoint()) { - const LLViewerJointAttachment* pAttachPt = - get_if_there(gAgentAvatarp->mAttachmentPoints, (S32)idxAttachPt, (LLViewerJointAttachment*)NULL); - if (pAttachPt) - RlvForceWear::instance().forceDetach(pAttachPt); + RlvForceWear::instance().forceDetach(rlvCmdOption.getAttachmentPoint()); return RLV_RET_SUCCESS; } // @remattach:<group>=force - force detach attachments points belonging to <group> // @remattach=force - force detach all attachments points - else if ( ((eAttachGroup = rlvGetAttachGroupTypeFromString(rlvCmd.getOption())) != RLV_ATTACHGROUP_INVALID) || - (rlvCmd.getOption().empty()) ) + else if ( (rlvCmdOption.isAttachmentPointGroup()) || (rlvCmdOption.isEmpty()) ) { for (LLVOAvatar::attachment_map_t::const_iterator itAttach = gAgentAvatarp->mAttachmentPoints.begin(); itAttach != gAgentAvatarp->mAttachmentPoints.end(); ++itAttach) { const LLViewerJointAttachment* pAttachPt = itAttach->second; if ( (pAttachPt) && (pAttachPt->getNumObjects()) && - ((RLV_ATTACHGROUP_INVALID == eAttachGroup) || (rlvGetAttachGroupTypeFromIndex(pAttachPt->getGroup()) == eAttachGroup)) ) + ((rlvCmdOption.isEmpty()) || (rlvAttachGroupFromIndex(pAttachPt->getGroup()) == rlvCmdOption.getAttachmentPointGroup())) ) { RlvForceWear::instance().forceDetach(pAttachPt); } @@ -1456,18 +1412,17 @@ ERlvCmdRet RlvHandler::onForceRemAttach(const LLUUID& idObj, const RlvCommand& r return RLV_RET_FAILED_OPTION; } -// Checked: 2010-03-19 (RLVa-1.2.0c) | Modified: RLVa-1.1.0i +// Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c ERlvCmdRet RlvHandler::onForceRemOutfit(const LLUUID& idObj, const RlvCommand& rlvCmd) const { - LLWearableType::EType wtOption = LLWearableType::typeNameToType(rlvCmd.getOption()), wtType; - if ( (LLWearableType::WT_INVALID == wtOption) && (!rlvCmd.getOption().empty()) ) + RlvCommandOptionGeneric rlvCmdOption(rlvCmd.getOption()); + if ( (!rlvCmdOption.isWearableType()) && (!rlvCmdOption.isEmpty()) ) return RLV_RET_FAILED_OPTION; for (int idxType = 0; idxType < LLWearableType::WT_COUNT; idxType++) { - wtType = (LLWearableType::EType)idxType; - if ( (wtType == wtOption) || (LLWearableType::WT_INVALID == wtOption) ) - RlvForceWear::instance().forceRemove(wtType); + if ( (rlvCmdOption.isEmpty()) || ((LLWearableType::EType)idxType == rlvCmdOption.getWearableType())) + RlvForceWear::instance().forceRemove((LLWearableType::EType)idxType); } return RLV_RET_SUCCESS; } @@ -1709,12 +1664,12 @@ ERlvCmdRet RlvHandler::onGetAttachNames(const LLUUID& idObj, const RlvCommand& r if (!isAgentAvatarValid()) return RLV_RET_FAILED; - ERlvAttachGroupType eAttachGroup = rlvGetAttachGroupTypeFromString(rlvCmd.getOption()); + ERlvAttachGroupType eAttachGroup = rlvAttachGroupFromString(rlvCmd.getOption()); for (LLVOAvatar::attachment_map_t::const_iterator itAttach = gAgentAvatarp->mAttachmentPoints.begin(); itAttach != gAgentAvatarp->mAttachmentPoints.end(); ++itAttach) { const LLViewerJointAttachment* pAttachPt = itAttach->second; - if ( (RLV_ATTACHGROUP_INVALID == eAttachGroup) || (rlvGetAttachGroupTypeFromIndex(pAttachPt->getGroup()) == eAttachGroup) ) + if ( (RLV_ATTACHGROUP_INVALID == eAttachGroup) || (rlvAttachGroupFromIndex(pAttachPt->getGroup()) == eAttachGroup) ) { bool fAdd = false; switch (rlvCmd.getBehaviourType()) diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h index d4af20a7c14d6007d26ebec3500225cf5fdc4ab0..64c21a759f7c2f39dd7c11f7b64ee0362b09c1bd 100644 --- a/indra/newview/rlvhandler.h +++ b/indra/newview/rlvhandler.h @@ -345,10 +345,10 @@ inline ERlvCmdRet RlvHandler::processCommand(const LLUUID& idObj, const std::str { if (STATE_STARTED != LLStartUp::getStartupState()) { - m_Retained.push_back(RlvRetainedCommand(idObj, RlvCommand(strCommand))); + m_Retained.push_back(RlvRetainedCommand(idObj, RlvCommand(idObj, strCommand))); return RLV_RET_RETAINED; } - return processCommand(idObj, RlvCommand(strCommand), fFromObj); + return processCommand(idObj, RlvCommand(idObj, strCommand), fFromObj); } // ============================================================================ diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index ec38b3d902933bb908bc43753ed5cacfeba6bcb6..a9426b314ed78219b508728cda38cebce8e3104f 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -35,8 +35,8 @@ RlvCommand::RlvBhvrTable RlvCommand::m_BhvrMap; // Checked: 2009-12-27 (RLVa-1.1.0k) | Modified: RLVa-1.1.0k -RlvCommand::RlvCommand(const std::string& strCommand) - : m_eBehaviour(RLV_BHVR_UNKNOWN), m_fStrict(false), m_eParamType(RLV_TYPE_UNKNOWN) +RlvCommand::RlvCommand(const LLUUID& idObj, const std::string& strCommand) + : m_idObj(idObj), m_eBehaviour(RLV_BHVR_UNKNOWN), m_fStrict(false), m_eParamType(RLV_TYPE_UNKNOWN) { if ((m_fValid = parseCommand(strCommand, m_strBehaviour, m_strOption, m_strParam))) { @@ -145,6 +145,33 @@ void RlvCommand::initLookupTable() } } +// ============================================================================ +// RlvCommandOption +// + +// Checked: 2010-09-28 (RLVa-1.2.1c) | Added: RLVa-1.2.1c +RlvCommandOptionGeneric::RlvCommandOptionGeneric(const std::string& strOption) +{ + LLWearableType::EType wtType(LLWearableType::WT_INVALID); LLUUID idOption; ERlvAttachGroupType eAttachGroup(RLV_ATTACHGROUP_INVALID); + LLViewerJointAttachment* pAttachPt = NULL; LLViewerInventoryCategory* pFolder = NULL; + + if (!(m_fEmpty = strOption.empty())) // <option> could be an empty string + { + if ((wtType = LLWearableType::typeNameToType(strOption)) != LLWearableType::WT_INVALID) + m_varOption = wtType; // ... or specify a clothing layer + else if ((pAttachPt = RlvAttachPtLookup::getAttachPoint(strOption)) != NULL) + m_varOption = pAttachPt; // ... or specify an attachment point + else if (idOption.set(strOption)) + m_varOption = idOption; // ... or specify an UUID + else if ((pFolder = RlvInventory::instance().getSharedFolder(strOption)) != NULL) + m_varOption = pFolder; // ... or specify a shared folder path + else if ((eAttachGroup = rlvAttachGroupFromString(strOption)) != RLV_ATTACHGROUP_INVALID) + m_varOption = eAttachGroup; // ... or specify an attachment point group + else + m_varOption = strOption; // ... or it might just be a string + } +} + // ========================================================================= // RlvObject // @@ -867,6 +894,46 @@ bool rlvCanDeleteOrReturn() return fIsAllowed; } +// ============================================================================ +// Attachment group helper functions +// + +// Has to match the order of ERlvAttachGroupType +const std::string cstrAttachGroups[RLV_ATTACHGROUP_COUNT] = { "head", "torso", "arms", "legs", "hud" }; + +// Checked: 2009-10-19 (RLVa-1.1.0e) | Added: RLVa-1.1.0e +ERlvAttachGroupType rlvAttachGroupFromIndex(S32 idxGroup) +{ + switch (idxGroup) + { + case 0: // Right Hand + case 1: // Right Arm + case 3: // Left Arm + case 4: // Left Hand + return RLV_ATTACHGROUP_ARMS; + case 2: // Head + return RLV_ATTACHGROUP_HEAD; + case 5: // Left Leg + case 7: // Right Leg + return RLV_ATTACHGROUP_LEGS; + case 6: // Torso + return RLV_ATTACHGROUP_TORSO; + case 8: // HUD + return RLV_ATTACHGROUP_HUD; + default: + return RLV_ATTACHGROUP_INVALID; + } +} + +// Checked: 2009-10-19 (RLVa-1.1.0e) | Added: RLVa-1.1.0e +ERlvAttachGroupType rlvAttachGroupFromString(const std::string& strGroup) +{ + for (int idx = 0; idx < RLV_ATTACHGROUP_COUNT; idx++) + if (cstrAttachGroups[idx] == strGroup) + return (ERlvAttachGroupType)idx; + return RLV_ATTACHGROUP_INVALID; +} + // ========================================================================= // String helper functions // diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index 26a3c8fcdfe9bc2b38be364545b85661b911b09e..4ef4c823e4cb47724bdbc2c550f80266f3c7e252 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -39,20 +39,21 @@ class RlvCommand { public: - explicit RlvCommand(const std::string& strCommand); + explicit RlvCommand(const LLUUID& idObj, const std::string& strCommand); /* * Member functions */ public: std::string asString() const; - const std::string& getBehaviour() const { return m_strBehaviour; } - ERlvBehaviour getBehaviourType() const { return m_eBehaviour; } - const std::string& getOption() const { return m_strOption; } - const std::string& getParam() const { return m_strParam; } - ERlvParamType getParamType() const { return m_eParamType; } + const std::string& getBehaviour() const { return m_strBehaviour; } + ERlvBehaviour getBehaviourType() const { return m_eBehaviour; } + const LLUUID& getObjectID() const { return m_idObj; } + const std::string& getOption() const { return m_strOption; } + const std::string& getParam() const { return m_strParam; } + ERlvParamType getParamType() const { return m_eParamType; } bool isStrict() const { return m_fStrict; } - bool isValid() const { return m_fValid; } + bool isValid() const { return m_fValid; } static ERlvBehaviour getBehaviourFromString(const std::string& strBhvr, bool* pfStrict = NULL); static const std::string& getStringFromBehaviour(ERlvBehaviour eBhvr); @@ -72,13 +73,14 @@ public: * Member variables */ protected: - bool m_fValid; - std::string m_strBehaviour; - ERlvBehaviour m_eBehaviour; - bool m_fStrict; - std::string m_strOption; - std::string m_strParam; - ERlvParamType m_eParamType; + bool m_fValid; + LLUUID m_idObj; + std::string m_strBehaviour; + ERlvBehaviour m_eBehaviour; + bool m_fStrict; + std::string m_strOption; + std::string m_strParam; + ERlvParamType m_eParamType; typedef std::map<std::string, ERlvBehaviour> RlvBhvrTable; static RlvBhvrTable m_BhvrMap; @@ -87,6 +89,73 @@ protected: }; typedef std::list<RlvCommand> rlv_command_list_t; +// ============================================================================ +// RlvCommandOption (and derived classed) +// + +class RlvCommandOption +{ +protected: + RlvCommandOption() {} +public: + virtual ~RlvCommandOption() {} + +public: + virtual bool isAttachmentPoint() const { return false; } + virtual bool isAttachmentPointGroup() const { return false; } + virtual bool isEmpty() const = 0; + virtual bool isSharedFolder() const { return false; } + virtual bool isString() const { return false; } + virtual bool isUUID() const { return false; } + virtual bool isValid() const = 0; + virtual bool isWearableType() const { return false; } + + virtual LLViewerJointAttachment* getAttachmentPoint() const { return NULL; } + virtual ERlvAttachGroupType getAttachmentPointGroup() const { return RLV_ATTACHGROUP_INVALID; } + virtual LLViewerInventoryCategory* getSharedFolder() const { return NULL; } + virtual const std::string& getString() const { return LLStringUtil::null; } + virtual const LLUUID& getUUID() const { return LLUUID::null; } + virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_INVALID; } +}; + +class RlvCommandOptionGeneric : public RlvCommandOption +{ +public: + explicit RlvCommandOptionGeneric(const std::string& strOption); + RlvCommandOptionGeneric(LLViewerJointAttachment* pAttachPt) : m_fEmpty(false) { m_varOption = pAttachPt; } + RlvCommandOptionGeneric(LLViewerInventoryCategory* pFolder) : m_fEmpty(false) { m_varOption = pFolder; } + RlvCommandOptionGeneric(const LLUUID& idOption) : m_fEmpty(false) { m_varOption = idOption; } + RlvCommandOptionGeneric(LLWearableType::EType wtType) : m_fEmpty(false) { m_varOption = wtType; } + /*virtual*/ ~RlvCommandOptionGeneric() {} + +public: + /*virtual*/ bool isAttachmentPoint() const { return typeid(LLViewerJointAttachment*) == m_varOption.type(); } + /*virtual*/ bool isAttachmentPointGroup() const { return typeid(ERlvAttachGroupType) == m_varOption.type(); } + /*virtual*/ bool isEmpty() const { return m_fEmpty; } + /*virtual*/ bool isSharedFolder() const { return typeid(LLViewerInventoryCategory*) == m_varOption.type(); } + /*virtual*/ bool isString() const { return typeid(std::string) == m_varOption.type(); } + /*virtual*/ bool isUUID() const { return typeid(LLUUID) == m_varOption.type(); } + /*virtual*/ bool isValid() const { return true; } // This doesn't really have any significance for the generic class + /*virtual*/ bool isWearableType() const { return typeid(LLWearableType::EType) == m_varOption.type(); } + + /*virtual*/ LLViewerJointAttachment* getAttachmentPoint() const + { return (isAttachmentPoint()) ? boost::get<LLViewerJointAttachment*>(m_varOption) : RlvCommandOption::getAttachmentPoint(); } + /*virtual*/ ERlvAttachGroupType getAttachmentPointGroup() const + { return (isAttachmentPointGroup()) ? boost::get<ERlvAttachGroupType>(m_varOption) : RlvCommandOption::getAttachmentPointGroup(); } + /*virtual*/ LLViewerInventoryCategory* getSharedFolder() const + { return (isSharedFolder()) ? boost::get<LLViewerInventoryCategory*>(m_varOption) : RlvCommandOption::getSharedFolder(); } + /*virtual*/ const std::string& getString() const + { return (isString()) ? boost::get<std::string>(m_varOption) : RlvCommandOption::getString(); } + /*virtual*/ const LLUUID& getUUID() const + { return (isUUID()) ? boost::get<LLUUID>(m_varOption) : RlvCommandOption::getUUID(); } + /*virtual*/ LLWearableType::EType getWearableType() const + { return (isWearableType()) ? boost::get<LLWearableType::EType>(m_varOption) : RlvCommandOption::getWearableType(); } + +protected: + bool m_fEmpty; + boost::variant<LLViewerJointAttachment*, ERlvAttachGroupType, LLViewerInventoryCategory*, std::string, LLUUID, LLWearableType::EType> m_varOption; +}; + // ============================================================================ // RlvObject // @@ -306,6 +375,9 @@ public: bool rlvCanDeleteOrReturn(); +ERlvAttachGroupType rlvAttachGroupFromIndex(S32 idxGroup); +ERlvAttachGroupType rlvAttachGroupFromString(const std::string& strGroup); + std::string rlvGetFirstParenthesisedText(const std::string& strText, std::string::size_type* pidxMatch = NULL); std::string rlvGetLastParenthesisedText(const std::string& strText, std::string::size_type* pidxStart = NULL); void rlvStringReplace(std::string& strText, std::string strFrom, const std::string& strTo);