diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 11d3706821fa5cf20411502ce71ddd05f57c526a..a98c4145099b7062cdcbb1a070575ed78dbd7616 100755 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1327,6 +1327,35 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi } } +// [RLVa:KB] - Checked: RLVa-2.0.1 +bool LLWorld::getAvatar(const LLUUID& idAvatar, LLVector3d& posAvatar) const +{ + for (const LLCharacter* pCharacter : LLCharacter::sInstances) + { + const LLVOAvatar* pAvatar = static_cast<const LLVOAvatar*>(pCharacter); + if ( (!pAvatar->isDead()) && (!pAvatar->mIsDummy) && (!pAvatar->isOrphaned()) && (idAvatar == pAvatar->getID()) ) + { + posAvatar = pAvatar->getPositionGlobal(); + return true; + } + } + + for (const LLViewerRegion* pRegion : LLWorld::getInstance()->getRegionList()) + { + for (S32 idxAgent = 0, cntAgent = pRegion->mMapAvatarIDs.size(); idxAgent < cntAgent; ++idxAgent) + { + if (idAvatar == pRegion->mMapAvatarIDs[idxAgent]) + { + posAvatar = unpackLocalToGlobalPosition(pRegion->mMapAvatars[idxAgent], pRegion->getOriginGlobal()); + return true; + } + } + } + + return false; +} +// [/RLVa:KB] + bool LLWorld::isRegionListed(const LLViewerRegion* region) const { region_list_t::const_iterator it = find(mRegionList.begin(), mRegionList.end(), region); diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index b2d84180648ddfadc41c3ce0185f9354153451d8..325a120f55b6e921c29144fc0bda040ff3a12f33 100755 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -162,6 +162,9 @@ public: uuid_vec_t* avatar_ids = NULL, std::vector<LLVector3d>* positions = NULL, const LLVector3d& relative_to = LLVector3d(), F32 radius = FLT_MAX) const; +// [RLVa:KB] - Checked: RLVa-2.0.1 + bool getAvatar(const LLUUID& idAvatar, LLVector3d& posAvatar) const; +// [/RLVa:KB] // Returns 'true' if the region is in mRegionList, // 'false' if the region has been removed due to region change diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index 381e166de883e3ebaf06e40c6412a832b8aa1de9..aa9ac180b4ecea68cae712b33c7e4ac0d2db30ff 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -18,25 +18,38 @@ #include "llagent.h" #include "llimview.h" #include "llvoavatarself.h" +#include "llworld.h" #include "rlvactions.h" #include "rlvhelper.h" #include "rlvhandler.h" // ============================================================================ // Communication/Avatar interaction -// +// bool RlvActions::s_BlockNamesContexts[SNC_COUNT] = { 0 }; -// Checked: 2010-11-30 (RLVa-1.3.0) +// Little helper function to check the IM exclusion range for @recvim, @sendim and @startim (returns: min_dist <= (pos user - pos target) <= max_dist) +static bool rlvCheckAvatarIMDistance(const LLUUID& idAvatar, ERlvBehaviourModifier eModDistMin, ERlvBehaviourModifier eModDistMax) +{ + LLVector3d posAgent; + const RlvBehaviourModifier *pBhvrModDistMin = RlvBehaviourDictionary::instance().getModifier(eModDistMin), *pBhvrModDistMax = RlvBehaviourDictionary::instance().getModifier(eModDistMax); + if ( ((pBhvrModDistMin->hasValue()) || (pBhvrModDistMax->hasValue())) && (LLWorld::getInstance()->getAvatar(idAvatar, posAgent)) ) + { + float nDist = llabs(dist_vec_squared(gAgent.getPositionGlobal(), posAgent)); + return (nDist >= pBhvrModDistMin->getValue<float>()) && (nDist <= pBhvrModDistMax->getValue<float>()); + } + return false; +} + bool RlvActions::canReceiveIM(const LLUUID& idSender) { // User can receive an IM from "sender" (could be an agent or a group) if: - // - not generally restricted from receiving IMs (or the sender is an exception) + // - not generally restricted from receiving IMs (or the sender is an exception or inside the exclusion range) // - not specifically restricted from receiving an IM from the sender - return - (!rlv_handler_t::isEnabled()) || - ( ( (!gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) || (gRlvHandler.isException(RLV_BHVR_RECVIM, idSender)) ) && + return + (!isRlvEnabled()) || + ( ( (!gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) || (gRlvHandler.isException(RLV_BHVR_RECVIM, idSender)) || (rlvCheckAvatarIMDistance(idSender, RLV_MODIFIER_RECVIMDISTMIN, RLV_MODIFIER_RECVIMDISTMAX)) ) && ( (!gRlvHandler.hasBehaviour(RLV_BHVR_RECVIMFROM)) || (!gRlvHandler.isException(RLV_BHVR_RECVIMFROM, idSender)) ) ); } @@ -52,27 +65,26 @@ bool RlvActions::canSendChannel(int nChannel) ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHANNELEXCEPT)) || (!gRlvHandler.isException(RLV_BHVR_SENDCHANNELEXCEPT, nChannel)) ); } -// Checked: 2010-11-30 (RLVa-1.3.0) bool RlvActions::canSendIM(const LLUUID& idRecipient) { // User can send an IM to "recipient" (could be an agent or a group) if: - // - not generally restricted from sending IMs (or the recipient is an exception) + // - not generally restricted from sending IMs (or the recipient is an exception or inside the exclusion range) // - not specifically restricted from sending an IM to the recipient - return - (!rlv_handler_t::isEnabled()) || - ( ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.isException(RLV_BHVR_SENDIM, idRecipient)) ) && + return + (!isRlvEnabled()) || + ( ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.isException(RLV_BHVR_SENDIM, idRecipient)) || (rlvCheckAvatarIMDistance(idRecipient, RLV_MODIFIER_SENDIMDISTMIN, RLV_MODIFIER_SENDIMDISTMAX)) ) && ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) || (!gRlvHandler.isException(RLV_BHVR_SENDIMTO, idRecipient)) ) ); } 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 generally restricted from starting IM sessions (or the recipient is an exception or inside the exclusion range) // - 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)) ) && + return + (!isRlvEnabled()) || + ( ( (!gRlvHandler.hasBehaviour(RLV_BHVR_STARTIM)) || (gRlvHandler.isException(RLV_BHVR_STARTIM, idRecipient)) || (rlvCheckAvatarIMDistance(idRecipient, RLV_MODIFIER_STARTIMDISTMIN, RLV_MODIFIER_STARTIMDISTMAX)) ) && ( (!gRlvHandler.hasBehaviour(RLV_BHVR_STARTIMTO)) || (!gRlvHandler.isException(RLV_BHVR_STARTIMTO, idRecipient)) ) ) || ( (hasOpenP2PSession(idRecipient)) || (hasOpenGroupSession(idRecipient)) ); } diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 99bea2b3aa8abec4aceaf9ed7ce29e85d8ccd1f3..a431b7d6f41f94328d1e9e2023b2ec4240d12222 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -201,7 +201,13 @@ enum ERlvBehaviour { enum ERlvBehaviourModifier { - RLV_MODIFIER_FARTOUCHDIST, + RLV_MODIFIER_FARTOUCHDIST, // Radius of a sphere around the user in which they can interact with the world + RLV_MODIFIER_RECVIMDISTMIN, // Minimum distance to receive an IM from an otherwise restricted sender (squared value) + RLV_MODIFIER_RECVIMDISTMAX, // Maximum distance to receive an IM from an otherwise restricted sender (squared value) + RLV_MODIFIER_SENDIMDISTMIN, // Minimum distance to send an IM to an otherwise restricted recipient (squared value) + RLV_MODIFIER_SENDIMDISTMAX, // Maximum distance to send an IM to an otherwise restricted recipient (squared value) + RLV_MODIFIER_STARTIMDISTMIN, // Minimum distance to start an IM to an otherwise restricted recipient (squared value) + RLV_MODIFIER_STARTIMDISTMAX, // Maximum distance to start an IM to an otherwise restricted recipient (squared value) RLV_MODIFIER_SITTPDIST, RLV_MODIFIER_TPLOCALDIST, diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 2022fbfb22891d126161d0cfbc7dd1734afd5e77..97762343aa1440dc13353bc6b810b05e632e7b38 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -1583,6 +1583,59 @@ ERlvCmdRet RlvBehaviourSendChannelHandler::onCommand(const RlvCommand& rlvCmd, b return RLV_RET_SUCCESS; } +// Handles: @recvim[:<uuid|range>]=n|y, @sendim[:<uuid|range>]=n|y and @startim[:<uuid|range>]=n|y +template<> template<> +ERlvCmdRet RlvBehaviourRecvSendStartIMHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) +{ + ERlvCmdRet eRet = RlvBehaviourGenericHandler<RLV_OPTION_NONE_OR_EXCEPTION>::onCommand(rlvCmd, fRefCount); + if ( (RLV_RET_SUCCESS != eRet) && (rlvCmd.hasOption()) ) + { + // Check for <dist_min>[;<dist_max>] option + std::vector<std::string> optionList; float nDistMin = F32_MAX, nDistMax = F32_MAX; + if ( (!RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList)) || (optionList.size() > 2) || + (!RlvCommandOptionHelper::parseOption(optionList[0], nDistMin)) || (nDistMin < 0) || + ( (optionList.size() >= 2) && (!RlvCommandOptionHelper::parseOption(optionList[1], nDistMax)) ) || (nDistMax < 0) ) + { + return RLV_RET_FAILED_OPTION; + } + + // Valid option(s) - figure out which modifier(s) to change + ERlvBehaviourModifier eModDistMin, eModDistMax; + switch (rlvCmd.getBehaviourType()) + { + case RLV_BHVR_RECVIM: + eModDistMin = RLV_MODIFIER_RECVIMDISTMIN; eModDistMax = RLV_MODIFIER_RECVIMDISTMAX; + break; + case RLV_BHVR_SENDIM: + eModDistMin = RLV_MODIFIER_SENDIMDISTMIN; eModDistMax = RLV_MODIFIER_SENDIMDISTMAX; + break; + case RLV_BHVR_STARTIM: + eModDistMin = RLV_MODIFIER_STARTIMDISTMIN; eModDistMax = RLV_MODIFIER_STARTIMDISTMAX; + break; + default: + return RLV_RET_FAILED_OPTION; + } + + RlvBehaviourModifier *pBhvrModDistMin = RlvBehaviourDictionary::instance().getModifier(eModDistMin), *pBhvrModDistMax = RlvBehaviourDictionary::instance().getModifier(eModDistMax); + if (RLV_TYPE_ADD == rlvCmd.getParamType()) + { + pBhvrModDistMin->addValue(nDistMin * nDistMin, rlvCmd.getObjectID()); + if (optionList.size() >= 2) + pBhvrModDistMax->addValue(nDistMax * nDistMax, rlvCmd.getObjectID()); + } + else + { + pBhvrModDistMin->removeValue(nDistMin * nDistMin, rlvCmd.getObjectID()); + if (optionList.size() >= 2) + pBhvrModDistMax->removeValue(nDistMax * nDistMax, rlvCmd.getObjectID()); + } + + fRefCount = true; + return RLV_RET_SUCCESS; + } + return eRet; +} + // Handles: @sendim=n|y toggles template<> template<> void RlvBehaviourToggleHandler<RLV_BHVR_SENDIM>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index e884fed1f2f91a802bc3b743a1bc7a06d371332c..63f0269b502b0710f306ae693e3032b06bfabacd 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -112,7 +112,9 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_EXCEPTION>("recvchatfrom", RLV_BHVR_RECVCHATFROM, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("recvemote", RLV_BHVR_RECVEMOTE, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_EXCEPTION>("recvemotefrom", RLV_BHVR_RECVEMOTEFROM, RlvBehaviourInfo::BHVR_STRICT)); - addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("recvim", RLV_BHVR_RECVIM, RlvBehaviourInfo::BHVR_STRICT)); + addEntry(new RlvBehaviourProcessor<RLV_BHVR_RECVIM, RlvBehaviourRecvSendStartIMHandler>("recvim", RlvBehaviourInfo::BHVR_STRICT)); + addModifier(RLV_BHVR_RECVIM, RLV_MODIFIER_RECVIMDISTMIN, new RlvBehaviourModifier("RecvIM Distance (Min)", F32_MAX, true, &s_RlvBehaviourModifier_CompMax)); + addModifier(RLV_BHVR_RECVIM, RLV_MODIFIER_RECVIMDISTMAX, new RlvBehaviourModifier("RecvIM Distance (Max)", F32_MAX, true, &s_RlvBehaviourModifier_CompMin)); 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)); @@ -122,7 +124,9 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourProcessor<RLV_BHVR_SENDCHANNEL, RlvBehaviourSendChannelHandler>("sendchannel", RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourProcessor<RLV_BHVR_SENDCHANNELEXCEPT, RlvBehaviourSendChannelHandler>("sendchannel_except", RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("sendchat", RLV_BHVR_SENDCHAT)); - addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SENDIM, RLV_OPTION_NONE_OR_EXCEPTION>("sendim", RlvBehaviourInfo::BHVR_STRICT)); + addEntry(new RlvBehaviourToggleProcessor<RLV_BHVR_SENDIM, RlvBehaviourRecvSendStartIMHandler>("sendim", RlvBehaviourInfo::BHVR_STRICT)); + addModifier(RLV_BHVR_SENDIM, RLV_MODIFIER_SENDIMDISTMIN, new RlvBehaviourModifier("SendIM Distance (Min)", F32_MAX, true, &s_RlvBehaviourModifier_CompMax)); + addModifier(RLV_BHVR_SENDIM, RLV_MODIFIER_SENDIMDISTMAX, new RlvBehaviourModifier("SendIM Distance (Max)", F32_MAX, true, &s_RlvBehaviourModifier_CompMin)); 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 RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETDEBUG, RLV_OPTION_NONE>("setdebug")); @@ -146,7 +150,9 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_MODIFIER>("sittp", RLV_BHVR_SITTP)); addModifier(RLV_BHVR_SITTP, RLV_MODIFIER_SITTPDIST, new RlvBehaviourModifier("SitTp Distance", RLV_MODIFIER_SITTP_DEFAULT, true, &s_RlvBehaviourModifier_CompMin)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("standtp", RLV_BHVR_STANDTP)); - addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("startim", RLV_BHVR_STARTIM, RlvBehaviourInfo::BHVR_STRICT)); + addEntry(new RlvBehaviourProcessor<RLV_BHVR_STARTIM, RlvBehaviourRecvSendStartIMHandler>("startim", RlvBehaviourInfo::BHVR_STRICT)); + addModifier(RLV_BHVR_STARTIM, RLV_MODIFIER_STARTIMDISTMIN, new RlvBehaviourModifier("StartIM Distance (Min)", F32_MAX, true, &s_RlvBehaviourModifier_CompMax)); + addModifier(RLV_BHVR_STARTIM, RLV_MODIFIER_STARTIMDISTMAX, new RlvBehaviourModifier("StartIM Distance (Max)", F32_MAX, true, &s_RlvBehaviourModifier_CompMin)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_EXCEPTION>("startimto", RLV_BHVR_STARTIMTO, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("temprun", RLV_BHVR_TEMPRUN)); addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("touchall", RLV_BHVR_TOUCHALL)); diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index 7f11f8047bf6c0408961cf68f4c7b405d8cdc99a..963a8372da15a15522a154fa574de0f0fdf46c04 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -115,7 +115,8 @@ template<ERlvBehaviour eBhvr> using RlvReplyHandler = RlvCommandHandler<RLV_TYPE // List of shared handlers typedef RlvBehaviourHandler<RLV_BHVR_REMATTACH> RlvBehaviourAddRemAttachHandler; // Shared between @addattach and @remattach -typedef RlvBehaviourHandler<RLV_BHVR_SENDCHANNEL> RlvBehaviourSendChannelHandler; // Shared between @addattach and @remattach +typedef RlvBehaviourHandler<RLV_BHVR_SENDCHANNEL> RlvBehaviourSendChannelHandler; // Shared between @sendchannel and @sendchannel_except +typedef RlvBehaviourHandler<RLV_BHVR_SENDIM> RlvBehaviourRecvSendStartIMHandler; // Shared between @recvim, @sendim and @startim typedef RlvBehaviourToggleHandler<RLV_BHVR_SHOWSELF> RlvBehaviourShowSelfToggleHandler; // Shared between @showself and @showselfhead typedef RlvForceHandler<RLV_BHVR_REMATTACH> RlvForceRemAttachHandler; // Shared between @remattach and @detach