aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/rlvhelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/rlvhelper.cpp')
-rw-r--r--linden/indra/newview/rlvhelper.cpp649
1 files changed, 526 insertions, 123 deletions
diff --git a/linden/indra/newview/rlvhelper.cpp b/linden/indra/newview/rlvhelper.cpp
index f509a43..9ef74ac 100644
--- a/linden/indra/newview/rlvhelper.cpp
+++ b/linden/indra/newview/rlvhelper.cpp
@@ -1,27 +1,31 @@
1#include "llviewerprecompiledheaders.h" 1#include "llviewerprecompiledheaders.h"
2#include "llagent.h"
3#include "llfloaterwindlight.h" 2#include "llfloaterwindlight.h"
3#include "llgesturemgr.h"
4#include "llinventoryview.h"
5#include "llinventorybridge.h"
4#include "llviewerobject.h" 6#include "llviewerobject.h"
7#include "llviewerobjectlist.h"
8#include "llviewerregion.h"
5#include "llviewerstats.h" 9#include "llviewerstats.h"
6#include "llviewerwindow.h" 10#include "llviewerwindow.h"
7#include "llvoavatar.h" 11#include "llvoavatar.h"
12#include "llwearablelist.h"
8#include "llwlparammanager.h" 13#include "llwlparammanager.h"
9 14
10#include "rlvhelper.h" 15#include "rlvhelper.h"
11#include "rlvevent.h"
12#include "rlvhandler.h" 16#include "rlvhandler.h"
13 17
14// ============================================================================ 18// Defined in llinventorybridge.cpp
15// Static variable initialization 19void wear_attachments_on_avatar(const LLInventoryModel::item_array_t& items, BOOL remove);
16// 20void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void*);
17
18RlvCommand::RlvBhvrTable RlvCommand::m_BhvrMap;
19 21
20// ============================================================================ 22// ============================================================================
21// RlvCommmand 23// RlvCommmand
22// 24//
23 25
24// Checked: 2009-09-10 (RLVa-1.0.3a) | Modified: RLVa-1.0.3a 26RlvCommand::RlvBhvrTable RlvCommand::m_BhvrMap;
27
28// Checked: 2009-12-27 (RLVa-1.1.0k) | Modified: RLVa-1.1.0k
25RlvCommand::RlvCommand(const std::string& strCommand) 29RlvCommand::RlvCommand(const std::string& strCommand)
26 : m_eBehaviour(RLV_BHVR_UNKNOWN), m_fStrict(false), m_eParamType(RLV_TYPE_UNKNOWN) 30 : m_eBehaviour(RLV_BHVR_UNKNOWN), m_fStrict(false), m_eParamType(RLV_TYPE_UNKNOWN)
27{ 31{
@@ -32,12 +36,12 @@ RlvCommand::RlvCommand(const std::string& strCommand)
32 m_eParamType = RLV_TYPE_ADD; 36 m_eParamType = RLV_TYPE_ADD;
33 else if ( ("y" == m_strParam) || ("rem" == m_strParam) ) 37 else if ( ("y" == m_strParam) || ("rem" == m_strParam) )
34 m_eParamType = RLV_TYPE_REMOVE; 38 m_eParamType = RLV_TYPE_REMOVE;
39 else if (m_strBehaviour == "clear") // clear is the odd one out so just make it its own type
40 m_eParamType = RLV_TYPE_CLEAR;
35 else if ("force" == m_strParam) 41 else if ("force" == m_strParam)
36 m_eParamType = RLV_TYPE_FORCE; 42 m_eParamType = RLV_TYPE_FORCE;
37 else if (LLStringUtil::convertToS32(m_strParam, nTemp)) // Assume it's a reply command if we can convert <param> to an S32 43 else if (LLStringUtil::convertToS32(m_strParam, nTemp)) // Assume it's a reply command if we can convert <param> to an S32
38 m_eParamType = RLV_TYPE_REPLY; 44 m_eParamType = RLV_TYPE_REPLY;
39 else if (m_strBehaviour == "clear") // clear is the odd one out so just make it its own type
40 m_eParamType = RLV_TYPE_CLEAR;
41 else 45 else
42 { 46 {
43 m_eParamType = RLV_TYPE_UNKNOWN; 47 m_eParamType = RLV_TYPE_UNKNOWN;
@@ -51,13 +55,7 @@ RlvCommand::RlvCommand(const std::string& strCommand)
51 return; 55 return;
52 } 56 }
53 57
54 // Check if this is the "strict" (aka "secure") variation of a behaviour 58 m_eBehaviour = getBehaviourFromString(m_strBehaviour, &m_fStrict);
55 std::string::size_type idxStrict = m_strBehaviour.find("_sec");
56 m_fStrict = (std::string::npos != idxStrict) && (idxStrict + 4 == m_strBehaviour.length());
57
58 RlvBhvrTable::const_iterator itBhvr = m_BhvrMap.find( (!m_fStrict) ? m_strBehaviour : m_strBehaviour.substr(0, idxStrict));
59 if ( (itBhvr != m_BhvrMap.end()) && ((!m_fStrict) || (hasStrictVariant(itBhvr->second))) )
60 m_eBehaviour = itBhvr->second;
61} 59}
62 60
63 61
@@ -95,6 +93,20 @@ bool RlvCommand::parseCommand(const std::string& strCommand, std::string& strBeh
95 return true; 93 return true;
96} 94}
97 95
96// Checked: 2009-12-05 (RLVa-1.1.0h) | Added: RLVa-1.1.0h
97ERlvBehaviour RlvCommand::getBehaviourFromString(const std::string& strBhvr, bool* pfStrict /*=NULL*/)
98{
99 std::string::size_type idxStrict = strBhvr.find("_sec");
100 bool fStrict = (std::string::npos != idxStrict) && (idxStrict + 4 == strBhvr.length());
101 if (pfStrict)
102 *pfStrict = fStrict;
103
104 RlvBhvrTable::const_iterator itBhvr = m_BhvrMap.find( (!fStrict) ? strBhvr : strBhvr.substr(0, idxStrict));
105 if ( (itBhvr != m_BhvrMap.end()) && ((!fStrict) || (hasStrictVariant(itBhvr->second))) )
106 return itBhvr->second;
107 return RLV_BHVR_UNKNOWN;
108}
109
98void RlvCommand::initLookupTable() 110void RlvCommand::initLookupTable()
99{ 111{
100 static bool fInitialized = false; 112 static bool fInitialized = false;
@@ -103,14 +115,16 @@ void RlvCommand::initLookupTable()
103 // NOTE: keep this matched with the enumeration at all times 115 // NOTE: keep this matched with the enumeration at all times
104 std::string arBehaviours[RLV_BHVR_COUNT] = 116 std::string arBehaviours[RLV_BHVR_COUNT] =
105 { 117 {
106 "version", "detach", "sendchat", "emote", "chatshout", "chatnormal", "chatwhisper", "redirchat", "rediremote", 118 "detach", "attach", "addattach", "remattach", "addoutfit", "remoutfit", "emote", "sendchat", "recvchat", "recvemote",
107 "sendim", "recvchat", "recvemote", "recvim", "tplm", "tploc", "tplure", "sittp", "edit", "rez", 119 "redirchat", "rediremote", "chatwhisper", "chatnormal", "chatshout", "sendchannel", "sendim", "recvim", "permissive",
108 "addoutfit", "remoutfit", "getoutfit", "addattach", "remattach", "getattach", "showinv", "viewnote", "unsit", "sit", 120 "notify", "showinv", "showminimap", "showworldmap", "showloc", "shownames", "showhovertext", "showhovertexthud",
109 "sendchannel", "getstatus", "getstatusall", "getinv", "getinvworn", "findfolder", "findfolders", 121 "showhovertextworld", "showhovertextall", "tplm", "tploc", "tplure", "viewnote", "viewscript", "viewtexture",
110 "attach", "attachall", "detachall", "getpath", "attachthis", "attachallthis", "detachthis", "detachallthis", 122 "acceptpermission", "accepttp", "defaultwear", "allowidle", "edit", "rez", "fartouch", "interact", "touch",
111 "fartouch", "showworldmap", "showminimap", "showloc", "tpto", "accepttp", "acceptpermission", "shownames", "fly", 123 "touchattach", "touchhud", "touchworld", "fly", "unsit", "sit", "sittp", "setdebug", "setenv", "detachme", "detachthis",
112 "getsitid", "setdebug", "setenv", "detachme", "showhovertextall", "showhovertextworld", "showhovertexthud", 124 "detachall", "detachallthis", "attachthis", "attachall", "attachallthis", "tpto", "version", "versionnew", "versionnum",
113 "showhovertext", "notify", "defaultwear", "versionnum", "permissive", "viewscript", "viewtexture" 125 "getattach", "getattachnames", "getaddattachnames", "getremattachnames", "getoutfit", "getoutfitnames",
126 "getaddoutfitnames", "getremoutfitnames", "findfolder", "findfolders", "getpath", "getinv", "getinvworn", "getsitid",
127 "getstatus", "getstatusall"
114 }; 128 };
115 129
116 for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++) 130 for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++)
@@ -133,9 +147,7 @@ RlvObject::RlvObject(const LLUUID& idObj) : m_UUID(idObj), m_nLookupMisses(0)
133 147
134bool RlvObject::addCommand(const RlvCommand& rlvCmd) 148bool RlvObject::addCommand(const RlvCommand& rlvCmd)
135{ 149{
136 // Sanity checking 150 RLV_ASSERT(RLV_TYPE_ADD == rlvCmd.getParamType());
137 if (RLV_TYPE_ADD != rlvCmd.getParamType())
138 return false;
139 151
140 // Don't add duplicate commands for this object (ie @detach=n followed by another @detach=n later on) 152 // Don't add duplicate commands for this object (ie @detach=n followed by another @detach=n later on)
141 for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) 153 for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
@@ -155,9 +167,7 @@ bool RlvObject::addCommand(const RlvCommand& rlvCmd)
155 167
156bool RlvObject::removeCommand(const RlvCommand& rlvCmd) 168bool RlvObject::removeCommand(const RlvCommand& rlvCmd)
157{ 169{
158 // Sanity checking 170 RLV_ASSERT(RLV_TYPE_REMOVE == rlvCmd.getParamType());
159 if (RLV_TYPE_REMOVE != rlvCmd.getParamType())
160 return false;
161 171
162 for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) 172 for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
163 { 173 {
@@ -188,7 +198,7 @@ bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOpt
188 return false; 198 return false;
189} 199}
190 200
191// Checked: 2009-06-07 (RLVa-0.2.1c) 201// Checked: 2009-11-27 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f
192std::string RlvObject::getStatusString(const std::string& strMatch) const 202std::string RlvObject::getStatusString(const std::string& strMatch) const
193{ 203{
194 std::string strStatus, strCmd; 204 std::string strStatus, strCmd;
@@ -198,8 +208,7 @@ std::string RlvObject::getStatusString(const std::string& strMatch) const
198 strCmd = itCmd->asString(); 208 strCmd = itCmd->asString();
199 if ( (strMatch.empty()) || (std::string::npos != strCmd.find(strMatch)) ) 209 if ( (strMatch.empty()) || (std::string::npos != strCmd.find(strMatch)) )
200 { 210 {
201 if (!strStatus.empty()) 211 strStatus.push_back('/');
202 strStatus.push_back('/');
203 strStatus += strCmd; 212 strStatus += strCmd;
204 } 213 }
205 } 214 }
@@ -212,7 +221,7 @@ std::string RlvObject::getStatusString(const std::string& strMatch) const
212// 221//
213 222
214// Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b 223// Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b
215void RlvAttachmentManager::forceAttach(const LLUUID& idItem, S32 idxAttachPt) 224void RlvAttachmentManager::attach(const LLUUID& idItem, S32 idxAttachPt)
216{ 225{
217 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 226 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11
218 LLAttachmentRezAction* rez_action = new LLAttachmentRezAction(); 227 LLAttachmentRezAction* rez_action = new LLAttachmentRezAction();
@@ -224,18 +233,15 @@ void RlvAttachmentManager::forceAttach(const LLUUID& idItem, S32 idxAttachPt)
224 LLSD payload; 233 LLSD payload;
225 payload["item_id"] = idItem; 234 payload["item_id"] = idItem;
226 payload["attachment_point"] = idxAttachPt; 235 payload["attachment_point"] = idxAttachPt;
227 236 LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/);
228 LLNotifications::instance().forceResponse(
229 LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/);
230 #endif 237 #endif
231} 238}
232 239
233// Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b 240// Checked: 2009-11-24 (RLVa-1.1.0k) | Added: RLVa-1.1.0e
234void RlvAttachmentManager::forceDetach(LLViewerJointAttachment* pAttachPt) 241void RlvAttachmentManager::detach(LLViewerJointAttachment* pAttachPt)
235{ 242{
236 // Copy/paste from handle_detach_from_avatar() 243 // [See handle_detach_from_avatar()]
237 LLViewerObject* attached_object = pAttachPt->getObject(); 244 if ( (pAttachPt) && (pAttachPt->getObject()) )
238 if (attached_object)
239 { 245 {
240 gMessageSystem->newMessage("ObjectDetach"); 246 gMessageSystem->newMessage("ObjectDetach");
241 gMessageSystem->nextBlockFast(_PREHASH_AgentData); 247 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
@@ -243,7 +249,7 @@ void RlvAttachmentManager::forceDetach(LLViewerJointAttachment* pAttachPt)
243 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 249 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
244 250
245 gMessageSystem->nextBlockFast(_PREHASH_ObjectData); 251 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
246 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID()); 252 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, pAttachPt->getObject()->getLocalID());
247 gMessageSystem->sendReliable( gAgent.getRegionHost() ); 253 gMessageSystem->sendReliable( gAgent.getRegionHost() );
248 } 254 }
249} 255}
@@ -278,7 +284,7 @@ void RlvAttachmentManager::onAttach(LLViewerJointAttachment* pAttachPt)
278 // If it was empty we need to force detach the new attachment; if it wasn't we need to reattach the old one 284 // If it was empty we need to force detach the new attachment; if it wasn't we need to reattach the old one
279 if (itAttachPrev->second.isNull()) 285 if (itAttachPrev->second.isNull())
280 { 286 {
281 forceDetach(pAttachPt); 287 detach(pAttachPt);
282 m_PendingDetach.insert(std::pair<S32, LLUUID>(idxAttachPt, pAttachPt->getItemID())); 288 m_PendingDetach.insert(std::pair<S32, LLUUID>(idxAttachPt, pAttachPt->getItemID()));
283 } 289 }
284 else if (m_PendingAttach.find(idxAttachPt) == m_PendingAttach.end()) // (only if we're not reattaching something else there) 290 else if (m_PendingAttach.find(idxAttachPt) == m_PendingAttach.end()) // (only if we're not reattaching something else there)
@@ -321,7 +327,7 @@ void RlvAttachmentManager::onSavedAssetIntoInventory(const LLUUID& idItem)
321 { 327 {
322 if ( (!itAttach->second.fAssetSaved) && (idItem == itAttach->second.idItem) ) 328 if ( (!itAttach->second.fAssetSaved) && (idItem == itAttach->second.idItem) )
323 { 329 {
324 forceAttach(itAttach->second.idItem, itAttach->first); 330 attach(itAttach->second.idItem, itAttach->first);
325 itAttach->second.tsAttach = LLFrameTimer::getElapsedSeconds(); 331 itAttach->second.tsAttach = LLFrameTimer::getElapsedSeconds();
326 } 332 }
327 } 333 }
@@ -368,7 +374,7 @@ BOOL RlvAttachmentManager::onTimer()
368 374
369 if (fAttach) 375 if (fAttach)
370 { 376 {
371 forceAttach(itAttach->second.idItem, itAttach->first); 377 attach(itAttach->second.idItem, itAttach->first);
372 itAttach->second.tsAttach = tsCurrent; 378 itAttach->second.tsAttach = tsCurrent;
373 } 379 }
374 380
@@ -421,7 +427,7 @@ const LLUUID& RlvWearableItemCollector::getFoldedParent(const LLUUID& idFolder)
421 return (m_Folding.end() == itFolder) ? idFolder : itFolder->second; 427 return (m_Folding.end() == itFolder) ? idFolder : itFolder->second;
422} 428}
423 429
424// Checked: 2009-07-29 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b 430// Checked: 2009-12-18 (RLVa-1.1.0k) | Modified: RLVa-1.1.0i
425bool RlvWearableItemCollector::onCollectFolder(const LLInventoryCategory* pFolder) 431bool RlvWearableItemCollector::onCollectFolder(const LLInventoryCategory* pFolder)
426{ 432{
427 const LLUUID& idParent = pFolder->getParentUUID(); 433 const LLUUID& idParent = pFolder->getParentUUID();
@@ -437,25 +443,35 @@ bool RlvWearableItemCollector::onCollectFolder(const LLInventoryCategory* pFolde
437 return false; 443 return false;
438 #endif // RLV_EXTENSION_FLAG_NOSTRIP 444 #endif // RLV_EXTENSION_FLAG_NOSTRIP
439 445
440 if (gRlvHandler.isFoldedFolder(pFolder, m_fAttach)) // Check for folder that should get folded under its parent 446 if (gRlvHandler.isFoldedFolder(pFolder, m_fAttach, false)) // Check for folder that should get folded under its parent
441 { 447 {
442 m_Tentative.push_front(pFolder->getUUID()); 448 m_Tentative.push_front(pFolder->getUUID());
443 m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent)); 449 m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent));
444 } 450 }
445 else if ( (RLV_FOLDER_PREFIX_HIDDEN != strFolder[0]) && (m_fMatchAll) ) // Collect from any non-hidden child folder for *all 451 else if ( (RLV_FOLDER_PREFIX_HIDDEN != strFolder[0]) && (m_fMatchAll) ) // Collect from any non-hidden child folder for *all
446 { 452 {
447 m_Wearable.push_front(pFolder->getUUID()); 453 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
454 if ( (!RlvSettings::getEnableComposites()) || // ... if we're not checking composite folders
455 (!gRlvHandler.isCompositeFolder(pFolder)) || // ... or if it's not a composite folder
456 ((m_fAttach) && (gRlvHandler.canWearComposite(pFolder))) || // ... or if we're attaching and can attach it OR
457 (!m_fAttach) && (gRlvHandler.canTakeOffComposite(pFolder)) ) // ... or if we're detaching and can detach it
458 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
459 {
460 m_Wearable.push_front(pFolder->getUUID());
461 }
448 return (idParent == m_idFolder); // (Convenience for @getinvworn) 462 return (idParent == m_idFolder); // (Convenience for @getinvworn)
449 } 463 }
450 #ifdef RLV_EXPERIMENTAL_COMPOSITES 464 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
451 else if ( (RLV_FOLDER_PREFIX_HIDDEN == strFolder[0]) && // Hidden folder that's a... 465 else if ( (RlvSettings::getEnableComposites()) &&
466 (RLV_FOLDER_PREFIX_HIDDEN == strFolder[0]) && // Hidden folder that's a...
452 (gRlvHandler.isCompositeFolder(pFolder)) && // ... composite folder which we... 467 (gRlvHandler.isCompositeFolder(pFolder)) && // ... composite folder which we...
453 ((m_fAttach) || (gRlvHandler.canTakeOffComposite(pFolder))) ) // ... attach or can detach (see composite locking) 468 ( ((m_fAttach) && (gRlvHandler.canWearComposite(pFolder))) || // ... are attaching and can attach OR
469 (!m_fAttach) && (gRlvHandler.canTakeOffComposite(pFolder)) ) ) // ... are detaching and can detach
454 { 470 {
455 m_Wearable.push_front(pFolder->getUUID()); 471 m_Wearable.push_front(pFolder->getUUID());
456 m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent)); 472 m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent));
457 } 473 }
458 #endif // RLV_EXPERIMENTAL_COMPOSITES 474 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
459 475
460 return false; 476 return false;
461} 477}
@@ -486,13 +502,13 @@ bool RlvWearableItemCollector::onCollectItem(const LLInventoryItem* pItem)
486 case LLAssetType::AT_OBJECT: 502 case LLAssetType::AT_OBJECT:
487 fRet = ( (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)) || 503 fRet = ( (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)) ||
488 (m_Tentative.end() != std::find(m_Tentative.begin(), m_Tentative.end(), idParent)) ) && 504 (m_Tentative.end() != std::find(m_Tentative.begin(), m_Tentative.end(), idParent)) ) &&
489 ( (!m_fAttach) || (gRlvHandler.hasAttachPointName(pItem, true)) ); // Only care about attach point on attach* 505 ( (!m_fAttach) || (gRlvHandler.hasAttachPointName(pItem, true)) || (RlvSettings::getEnableSharedWear()) );
490 break; 506 break;
491 #ifdef RLV_EXPERIMENTAL_FORCEWEAR_GESTURES 507 #ifdef RLV_EXTENSION_FORCEWEAR_GESTURES
492 case LLAssetType::AT_GESTURE: 508 case LLAssetType::AT_GESTURE:
493 fRet = (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)); 509 fRet = (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent));
494 break; 510 break;
495 #endif // RLV_EXPERIMENTAL_FORCEWEAR_GESTURES 511 #endif // RLV_EXTENSION_FORCEWEAR_GESTURES
496 default: 512 default:
497 break; 513 break;
498 } 514 }
@@ -507,6 +523,431 @@ bool RlvWearableItemCollector::operator()(LLInventoryCategory* pFolder, LLInvent
507} 523}
508 524
509// ============================================================================ 525// ============================================================================
526// RlvForceWear
527//
528
529// Checked: 2010-02-17 (RLVa-1.1.0o) | Modified: RLVa-1.1.0o
530void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, eWearAction eAction, eWearFlags eFlags)
531{
532 // [See LLWearableBridge::wearOnAvatar(): don't wear anything until initial wearables are loaded, can destroy clothing items]
533 if (!gAgent.areWearablesLoaded())
534 {
535 LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
536 return;
537 }
538 // Sanity check - getAvatarObject() can't be NULL [see RlvForceWear::isWearingItem()]
539 LLVOAvatar* pAvatar = gAgent.getAvatarObject();
540 if (!pAvatar)
541 return;
542
543 LLInventoryModel::cat_array_t folders;
544 LLInventoryModel::item_array_t items;
545 RlvWearableItemCollector functor(pFolder->getUUID(), (ACTION_ATTACH == eAction), (FLAG_MATCHALL & eFlags));
546
547 // Grab a list of all the items we'll be wearing/attaching
548 gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor);
549
550 for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
551 {
552 LLViewerInventoryItem* pItem = items.get(idxItem);
553
554 // If it's wearable it should be worn on detach
555 if ( (ACTION_DETACH == eAction) && (isWearableItem(pItem)) && (!isWearingItem(pItem)) )
556 continue;
557
558 // NOTES: * if there are composite items then RlvWearableItemCollector made sure they can be worn (or taken off depending)
559 // * some scripts issue @remattach=force,attach:worn-items=force so we need to attach items even if they're currently worn
560 switch (pItem->getType())
561 {
562 case LLAssetType::AT_BODYPART:
563 RLV_ASSERT(ACTION_ATTACH == eAction); // RlvWearableItemCollector shouldn't be supplying us with body parts on detach
564 case LLAssetType::AT_CLOTHING:
565 if (ACTION_ATTACH == eAction)
566 {
567 // The check for whether we're replacing a currently worn composite item happens in onWearableArrived()
568 if (std::find(m_addWearables.begin(), m_addWearables.end(), pItem) == m_addWearables.end())
569 m_addWearables.push_back(pItem);
570 }
571 else
572 {
573 LLWearable* pWearable = gAgent.getWearableFromWearableItem(pItem->getUUID());
574 if ( (pWearable) && (isForceRemovable(pWearable->getType(), false)) )
575 {
576 if (std::find(m_remWearables.begin(), m_remWearables.end(), pWearable->getType()) == m_remWearables.end())
577 m_remWearables.push_back(pWearable->getType());
578 }
579 }
580 break;
581
582 case LLAssetType::AT_OBJECT:
583 if (ACTION_ATTACH == eAction)
584 {
585 LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(pItem, true);
586 if ( ( (pAttachPt) && // Need a specific attach pt that
587 (!gRlvHandler.isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE)) && // doesn't have a locked object
588 (!gRlvHandler.isLockedAttachment(pAttachPt, RLV_LOCK_ADD)) ) || // and that can be attached to
589 (RlvSettings::getEnableSharedWear()) )
590 {
591 if (std::find(m_addAttachments.begin(), m_addAttachments.end(), pItem) == m_addAttachments.end())
592 {
593 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
594 // We still need to check whether we're about to replace a currently worn composite item
595 // (which we're not if we're just reattaching an attachment we're already wearing)
596 LLViewerInventoryCategory* pCompositeFolder = NULL;
597 if ( (pAttachPt->getObject()) && (RlvSettings::getEnableComposites()) &&
598 (pAttachPt->getItemID() != pItem->getUUID()) &&
599 (gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pCompositeFolder)) )
600 {
601 // If we can't take off the composite folder this item would replace then don't allow it to get attached
602 if (gRlvHandler.canTakeOffComposite(pCompositeFolder))
603 {
604 forceFolder(pCompositeFolder, ACTION_DETACH, FLAG_DEFAULT);
605 m_addAttachments.push_back(pItem);
606 }
607 }
608 else
609 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
610 {
611 m_addAttachments.push_back(pItem);
612 }
613 }
614 }
615 }
616 else
617 {
618 LLViewerJointAttachment* pAttachPt = pAvatar->getWornAttachmentPoint(pItem->getUUID());
619 if ( (pAttachPt) && (isForceDetachable(pAttachPt, false)) )
620 {
621 if (std::find(m_remAttachments.begin(), m_remAttachments.end(), pAttachPt) == m_remAttachments.end())
622 m_remAttachments.push_back(pAttachPt);
623 }
624 }
625 break;
626
627 #ifdef RLV_EXTENSION_FORCEWEAR_GESTURES
628 case LLAssetType::AT_GESTURE:
629 if (ACTION_ATTACH == eAction)
630 {
631 if (std::find(m_addGestures.begin(), m_addGestures.end(), pItem) == m_addGestures.end())
632 m_addGestures.push_back(pItem);
633 }
634 else
635 {
636 if (std::find(m_remGestures.begin(), m_remGestures.end(), pItem) == m_remGestures.end())
637 m_remGestures.push_back(pItem);
638 }
639 break;
640 #endif // RLV_EXTENSION_FORCEWEAR_GESTURES
641
642 default:
643 break;
644 }
645 }
646}
647
648// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
649bool RlvForceWear::isForceDetachable(LLViewerJointAttachment* pAttachPt, bool fCheckComposite /*=true*/, LLViewerObject* pExceptObj /*=NULL*/)
650{
651 // Attachment point can be detached by an RLV command if:
652 // - something is worn on the attachment point
653 // - what's worn isn't "remove locked" by anything (or anything except the object specified by pExceptObj)
654 // - what's worn is strippable
655 // - composite folders are disabled *or* what's worn isn't part of a composite folder that has at least one item locked
656 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
657 LLViewerInventoryCategory* pFolder = NULL;
658 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
659 return
660 (
661 (pAttachPt) && (pAttachPt->getObject()) &&
662 ( (!pExceptObj) ? (!gRlvHandler.isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE))
663 : (!gRlvHandler.isLockedAttachmentExcept(pAttachPt->getObject(), RLV_LOCK_REMOVE, pExceptObj)) )
664 #ifdef RLV_EXTENSION_FLAG_NOSTRIP
665 && (gRlvHandler.isStrippable(pAttachPt->getItemID()))
666 #endif // RLV_EXTENSION_FLAG_NOSTRIP
667 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
668 && ( (!fCheckComposite) || (!RlvSettings::getEnableComposites()) ||
669 (!gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pFolder)) || (gRlvHandler.canTakeOffComposite(pFolder)) )
670 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
671 );
672}
673
674// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
675void RlvForceWear::forceDetach(LLViewerJointAttachment* pAttachPt)
676{
677 // Sanity check - no need to process duplicate removes
678 if ( (!pAttachPt) || (std::find(m_remAttachments.begin(), m_remAttachments.end(), pAttachPt) != m_remAttachments.end()) )
679 return;
680
681 if (isForceDetachable(pAttachPt))
682 {
683 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
684 LLViewerInventoryCategory* pFolder = NULL;
685 if ( (RlvSettings::getEnableComposites()) &&
686 (gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pFolder)) )
687 {
688 // Attachment belongs to a composite folder so detach the entire folder (if we can take it off)
689 if (gRlvHandler.canTakeOffComposite(pFolder))
690 forceFolder(pFolder, ACTION_DETACH, FLAG_DEFAULT);
691 }
692 else
693 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
694 {
695 m_remAttachments.push_back(pAttachPt);
696 }
697 }
698}
699
700// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
701bool RlvForceWear::isForceRemovable(EWearableType wtType, bool fCheckComposite /*=true*/, const LLUUID& idExcept /*=LLUUID::null*/)
702{
703 // Wearable type can be removed by an RLV command if:
704 // - something is worn on that layer
705 // - its asset type is AT_CLOTHING
706 // - what's worn isn't "remove locked" by anything (or anything except the object specified by idExcept)
707 // - what's worn is strippable
708 // - composite folders are disabled *or* what's worn isn't part of a composite folder that has at least one item locked
709 LLWearable* pWearable = gAgent.getWearable(wtType);
710 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
711 LLViewerInventoryCategory* pFolder = NULL;
712 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
713 return
714 (
715 (pWearable) &&
716 (LLAssetType::AT_CLOTHING == LLWearable::typeToAssetType(wtType)) &&
717 ( (idExcept.notNull()) ? (gRlvHandler.isRemovable(wtType))
718 : (gRlvHandler.isRemovableExcept(wtType, idExcept)) )
719 #ifdef RLV_EXTENSION_FLAG_NOSTRIP
720 && (gRlvHandler.isStrippable(gAgent.getWearableItem(wtType)))
721 #endif // RLV_EXTENSION_FLAG_NOSTRIP
722 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
723 && ( (!fCheckComposite) || (!RlvSettings::getEnableComposites()) ||
724 (!gRlvHandler.getCompositeInfo(gAgent.getWearableItem(wtType), NULL, &pFolder)) || (gRlvHandler.canTakeOffComposite(pFolder)) )
725 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
726 );
727}
728
729// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
730void RlvForceWear::forceRemove(EWearableType wtType)
731{
732 // Sanity check - no need to process duplicate removes
733 if ( (WT_INVALID == wtType) || (std::find(m_remWearables.begin(), m_remWearables.end(), wtType) != m_remWearables.end()) )
734 return;
735
736 if (isForceRemovable(wtType))
737 {
738 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
739 LLViewerInventoryCategory* pFolder = NULL;
740 if ( (RlvSettings::getEnableComposites()) &&
741 (gRlvHandler.getCompositeInfo(gAgent.getWearableItem(wtType), NULL, &pFolder)) )
742 {
743 // Wearable belongs to a composite folder so detach the entire folder (if we can take it off)
744 if (gRlvHandler.canTakeOffComposite(pFolder))
745 forceFolder(pFolder, ACTION_DETACH, FLAG_DEFAULT);
746 }
747 else
748 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
749 {
750 m_remWearables.push_back(wtType);
751 }
752 }
753}
754
755// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
756void RlvForceWear::processAdd()
757{
758 // Process attachments
759 if (m_addAttachments.size())
760 {
761 // Workaround for RezMultipleAttachmentsFromInv bug (see http://jira.secondlife.com/browse/SVC-5383)
762 #ifndef RLV_WORKAROUND_REZMULTIPLEATTACH
763 wear_attachments_on_avatar(m_addAttachments, FALSE);
764 #else
765 for (S32 idxItem = 0, cntItem = m_addAttachments.count(); idxItem < cntItem; idxItem++)
766 {
767 LLViewerInventoryItem* pItem = m_addAttachments.get(idxItem);
768
769 S32 idxAttachPt = gRlvHandler.getAttachPointIndex(pItem, true);
770 if (0 != idxAttachPt)
771 {
772 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11
773 LLAttachmentRezAction* rez_action = new LLAttachmentRezAction();
774 rez_action->mItemID = pItem->getUUID();
775 rez_action->mAttachPt = idxAttachPt;
776
777 confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); // (Will call delete on rez_action)
778 #else // Version: 1.23.4
779 LLSD payload;
780 payload["item_id"] = pItem->getUUID();
781 payload["attachment_point"] = idxAttachPt;
782
783 LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/);
784 #endif
785 }
786 }
787 #endif // RLV_WORKAROUND_REZMULTIPLEATTACH
788
789 m_addAttachments.clear();
790 }
791
792 // Process wearables
793 if (m_addWearables.size())
794 {
795 // [See wear_inventory_category_on_avatar_step2()]
796 LLWearableHoldingPattern* pWearData = new LLWearableHoldingPattern(TRUE);
797
798 // We need to populate 'pWearData->mFoundList' before doing anything else because (some of) the assets might already be available
799 for (S32 idxItem = 0, cntItem = m_addWearables.count(); idxItem < cntItem; idxItem++)
800 {
801 LLViewerInventoryItem* pItem = m_addWearables.get(idxItem);
802 if ( (pItem) && ((LLAssetType::AT_BODYPART == pItem->getType()) || (LLAssetType::AT_CLOTHING == pItem->getType())) )
803 {
804 LLFoundData* pFound = new LLFoundData(pItem->getUUID(), pItem->getAssetUUID(), pItem->getName(), pItem->getType());
805 pWearData->mFoundList.push_front(pFound);
806 }
807 }
808
809 if (!pWearData->mFoundList.size())
810 {
811 delete pWearData;
812 return;
813 }
814
815 // If all the assets are available locally then "pWearData" will be freed *before* the last "gWearableList.getAsset()" call returns
816 bool fContinue = true; LLWearableHoldingPattern::found_list_t::const_iterator itWearable = pWearData->mFoundList.begin();
817 while ( (fContinue) && (itWearable != pWearData->mFoundList.end()) )
818 {
819 const LLFoundData* pFound = *itWearable;
820 ++itWearable;
821 fContinue = (itWearable != pWearData->mFoundList.end());
822 gWearableList.getAsset(pFound->mAssetID, pFound->mName, pFound->mAssetType, onWearableArrived, (void*)pWearData);
823 }
824
825 m_addWearables.clear();
826 }
827
828 // Process gestures
829 if (m_addGestures.size())
830 {
831 gGestureManager.activateGestures(m_addGestures);
832 for (S32 idxGesture = 0, cntGesture = m_addGestures.count(); idxGesture < cntGesture; idxGesture++)
833 gInventory.updateItem(m_addGestures.get(idxGesture));
834 gInventory.notifyObservers();
835
836 m_addGestures.clear();
837 }
838}
839
840// Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i
841void RlvForceWear::processRem()
842{
843 // Process attachments
844 if (m_remAttachments.size())
845 {
846 // [See LLAgent::userRemoveAllAttachments()]
847 gMessageSystem->newMessage("ObjectDetach");
848 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
849 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
850 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
851
852 for (std::list<LLViewerJointAttachment*>::const_iterator itAttachPt = m_remAttachments.begin();
853 itAttachPt != m_remAttachments.end(); ++itAttachPt)
854 {
855 LLViewerJointAttachment* pAttachPt = *itAttachPt;
856 if (pAttachPt->getObject())
857 {
858 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
859 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, pAttachPt->getObject()->getLocalID());
860 }
861 }
862
863 gMessageSystem->sendReliable(gAgent.getRegionHost());
864
865 m_remAttachments.clear();
866 }
867
868 // Process wearables
869 if (m_remWearables.size())
870 {
871 for (std::list<EWearableType>::const_iterator itWearable = m_remWearables.begin(); itWearable != m_remWearables.end(); ++itWearable)
872 gAgent.removeWearable(*itWearable);
873
874 m_remWearables.clear();
875 }
876
877 // Process gestures
878 if (m_remGestures.size())
879 {
880 for (S32 idxGesture = 0, cntGesture = m_remGestures.count(); idxGesture < cntGesture; idxGesture++)
881 {
882 LLViewerInventoryItem* pItem = m_remGestures.get(idxGesture);
883 gGestureManager.deactivateGesture(pItem->getUUID());
884 gInventory.updateItem(pItem);
885 gInventory.notifyObservers();
886 }
887
888 m_remGestures.clear();
889 }
890}
891
892// Checked: 2010-02-17 (RLVa-1.1.0o) | Modified: RLVa-1.1.0o
893void RlvForceWear::onWearableArrived(LLWearable* pWearable, void* pParam)
894{
895 #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS
896 // If this wearable will end up replacing a currently worn one that belongs to a composite folder then we need to detach the composite
897 LLViewerInventoryCategory* pFolder = NULL;
898 if ( (RlvSettings::getEnableComposites()) && (pWearable) && (gAgent.getWearable(pWearable->getType())) )
899 {
900 // If we're just rewearing the same item we're already wearing then we're not replacing a composite folder
901 LLWearableHoldingPattern* pWearData = (LLWearableHoldingPattern*)pParam; LLUUID idItem;
902 for (LLWearableHoldingPattern::found_list_t::const_iterator itWearable = pWearData->mFoundList.begin();
903 itWearable != pWearData->mFoundList.end(); ++itWearable)
904 {
905 LLFoundData* pFound = *itWearable;
906 if (pWearable->getID() == pFound->mAssetID)
907 {
908 idItem = pFound->mItemID;
909 break;
910 }
911 }
912 if ( (idItem.notNull()) && (idItem != gAgent.getWearableItem(pWearable->getType())) &&
913 (gRlvHandler.getCompositeInfo(gAgent.getWearableItem(pWearable->getType()), NULL, &pFolder)) )
914 {
915 RlvForceWear rlvWear;
916 rlvWear.forceFolder(pFolder, ACTION_DETACH, FLAG_DEFAULT);
917 rlvWear.done();
918 }
919 }
920 #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS
921
922 wear_inventory_category_on_avatar_loop(pWearable, pParam);
923}
924
925// ============================================================================
926// RlvBehaviourNotifyObserver
927//
928
929void RlvBehaviourNotifyObserver::changed(const RlvCommand& rlvCmd, bool fInternal)
930{
931 if (fInternal)
932 return;
933
934 std::string strCmd = rlvCmd.asString(), strNotify; ERlvParamType eCmdType = rlvCmd.getParamType();
935 if ( (RLV_TYPE_ADD == eCmdType) || (RLV_TYPE_REMOVE == eCmdType) )
936 strNotify = llformat("/%s=%s", strCmd.c_str(), rlvCmd.getParam().c_str());
937 else if (RLV_TYPE_CLEAR == eCmdType)
938 strNotify = llformat("/%s", strCmd.c_str());
939 else
940 return;
941
942 for (std::multimap<LLUUID, notifyData>::const_iterator itNotify = m_Notifications.begin();
943 itNotify != m_Notifications.end(); ++itNotify)
944 {
945 if ( (itNotify->second.strFilter.empty()) || (std::string::npos != strCmd.find(itNotify->second.strFilter)) )
946 rlvSendChatReply(itNotify->second.nChannel, strNotify);
947 }
948}
949
950// ============================================================================
510// RlvWLSnapshot 951// RlvWLSnapshot
511// 952//
512 953
@@ -546,38 +987,6 @@ RlvWLSnapshot* RlvWLSnapshot::takeSnapshot()
546} 987}
547 988
548// ========================================================================= 989// =========================================================================
549// RlvSettings
550//
551
552BOOL RlvSettings::fShowNameTags = FALSE;
553
554BOOL RlvSettings::getEnableWear()
555{
556 return
557 rlvGetSettingBOOL(RLV_SETTING_ENABLEWEAR, TRUE) && // "Enable Wear" is toggled on and...
558 (!gRlvHandler.hasBehaviour(RLV_BHVR_DEFAULTWEAR)) && // not restricted and...
559 (!gRlvHandler.hasBehaviour(RLV_BHVR_ADDATTACH)); // we have attach points we can attach to [see RlvHandler::onAddRemAttach()]
560}
561
562#ifdef RLV_EXTENSION_STARTLOCATION
563 // Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1d
564 void RlvSettings::updateLoginLastLocation()
565 {
566 if (gSavedPerAccountSettings.controlExists(RLV_SETTING_LOGINLASTLOCATION))
567 {
568 BOOL fValue = (gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)) ||
569 ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) &&
570 (gAgent.getAvatarObject()) && (!gAgent.getAvatarObject()->mIsSitting) );
571 if (gSavedPerAccountSettings.getBOOL(RLV_SETTING_LOGINLASTLOCATION) != fValue)
572 {
573 gSavedPerAccountSettings.setBOOL(RLV_SETTING_LOGINLASTLOCATION, fValue);
574 gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
575 }
576 }
577 }
578#endif // RLV_EXTENSION_STARTLOCATION
579
580// =========================================================================
581// Various helper classes/timers/functors 990// Various helper classes/timers/functors
582// 991//
583 992
@@ -618,39 +1027,40 @@ void RlvCurrentlyWorn::fetchWorn()
618 f.fetchItems(idItems); 1027 f.fetchItems(idItems);
619} 1028}
620 1029
621// Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0f 1030void RlvGiveToRLVAgentOffer::done()
622bool RlvSelectHasLockedAttach::apply(LLSelectNode* pNode)
623{
624 return (pNode->getObject()) ? gRlvHandler.isLockedAttachment(pNode->getObject(), m_eLock) : false;
625}
626
627// Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0f
628bool RlvSelectIsOwnedByOrGroupOwned::apply(LLSelectNode* pNode)
629{ 1031{
630 return (pNode->mPermissions->isGroupOwned()) || (pNode->mPermissions->getOwner() == m_idAgent); 1032 LLViewerInventoryCategory* pRlvRoot = gRlvHandler.getSharedRoot();
631} 1033 LLViewerInventoryCategory* pFolder = (mCompleteFolders.size()) ? gInventory.getCategory(mCompleteFolders[0]) : NULL;
1034 if ( (pRlvRoot) && (pFolder) )
1035 {
1036 std::string strName = pFolder->getName();
1037 if (strName.find(RLV_PUTINV_PREFIX) == 0)
1038 {
1039 LLInventoryModel::update_list_t update;
1040 LLInventoryModel::LLCategoryUpdate updOldParent(pFolder->getParentUUID(), -1);
1041 update.push_back(updOldParent);
1042 LLInventoryModel::LLCategoryUpdate updNewParent(pRlvRoot->getUUID(), 1);
1043 update.push_back(updNewParent);
1044 gInventory.accountForUpdate(update);
1045
1046 LLPointer<LLViewerInventoryCategory> pNewFolder = new LLViewerInventoryCategory(pFolder);
1047 pNewFolder->setParent(pRlvRoot->getUUID());
1048 pNewFolder->updateParentOnServer(FALSE);
1049 pNewFolder->rename(strName.erase(0, strName.find(RLV_FOLDER_PREFIX_PUTINV)));
1050 pNewFolder->updateServer(FALSE);
1051 gInventory.updateCategory(pNewFolder);
1052 }
1053 }
632 1054
633// Checked: 2009-05-31 (RLVa-0.2.0f) | Modified: RLVa-0.2.0f 1055 gInventory.removeObserver(this);
634bool RlvSelectIsSittingOn::apply(LLSelectNode* pNode) 1056 gInventory.notifyObservers();
635{ 1057 delete this;
636 return (pNode->getObject()) && (pNode->getObject()->getRootEdit() == m_pObject);
637} 1058}
638 1059
639// ============================================================================ 1060// ============================================================================
640// Various helper functions 1061// Various helper functions
641// 1062//
642 1063
643// Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a
644BOOL rlvAttachToEnabler(void* pParam)
645{
646 // Disable an option on the "Attach to (HUD)" submenu if:
647 // - the attachment point is locked non-detachable with an object attached
648 // - the attachment point is locked non-attachable
649 return (pParam != NULL) &&
650 (!gRlvHandler.isLockedAttachment(((LLViewerJointAttachment*)pParam)->getObject(), RLV_LOCK_REMOVE)) &&
651 (!gRlvHandler.isLockedAttachment((LLViewerJointAttachment*)pParam, RLV_LOCK_ADD));
652}
653
654// Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0g 1064// Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0g
655bool rlvCanDeleteOrReturn() 1065bool rlvCanDeleteOrReturn()
656{ 1066{
@@ -677,13 +1087,6 @@ bool rlvCanDeleteOrReturn()
677 return fIsAllowed; 1087 return fIsAllowed;
678} 1088}
679 1089
680// Checked: 2009-10-04 (RLVa-1.0.4b) | Modified: RLVa-1.0.4b
681BOOL rlvEnableWearEnabler(void* pParam)
682{
683 // Visually disables the "Enable Wear" option when restricted from toggling it
684 return (!gRlvHandler.hasBehaviour(RLV_BHVR_DEFAULTWEAR));
685}
686
687// Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d 1090// Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d
688S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type) 1091S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type)
689{ 1092{
@@ -712,12 +1115,12 @@ S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType
712 1115
713 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 1116 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11
714 LLStringUtil::format_map_t args; 1117 LLStringUtil::format_map_t args;
715 args["[MESSAGE]"] = llformat("Restrained Life Support will be %s after you restart", 1118 args["[MESSAGE]"] = llformat("RestrainedLove Support will be %s after you restart",
716 (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" ); 1119 (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" );
717 gViewerWindow->alertXml("GenericAlert", args); 1120 gViewerWindow->alertXml("GenericAlert", args);
718 #else // Version: 1.23.4 1121 #else // Version: 1.23.4
719 LLSD args; 1122 LLSD args;
720 args["MESSAGE"] = llformat("Restrained Life Support will be %s after you restart", 1123 args["MESSAGE"] = llformat("RestrainedLove Support will be %s after you restart",
721 (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" ); 1124 (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" );
722 LLNotifications::instance().add("GenericAlert", args); 1125 LLNotifications::instance().add("GenericAlert", args);
723 #endif 1126 #endif