Code cleanup: better handling of group joins when @setgroup restricted

-> bundle all permission checks in a predictable single function (see RlvActions::canChangeActiveGroup)
  -> properly handle the case where a user is ejected from a group
  -> provide feedback to the user after we force the previous group back when joining a new group

--HG--
branch : RLVa
master
Kitty Barnett 2016-07-09 22:08:23 +02:00
parent 21b6dd58ac
commit fda5eb9ccc
7 changed files with 65 additions and 25 deletions

View File

@ -294,8 +294,8 @@ bool LLGroupActions::onJoinGroup(const LLSD& notification, const LLSD& response)
void LLGroupActions::leave(const LLUUID& group_id)
{
// if (group_id.isNull())
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f
if ( (group_id.isNull()) || ((gAgent.getGroupID() == group_id) && (gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP))) )
// [RLVa:KB] - Checked: RLVa-1.3.0
if ( (group_id.isNull()) || ((gAgent.getGroupID() == group_id) && (!RlvActions::canChangeActiveGroup())) )
// [/RLVa:KB]
{
return;
@ -348,8 +348,8 @@ void LLGroupActions::processLeaveGroupDataResponse(const LLUUID group_id)
// static
void LLGroupActions::activate(const LLUUID& group_id)
{
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f
if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP)) && (gRlvHandler.getAgentGroup() != group_id) )
// [RLVa:KB] - Checked: RLVa-1.3.0
if ( (!RlvActions::canChangeActiveGroup()) && (gRlvHandler.getAgentGroup() != group_id) )
{
return;
}

View File

@ -43,8 +43,8 @@
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewermenu.h" // for gMenuHolder
#include "llvoiceclient.h"
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
#include "rlvhandler.h"
// [RLVa:KB] - Checked: RLVa-2.0.3
#include "rlvactions.h"
// [/RLVa:KB]
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
@ -284,14 +284,14 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
bool real_group_selected = selected_group_id.notNull(); // a "real" (not "none") group is selected
// each group including "none" can be activated
// [RLVa:KB] - Checked: RLVa-1.3.0
if (userdata.asString() == "activate")
return (gAgent.getGroupID() != selected_group_id) && (RlvActions::canChangeActiveGroup());
else if (userdata.asString() == "leave")
return (real_group_selected) && ((gAgent.getGroupID() != selected_group_id) || (RlvActions::canChangeActiveGroup()));
// [/RLVa:KB]
// if (userdata.asString() == "activate")
// return gAgent.getGroupID() != selected_group_id;
// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f
if (userdata.asString() == "activate")
return (gAgent.getGroupID() != selected_group_id) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP));
else if (userdata.asString() == "leave")
return (real_group_selected) && ((gAgent.getGroupID() != selected_group_id) || (!gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP)));
// [/RLVa:KB]
if (userdata.asString() == "call")
return real_group_selected && LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();

View File

@ -121,6 +121,13 @@ bool RlvActions::getCameraFOVLimits(F32& nFOVMin, F32& nFOVMax)
bool RlvActions::s_BlockNamesContexts[SNC_COUNT] = { 0 };
bool RlvActions::canChangeActiveGroup(const LLUUID& idRlvObject)
{
// User can change their active group if:
// - not specifically restricted (by another object that the one specified) from changing their active group
return (idRlvObject.isNull()) ? !gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP) : !gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETGROUP, idRlvObject);
}
// 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)
{

View File

@ -74,6 +74,11 @@ public:
// Communication/Avatar interaction
// ================================
public:
/*
* Returns true if the user is allowed to change their currently active group
*/
static bool canChangeActiveGroup(const LLUUID& idRlvObject = LLUUID::null);
/*
* Returns true if the user is allowed to receive IMs from the specified sender (can be an avatar or a group)
*/

View File

@ -370,6 +370,7 @@ enum ERlvAttachGroupType
#define RLV_STRING_BLOCKED_AUTOPILOT "blocked_autopilot"
#define RLV_STRING_BLOCKED_GENERIC "blocked_generic"
#define RLV_STRING_BLOCKED_GROUPCHANGE "blocked_groupchange"
#define RLV_STRING_BLOCKED_PERMATTACH "blocked_permattach"
#define RLV_STRING_BLOCKED_PERMTELEPORT "blocked_permteleport"
#define RLV_STRING_BLOCKED_RECVIM "blocked_recvim"

View File

@ -472,21 +472,43 @@ ERlvCmdRet RlvHandler::processClearCommand(const RlvCommand& rlvCmd)
// Externally invoked event handlers
//
// Checked: 2011-05-22 (RLVa-1.4.1a) | Added: RLVa-1.3.1b
bool RlvHandler::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& sdUserdata)
{
// If the user managed to change their active group (= newly joined or created group) we need to reactivate the previous one
if ( (hasBehaviour(RLV_BHVR_SETGROUP)) && ("new group" == event->desc()) && (m_idAgentGroup != gAgent.getGroupID()) )
// NOTE: we'll fire once for every group the user belongs to so we need to manually keep track of pending changes
static LLUUID s_idLastAgentGroup = LLUUID::null;
static bool s_fGroupChanging = false;
if (s_idLastAgentGroup != gAgent.getGroupID())
{
// [Copy/paste from LLGroupActions::activate()]
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ActivateGroup);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->addUUIDFast(_PREHASH_GroupID, m_idAgentGroup);
gAgent.sendReliableMessage();
return true;
s_idLastAgentGroup = gAgent.getGroupID();
s_fGroupChanging = false;
}
// If the user managed to change their active group (= newly joined or created group) we need to reactivate the previous one
if ( (!RlvActions::canChangeActiveGroup()) && ("new group" == event->desc()) && (m_idAgentGroup != gAgent.getGroupID()) )
{
// Make sure they still belong to the group
if ( (m_idAgentGroup.notNull()) && (!gAgent.isInGroup(m_idAgentGroup)) )
{
m_idAgentGroup.setNull();
s_fGroupChanging = false;
}
if (!s_fGroupChanging)
{
RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_GROUPCHANGE, LLSD().with("GROUP_SLURL", (m_idAgentGroup.notNull()) ? llformat("secondlife:///app/group/%s/about", m_idAgentGroup.asString()) : "(none)"));
// [Copy/paste from LLGroupActions::activate()]
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ActivateGroup);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->addUUIDFast(_PREHASH_GroupID, m_idAgentGroup);
gAgent.sendReliableMessage();
s_fGroupChanging = true;
return true;
}
}
else
{
@ -2384,7 +2406,7 @@ void RlvHandler::onForceWearCallback(const uuid_vec_t& idItems, U32 nFlags) cons
template<> template<>
ERlvCmdRet RlvForceHandler<RLV_BHVR_SETGROUP>::onCommand(const RlvCommand& rlvCmd)
{
if (gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETGROUP, rlvCmd.getObjectID()))
if (!RlvActions::canChangeActiveGroup(rlvCmd.getObjectID()))
{
return RLV_RET_FAILED_LOCK;
}

View File

@ -56,6 +56,11 @@
<key>value</key>
<string>Unable to perform action due to RLV restrictions</string>
</map>
<key>blocked_groupchange</key>
<map>
<key>value</key>
<string>Unable to change your active group due to an RLV restriction; switching back to [GROUP_SLURL]</string>
</map>
<key>blocked_permattach</key>
<map>
<key>value</key>