aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llinventorybridge.cpp6
-rw-r--r--linden/indra/newview/lltooldraganddrop.cpp4
-rw-r--r--linden/indra/newview/llviewermenu.cpp12
-rw-r--r--linden/indra/newview/llviewermessage.cpp10
-rw-r--r--linden/indra/newview/rlvhandler.cpp104
-rw-r--r--linden/indra/newview/rlvhandler.h9
-rw-r--r--linden/indra/newview/rlvhelper.cpp9
-rw-r--r--linden/indra/newview/rlvhelper.h78
8 files changed, 104 insertions, 128 deletions
diff --git a/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp
index 618c4f9..0d5625c 100644
--- a/linden/indra/newview/llinventorybridge.cpp
+++ b/linden/indra/newview/llinventorybridge.cpp
@@ -3505,7 +3505,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
3505 if ( (rlv_handler_t::isEnabled()) && (!RlvSettings::getEnableWear()) && (gRlvHandler.hasLockedAttachment()) ) 3505 if ( (rlv_handler_t::isEnabled()) && (!RlvSettings::getEnableWear()) && (gRlvHandler.hasLockedAttachment()) )
3506 { 3506 {
3507 LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(item, true); 3507 LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(item, true);
3508 if ( (!pAttachPt) || (!gRlvHandler.isDetachable(pAttachPt->getObject())) ) 3508 if ( (!pAttachPt) || (!gRlvHandler.isDetachable(pAttachPt)) )
3509 disabled_items.push_back(std::string("Object Wear")); 3509 disabled_items.push_back(std::string("Object Wear"));
3510 } 3510 }
3511// [/RLVa:KB] 3511// [/RLVa:KB]
@@ -4057,7 +4057,7 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
4057 for (S32 idxObj = obj_item_array.count() - 1; idxObj >= 0; idxObj--) 4057 for (S32 idxObj = obj_item_array.count() - 1; idxObj >= 0; idxObj--)
4058 { 4058 {
4059 LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(obj_item_array.get(idxObj).get(), true); 4059 LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(obj_item_array.get(idxObj).get(), true);
4060 if ( ((!pAttachPt) || (!gRlvHandler.isDetachable(pAttachPt->getObject()))) ) 4060 if ( ((!pAttachPt) || (!gRlvHandler.isDetachable(pAttachPt))) )
4061 obj_item_array.remove(idxObj); 4061 obj_item_array.remove(idxObj);
4062 } 4062 }
4063 obj_count = obj_item_array.count(); 4063 obj_count = obj_item_array.count();
@@ -4245,7 +4245,7 @@ void wear_attachments_on_avatar(const std::set<LLUUID>& item_ids, BOOL remove)
4245// [RLVa:KB] - Checked: 2009-09-11 (RLVa-1.0.2c) | Modified: RLVa-1.0.2c 4245// [RLVa:KB] - Checked: 2009-09-11 (RLVa-1.0.2c) | Modified: RLVa-1.0.2c
4246 LLViewerJointAttachment* pAttachPt = NULL; 4246 LLViewerJointAttachment* pAttachPt = NULL;
4247 if ( (!rlv_handler_t::isEnabled()) || (RlvSettings::getEnableWear()) || (!gRlvHandler.hasLockedAttachment()) || 4247 if ( (!rlv_handler_t::isEnabled()) || (RlvSettings::getEnableWear()) || (!gRlvHandler.hasLockedAttachment()) ||
4248 (((pAttachPt = gRlvHandler.getAttachPoint(item, true)) != NULL) && (gRlvHandler.isDetachable(pAttachPt->getObject()))) ) 4248 (((pAttachPt = gRlvHandler.getAttachPoint(item, true)) != NULL) && (gRlvHandler.isDetachable(pAttachPt))) )
4249 { 4249 {
4250 items.put(item); 4250 items.put(item);
4251 } 4251 }
diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp
index c99ccbf..178bde6 100644
--- a/linden/indra/newview/lltooldraganddrop.cpp
+++ b/linden/indra/newview/lltooldraganddrop.cpp
@@ -2014,10 +2014,10 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
2014 return ACCEPT_NO; 2014 return ACCEPT_NO;
2015 } 2015 }
2016 2016
2017// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-1.0.0c 2017// [RLVa:KB] - Checked: 2009-09-08 (RLVa-1.0.2c) | Modified: RLVa-1.0.2c
2018 LLViewerJointAttachment* pAttachPt = NULL; 2018 LLViewerJointAttachment* pAttachPt = NULL;
2019 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) && (!RlvSettings::getEnableWear()) && 2019 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) && (!RlvSettings::getEnableWear()) &&
2020 ( ((pAttachPt = gRlvHandler.getAttachPoint(item, true)) == NULL) || (!gRlvHandler.isDetachable(pAttachPt->getObject())) ) ) 2020 ( ((pAttachPt = gRlvHandler.getAttachPoint(item, true)) == NULL) || (!gRlvHandler.isDetachable(pAttachPt)) ) )
2021 { 2021 {
2022 return ACCEPT_NO_LOCKED; 2022 return ACCEPT_NO_LOCKED;
2023 } 2023 }
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp
index d11bc02..98dd0ea 100644
--- a/linden/indra/newview/llviewermenu.cpp
+++ b/linden/indra/newview/llviewermenu.cpp
@@ -6045,9 +6045,9 @@ private:
6045 6045
6046// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) 6046// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c)
6047 if ( (rlv_handler_t::isEnabled()) && 6047 if ( (rlv_handler_t::isEnabled()) &&
6048 ( ((index == 0) && (gRlvHandler.hasLockedAttachment())) || // Can't wear on default attach point 6048 ( ((index == 0) && (gRlvHandler.hasLockedAttachment())) || // Can't wear on default attach point
6049 ((index > 0) && (!gRlvHandler.isDetachable(attachment_point->getObject()))) || // Can't replace locked attachment 6049 ((index > 0) && (!gRlvHandler.isDetachable(attachment_point))) || // Can't replace locked attachment
6050 (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) ) // Attach on rezzed object == "Take" 6050 (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) ) // Attach on rezzed object == "Take"
6051 { 6051 {
6052 setObjectSelection(NULL); // Clear the selection or it'll get stuck 6052 setObjectSelection(NULL); // Clear the selection or it'll get stuck
6053 return true; 6053 return true;
@@ -6449,9 +6449,9 @@ BOOL object_selected_and_point_valid(void *user_data)
6449 // - enabler set up in LLVOAvatar::buildCharacter() => Rezzed prim / right-click / "Attach >" [user_data == pAttachPt] 6449 // - enabler set up in LLVOAvatar::buildCharacter() => Rezzed prim / right-click / "Attach >" [user_data == pAttachPt]
6450 // - enabler set up in LLVOAvatar::buildCharacter() => Rezzed prim / Edit menu / "Attach Object" [user_data == pAttachPt] 6450 // - enabler set up in LLVOAvatar::buildCharacter() => Rezzed prim / Edit menu / "Attach Object" [user_data == pAttachPt]
6451 LLViewerJointAttachment* pAttachPt = (LLViewerJointAttachment*)user_data; 6451 LLViewerJointAttachment* pAttachPt = (LLViewerJointAttachment*)user_data;
6452 if ( ((!pAttachPt) && (gRlvHandler.hasLockedAttachment())) || // Don't allow attach to default attach point 6452 if ( ((!pAttachPt) && (gRlvHandler.hasLockedAttachment())) || // Don't allow attach to default attach point
6453 ((pAttachPt) && (!gRlvHandler.isDetachable(pAttachPt->getObject()))) || // Don't allow replacing of locked attachment 6453 ((pAttachPt) && (!gRlvHandler.isDetachable(pAttachPt))) || // Don't allow replacing of locked attachment
6454 (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) // Attaching a rezzed object == "Take" 6454 (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) // Attaching a rezzed object == "Take"
6455 { 6455 {
6456 return FALSE; 6456 return FALSE;
6457 } 6457 }
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp
index cecef95..33d3d51 100644
--- a/linden/indra/newview/llviewermessage.cpp
+++ b/linden/indra/newview/llviewermessage.cpp
@@ -2579,18 +2579,16 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
2579 verb = " " + LLTrans::getString("whisper") + " "; 2579 verb = " " + LLTrans::getString("whisper") + " ";
2580 break; 2580 break;
2581 case CHAT_TYPE_OWNER: 2581 case CHAT_TYPE_OWNER:
2582// [RLVa:KB] - Checked: 2009-08-05 (RLVa-1.0.1e) | Modified: RLVa-1.0.1e 2582// [RLVa:KB] - Checked: 2009-08-28 (RLVa-1.0.2a) | Modified: RLVa-1.0.2a
2583 if ( (rlv_handler_t::isEnabled()) && (mesg.length() > 3) && (RLV_CMD_PREFIX == mesg[0]) ) 2583 if ( (rlv_handler_t::isEnabled()) && (mesg.length() > 3) && (RLV_CMD_PREFIX == mesg[0]) && (CHAT_TYPE_OWNER == chat.mChatType) )
2584 { 2584 {
2585 mesg.erase(0, 1); 2585 mesg.erase(0, 1);
2586 LLStringUtil::toLower(mesg); 2586 LLStringUtil::toLower(mesg);
2587 2587
2588 std::string strExecuted, strFailed, strRetained, *pstr; 2588 std::string strExecuted, strFailed, strRetained, *pstr;
2589 2589
2590 typedef boost::tokenizer<boost::char_separator<char> > tokenizer; 2590 boost_tokenizer tokens(mesg, boost::char_separator<char>(",", "", boost::drop_empty_tokens));
2591 boost::char_separator<char> sep(",", "", boost::drop_empty_tokens); 2591 for (boost_tokenizer::const_iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken)
2592 tokenizer tokens(mesg, sep);
2593 for (tokenizer::iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken)
2594 { 2592 {
2595 if (LLStartUp::getStartupState() == STATE_STARTED) 2593 if (LLStartUp::getStartupState() == STATE_STARTED)
2596 { 2594 {
diff --git a/linden/indra/newview/rlvhandler.cpp b/linden/indra/newview/rlvhandler.cpp
index 2915002..987c62a 100644
--- a/linden/indra/newview/rlvhandler.cpp
+++ b/linden/indra/newview/rlvhandler.cpp
@@ -93,7 +93,7 @@ inline bool rlvIsWearingItem(const LLInventoryItem* pItem)
93static bool rlvParseNotifyOption(const std::string& strOption, S32& nChannel, std::string& strFilter) 93static bool rlvParseNotifyOption(const std::string& strOption, S32& nChannel, std::string& strFilter)
94{ 94{
95 boost_tokenizer tokens(strOption, boost::char_separator<char>(";", "", boost::keep_empty_tokens)); 95 boost_tokenizer tokens(strOption, boost::char_separator<char>(";", "", boost::keep_empty_tokens));
96 boost_tokenizer::iterator itTok = tokens.begin(); 96 boost_tokenizer::const_iterator itTok = tokens.begin();
97 97
98 // Extract and sanity check the first token (required) which is the channel 98 // Extract and sanity check the first token (required) which is the channel
99 if ( (itTok == tokens.end()) || (!LLStringUtil::convertToS32(*itTok, nChannel)) || (!rlvIsValidChannel(nChannel)) ) 99 if ( (itTok == tokens.end()) || (!LLStringUtil::convertToS32(*itTok, nChannel)) || (!rlvIsValidChannel(nChannel)) )
@@ -274,7 +274,7 @@ bool RlvHandler::isDetachableExcept(S32 idxAttachPt, LLViewerObject *pObj) const
274 return true; 274 return true;
275} 275}
276 276
277// Checked: 2009-05-31 (RLVa-0.2.0e) | Modified: RLVa-0.2.0e 277// Checked: 2009-09-06 (RLVa-1.0.2b) | Modified: RLVa-1.0.2b
278bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable) 278bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable)
279{ 279{
280 // Sanity check - make sure it's an object we know about 280 // Sanity check - make sure it's an object we know about
@@ -284,20 +284,12 @@ bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDe
284 284
285 if (!fDetachable) 285 if (!fDetachable)
286 { 286 {
287 // Sanity check - make sure it's not already marked undetachable by this object (NOTE: m_Attachments is a *multimap*, not a map) 287 // NOTE: m_Attachments can contain duplicate <idxAttachPt, idRlvObj> pairs (ie @detach:spine=n,detach=n from an attachment on spine)
288 for (rlv_detach_map_t::const_iterator itAttach = m_Attachments.lower_bound(idxAttachPt),
289 endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach)
290 {
291 if (itObj->second.m_UUID == itAttach->second)
292 return false;
293 }
294
295 m_Attachments.insert(std::pair<S32, LLUUID>(idxAttachPt, itObj->second.m_UUID)); 288 m_Attachments.insert(std::pair<S32, LLUUID>(idxAttachPt, itObj->second.m_UUID));
296 return true; 289 return true;
297 } 290 }
298 else 291 else
299 { 292 {
300 // NOTE: m_Attachments is a *multimap*, not a map
301 for (rlv_detach_map_t::iterator itAttach = m_Attachments.lower_bound(idxAttachPt), 293 for (rlv_detach_map_t::iterator itAttach = m_Attachments.lower_bound(idxAttachPt),
302 endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) 294 endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach)
303 { 295 {
@@ -325,11 +317,11 @@ bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDe
325 LLViewerInventoryItem* pItem = gInventory.getItem(idItem); 317 LLViewerInventoryItem* pItem = gInventory.getItem(idItem);
326 if (pItem) 318 if (pItem)
327 { 319 {
328 if (-1 != pItem->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) 320 if (std::string::npos != pItem->getName().find(RLV_FOLDER_FLAG_NOSTRIP))
329 return false; 321 return false;
330 322
331 LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); 323 LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID());
332 if ( (pFolder) && (-1 != pFolder->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) ) 324 if ( (pFolder) && (std::string::npos != pFolder->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) )
333 return false; 325 return false;
334 } 326 }
335 } 327 }
@@ -499,7 +491,7 @@ BOOL RlvHandler::processCommand(const LLUUID& uuid, const std::string& strCmd, b
499 itCurCmd = itCmd++; // Point itCmd ahead so it won't get invalidated if/when we erase a command 491 itCurCmd = itCmd++; // Point itCmd ahead so it won't get invalidated if/when we erase a command
500 492
501 const RlvCommand& rlvCmdRem = *itCurCmd; 493 const RlvCommand& rlvCmdRem = *itCurCmd;
502 if ( (strFilter.empty()) || (-1 != rlvCmdRem.asString().find(strFilter)) ) 494 if ( (strFilter.empty()) || (std::string::npos != rlvCmdRem.asString().find(strFilter)) )
503 { 495 {
504 fContinue = (rlvObj.m_Commands.size() > 1); // rlvObj will become invalid once we remove the last command 496 fContinue = (rlvObj.m_Commands.size() > 1); // rlvObj will become invalid once we remove the last command
505 strCmdRem = rlvCmdRem.getBehaviour() + ":" + rlvCmdRem.getOption() + "=y"; 497 strCmdRem = rlvCmdRem.getBehaviour() + ":" + rlvCmdRem.getOption() + "=y";
@@ -780,22 +772,15 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC
780 { 772 {
781 case RLV_BHVR_DETACH: // @detach[:<option>]=y - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d 773 case RLV_BHVR_DETACH: // @detach[:<option>]=y - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d
782 { 774 {
783 S32 idxAttachPt; 775 S32 idxAttachPt = 0;
784 if (strOption.empty()) // @detach=y 776 if (strOption.empty()) // @detach=y
785 { 777 {
786 // The object may or may not (if it got detached) still exist so clean up the hard way 778 // The object may or may not (if it got detached) still exist
787 if (m_Objects.find(uuid) != m_Objects.end()) 779 rlv_object_map_t::const_iterator itObj = m_Objects.find(uuid);
788 { 780 if (itObj != m_Objects.end())
789 for (rlv_detach_map_t::const_iterator itAttach = m_Attachments.begin(), endAttach = m_Attachments.end(); 781 idxAttachPt = itObj->second.m_idxAttachPt;
790 itAttach != endAttach; ++itAttach) 782 if (idxAttachPt)
791 { 783 setDetachable(idxAttachPt, uuid, true);
792 if (itAttach->second == uuid)
793 {
794 setDetachable(itAttach->first, uuid, true); // <- invalidates our iterators on return
795 break;
796 }
797 }
798 }
799 } 784 }
800 else if ((idxAttachPt = getAttachPointIndex(strOption, true))) // @detach:<attachpt>=y 785 else if ((idxAttachPt = getAttachPointIndex(strOption, true))) // @detach:<attachpt>=y
801 { 786 {
@@ -946,10 +931,8 @@ BOOL RlvHandler::processForceCommand(const LLUUID& idObj, const RlvCommand& rlvC
946 { 931 {
947 LLVector3d posGlobal; 932 LLVector3d posGlobal;
948 933
949 typedef boost::tokenizer<boost::char_separator<char> > tokenizer; 934 boost_tokenizer tokens(strOption, boost::char_separator<char>("/", "", boost::keep_empty_tokens)); int idx = 0;
950 boost::char_separator<char> sep("/", "", boost::keep_empty_tokens); 935 for (boost_tokenizer::const_iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken)
951 tokenizer tokens(strOption, sep); int idx = 0;
952 for (tokenizer::iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken)
953 { 936 {
954 if (idx < 3) 937 if (idx < 3)
955 LLStringUtil::convertToF64(*itToken, posGlobal[idx++]); 938 LLStringUtil::convertToF64(*itToken, posGlobal[idx++]);
@@ -1165,7 +1148,7 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm
1165 case RLV_BHVR_GETINVWORN: // @getinvworn[:path]=<channel> - Checked: 1148 case RLV_BHVR_GETINVWORN: // @getinvworn[:path]=<channel> - Checked:
1166 onGetInvWorn(rlvCmd.getOption(), strReply); 1149 onGetInvWorn(rlvCmd.getOption(), strReply);
1167 break; 1150 break;
1168 case RLV_BHVR_FINDFOLDER: // @findfolder:<criteria>=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) 1151 case RLV_BHVR_FINDFOLDER: // @findfolder:<criteria>=<channel> - Checked: 2009-08-26 (RLVa-1.0.2a) | Modified: RLVa-1.0.2a
1169 { 1152 {
1170 // COMPAT-RLV: RLV 1.16.1 returns the first random folder it finds (probably tries to match "" to a folder name?) 1153 // COMPAT-RLV: RLV 1.16.1 returns the first random folder it finds (probably tries to match "" to a folder name?)
1171 // (just going to stick with what's there for now... no option => no folder) 1154 // (just going to stick with what's there for now... no option => no folder)
@@ -1173,7 +1156,8 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm
1173 if ( (!strOption.empty()) && (findSharedFolders(strOption, folders)) ) 1156 if ( (!strOption.empty()) && (findSharedFolders(strOption, folders)) )
1174 { 1157 {
1175 // We need to return an "in depth" result so whoever has the most '/' is our lucky winner 1158 // We need to return an "in depth" result so whoever has the most '/' is our lucky winner
1176 int maxSlashes = 0, curSlashes; std::string strFolderName; 1159 // (maxSlashes needs to be initialized to -1 since children of the #RLV folder won't have '/' in their shared path)
1160 int maxSlashes = -1, curSlashes; std::string strFolderName;
1177 for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) 1161 for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++)
1178 { 1162 {
1179 strFolderName = getSharedPath(folders.get(idxFolder)); 1163 strFolderName = getSharedPath(folders.get(idxFolder));
@@ -1307,6 +1291,9 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded)
1307 rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID()); 1291 rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID());
1308 if (itObj != m_Objects.end()) 1292 if (itObj != m_Objects.end())
1309 { 1293 {
1294 // Save the attachment point index
1295 itObj->second.m_idxAttachPt = idxAttachPt;
1296
1310 // If it's an attachment we processed commands for but that only just rezzed in we need to mark it as existing in gObjectList 1297 // If it's an attachment we processed commands for but that only just rezzed in we need to mark it as existing in gObjectList
1311 if (!itObj->second.m_fLookup) 1298 if (!itObj->second.m_fLookup)
1312 itObj->second.m_fLookup = true; 1299 itObj->second.m_fLookup = true;
@@ -1315,7 +1302,7 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded)
1315 if (itObj->second.hasBehaviour(RLV_BHVR_DETACH)) 1302 if (itObj->second.hasBehaviour(RLV_BHVR_DETACH))
1316 { 1303 {
1317 // (Copy/paste from processAddCommand) 1304 // (Copy/paste from processAddCommand)
1318 setDetachable(pObj, pObj->getID(), false); 1305 setDetachable(idxAttachPt, pObj->getID(), false);
1319 1306
1320 if (pObj->isHUDAttachment()) 1307 if (pObj->isHUDAttachment())
1321 LLPipeline::sShowHUDAttachments = TRUE; // Prevents hiding of locked HUD attachments 1308 LLPipeline::sShowHUDAttachments = TRUE; // Prevents hiding of locked HUD attachments
@@ -1365,29 +1352,15 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded)
1365 (!getAttachPoint(pFolder, true)) ) 1352 (!getAttachPoint(pFolder, true)) )
1366 { 1353 {
1367 // It's no mod and its parent folder doesn't contain an attach point 1354 // It's no mod and its parent folder doesn't contain an attach point
1368 LLInventoryModel::cat_array_t* pFolders; 1355 if ( (1 == rlvGetDirectDescendentsCount(pFolder, LLAssetType::AT_OBJECT)) && (NEW_CATEGORY_NAME == pFolder->getName()) )
1369 LLInventoryModel::item_array_t* pItems;
1370 gInventory.getDirectDescendentsOf(pFolder->getUUID(), pFolders, pItems);
1371
1372 if (pItems)
1373 { 1356 {
1374 int cntObjects = 0;
1375 for (S32 idxItem = 0, cntItem = pItems->size(); idxItem < cntItem; idxItem++)
1376 {
1377 if (LLAssetType::AT_OBJECT == pItems->get(idxItem)->getType())
1378 cntObjects++;
1379 }
1380
1381 // Only rename if there's exactly 1 object/attachment inside of it [see LLFolderBridge::renameItem()] 1357 // Only rename if there's exactly 1 object/attachment inside of it [see LLFolderBridge::renameItem()]
1382 if ( (1 == cntObjects) && (NEW_CATEGORY_NAME == pFolder->getName()) ) 1358 std::string strName = ".(" + strAttachPt + ")";
1383 {
1384 std::string strName = ".(" + strAttachPt + ")";
1385 1359
1386 pFolder->rename(strName); 1360 pFolder->rename(strName);
1387 pFolder->updateServer(FALSE); 1361 pFolder->updateServer(FALSE);
1388 gInventory.updateCategory(pFolder); 1362 gInventory.updateCategory(pFolder);
1389 //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject() 1363 //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject()
1390 }
1391 } 1364 }
1392 } 1365 }
1393 } 1366 }
@@ -1864,10 +1837,8 @@ LLViewerInventoryCategory* RlvHandler::getSharedFolder(const std::string& strPat
1864 return NULL; 1837 return NULL;
1865 1838
1866 // Walk the path (starting at the root) 1839 // Walk the path (starting at the root)
1867 typedef boost::tokenizer<boost::char_separator<char> > tokenizer; 1840 boost_tokenizer tokens(strPath, boost::char_separator<char>("/", "", boost::drop_empty_tokens));
1868 boost::char_separator<char> sep("/", "", boost::drop_empty_tokens); 1841 for (boost_tokenizer::const_iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken)
1869 tokenizer tokens(strPath, sep);
1870 for (tokenizer::iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken)
1871 { 1842 {
1872 pFolder = getSharedFolder(pFolder->getUUID(), *itToken); 1843 pFolder = getSharedFolder(pFolder->getUUID(), *itToken);
1873 if (!pFolder) 1844 if (!pFolder)
@@ -2102,15 +2073,10 @@ void RlvHandler::onForceRemOutfit(const LLUUID& idObj, const std::string& strOpt
2102 for (int idxType = 0; idxType < WT_COUNT; idxType++) 2073 for (int idxType = 0; idxType < WT_COUNT; idxType++)
2103 { 2074 {
2104 type = (EWearableType)idxType; 2075 type = (EWearableType)idxType;
2076 if (LLAssetType::AT_CLOTHING != LLWearable::typeToAssetType(type))
2077 continue; // Only strip clothing, not bodyparts
2105 2078
2106 // Only strip clothing (that's currently worn and not marked "nostrip") 2079 if ( ((typeOption == type) || (strOption.empty())) && (gAgent.getWearable(type)) && (isStrippable(gAgent.getWearableItem(type))) )
2107 if ( (LLAssetType::AT_CLOTHING != LLWearable::typeToAssetType(type)) ||
2108 (!gAgent.getWearable(type)) || (!isStrippable(gAgent.getWearableItem(type))) )
2109 {
2110 continue;
2111 }
2112
2113 if ( (typeOption == type) || (strOption.empty()) )
2114 { 2080 {
2115 #ifdef RLV_EXPERIMENTAL_COMPOSITES 2081 #ifdef RLV_EXPERIMENTAL_COMPOSITES
2116 // If we're stripping something that's part of a composite folder then we should @detachthis instead 2082 // If we're stripping something that's part of a composite folder then we should @detachthis instead
@@ -2238,7 +2204,7 @@ void RlvHandler::onForceWear(const std::string& strPath, bool fAttach, bool fMat
2238 // Simulate wearing an object to a specific attachment point (copy/paste to suppress replacement dialog) 2204 // Simulate wearing an object to a specific attachment point (copy/paste to suppress replacement dialog)
2239 // LLAttachObject::handleEvent() => rez_attachment() 2205 // LLAttachObject::handleEvent() => rez_attachment()
2240 LLViewerJointAttachment* pAttachPt = getAttachPoint(pItem, true); 2206 LLViewerJointAttachment* pAttachPt = getAttachPoint(pItem, true);
2241 if ( (pAttachPt) && (isDetachable(pAttachPt->getObject())) ) 2207 if ( (pAttachPt) && (isDetachable(pAttachPt)) )
2242 { 2208 {
2243 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 2209 #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11
2244 LLAttachmentRezAction* rez_action = new LLAttachmentRezAction; 2210 LLAttachmentRezAction* rez_action = new LLAttachmentRezAction;
@@ -2498,7 +2464,7 @@ BOOL RlvHandler::setEnabled(BOOL fEnable)
2498 2464
2499BOOL RlvHandler::canDisable() 2465BOOL RlvHandler::canDisable()
2500{ 2466{
2501 return TRUE; 2467 return FALSE;
2502} 2468}
2503 2469
2504void RlvHandler::clearState() 2470void RlvHandler::clearState()
diff --git a/linden/indra/newview/rlvhandler.h b/linden/indra/newview/rlvhandler.h
index df3ff9b..505bfd5 100644
--- a/linden/indra/newview/rlvhandler.h
+++ b/linden/indra/newview/rlvhandler.h
@@ -73,6 +73,7 @@ public:
73 // Returns TRUE if the specified attachment point is detachable 73 // Returns TRUE if the specified attachment point is detachable
74 bool isDetachable(S32 idxAttachPt) const { return (idxAttachPt) && (m_Attachments.find(idxAttachPt) == m_Attachments.end()); } 74 bool isDetachable(S32 idxAttachPt) const { return (idxAttachPt) && (m_Attachments.find(idxAttachPt) == m_Attachments.end()); }
75 bool isDetachable(const LLInventoryItem* pItem) const; 75 bool isDetachable(const LLInventoryItem* pItem) const;
76 bool isDetachable(LLViewerJointAttachment* pAttachPt) const;
76 bool isDetachable(LLViewerObject* pObj) const; 77 bool isDetachable(LLViewerObject* pObj) const;
77 // Returns TRUE if the specified attachment point is set undetachable by anything other than pObj (or one of its children) 78 // Returns TRUE if the specified attachment point is set undetachable by anything other than pObj (or one of its children)
78 bool isDetachableExcept(S32 idxAttachPt, LLViewerObject* pObj) const; 79 bool isDetachableExcept(S32 idxAttachPt, LLViewerObject* pObj) const;
@@ -370,6 +371,14 @@ inline bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUI
370 } 371 }
371#endif // RLV_EXPERIMENTAL_COMPOSITES 372#endif // RLV_EXPERIMENTAL_COMPOSITES
372 373
374// Checked: 2009-09-08 (RLVa-1.0.2c) | Added: RLVa-1.0.2c
375inline bool RlvHandler::isDetachable(LLViewerJointAttachment *pAttachPt) const
376{
377 // If there's an attached object it's faster to just use that; otherwise look up the attachment index because it might be locked empty
378 return (pAttachPt == NULL) ||
379 ( (pAttachPt->getObject() != NULL) && isDetachable(pAttachPt->getObject()) ) || (isDetachable(getAttachPointIndex(pAttachPt)));
380}
381
373// Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d 382// Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d
374inline bool RlvHandler::isDetachable(LLViewerObject* pObj) const 383inline bool RlvHandler::isDetachable(LLViewerObject* pObj) const
375{ 384{
diff --git a/linden/indra/newview/rlvhelper.cpp b/linden/indra/newview/rlvhelper.cpp
index 6b2a1a0..429a527 100644
--- a/linden/indra/newview/rlvhelper.cpp
+++ b/linden/indra/newview/rlvhelper.cpp
@@ -409,12 +409,11 @@ bool rlvCanDeleteOrReturn()
409 return fIsAllowed; 409 return fIsAllowed;
410} 410}
411 411
412// Checked: 2009-07-05 (RLVa-1.0.0c) 412// Checked: 2009-09-08 (RLVa-1.0.2c) | Modified: RLVa-1.0.2c
413BOOL rlvAttachToEnabler(void* pParam) 413BOOL rlvAttachToEnabler(void* pParam)
414{ 414{
415 // Enables/disables an option on the "Attach to (HUD)" submenu depending on whether it is (un)detachable 415 // Enables/disables an option on the "Attach to (HUD)" submenu depending on whether it is (un)detachable
416 LLViewerJointAttachment* pAttachment = (LLViewerJointAttachment*)pParam; 416 return gRlvHandler.isDetachable((LLViewerJointAttachment*)pParam);
417 return (!pAttachment) || (gRlvHandler.isDetachable(pAttachment->getObject()));
418} 417}
419 418
420BOOL RlvGCTimer::tick() 419BOOL RlvGCTimer::tick()
@@ -672,3 +671,7 @@ std::string rlvGetLastParenthesisedText(const std::string& strText, std::string:
672} 671}
673 672
674// ========================================================================= 673// =========================================================================
674// Debug helper functions
675//
676
677// =========================================================================
diff --git a/linden/indra/newview/rlvhelper.h b/linden/indra/newview/rlvhelper.h
index a0e040e..9ceb799 100644
--- a/linden/indra/newview/rlvhelper.h
+++ b/linden/indra/newview/rlvhelper.h
@@ -55,8 +55,8 @@ const S32 RLV_VERSION_PATCH = 0;
55// Implementation version 55// Implementation version
56const S32 RLVa_VERSION_MAJOR = 1; 56const S32 RLVa_VERSION_MAJOR = 1;
57const S32 RLVa_VERSION_MINOR = 0; 57const S32 RLVa_VERSION_MINOR = 0;
58const S32 RLVa_VERSION_PATCH = 1; 58const S32 RLVa_VERSION_PATCH = 2;
59const S32 RLVa_VERSION_BUILD = 7; 59const S32 RLVa_VERSION_BUILD = 2;
60 60
61// The official viewer version we're patching against 61// The official viewer version we're patching against
62#define RLV_MAKE_TARGET(x, y, z) ((x << 16) | (y << 8) | z) 62#define RLV_MAKE_TARGET(x, y, z) ((x << 16) | (y << 8) | z)
@@ -249,7 +249,12 @@ typedef std::list<RlvCommand> rlv_command_list_t;
249class RlvObject 249class RlvObject
250{ 250{
251public: 251public:
252 RlvObject(const LLUUID& uuid) : m_UUID(uuid), m_nLookupMisses(0) { m_fLookup = (NULL != gObjectList.findObject(uuid)); } 252 RlvObject(const LLUUID& uuid) : m_UUID(uuid), m_nLookupMisses(0)
253 {
254 LLViewerObject* pObj = gObjectList.findObject(uuid);
255 m_fLookup = (NULL != pObj);
256 m_idxAttachPt = (pObj) ? ATTACHMENT_ID_FROM_STATE(pObj->getState()) : 0;
257 }
253 258
254 BOOL addCommand(const RlvCommand& rlvCmd); 259 BOOL addCommand(const RlvCommand& rlvCmd);
255 BOOL removeCommand(const RlvCommand& rlvCmd); 260 BOOL removeCommand(const RlvCommand& rlvCmd);
@@ -264,6 +269,7 @@ public:
264 const rlv_command_list_t* getCommandList() const { return &m_Commands; } 269 const rlv_command_list_t* getCommandList() const { return &m_Commands; }
265protected: 270protected:
266 LLUUID m_UUID; // The object's UUID 271 LLUUID m_UUID; // The object's UUID
272 S32 m_idxAttachPt; // The object's attachment point (or 0 if it's not an attachment)
267 bool m_fLookup; // TRUE if the object existed in gObjectList at one point in time 273 bool m_fLookup; // TRUE if the object existed in gObjectList at one point in time
268 S16 m_nLookupMisses; // Count of unsuccessful lookups in gObjectList by the GC 274 S16 m_nLookupMisses; // Count of unsuccessful lookups in gObjectList by the GC
269 rlv_command_list_t m_Commands; // List of behaviours held by this object (in the order they were received) 275 rlv_command_list_t m_Commands; // List of behaviours held by this object (in the order they were received)
@@ -284,11 +290,16 @@ class RlvCriteriaCategoryCollector : public LLInventoryCollectFunctor
284public: 290public:
285 RlvCriteriaCategoryCollector(const std::string& strCriteria) 291 RlvCriteriaCategoryCollector(const std::string& strCriteria)
286 { 292 {
287 typedef boost::tokenizer<boost::char_separator<char> > tokenizer; 293 std::string::size_type idxIt, idxLast = 0;
288 boost::char_separator<char> sep("&&", "", boost::drop_empty_tokens); 294 while (idxLast < strCriteria.length())
289 tokenizer tokens(strCriteria, sep); 295 {
290 for (tokenizer::iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken) 296 idxIt = strCriteria.find("&&", idxLast);
291 m_Criteria.push_back(*itToken); 297 if (std::string::npos == idxIt)
298 idxIt = strCriteria.length();
299 if (idxIt != idxLast)
300 m_Criteria.push_back(strCriteria.substr(idxLast, idxIt - idxLast));
301 idxLast = idxIt + 2;
302 }
292 } 303 }
293 virtual ~RlvCriteriaCategoryCollector() {} 304 virtual ~RlvCriteriaCategoryCollector() {}
294 305
@@ -304,7 +315,7 @@ public:
304 return false; 315 return false;
305 316
306 for (std::list<std::string>::const_iterator itCrit = m_Criteria.begin(); itCrit != m_Criteria.end(); ++itCrit) 317 for (std::list<std::string>::const_iterator itCrit = m_Criteria.begin(); itCrit != m_Criteria.end(); ++itCrit)
307 if (-1 == strFolderName.find(*itCrit)) // Return false on the first mismatch 318 if (std::string::npos == strFolderName.find(*itCrit)) // Return false on the first mismatch
308 return false; 319 return false;
309 return true; 320 return true;
310 } 321 }
@@ -317,7 +328,7 @@ protected:
317/* 328/*
318 * RlvWearableItemCollector 329 * RlvWearableItemCollector
319 * ======================== 330 * ========================
320 * Inventory item filter used by attach/detach/attachall/detachall/getinvworn (also used by "Add/Replace Outfit" and "Take Off Items") 331 * Inventory item filter used by attach/detach/attachall/detachall/getinvworn
321 * 332 *
322 */ 333 */
323 334
@@ -349,11 +360,8 @@ protected:
349}; 360};
350 361
351// ============================================================================ 362// ============================================================================
352/* 363// RlvRetainedCommand
353 * RlvRetainedCommand 364//
354 * ==================
355 *
356 */
357 365
358struct RlvRetainedCommand 366struct RlvRetainedCommand
359{ 367{
@@ -369,11 +377,8 @@ private:
369typedef std::list<RlvRetainedCommand> rlv_retained_list_t; 377typedef std::list<RlvRetainedCommand> rlv_retained_list_t;
370 378
371// ============================================================================ 379// ============================================================================
372/* 380// RlvWLSnapshot
373 * RlvWLSnapshot 381//
374 * =============
375 *
376 */
377 382
378struct RlvWLSnapshot 383struct RlvWLSnapshot
379{ 384{
@@ -389,11 +394,8 @@ private:
389}; 394};
390 395
391// ============================================================================ 396// ============================================================================
392/* 397// RlvSettings
393 * RlvSettings 398//
394 * ===========
395 *
396 */
397 399
398#define RLV_SETTING_MAIN "RestrainedLife" 400#define RLV_SETTING_MAIN "RestrainedLife"
399#define RLV_SETTING_DEBUG "RestrainedLifeDebug" 401#define RLV_SETTING_DEBUG "RestrainedLifeDebug"
@@ -437,10 +439,8 @@ public:
437}; 439};
438 440
439// ============================================================================ 441// ============================================================================
440/* 442// State keeping classes/structure
441 * State keeping classes/structure 443//
442 *
443 */
444 444
445struct RlvRedirInfo 445struct RlvRedirInfo
446{ 446{
@@ -461,10 +461,8 @@ struct RlvReattachInfo
461}; 461};
462 462
463// ============================================================================ 463// ============================================================================
464/* 464// Various helper classes/timers/functors
465 * Various helper classes/timers/functors 465//
466 *
467 */
468 466
469class RlvGCTimer : public LLEventTimer 467class RlvGCTimer : public LLEventTimer
470{ 468{
@@ -504,10 +502,8 @@ struct RlvSelectIsSittingOn : public LLSelectedNodeFunctor
504}; 502};
505 503
506// ============================================================================ 504// ============================================================================
507/* 505// Various helper functions
508 * Various helper functions 506//
509 *
510 */
511 507
512BOOL rlvAttachToEnabler(void* pParam); 508BOOL rlvAttachToEnabler(void* pParam);
513bool rlvCanDeleteOrReturn(); 509bool rlvCanDeleteOrReturn();
@@ -525,6 +521,10 @@ void rlvStringReplace(std::string& strText, std::string strFrom, const std::stri
525std::string rlvGetFirstParenthesisedText(const std::string& strText, std::string::size_type* pidxMatch = NULL); 521std::string rlvGetFirstParenthesisedText(const std::string& strText, std::string::size_type* pidxMatch = NULL);
526std::string rlvGetLastParenthesisedText(const std::string& strText, std::string::size_type* pidxStart = NULL); 522std::string rlvGetLastParenthesisedText(const std::string& strText, std::string::size_type* pidxStart = NULL);
527 523
524// ============================================================================
525// Debug helper functions
526//
527
528#ifdef RLV_ADVANCED_TOGGLE_RLVA 528#ifdef RLV_ADVANCED_TOGGLE_RLVA
529 // "Advanced / RLVa / Enable RLV" menu option 529 // "Advanced / RLVa / Enable RLV" menu option
530 void rlvDbgToggleEnabled(void*); 530 void rlvDbgToggleEnabled(void*);
@@ -561,10 +561,10 @@ inline bool rlvIsEmote(const std::string& strUTF8Text)
561 return (strUTF8Text.length() > 4) && ( (strUTF8Text.compare(0, 4, "/me ") == 0) || (strUTF8Text.compare(0, 4, "/me'") == 0) ); 561 return (strUTF8Text.length() > 4) && ( (strUTF8Text.compare(0, 4, "/me ") == 0) || (strUTF8Text.compare(0, 4, "/me'") == 0) );
562} 562}
563 563
564// Checked: 2009-08-05 (RLVa-1.0.1e) | Added: RLVa-1.0.0e 564// Checked: 2009-09-05 (RLVa-1.0.2a) | Added: RLVa-1.0.2a
565inline bool rlvIsValidChannel(S32 nChannel) 565inline bool rlvIsValidChannel(S32 nChannel)
566{ 566{
567 return (nChannel >= 0) && (CHAT_CHANNEL_DEBUG != nChannel); 567 return (nChannel > 0) && (CHAT_CHANNEL_DEBUG != nChannel);
568} 568}
569 569
570// Checked: 2009-08-05 (RLVa-1.0.1e) | Added: RLVa-1.0.0e 570// Checked: 2009-08-05 (RLVa-1.0.1e) | Added: RLVa-1.0.0e