352 lines
14 KiB
C++
352 lines
14 KiB
C++
/**
|
|
*
|
|
* Copyright (c) 2009-2020, Kitty Barnett
|
|
*
|
|
* The source code in this file is provided to you under the terms of the
|
|
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
|
|
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
|
|
*
|
|
* By copying, modifying or distributing this software, you acknowledge that
|
|
* you have read and understood your obligations described above, and agree to
|
|
* abide by those obligations.
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "llavatarname.h"
|
|
#include "llselectmgr.h"
|
|
#include "lltrans.h"
|
|
#include "llviewercontrol.h"
|
|
|
|
#include "rlvdefines.h"
|
|
|
|
#ifdef LL_WINDOWS
|
|
#pragma warning (push)
|
|
#pragma warning (disable : 4702) // warning C4702: unreachable code
|
|
#endif
|
|
#include <boost/variant.hpp>
|
|
#ifdef LL_WINDOWS
|
|
#pragma warning (pop)
|
|
#endif
|
|
|
|
// ============================================================================
|
|
// Forward declarations
|
|
//
|
|
|
|
//
|
|
// General viewer source
|
|
//
|
|
class LLInventoryItem;
|
|
class LLUICtrl;
|
|
class LLViewerInventoryCategory;
|
|
class LLViewerInventoryItem;
|
|
class LLViewerJointAttachment;
|
|
class LLViewerWearable;
|
|
class LLWearable;
|
|
|
|
//
|
|
// RLVa-specific
|
|
//
|
|
class RlvCommand;
|
|
typedef std::list<RlvCommand> rlv_command_list_t;
|
|
class RlvObject;
|
|
|
|
struct RlvException;
|
|
typedef boost::variant<std::string, LLUUID, S32, ERlvBehaviour> RlvExceptionOption;
|
|
typedef boost::variant<int, float, bool, LLVector3, LLVector3d, LLUUID> RlvBehaviourModifierValue;
|
|
|
|
class RlvGCTimer;
|
|
|
|
// ============================================================================
|
|
// RlvSettings
|
|
//
|
|
|
|
#ifdef CATZNIP_STRINGVIEW
|
|
template<typename T> inline T rlvGetSetting(const boost::string_view& strSetting, const T& defaultValue)
|
|
#else
|
|
template<typename T> inline T rlvGetSetting(const std::string& strSetting, const T& defaultValue)
|
|
#endif // CATZNIP_STRINGVIEW
|
|
{
|
|
RLV_ASSERT_DBG(gSavedSettings.controlExists(strSetting));
|
|
return (gSavedSettings.controlExists(strSetting)) ? gSavedSettings.get<T>(strSetting) : defaultValue;
|
|
}
|
|
|
|
#ifdef CATZNIP_STRINGVIEW
|
|
template<typename T> inline T rlvGetPerUserSetting(const boost::string_view& strSetting, const T& defaultValue)
|
|
#else
|
|
template<typename T> inline T rlvGetPerUserSetting(const std::string& strSetting, const T& defaultValue)
|
|
#endif // CATZNIP_STRINGVIEW
|
|
{
|
|
RLV_ASSERT_DBG(gSavedPerAccountSettings.controlExists(strSetting));
|
|
return (gSavedPerAccountSettings.controlExists(strSetting)) ? gSavedPerAccountSettings.get<T>(strSetting) : defaultValue;
|
|
}
|
|
|
|
class RlvSettings
|
|
{
|
|
public:
|
|
static bool getDebug() { return rlvGetSetting<bool>(RlvSettingNames::Debug, false); }
|
|
static bool getCanOOC() { return s_fCanOOC; }
|
|
static bool getForbidGiveToRLV() { return rlvGetSetting<bool>(RlvSettingNames::ForbidGiveToRlv, true); }
|
|
static bool getNoSetEnv() { return s_fNoSetEnv; }
|
|
|
|
static std::string getWearAddPrefix() { return rlvGetSetting<std::string>(RlvSettingNames::WearAddPrefix, LLStringUtil::null); }
|
|
static std::string getWearReplacePrefix() { return rlvGetSetting<std::string>(RlvSettingNames::WearReplacePrefix, LLStringUtil::null); }
|
|
|
|
static bool getDebugHideUnsetDup() { return rlvGetSetting<bool>(RlvSettingNames::DebugHideUnsetDup, false); }
|
|
#ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
|
|
static BOOL getEnableComposites() { return s_fCompositeFolders; }
|
|
#endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
|
|
static bool getEnableIMQuery() { return rlvGetSetting<bool>(RlvSettingNames::EnableIMQuery, true); }
|
|
static bool getEnableLegacyNaming() { return s_fLegacyNaming; }
|
|
static bool getEnableSharedWear() { return rlvGetSetting<bool>(RlvSettingNames::EnableSharedWear, false); }
|
|
static bool getEnableTemporaryAttachments() { return s_fTempAttach; }
|
|
static bool getHideLockedLayers() { return rlvGetSetting<bool>(RlvSettingNames::HideLockedLayer, false); }
|
|
static bool getHideLockedAttach() { return rlvGetSetting<bool>(RlvSettingNames::HideLockedAttach, false); }
|
|
static bool getHideLockedInventory() { return rlvGetSetting<bool>(RlvSettingNames::HideLockedInventory, false); }
|
|
static bool getSharedInvAutoRename() { return rlvGetSetting<bool>(RlvSettingNames::SharedInvAutoRename, true); }
|
|
static bool getSplitRedirectChat() { return rlvGetSetting<bool>(RlvSettingNames::SplitRedirectChat, false); }
|
|
|
|
static bool getLoginLastLocation() { return rlvGetPerUserSetting<bool>(RlvSettingNames::LoginLastLocation, true); }
|
|
static void updateLoginLastLocation();
|
|
|
|
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:
|
|
static bool onChangedMenuLevel();
|
|
static bool onChangedSettingBOOL(const LLSD& sdValue, bool* pfSetting);
|
|
|
|
#ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
|
|
static BOOL s_fCompositeFolders;
|
|
#endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
|
|
|
|
/*
|
|
* Member variables
|
|
*/
|
|
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;
|
|
};
|
|
|
|
// ============================================================================
|
|
// RlvStrings
|
|
//
|
|
|
|
class RlvStrings
|
|
{
|
|
public:
|
|
static void initClass();
|
|
static void loadFromFile(const std::string& strFilePath, bool fDefault);
|
|
static void saveToFile(const std::string& strFilePath);
|
|
|
|
static std::string getAnonym(const LLAvatarName& avName); // @shownames
|
|
static std::string getAnonym(const std::string& strName); // @shownames
|
|
#ifdef CATZNIP_STRINGVIEW
|
|
static const std::string& getString(const boost::string_view& strStringName);
|
|
#else
|
|
static const std::string& getString(const std::string& strStringName);
|
|
#endif // CATZNIP_STRINGVIEW
|
|
static const char* getStringFromReturnCode(ERlvCmdRet eRet);
|
|
static const std::string& getStringMapPath() { return m_StringMapPath; }
|
|
static std::string getVersion(const LLUUID& idRlvObject, bool fLegacy = false);
|
|
static std::string getVersionAbout();
|
|
static std::string getVersionImplNum();
|
|
static std::string getVersionNum(const LLUUID& idRlvObject);
|
|
static bool hasString(const std::string& strStringName, bool fCheckCustom = false);
|
|
static void setCustomString(const std::string& strStringName, const std::string& strStringValue);
|
|
|
|
protected:
|
|
static std::vector<std::string> m_Anonyms;
|
|
typedef std::map<std::string, std::list<std::string>, std::less<>> string_map_t;
|
|
static string_map_t m_StringMap;
|
|
static std::string m_StringMapPath;
|
|
};
|
|
|
|
// ============================================================================
|
|
// RlvUtil - Collection of (static) helper functions
|
|
//
|
|
|
|
class RlvUtil
|
|
{
|
|
public:
|
|
static bool isEmote(const std::string& strUTF8Text);
|
|
static bool isNearbyAgent(const LLUUID& idAgent); // @shownames
|
|
static bool isNearbyRegion(const std::string& strRegion); // @showloc
|
|
|
|
static void filterLocation(std::string& strUTF8Text); // @showloc
|
|
static void filterNames(std::string& strUTF8Text, bool fFilterLegacy = true, bool fClearMatches = false); // @shownames
|
|
static void filterScriptQuestions(S32& nQuestions, LLSD& sdPayload);
|
|
|
|
static bool isForceTp() { return m_fForceTp; }
|
|
static void forceTp(const LLVector3d& posDest); // Ignores restrictions that might otherwise prevent tp'ing
|
|
|
|
#ifdef CATZNIP_STRINGVIEW
|
|
static void notifyBlocked(const std::string& strNotifcation, const LLSD& sdArgs = LLSD(), bool fLogToChat = false) { notifyBlocked(boost::string_view(strNotifcation), sdArgs, fLogToChat); }
|
|
static void notifyBlocked(const boost::string_view& strNotifcation, const LLSD& sdArgs = LLSD(), bool fLogToChat = false);
|
|
#else
|
|
static void notifyBlocked(const std::string& strNotifcation, const LLSD& sdArgs = LLSD(), bool fLogToChat = false);
|
|
#endif // CATZNIP_STRINGVIEW
|
|
static void notifyBlockedGeneric() { notifyBlocked(RlvStringKeys::Blocked::Generic); }
|
|
static void notifyBlockedViewXXX(LLAssetType::EType assetType) { notifyBlocked(RlvStringKeys::Blocked::ViewXxx, LLSD().with("[TYPE]", LLTrans::getString(LLAssetType::lookupHumanReadable(assetType)))); }
|
|
static void notifyFailedAssertion(const std::string& strAssert, const std::string& strFile, int nLine);
|
|
|
|
static void sendBusyMessage(const LLUUID& idTo, const std::string& strMsg, const LLUUID& idSession = LLUUID::null);
|
|
static bool isValidReplyChannel(S32 nChannel, bool fLoopback = false);
|
|
static bool sendChatReply(S32 nChannel, const std::string& strUTF8Text);
|
|
static bool sendChatReply(const std::string& strChannel, const std::string& strUTF8Text);
|
|
static bool sendChatReplySplit(S32 nChannel, const std::string& strUTF8Text, char chSplit = ' ');
|
|
static void sendIMMessage(const LLUUID& idTo, const std::string& strMsg, char chSplit);
|
|
protected:
|
|
static bool m_fForceTp; // @standtp
|
|
};
|
|
|
|
// ============================================================================
|
|
// Extensibility classes
|
|
//
|
|
|
|
class RlvExtCommandHandler
|
|
{
|
|
public:
|
|
virtual ~RlvExtCommandHandler() {}
|
|
virtual bool onAddRemCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet) { return false; }
|
|
virtual bool onClearCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet) { return false; }
|
|
virtual bool onReplyCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet) { return false; }
|
|
virtual bool onForceCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet) { return false; }
|
|
};
|
|
typedef bool (RlvExtCommandHandler::*rlvExtCommandHandler)(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet);
|
|
|
|
// ============================================================================
|
|
// Generic menu enablers
|
|
//
|
|
|
|
bool rlvMenuMainToggleVisible(LLUICtrl* pMenuItem);
|
|
void rlvMenuToggleVisible();
|
|
bool rlvMenuCanShowName();
|
|
bool rlvMenuEnableIfNot(const LLSD& sdParam);
|
|
|
|
// ============================================================================
|
|
// Selection functors
|
|
//
|
|
|
|
bool rlvCanDeleteOrReturn();
|
|
bool rlvCanDeleteOrReturn(const LLViewerObject* pObj);
|
|
|
|
struct RlvSelectHasLockedAttach : public LLSelectedNodeFunctor
|
|
{
|
|
RlvSelectHasLockedAttach() {}
|
|
virtual bool apply(LLSelectNode* pNode);
|
|
};
|
|
|
|
// Filters out selected objects that can't be editable (i.e. getFirstNode() will return NULL if the selection is fully editable)
|
|
struct RlvSelectIsEditable : public LLSelectedNodeFunctor
|
|
{
|
|
RlvSelectIsEditable() {}
|
|
/*virtual*/ bool apply(LLSelectNode* pNode);
|
|
};
|
|
|
|
struct RlvSelectIsSittingOn : public LLSelectedNodeFunctor
|
|
{
|
|
RlvSelectIsSittingOn(const LLVOAvatar* pAvatar) : m_pAvatar(pAvatar) {}
|
|
/*virtual*/ bool apply(LLSelectNode* pNode);
|
|
protected:
|
|
const LLVOAvatar* m_pAvatar;
|
|
};
|
|
|
|
// ============================================================================
|
|
// Predicates
|
|
//
|
|
|
|
bool rlvPredCanWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWearMask);
|
|
bool rlvPredCanNotWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWearMask);
|
|
bool rlvPredCanRemoveItem(const LLUUID& idItem);
|
|
bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem);
|
|
bool rlvPredCanNotRemoveItem(const LLUUID& idItem);
|
|
bool rlvPredCanNotRemoveItem(const LLViewerInventoryItem* pItem);
|
|
|
|
struct RlvPredCanWearItem
|
|
{
|
|
RlvPredCanWearItem(ERlvWearMask eWearMask) : m_eWearMask(eWearMask) {}
|
|
bool operator()(const LLViewerInventoryItem* pItem) { return rlvPredCanWearItem(pItem, m_eWearMask); }
|
|
protected:
|
|
ERlvWearMask m_eWearMask;
|
|
};
|
|
|
|
struct RlvPredCanNotWearItem
|
|
{
|
|
RlvPredCanNotWearItem(ERlvWearMask eWearMask) : m_eWearMask(eWearMask) {}
|
|
bool operator()(const LLViewerInventoryItem* pItem) { return rlvPredCanNotWearItem(pItem, m_eWearMask); }
|
|
protected:
|
|
ERlvWearMask m_eWearMask;
|
|
};
|
|
|
|
struct RlvPredCanRemoveItem
|
|
{
|
|
RlvPredCanRemoveItem() {}
|
|
bool operator()(const LLViewerInventoryItem* pItem) { return rlvPredCanRemoveItem(pItem); }
|
|
};
|
|
|
|
struct RlvPredCanNotRemoveItem
|
|
{
|
|
RlvPredCanNotRemoveItem() {}
|
|
bool operator()(const LLViewerInventoryItem* pItem) { return rlvPredCanNotRemoveItem(pItem); }
|
|
};
|
|
|
|
struct RlvPredIsEqualOrLinkedItem
|
|
{
|
|
RlvPredIsEqualOrLinkedItem(const LLViewerInventoryItem* pItem) : m_pItem(pItem) {}
|
|
RlvPredIsEqualOrLinkedItem(const LLUUID& idItem);
|
|
bool operator()(const LLViewerInventoryItem* pItem) const;
|
|
protected:
|
|
const LLViewerInventoryItem* m_pItem;
|
|
};
|
|
|
|
template<typename T> struct RlvPredValuesEqual
|
|
{
|
|
bool operator()(const T* pT2) const { return (pT1) && (pT2) && (*pT1 == *pT2); }
|
|
const T* pT1;
|
|
};
|
|
|
|
// ============================================================================
|
|
// Inlined class member functions
|
|
//
|
|
|
|
// Checked: 2010-10-31 (RLVa-1.2.2a) | Added: RLVa-1.2.2a
|
|
inline std::string RlvStrings::getAnonym(const LLAvatarName& avName)
|
|
{
|
|
return getAnonym(avName.getLegacyName());
|
|
}
|
|
|
|
// Checked: 2010-03-26 (RLVa-1.2.0b) | Modified: RLVa-1.0.2a
|
|
inline bool RlvUtil::isEmote(const std::string& strUTF8Text)
|
|
{
|
|
return (strUTF8Text.length() > 4) && ( (strUTF8Text.compare(0, 4, "/me ") == 0) || (strUTF8Text.compare(0, 4, "/me'") == 0) );
|
|
}
|
|
|
|
// Checked: 2010-03-09 (RLVa-1.2.0b) | Added: RLVa-1.0.2a
|
|
inline bool RlvUtil::isValidReplyChannel(S32 nChannel, bool fLoopback /*=false*/)
|
|
{
|
|
return (nChannel > ((!fLoopback) ? 0 : -1)) && (CHAT_CHANNEL_DEBUG != nChannel);
|
|
}
|
|
|
|
// Checked: 2009-08-05 (RLVa-1.0.1e) | Added: RLVa-1.0.0e
|
|
inline bool RlvUtil::sendChatReply(const std::string& strChannel, const std::string& strUTF8Text)
|
|
{
|
|
S32 nChannel;
|
|
return (LLStringUtil::convertToS32(strChannel, nChannel)) ? sendChatReply(nChannel, strUTF8Text) : false;
|
|
}
|
|
|
|
// ============================================================================
|