Merged with RLVa tip

master
Kitty Barnett 2018-06-18 01:09:54 +02:00
commit 4b19e4c1a5
27 changed files with 434 additions and 33 deletions

View File

@ -59,6 +59,9 @@ LLColor4 LLColor4::grey1(0.8f, 0.8f, 0.8f, 1.0f);
LLColor4 LLColor4::grey2(0.6f, 0.6f, 0.6f, 1.0f);
LLColor4 LLColor4::grey3(0.4f, 0.4f, 0.4f, 1.0f);
LLColor4 LLColor4::grey4(0.3f, 0.3f, 0.3f, 1.0f);
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
LLColor4 LLColor4::silhouette(0.05f, 0.05f, 0.05f, 1.0f);
// [/RLVa:KB]
LLColor4 LLColor4::red1(1.0f, 0.0f, 0.0f, 1.0f);
LLColor4 LLColor4::red2(0.6f, 0.0f, 0.0f, 1.0f);

View File

@ -154,6 +154,9 @@ class LLColor4
static LLColor4 grey2;
static LLColor4 grey3;
static LLColor4 grey4;
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
static LLColor4 silhouette;
// [/RLVa:KB]
static LLColor4 red1;
static LLColor4 red2;

View File

@ -317,7 +317,7 @@ BOOL LLGLTexture::getIsAlphaMask() const
}
//BOOL LLGLTexture::getMask(const LLVector2 &tc)
// [RLVa:KB] - Checked: RLVa-2.3 (@setoverlay)
// [RLVa:KB] - Checked: RLVa-2.2 (@setoverlay)
bool LLGLTexture::getMask(const LLVector2 &tc) const
// [/RLVa:KB]
{

View File

@ -143,7 +143,7 @@ public:
LLGLenum getPrimaryFormat() const;
BOOL getIsAlphaMask() const ;
LLTexUnit::eTextureType getTarget(void) const ;
// [RLVa:KB] - Checked: RLVa-2.3 (@setoverlay)
// [RLVa:KB] - Checked: RLVa-2.2 (@setoverlay)
bool getMask(const LLVector2 &tc) const;
// [/RLVa:KB]
// BOOL getMask(const LLVector2 &tc);

View File

@ -2002,7 +2002,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
}
//BOOL LLImageGL::getMask(const LLVector2 &tc)
// [RLVa:KB] - Checked: RLVa-2.3 (@setoverlay)
// [RLVa:KB] - Checked: RLVa-2.2 (@setoverlay)
BOOL LLImageGL::getMask(const LLVector2 &tc) const
// [/RLVa:KB]
{

View File

@ -153,7 +153,7 @@ public:
void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; }
void updatePickMask(S32 width, S32 height, const U8* data_in);
// [RLVa:KB] - Checked: RLVa-2.3 (@setoverlay)
// [RLVa:KB] - Checked: RLVa-2.2 (@setoverlay)
BOOL getMask(const LLVector2 &tc) const;
// [/RLVa:KB]
// BOOL getMask(const LLVector2 &tc);

View File

@ -1229,6 +1229,17 @@
<key>Value</key>
<string>+</string>
</map>
<key>RLVaBlockedExperiences</key>
<map>
<key>Comment</key>
<string>List of experiences blocked from interacting with RLVa</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>bfe25fb4-222c-11e5-85a2-fa4c4ccaa202</string>
</map>
<key>RLVaCompatibilityModeList</key>
<map>
<key>Comment</key>
@ -1328,6 +1339,17 @@
<key>Value</key>
<boolean>1</boolean>
</map>
<key>RLVaExperienceMaturityThreshold</key>
<map>
<key>Comment</key>
<string>Specifies the minimum maturity an experience has to be before it can interact with RLVa (0: never; 1: PG; 2: Mature; 3: Adult)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>2</integer>
</map>
<key>RLVaHideLockedLayers</key>
<map>
<key>Comment</key>

View File

@ -742,6 +742,13 @@ void LLAgent::moveLeftNudge(S32 direction)
//-----------------------------------------------------------------------------
void LLAgent::moveUp(S32 direction)
{
// [RLVa:KB] - Checked: RLVa-2.2 (@jump)
if ( (!RlvActions::canJump()) && (direction > 0) && (!getFlying()) )
{
return;
}
// [/Sl:KB]
mMoveTimer.reset();
LLFirstUse::notMoving(false);
@ -819,8 +826,11 @@ void LLAgent::movePitch(F32 mag)
// Does this parcel allow you to fly?
BOOL LLAgent::canFly()
{
// [RLVa:KB] - Checked: 2010-03-02 (RLVa-1.2.0d) | Modified: RLVa-1.0.0c
if (gRlvHandler.hasBehaviour(RLV_BHVR_FLY)) return FALSE;
// [RLVa:KB] - Checked: RLVa-1.0
if (!RlvActions::canFly())
{
return FALSE;
}
// [/RLVa:KB]
if (isGodlike()) return TRUE;
// <FS> Always fly
@ -876,8 +886,8 @@ void LLAgent::setFlying(BOOL fly)
if (fly)
{
// [RLVa:KB] - Checked: 2010-03-02 (RLVa-1.2.0d) | Modified: RLVa-1.0.0c
if (gRlvHandler.hasBehaviour(RLV_BHVR_FLY))
// [RLVa:KB] - Checked: RLVa-1.0
if (!RlvActions::canFly())
{
return;
}

View File

@ -1534,7 +1534,7 @@ void LLGroupMgr::notifyObservers(LLGroupChange gc)
return;
// observer_set_t& obs = obs_it->second;
// [RLVa:KB] - Checked: RLVa-2.3 (General bugfix)
// [RLVa:KB] - Checked: RLVa-2.2 (General bugfix)
// Iterate over a *copy* of the observer list
observer_set_t obs = obs_it->second;
// [/RLVa:KB]

View File

@ -5721,7 +5721,7 @@ bool LLTextureBridge::canSaveTexture(void)
return false;
}
// [RLVa:KB] - Checked: RLVa-2.2
// [RLVa:KB] - Checked: RLVa-2.2 (@viewtexture)
if (!RlvActions::canPreviewTextures())
{
return false;

View File

@ -1428,7 +1428,7 @@ void render_ui(F32 zoom_factor, int subfield)
}
render_hud_elements();
// [RLVa:KB] - Checked: RLVa-2.3 (@setoverlay)
// [RLVa:KB] - Checked: RLVa-2.2 (@setoverlay)
if (gRlvHandler.isEnabled())
{
gRlvHandler.renderOverlay();

View File

@ -140,6 +140,7 @@
#include "boost/unordered_map.hpp"
#include "llcleanup.h"
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "fsavatarrenderpersistence.h"
#include "rlvactions.h"
#include "rlvhandler.h"
#include "rlvlocks.h"
@ -3741,11 +3742,20 @@ bool check_avatar_render_mode(U32 mode)
switch (mode)
{
case 0:
return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_RENDER_NORMALLY);
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) == LLVOAvatar::AV_RENDER_NORMALLY;
// [/RLVa:KB]
// return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_RENDER_NORMALLY);
case 1:
return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) == LLVOAvatar::AV_DO_NOT_RENDER;
// [/RLVa:KB]
// return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);
case 2:
return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) == LLVOAvatar::AV_ALWAYS_RENDER;
// [/RLVa:KB]
// return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
default:
return false;
}

View File

@ -6941,7 +6941,7 @@ void LLPickInfo::fetchResults()
mPickPt = mMousePt;
// [RLVa:KB] - Checked: RLVa-2.3 (@setoverlay)
// [RLVa:KB] - Checked: RLVa-2.2 (@setoverlay)
if ( (gRlvHandler.isEnabled()) && (hit_object) && (!hit_object->isHUDAttachment()) )
{
if (gRlvHandler.hitTestOverlay(mMousePt))

View File

@ -101,6 +101,7 @@
// [RLVa:KB] - Checked: RLVa-2.0.1
#include "rlvactions.h"
#include "rlvhandler.h"
#include "rlvmodifiers.h"
// [/RLVa:KB]
#include "llgesturemgr.h" //needed to trigger the voice gesticulations
@ -3845,6 +3846,12 @@ bool LLVOAvatar::isVisuallyMuted()
// muted = true;
//}
// </FS:Ansariel>
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
else if (isRlvSilhouette())
{
muted = true;
}
// [/RLVa:KB]
else
{
muted = isTooComplex();
@ -3873,6 +3880,30 @@ bool LLVOAvatar::isInMuteList()
return muted;
}
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
bool LLVOAvatar::isRlvSilhouette()
{
if (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_AVDIST))
return false;
static RlvCachedBehaviourModifier<float> s_nSetCamAvDist(RLV_MODIFIER_SETCAM_AVDIST);
const F64 now = LLFrameTimer::getTotalSeconds();
if (now >= mCachedRlvSilhouetteUpdateTime)
{
const F64 SECONDS_BETWEEN_NEARBY_UPDATES = .5f;
bool fIsRlvSilhouette = dist_vec_squared(gAgent.getPositionGlobal(), getPositionGlobal()) > s_nSetCamAvDist() * s_nSetCamAvDist();
if (fIsRlvSilhouette != mCachedIsRlvSilhouette)
{
mCachedIsRlvSilhouette = fIsRlvSilhouette;
mNeedsImpostorUpdate = TRUE;
}
mCachedRlvSilhouetteUpdateTime = now + SECONDS_BETWEEN_NEARBY_UPDATES;
}
return mCachedIsRlvSilhouette;
}
// [/RLVa:KB]
void LLVOAvatar::updateDebugText()
{
// clear debug text
@ -10283,9 +10314,21 @@ void LLVOAvatar::calcMutedAVColor()
if (getVisualMuteSettings() == AV_DO_NOT_RENDER)
{
// explicitly not-rendered avatars are light grey
new_color = LLColor4::grey3;
change_msg = " not rendered: color is grey3";
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
if (isRlvSilhouette())
{
new_color = LLColor4::silhouette;
change_msg = " not rendered: color is silhouette";
}
else
{
// [/RLVa:KB]
// explicitly not-rendered avatars are light grey
new_color = LLColor4::grey3;
change_msg = " not rendered: color is grey3";
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
}
// [/RLVa:KB]
}
else if (LLMuteList::getInstance()->isMuted(av_id)) // the user blocked them
{
@ -10293,8 +10336,11 @@ void LLVOAvatar::calcMutedAVColor()
new_color = LLColor4::grey4;
change_msg = " blocked: color is grey4";
}
else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 )
{
// else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 )
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 || mMutedAVColor == LLColor4::silhouette)
// [/RLVa:KB]
{
// select a color based on the first byte of the agents uuid so any muted agent is always the same color
F32 color_value = (F32) (av_id.mData[0]);
F32 spectrum = (color_value / 256.0); // spectrum is between 0 and 1.f

View File

@ -409,6 +409,9 @@ public:
U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0);
bool isVisuallyMuted();
bool isInMuteList();
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
bool isRlvSilhouette();
// [/RLVa:KB]
void forceUpdateVisualMuteSettings();
enum VisualMuteSettings
@ -418,7 +421,10 @@ public:
AV_ALWAYS_RENDER = 2
};
void setVisualMuteSettings(VisualMuteSettings set);
VisualMuteSettings getVisualMuteSettings() { return mVisuallyMuteSetting; };
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
VisualMuteSettings getVisualMuteSettings() { return (!isRlvSilhouette()) ? mVisuallyMuteSetting : AV_DO_NOT_RENDER; };
// [/RLVa:KB]
// VisualMuteSettings getVisualMuteSettings() { return mVisuallyMuteSetting; };
U32 renderRigid();
U32 renderSkinned();
@ -449,6 +455,10 @@ public:
bool mCachedInMuteList;
F64 mCachedMuteListUpdateTime;
// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
mutable bool mCachedIsRlvSilhouette = false;
mutable F64 mCachedRlvSilhouetteUpdateTime = 0.f;
// [/RLVa:KB]
VisualMuteSettings mVisuallyMuteSetting; // Always or never visually mute this AV

View File

@ -297,6 +297,21 @@ bool RlvActions::autoAcceptTeleportRequest(const LLUUID& idRequester)
return ((idRequester.notNull()) && (gRlvHandler.isException(RLV_BHVR_ACCEPTTPREQUEST, idRequester))) || (gRlvHandler.hasBehaviour(RLV_BHVR_ACCEPTTPREQUEST));
}
bool RlvActions::canFly()
{
return (!gRlvHandler.getCurrentCommand()) ? !gRlvHandler.hasBehaviour(RLV_BHVR_FLY) : !gRlvHandler.hasBehaviourExcept(RLV_BHVR_FLY, gRlvHandler.getCurrentObject());
}
bool RlvActions::canFly(const LLUUID& idRlvObjExcept)
{
return !gRlvHandler.hasBehaviourExcept(RLV_BHVR_FLY, idRlvObjExcept);
}
bool RlvActions::canJump()
{
return !gRlvHandler.hasBehaviour(RLV_BHVR_JUMP);
}
// ============================================================================
// Teleporting
//

View File

@ -176,6 +176,18 @@ public:
*/
static bool autoAcceptTeleportRequest(const LLUUID& idRequester);
/*
* Returns true if the user can fly
* (NOTE: the parameter-less overload takes the currently executing command into account)
*/
static bool canFly();
static bool canFly(const LLUUID& idRlvObjExcept);
/*
* Returns true if the user can jump
*/
static bool canJump();
// ===========
// Teleporting
// ===========

View File

@ -86,9 +86,11 @@ void RlvNotifications::onGiveToRLVConfirmation(const LLSD& notification, const L
bool RlvSettings::s_fCompositeFolders = false;
#endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
bool RlvSettings::s_fCanOOC = true;
U8 RlvSettings::s_nExperienceMinMaturity = 0;
bool RlvSettings::s_fLegacyNaming = true;
bool RlvSettings::s_fNoSetEnv = false;
bool RlvSettings::s_fTempAttach = true;
std::list<std::string> RlvSettings::s_BlockedExperiences;
std::list<LLUUID> RlvSettings::s_CompatItemCreators;
std::list<std::string> RlvSettings::s_CompatItemNames;
@ -124,6 +126,10 @@ void RlvSettings::initClass()
if (gSavedSettings.controlExists(RLV_SETTING_TOPLEVELMENU))
gSavedSettings.getControl(RLV_SETTING_TOPLEVELMENU)->getSignal()->connect(boost::bind(&onChangedMenuLevel));
int nMinMaturity = gSavedSettings.getS32("RLVaExperienceMaturityThreshold");
s_nExperienceMinMaturity = (nMinMaturity == 0) ? 0 : ((nMinMaturity == 1) ? SIM_ACCESS_PG : ((nMinMaturity == 2) ? SIM_ACCESS_MATURE : SIM_ACCESS_ADULT));
boost::split(s_BlockedExperiences, gSavedSettings.getString("RLVaBlockedExperiences"), boost::is_any_of(";"));
fInitialized = true;
}
}
@ -226,6 +232,18 @@ bool RlvSettings::isCompatibilityModeObject(const LLUUID& idRlvObject)
return fCompatMode;
}
bool RlvSettings::isAllowedExperience(const LLUUID& idExperience, U8 nMaturity)
{
// An experience is allowed to interact with RLVa if:
// - temporary attachments can interact with RLVa
// - the user set a minimum maturity and the specified maturity is equal or higher
// - the experience isn't explicitly blocked (NOTE: case-sensitive string comparison)
return
(getEnableTemporaryAttachments()) &&
(s_nExperienceMinMaturity) && (s_nExperienceMinMaturity <= nMaturity) &&
(s_BlockedExperiences.end() == std::find(s_BlockedExperiences.begin(), s_BlockedExperiences.end(), idExperience.asString()));
}
// ============================================================================
// RlvStrings
//
@ -376,6 +394,8 @@ const char* RlvStrings::getStringFromReturnCode(ERlvCmdRet eRet)
return "deprecated and disabled";
case RLV_RET_FAILED_NOBEHAVIOUR:
return "no active behaviours";
case RLV_RET_FAILED_BLOCKED:
return "blocked object";
// The following are identified by the chat verb
case RLV_RET_RETAINED:
case RLV_RET_SUCCESS:

View File

@ -107,6 +107,8 @@ public:
static void initCompatibilityMode(std::string strCompatList);
static bool isCompatibilityModeObject(const LLUUID& idRlvObject);
static bool isAllowedExperience(const LLUUID& idExperience, U8 nMaturity);
static void initClass();
static void onChangedSettingMain(const LLSD& sdValue);
protected:
@ -122,9 +124,11 @@ protected:
*/
protected:
static bool s_fCanOOC;
static U8 s_nExperienceMinMaturity;
static bool s_fLegacyNaming;
static bool s_fNoSetEnv;
static bool s_fTempAttach;
static std::list<std::string> s_BlockedExperiences;
static std::list<LLUUID> s_CompatItemCreators;
static std::list<std::string> s_CompatItemNames;
};

View File

@ -163,6 +163,7 @@ enum ERlvBehaviour {
RLV_BHVR_TOUCHALL, // "touchall"
RLV_BHVR_TOUCHME, // "touchme"
RLV_BHVR_FLY, // "fly"
RLV_BHVR_JUMP, // "jump"
RLV_BHVR_SETGROUP, // "setgroup"
RLV_BHVR_UNSIT, // "unsit"
RLV_BHVR_SIT, // "sit"
@ -205,6 +206,7 @@ enum ERlvBehaviour {
// Camera (behaviours)
RLV_BHVR_SETCAM, // Gives an object exclusive control of the user's camera
RLV_BHVR_SETCAM_AVDIST, // Distance at which nearby avatars turn into a silhouette
RLV_BHVR_SETCAM_AVDISTMIN, // Enforces a minimum distance from the avatar (in m)
RLV_BHVR_SETCAM_AVDISTMAX, // Enforces a maximum distance from the avatar (in m)
RLV_BHVR_SETCAM_ORIGINDISTMIN, // Enforces a minimum distance from the camera origin (in m)
@ -257,6 +259,7 @@ enum ERlvBehaviourModifier
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_SETCAM_AVDIST, // Distance at which nearby avatars turn into a silhouette (normal value)
RLV_MODIFIER_SETCAM_AVDISTMIN, // Minimum distance between the camera position and the user's avatar (normal value)
RLV_MODIFIER_SETCAM_AVDISTMAX, // Maximum distance between the camera position and the user's avatar (normal value)
RLV_MODIFIER_SETCAM_ORIGINDISTMIN, // Minimum distance between the camera position and the origin point (normal value)
@ -310,6 +313,7 @@ enum ERlvCmdRet {
RLV_RET_FAILED_NOSHAREDROOT, // Command failed (missing #RLV)
RLV_RET_FAILED_DEPRECATED, // Command failed (deprecated and no longer supported)
RLV_RET_FAILED_NOBEHAVIOUR, // Command failed (force modifier on an object with no active restrictions)
RLV_RET_FAILED_BLOCKED, // Command failed (object is blocked)
RLV_RET_NO_PROCESSOR // Command doesn't have a template processor define (legacy code)
};
#define RLV_RET_SUCCEEDED(eCmdRet) (((eCmdRet) & RLV_RET_SUCCESS) == RLV_RET_SUCCESS)

View File

@ -230,7 +230,7 @@ void RlvFloaterBehaviours::onAvatarNameLookup(const LLUUID& idAgent, const LLAva
}
// static
const std::string RlvFloaterBehaviours::getFormattedBehaviourString()
std::string RlvFloaterBehaviours::getFormattedBehaviourString(ERlvBehaviourFilter eFilter)
{
std::ostringstream strRestrictions;
@ -241,6 +241,13 @@ const std::string RlvFloaterBehaviours::getFormattedBehaviourString()
strRestrictions << "\n" << rlvGetItemNameFromObjID(rlvObjectEntry.first) << ":\n";
for (const RlvCommand& rlvCmd : rlvObjectEntry.second.getCommandList())
{
bool fIsException = (rlvCmd.hasOption()) && (rlvGetShowException(rlvCmd.getBehaviourType()));
if ( ((ERlvBehaviourFilter::BEHAVIOURS_ONLY == eFilter) && (fIsException)) ||
((ERlvBehaviourFilter::EXCEPTIONS_ONLY == eFilter) && (!fIsException)) )
{
continue;
}
std::string strOption; LLUUID idOption;
if ( (rlvCmd.hasOption()) && (idOption.set(rlvCmd.getOption(), FALSE)) && (idOption.notNull()) )
{
@ -266,7 +273,7 @@ const std::string RlvFloaterBehaviours::getFormattedBehaviourString()
// Checked: 2011-05-26 (RLVa-1.3.1c) | Added: RLVa-1.3.1c
void RlvFloaterBehaviours::onBtnCopyToClipboard()
{
LLWString wstrRestrictions = utf8str_to_wstring(getFormattedBehaviourString());
LLWString wstrRestrictions = utf8str_to_wstring(getFormattedBehaviourString(ERlvBehaviourFilter::ALL));
LLClipboard::instance().copyToClipboard(wstrRestrictions, 0, wstrRestrictions.length());
}

View File

@ -32,6 +32,12 @@ class LLTextEditor;
// RlvFloaterLocks class declaration
//
enum class ERlvBehaviourFilter {
BEHAVIOURS_ONLY,
EXCEPTIONS_ONLY,
ALL
};
class RlvFloaterBehaviours : public LLFloater
{
friend class LLFloaterReg;
@ -49,7 +55,7 @@ public:
/*
* Member functions
*/
static const std::string getFormattedBehaviourString();
static std::string getFormattedBehaviourString(ERlvBehaviourFilter eFilter);
protected:
void onAvatarNameLookup(const LLUUID& idAgent, const LLAvatarName& avName);
void onBtnCopyToClipboard();

View File

@ -19,6 +19,8 @@
#include "llagent.h"
#include "llappearancemgr.h"
#include "llappviewer.h"
#include "llexperiencecache.h"
#include "llexperiencelog.h"
#include "llgroupactions.h"
#include "llhudtext.h"
#include "llmoveview.h"
@ -265,6 +267,78 @@ void RlvHandler::removeException(const LLUUID& idObj, ERlvBehaviour eBhvr, const
}
}
// ============================================================================
// Blocked object handling
//
void RlvHandler::addBlockedObject(const LLUUID& idObj, const std::string& strName)
{
m_BlockedObjects.push_back(std::make_tuple(idObj, strName, LLTimer::getTotalSeconds()));
}
bool RlvHandler::hasUnresolvedBlockedObject() const
{
return std::any_of(m_BlockedObjects.begin(), m_BlockedObjects.end(), [](const rlv_blocked_object_t& entry) { return std::get<0>(entry).isNull(); });
}
bool RlvHandler::isBlockedObject(const LLUUID& idObj) const
{
return std::any_of(m_BlockedObjects.begin(), m_BlockedObjects.end(), [&idObj](const rlv_blocked_object_t& entry) { return std::get<0>(entry) == idObj; });
}
void RlvHandler::removeBlockedObject(const LLUUID& idObj)
{
m_BlockedObjects.erase(std::remove_if(m_BlockedObjects.begin(), m_BlockedObjects.end(),
[&idObj](const rlv_blocked_object_t& entry) {
return (idObj.notNull()) ? std::get<0>(entry) == idObj : false;
}), m_BlockedObjects.end());
}
void RlvHandler::getAttachmentResourcesCoro(const std::string& strUrl)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("RlvHandler::getAttachmentResourcesCoro", httpPolicy));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
const LLSD sdResult = httpAdapter->getAndSuspend(httpRequest, strUrl);
const LLCore::HttpStatus httpStatus = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(sdResult[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]);
if ( (httpStatus) && (sdResult.has("attachments")) )
{
const LLSD& sdAttachments = sdResult["attachments"];
for (auto& itAttach = sdAttachments.beginArray(), endAttach = sdAttachments.endArray(); itAttach != endAttach; ++itAttach)
{
if (!itAttach->has("objects"))
continue;
const LLSD& sdAttachObjects = itAttach->get("objects");
for (auto& itAttachObj = sdAttachObjects.beginArray(), endAttachObj = sdAttachObjects.endArray(); itAttachObj != endAttachObj; ++itAttachObj)
{
const LLUUID idObj = itAttachObj->get("id").asUUID();
const std::string& strObjName = itAttachObj->get("name").asStringRef();
// If it's an attachment, it should be a temporary one (NOTE: we might catch it before it's had a chance to attach)
const LLViewerObject* pObj = gObjectList.findObject(idObj);
if ( (pObj) && ((!pObj->isAttachment()) || (!pObj->isTempAttachment()) || (isBlockedObject(idObj))) )
continue;
// Find it by object name
auto itBlockedObj = std::find_if(m_BlockedObjects.begin(), m_BlockedObjects.end(),
[&strObjName](const rlv_blocked_object_t& entry) {
return (std::get<0>(entry).isNull()) && (std::get<1>(entry) == strObjName);
});
if (m_BlockedObjects.end() != itBlockedObj)
{
std::get<0>(*itBlockedObj) = idObj;
RLV_INFOS << "Clearing restrictions from blocked object " << idObj.asString() << RLV_ENDL;
processCommand(idObj, "clear", true);
return;
}
}
}
}
}
// ============================================================================
// Command processing functions
//
@ -315,6 +389,11 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj)
{
RLV_DEBUGS << "[" << rlvCmd.getObjectID() << "]: " << rlvCmd.asString() << RLV_ENDL;
if ( (isBlockedObject(rlvCmd.getObjectID())) && (RLV_TYPE_REMOVE != rlvCmd.getParamType()) && (RLV_TYPE_CLEAR != rlvCmd.getParamType()) )
{
RLV_DEBUGS << "\t-> blocked object" << RLV_ENDL;
return RLV_RET_FAILED_BLOCKED;
}
if (!rlvCmd.isValid())
{
RLV_DEBUGS << "\t-> invalid syntax" << RLV_ENDL;
@ -515,13 +594,13 @@ bool RlvHandler::processIMQuery(const LLUUID& idSender, const std::string& strMe
RlvUtil::sendBusyMessage(idSender, RlvStrings::getVersion(LLUUID::null));
return true;
}
else if ("@list" == strMessage)
else if ( ("@list" == strMessage) || ("@except" == strMessage) )
{
LLNotification::Params params;
params.name = "RLVaListRequested";
params.functor.function(boost::bind(&RlvHandler::onIMQueryListResponse, this, _1, _2));
params.substitutions = LLSD().with("NAME_LABEL", LLSLURL("agent", idSender, "completename").getSLURLString()).with("NAME_SLURL", LLSLURL("agent", idSender, "about").getSLURLString());
params.payload = LLSD().with("from_id", idSender);
params.payload = LLSD().with("from_id", idSender).with("command", strMessage);
class RlvPostponedOfferNotification : public LLPostponedNotification
{
@ -543,9 +622,25 @@ bool RlvHandler::processIMQuery(const LLUUID& idSender, const std::string& strMe
void RlvHandler::onIMQueryListResponse(const LLSD& sdNotification, const LLSD sdResponse)
{
const LLUUID idRequester = sdNotification["payload"]["from_id"].asUUID();
if (LLNotificationsUtil::getSelectedOption(sdNotification, sdResponse) == 0)
const int idxOption = LLNotificationsUtil::getSelectedOption(sdNotification, sdResponse);
if ( (idxOption == 0) || (idxOption == 1) )
{
RlvUtil::sendIMMessage(idRequester, RlvFloaterBehaviours::getFormattedBehaviourString(), '\n');
if (idxOption == 1)
{
if (LLNotificationPtr pNotif = LLNotificationsUtil::find(sdNotification["id"]))
pNotif->setIgnored(true);
}
const std::string& strCommand = sdNotification["payload"]["command"].asStringRef();
if ("@list" == strCommand)
{
RlvUtil::sendIMMessage(idRequester, RlvFloaterBehaviours::getFormattedBehaviourString(ERlvBehaviourFilter::BEHAVIOURS_ONLY).append("\n").append(RlvStrings::getString("imquery_list_suffix")), '\n');
}
else if ("@except" == strCommand)
{
RlvUtil::sendIMMessage(idRequester, RlvFloaterBehaviours::getFormattedBehaviourString(ERlvBehaviourFilter::EXCEPTIONS_ONLY), '\n');
}
}
else
{
@ -808,6 +903,42 @@ void RlvHandler::onDetach(const LLViewerObject* pAttachObj, const LLViewerJointA
RLV_INFOS << "\t-> done" << RLV_ENDL;
}
}
if (pAttachObj->isTempAttachment())
{
removeBlockedObject(pAttachObj->getID());
}
}
}
void RlvHandler::onExperienceAttach(const LLSD& sdExperience, const std::string& strObjName)
{
if (!RlvSettings::isAllowedExperience(sdExperience[LLExperienceCache::EXPERIENCE_ID].asUUID(), sdExperience[LLExperienceCache::MATURITY].asInteger()))
{
addBlockedObject(LLUUID::null, strObjName);
const std::string strUrl = gAgent.getRegionCapability("AttachmentResources");
if (!strUrl.empty())
{
LLCoros::instance().launch("RlvHandler::getAttachmentResourcesCoro", boost::bind(&RlvHandler::getAttachmentResourcesCoro, this, strUrl));
}
}
}
void RlvHandler::onExperienceEvent(const LLSD& sdEvent)
{
const int nPermission = sdEvent["Permission"].asInteger();
switch (nPermission)
{
case 4: // Attach
{
const LLUUID& idExperience = sdEvent["public_id"].asUUID();
const std::string strObjName = sdEvent["ObjectName"].asString();
LLExperienceCache::instance().get(idExperience, boost::bind(&RlvHandler::onExperienceAttach, this, _1, strObjName));
}
break;
default:
break;
}
}
@ -862,6 +993,23 @@ bool RlvHandler::onGC()
RLV_ASSERT(gRlvAttachmentLocks.verifyAttachmentLocks()); // Verify that we haven't leaked any attachment locks somehow
// Clean up pending temp attachments that we were never able to resolve
rlv_blocked_object_list_t::const_iterator itBlocked = m_BlockedObjects.cbegin(), itCurBlocked;
while (itBlocked != m_BlockedObjects.end())
{
itCurBlocked = itBlocked++;
#ifdef RLV_DEBUG
bool itBlocked = true;
RLV_ASSERT(itBlocked);
#endif // RLV_DEBUG
const LLUUID& idObj = std::get<0>(*itCurBlocked);
if ( (idObj.notNull()) || (LLTimer::getTotalSeconds() - std::get<2>(*itCurBlocked) < 300.f) )
continue;
m_BlockedObjects.erase(itCurBlocked);
}
return (0 != m_Objects.size()); // GC will kill itself if it has nothing to do
}
@ -895,8 +1043,9 @@ void RlvHandler::onLoginComplete()
RlvInventory::instance().fetchSharedInventory();
RlvSettings::updateLoginLastLocation();
LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&RlvHandler::onTeleportFailed, this));
LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&RlvHandler::onTeleportFinished, this, _1));
m_ExperienceEventConn = LLExperienceLog::instance().addUpdateSignal(boost::bind(&RlvHandler::onExperienceEvent, this, _1));
m_TeleportFailedConn = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&RlvHandler::onTeleportFailed, this));
m_TeleportFinishedConn = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&RlvHandler::onTeleportFinished, this, _1));
processRetainedCommands();
}
@ -2457,6 +2606,23 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_DETACHME>::onCommand(const RlvCommand& rlvCm
return RLV_RET_SUCCESS;
}
// Handles: @fly:[true|false]=force
template<> template<>
ERlvCmdRet RlvForceHandler<RLV_BHVR_FLY>::onCommand(const RlvCommand& rlvCmd)
{
bool fForceFly = true;
if ( (rlvCmd.hasOption()) && (!RlvCommandOptionHelper::parseOption<bool>(rlvCmd.getOption(), fForceFly)) )
return RLV_RET_FAILED_OPTION;
if ( (fForceFly) && (!RlvActions::canFly(rlvCmd.getObjectID())) )
return RLV_RET_FAILED_LOCK;
if (fForceFly != (bool)gAgent.getFlying())
gAgent.setFlying(fForceFly);
return RLV_RET_SUCCESS;
}
// Handles: @remattach[:<folder|attachpt|attachgroup>]=force
template<> template<>
ERlvCmdRet RlvForceRemAttachHandler::onCommand(const RlvCommand& rlvCmd)
@ -3485,9 +3651,9 @@ void RlvHandler::renderOverlay()
m_pOverlayImage->addTextureStats(nWidth * nHeight);
m_pOverlayImage->setKnownDrawSize(nWidth, nHeight);
gGL.pushMatrix();
LLGLSUIDefault glsUI;
gViewerWindow->setup2DRender();
gGL.pushMatrix();
const LLVector2& displayScale = gViewerWindow->getDisplayScale();
gGL.scalef(displayScale.mV[VX], displayScale.mV[VY], 1.f);
@ -3516,6 +3682,7 @@ void RlvHandler::renderOverlay()
gGL.popMatrix();
gGL.flush();
gViewerWindow->setup3DRender();
if (LLGLSLShader::sNoFixedFunction)
{

View File

@ -96,6 +96,16 @@ public:
bool isHiddenCompositeItem(const LLUUID& idItem, const std::string& strItemType) const;
#endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
public:
// Adds a blocked object (= object that is blocked from issuing commands) by UUID (can be null) and/or name
void addBlockedObject(const LLUUID& idObj, const std::string& strObjName);
// Returns TRUE if there's an unresolved blocked object (known name but unknown UUID)
bool hasUnresolvedBlockedObject() const;
// Returns TRUE if the object with the specified UUID is blocked from issuing commands
bool isBlockedObject(const LLUUID& idObj) const;
// Removes a blocked object
void removeBlockedObject(const LLUUID& idObj);
// --------------------------------
/*
@ -163,6 +173,8 @@ public:
void onActiveGroupChanged();
void onAttach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt);
void onDetach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt);
void onExperienceAttach(const LLSD& sdExperience, const std::string& strObjName);
void onExperienceEvent(const LLSD& sdEvent);
bool onGC();
void onLoginComplete();
void onSitOrStand(bool fSitting);
@ -170,6 +182,7 @@ public:
void onTeleportFinished(const LLVector3d& posArrival);
static void onIdleStartup(void* pParam);
protected:
void getAttachmentResourcesCoro(const std::string& strUrl);
void onTeleportCallback(U64 hRegion, const LLVector3& posRegion, const LLVector3& vecLookAt, const LLUUID& idRlvObj);
/*
@ -214,9 +227,12 @@ protected:
*/
public:
typedef std::map<LLUUID, RlvObject> rlv_object_map_t;
typedef std::tuple<LLUUID, std::string, double> rlv_blocked_object_t;
typedef std::list<rlv_blocked_object_t> rlv_blocked_object_list_t;
typedef std::multimap<ERlvBehaviour, RlvException> rlv_exception_map_t;
protected:
rlv_object_map_t m_Objects; // Map of objects that have active restrictions (idObj -> RlvObject)
rlv_blocked_object_list_t m_BlockedObjects; // List of (attached) objects that can't issue commands
rlv_exception_map_t m_Exceptions; // Map of currently active restriction exceptions (ERlvBehaviour -> RlvException)
S16 m_Behaviours[RLV_BHVR_COUNT];
@ -230,6 +246,9 @@ protected:
rlv_behaviour_signal_t m_OnBehaviourToggle;
rlv_command_signal_t m_OnCommand;
mutable std::list<RlvExtCommandHandler*> m_CommandHandlers;
boost::signals2::scoped_connection m_ExperienceEventConn;
boost::signals2::scoped_connection m_TeleportFailedConn;
boost::signals2::scoped_connection m_TeleportFinishedConn;
static bool m_fEnabled; // Use setEnabled() to toggle this

View File

@ -108,6 +108,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
addModifier(RLV_BHVR_FARTOUCH, RLV_MODIFIER_FARTOUCHDIST, new RlvBehaviourModifier("Fartouch Distance", RLV_MODIFIER_FARTOUCH_DEFAULT, true, new RlvBehaviourModifierCompMin));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("fly", RLV_BHVR_FLY));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("interact", RLV_BHVR_INTERACT, RlvBehaviourInfo::BHVR_EXTENDED));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("jump", RLV_BHVR_JUMP));
addEntry(new RlvBehaviourInfo("notify", RLV_BHVR_NOTIFY, RLV_TYPE_ADDREM));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("permissive", RLV_BHVR_PERMISSIVE));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_EXCEPTION>("recvchat", RLV_BHVR_RECVCHAT, RlvBehaviourInfo::BHVR_STRICT));
@ -182,6 +183,8 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
// Camera
addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETCAM, RLV_OPTION_NONE>("setcam"));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_MODIFIER>("setcam_avdist", RLV_BHVR_SETCAM_AVDIST));
addModifier(RLV_BHVR_SETCAM_AVDIST, RLV_MODIFIER_SETCAM_AVDIST, new RlvBehaviourModifier("Camera - Silhouette Distance", 0.0f, false, new RlvBehaviourModifierCompMax()));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_MODIFIER>("setcam_avdistmin", RLV_BHVR_SETCAM_AVDISTMIN, RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addModifier(RLV_BHVR_SETCAM_AVDISTMIN, RLV_MODIFIER_SETCAM_AVDISTMIN, new RlvBehaviourModifierHandler<RLV_MODIFIER_SETCAM_AVDISTMIN>("Camera - Avatar Distance (Min)", 0.0f, false, new RlvBehaviourModifierCompMax()));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_MODIFIER>("setcam_avdistmax", RLV_BHVR_SETCAM_AVDISTMAX, RlvBehaviourInfo::BHVR_EXPERIMENTAL));
@ -203,6 +206,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
addModifier(RLV_BHVR_SETCAM_TEXTURES, RLV_MODIFIER_SETCAM_TEXTURE, new RlvBehaviourModifierHandler<RLV_MODIFIER_SETCAM_TEXTURE>("Camera - Forced Texture", IMG_DEFAULT, true, nullptr));
addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETCAM_UNLOCK, RLV_OPTION_NONE>("setcam_unlock"));
// Camera (compatibility shim - to be deprecated)
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_MODIFIER>("camavdist", RLV_BHVR_SETCAM_AVDIST, RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_MODIFIER>("camdistmin", RLV_BHVR_SETCAM_AVDISTMIN, RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_MODIFIER>("camdistmax", RLV_BHVR_SETCAM_AVDISTMAX, RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED));
addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_MODIFIER>("camtextures", RLV_BHVR_SETCAM_TEXTURES, RlvBehaviourInfo::BHVR_SYNONYM | RlvBehaviourInfo::BHVR_DEPRECATED));
@ -259,6 +263,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
//
addEntry(new RlvBehaviourInfo("adjustheight", RLV_BHVR_ADJUSTHEIGHT, RLV_TYPE_FORCE));
addEntry(new RlvForceProcessor<RLV_BHVR_DETACHME>("detachme"));
addEntry(new RlvForceProcessor<RLV_BHVR_FLY>("fly"));
addEntry(new RlvForceProcessor<RLV_BHVR_SETCAM_FOCUS>("setcam_focus", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvForceProcessor<RLV_BHVR_SETCAM_EYEOFFSET, RlvForceCamEyeFocusOffsetHandler>("setcam_eyeoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
addEntry(new RlvForceProcessor<RLV_BHVR_SETCAM_FOCUSOFFSET, RlvForceCamEyeFocusOffsetHandler>("setcam_focusoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
@ -703,6 +708,25 @@ bool RlvCommandOptionHelper::parseOption<int>(const std::string& strOption, int&
return true;
}
template<>
bool RlvCommandOptionHelper::parseOption<bool>(const std::string& strOption, bool& fOption)
{
try
{
// Try and parse it as a number first
int nOption = std::stoi(strOption);
fOption = (bool)nOption;
return (nOption == 0) || (nOption == 1);
}
catch (const std::invalid_argument&)
{
// Then try and parse it as true/false
std::istringstream ss(strOption);
ss >> std::boolalpha >> fOption;
return !ss.fail();
}
}
template<>
bool RlvCommandOptionHelper::parseOption<float>(const std::string& strOption, float& nOption)
{

View File

@ -12249,12 +12249,18 @@ Changes won't take effect until after you restart [APP_NAME].
<form name="form">
<button
index="0"
default="true"
name="Allow"
text="Allow"/>
<button
index="1"
name="Always Allow"
text="Always Allow"/>
<button
index="2"
name="Deny"
text="Deny"/>
<ignore text="Confirm before sending anyone a list of my current RLV restrictions."/>
</form>
</notification>

View File

@ -45,7 +45,7 @@
<boolean>1</boolean>
</map>
<!-- Sent to the remote party when they issue @list as an IM query (if enabled) -->
<!-- Sent to the remote party when they issue @list or @except as an IM query (if enabled) -->
<key>imquery_list_deny</key>
<map>
<key>value</key>
@ -53,11 +53,24 @@
<key>description</key>
<string>Sent to the remote party when you deny their request to list your active RLV restrictions)</string>
<key>label</key>
<string>@list command (remote)</string>
<string>@list and @except command (remote)</string>
<key>customizable</key>
<boolean>1</boolean>
</map>
<!-- Sent to the remote party as a suffix to @list to inform them there might be more information -->
<key>imquery_list_suffix</key>
<map>
<key>value</key>
<string>(Use @except to see the list of active exceptions)</string>
<key>description</key>
<string>Sent to the remote party as a suffix to @list to inform them how to request your exceptions</string>
<key>label</key>
<string>@list command suffix (remote)</string>
<key>customizable</key>
<boolean>0</boolean>
</map>
<!-- Sent to the remote party when they issue @stopim as an IM query (if enabled) -->
<key>stopim_nosession</key>
<map>