aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview
diff options
context:
space:
mode:
authorMcCabe Maxsted2009-10-16 16:39:44 -0700
committerMcCabe Maxsted2009-10-16 16:39:44 -0700
commitce82adec2a0124fe27f363653d2652b0f5c61f04 (patch)
tree35b3877b1d1fc92329a44a9a17d183b74b92890b /linden/indra/newview
parentApplied patch for VWR-6787 by Alissa Sabre - 'none' text in group window not ... (diff)
downloadmeta-impy-ce82adec2a0124fe27f363653d2652b0f5c61f04.zip
meta-impy-ce82adec2a0124fe27f363653d2652b0f5c61f04.tar.gz
meta-impy-ce82adec2a0124fe27f363653d2652b0f5c61f04.tar.bz2
meta-impy-ce82adec2a0124fe27f363653d2652b0f5c61f04.tar.xz
Applied RLVa-1.0.4e_20091010_SL-1.22.11-diff.patch
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/app_settings/settings.xml2
-rw-r--r--linden/indra/newview/llagent.cpp4
-rw-r--r--linden/indra/newview/llchatbar.cpp18
-rw-r--r--linden/indra/newview/llinventorybridge.cpp2
-rw-r--r--linden/indra/newview/llpanelinventory.cpp2
-rw-r--r--linden/indra/newview/llviewermenu.cpp2
-rw-r--r--linden/indra/newview/llviewermessage.cpp9
-rw-r--r--linden/indra/newview/llviewertexteditor.cpp2
-rw-r--r--linden/indra/newview/rlvdefines.h17
-rw-r--r--linden/indra/newview/rlvextensions.cpp34
-rw-r--r--linden/indra/newview/rlvextensions.h2
-rw-r--r--linden/indra/newview/rlvhandler.cpp122
-rw-r--r--linden/indra/newview/rlvhandler.h108
-rw-r--r--linden/indra/newview/rlvhelper.cpp67
-rw-r--r--linden/indra/newview/rlvhelper.h55
15 files changed, 285 insertions, 161 deletions
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml
index 55e6131..15bb319 100644
--- a/linden/indra/newview/app_settings/settings.xml
+++ b/linden/indra/newview/app_settings/settings.xml
@@ -65,7 +65,7 @@
65 <key>Type</key> 65 <key>Type</key>
66 <string>Boolean</string> 66 <string>Boolean</string>
67 <key>Value</key> 67 <key>Value</key>
68 <integer>0</integer> 68 <integer>1</integer>
69 </map> 69 </map>
70 <key>RLVaHideLockedLayers</key> 70 <key>RLVaHideLockedLayers</key>
71 <map> 71 <map>
diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp
index 022e1cc..8b118e0 100644
--- a/linden/indra/newview/llagent.cpp
+++ b/linden/indra/newview/llagent.cpp
@@ -5991,7 +5991,7 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
5991{ 5991{
5992// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) 5992// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d)
5993 if ( (rlv_handler_t::isEnabled()) && 5993 if ( (rlv_handler_t::isEnabled()) &&
5994 ( (gRlvHandler.hasBehaviour("tplm")) || 5994 ( (gRlvHandler.hasBehaviour(RLV_BHVR_TPLM)) ||
5995 ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting)) )) 5995 ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting)) ))
5996 { 5996 {
5997 return; 5997 return;
@@ -6065,7 +6065,7 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
6065// [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-07 (RLVa-1.0.0d) 6065// [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-07 (RLVa-1.0.0d)
6066 // If we're getting teleported due to @tpto we should disregard any @tploc=n or @unsit=n restrictions from the same object 6066 // If we're getting teleported due to @tpto we should disregard any @tploc=n or @unsit=n restrictions from the same object
6067 if ( (rlv_handler_t::isEnabled()) && 6067 if ( (rlv_handler_t::isEnabled()) &&
6068 ( (gRlvHandler.hasBehaviourExcept("tploc", gRlvHandler.getCurrentObject())) || 6068 ( (gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOC, gRlvHandler.getCurrentObject())) ||
6069 ( (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting) && 6069 ( (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting) &&
6070 (gRlvHandler.hasBehaviourExcept(RLV_BHVR_UNSIT, gRlvHandler.getCurrentObject()))) ) ) 6070 (gRlvHandler.hasBehaviourExcept(RLV_BHVR_UNSIT, gRlvHandler.getCurrentObject()))) ) )
6071 { 6071 {
diff --git a/linden/indra/newview/llchatbar.cpp b/linden/indra/newview/llchatbar.cpp
index 608fb54..710677a 100644
--- a/linden/indra/newview/llchatbar.cpp
+++ b/linden/indra/newview/llchatbar.cpp
@@ -634,11 +634,11 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
634 if ( (0 == channel) && (rlv_handler_t::isEnabled()) ) 634 if ( (0 == channel) && (rlv_handler_t::isEnabled()) )
635 { 635 {
636 // Adjust the (public) chat "volume" on chat and gestures (also takes care of playing the proper animation) 636 // Adjust the (public) chat "volume" on chat and gestures (also takes care of playing the proper animation)
637 if ( ((CHAT_TYPE_SHOUT == type) || (CHAT_TYPE_NORMAL == type)) && (gRlvHandler.hasBehaviour("chatnormal")) ) 637 if ( ((CHAT_TYPE_SHOUT == type) || (CHAT_TYPE_NORMAL == type)) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATNORMAL)) )
638 type = CHAT_TYPE_WHISPER; 638 type = CHAT_TYPE_WHISPER;
639 else if ( (CHAT_TYPE_SHOUT == type) && (gRlvHandler.hasBehaviour("chatshout")) ) 639 else if ( (CHAT_TYPE_SHOUT == type) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATSHOUT)) )
640 type = CHAT_TYPE_NORMAL; 640 type = CHAT_TYPE_NORMAL;
641 else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour("chatwhisper")) ) 641 else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATWHISPER)) )
642 type = CHAT_TYPE_NORMAL; 642 type = CHAT_TYPE_NORMAL;
643 643
644 animate &= !gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT); 644 animate &= !gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT);
@@ -692,11 +692,11 @@ void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channe
692 if (0 == channel) 692 if (0 == channel)
693 { 693 {
694 // (We already did this before, but LLChatHandler::handle() calls this directly) 694 // (We already did this before, but LLChatHandler::handle() calls this directly)
695 if ( ((CHAT_TYPE_SHOUT == type) || (CHAT_TYPE_NORMAL == type)) && (gRlvHandler.hasBehaviour("chatnormal")) ) 695 if ( ((CHAT_TYPE_SHOUT == type) || (CHAT_TYPE_NORMAL == type)) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATNORMAL)) )
696 type = CHAT_TYPE_WHISPER; 696 type = CHAT_TYPE_WHISPER;
697 else if ( (CHAT_TYPE_SHOUT == type) && (gRlvHandler.hasBehaviour("chatshout")) ) 697 else if ( (CHAT_TYPE_SHOUT == type) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATSHOUT)) )
698 type = CHAT_TYPE_NORMAL; 698 type = CHAT_TYPE_NORMAL;
699 else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour("chatwhisper")) ) 699 else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATWHISPER)) )
700 type = CHAT_TYPE_NORMAL; 700 type = CHAT_TYPE_NORMAL;
701 701
702 // Redirect chat if needed 702 // Redirect chat if needed
@@ -707,20 +707,20 @@ void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channe
707 } 707 }
708 708
709 // Filter public chat if sendchat restricted (and filter anything that redirchat didn't redirect) 709 // Filter public chat if sendchat restricted (and filter anything that redirchat didn't redirect)
710 if ( (gRlvHandler.hasBehaviour("sendchat")) || (gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT)) ) 710 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHAT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT)) )
711 gRlvHandler.filterChat(utf8_out_text, true); 711 gRlvHandler.filterChat(utf8_out_text, true);
712 } 712 }
713 else 713 else
714 { 714 {
715 // Don't allow chat on a non-public channel if sendchannel restricted (unless the channel is an exception) 715 // Don't allow chat on a non-public channel if sendchannel restricted (unless the channel is an exception)
716 if ( (gRlvHandler.hasBehaviour("sendchannel")) && (!gRlvHandler.hasBehaviour("sendchannel", llformat("%d", channel))) ) 716 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHANNEL)) && (!gRlvHandler.isException(RLV_BHVR_SENDCHANNEL, channel)) )
717 return; 717 return;
718 718
719 // Don't allow chat on debug channel if @sendchat, @redirchat or @rediremote restricted (shows as public chat on viewers) 719 // Don't allow chat on debug channel if @sendchat, @redirchat or @rediremote restricted (shows as public chat on viewers)
720 if (channel >= CHAT_CHANNEL_DEBUG) 720 if (channel >= CHAT_CHANNEL_DEBUG)
721 { 721 {
722 bool fIsEmote = rlvIsEmote(utf8_out_text); 722 bool fIsEmote = rlvIsEmote(utf8_out_text);
723 if ( (gRlvHandler.hasBehaviour("sendchat")) || 723 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHAT)) ||
724 ((!fIsEmote) && (gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT))) || 724 ((!fIsEmote) && (gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT))) ||
725 ((fIsEmote) && (gRlvHandler.hasBehaviour(RLV_BHVR_REDIREMOTE))) ) 725 ((fIsEmote) && (gRlvHandler.hasBehaviour(RLV_BHVR_REDIREMOTE))) )
726 { 726 {
diff --git a/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp
index 0d5625c..5060d21 100644
--- a/linden/indra/newview/llinventorybridge.cpp
+++ b/linden/indra/newview/llinventorybridge.cpp
@@ -2943,7 +2943,7 @@ void open_notecard(LLViewerInventoryItem* inv_item,
2943 BOOL take_focus) 2943 BOOL take_focus)
2944{ 2944{
2945// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) 2945// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c)
2946 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour("viewnote")) ) 2946 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) )
2947 { 2947 {
2948 return; 2948 return;
2949 } 2949 }
diff --git a/linden/indra/newview/llpanelinventory.cpp b/linden/indra/newview/llpanelinventory.cpp
index 7ab850f..0ae2aec 100644
--- a/linden/indra/newview/llpanelinventory.cpp
+++ b/linden/indra/newview/llpanelinventory.cpp
@@ -1377,7 +1377,7 @@ void LLTaskNotecardBridge::openItem()
1377 return; 1377 return;
1378 } 1378 }
1379// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) 1379// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c)
1380 if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour("viewnote")) || (!gRlvHandler.isDetachable(object))) ) 1380 if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) || (!gRlvHandler.isDetachable(object))) )
1381 { 1381 {
1382 return; 1382 return;
1383 } 1383 }
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp
index ceb5d5f..4493ddf 100644
--- a/linden/indra/newview/llviewermenu.cpp
+++ b/linden/indra/newview/llviewermenu.cpp
@@ -1423,7 +1423,7 @@ void init_debug_rlva_menu(LLMenuGL* menu)
1423 1423
1424 #ifdef RLV_EXTENSION_ENABLE_WEAR 1424 #ifdef RLV_EXTENSION_ENABLE_WEAR
1425 if (gSavedSettings.controlExists(RLV_SETTING_ENABLEWEAR)) 1425 if (gSavedSettings.controlExists(RLV_SETTING_ENABLEWEAR))
1426 menu->append(new LLMenuItemCheckGL("Enable Wear", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_ENABLEWEAR)); 1426 menu->append(new LLMenuItemCheckGL("Enable Wear", menu_toggle_control, rlvEnableWearEnabler, menu_check_control, (void*)RLV_SETTING_ENABLEWEAR));
1427 menu->appendSeparator(); 1427 menu->appendSeparator();
1428 #endif // RLV_EXTENSION_ENABLE_WEAR 1428 #endif // RLV_EXTENSION_ENABLE_WEAR
1429 1429
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp
index 3baeec0..c403e3e 100644
--- a/linden/indra/newview/llviewermessage.cpp
+++ b/linden/indra/newview/llviewermessage.cpp
@@ -2485,7 +2485,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
2485 color.setVec(1.f,1.f,1.f,1.f); 2485 color.setVec(1.f,1.f,1.f,1.f);
2486 msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg); 2486 msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg);
2487 2487
2488// [RLVa:KB] - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d 2488// [RLVa:KB] - Checked: 2009-10-06 (RLVa-1.0.4d) | Modified: RLVa-1.0.4d
2489 if ( (rlv_handler_t::isEnabled()) && 2489 if ( (rlv_handler_t::isEnabled()) &&
2490 (CHAT_TYPE_START != chat.mChatType) && (CHAT_TYPE_STOP != chat.mChatType) && (CHAT_TYPE_OWNER != chat.mChatType) ) 2490 (CHAT_TYPE_START != chat.mChatType) && (CHAT_TYPE_STOP != chat.mChatType) && (CHAT_TYPE_OWNER != chat.mChatType) )
2491 { 2491 {
@@ -2495,7 +2495,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
2495 // Filtering "rules": 2495 // Filtering "rules":
2496 // avatar => filter all avie text (unless it's this avie or they're an exemption) 2496 // avatar => filter all avie text (unless it's this avie or they're an exemption)
2497 // objects => filter everything except attachments this avie owns 2497 // objects => filter everything except attachments this avie owns
2498 if ( ((CHAT_SOURCE_AGENT == chat.mSourceType) && (from_id != gAgent.getID())) || (!is_owned_by_me) || (!is_attachment) ) 2498 if ( ( (CHAT_SOURCE_AGENT == chat.mSourceType) && (from_id != gAgent.getID()) ) ||
2499 ( (CHAT_SOURCE_OBJECT == chat.mSourceType) && ((!is_owned_by_me) || (!is_attachment)) ) )
2499 { 2500 {
2500 if (!rlvIsEmote(mesg)) 2501 if (!rlvIsEmote(mesg))
2501 { 2502 {
@@ -4933,7 +4934,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
4933// [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0e 4934// [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0e
4934 S32 rlvQuestionsOther = questions; 4935 S32 rlvQuestionsOther = questions;
4935 4936
4936 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour("acceptpermission")) ) 4937 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_ACCEPTPERMISSION)) )
4937 { 4938 {
4938 LLViewerObject* pObj = gObjectList.findObject(taskid); 4939 LLViewerObject* pObj = gObjectList.findObject(taskid);
4939 if (pObj) 4940 if (pObj)
@@ -5308,7 +5309,7 @@ void handle_lure(LLDynamicArray<LLUUID>& ids)
5308 for (LLDynamicArray<LLUUID>::iterator it = ids.begin(); it != ids.end(); ++it) 5309 for (LLDynamicArray<LLUUID>::iterator it = ids.begin(); it != ids.end(); ++it)
5309 { 5310 {
5310 const LLRelationship* pBuddyInfo = LLAvatarTracker::instance().getBuddyInfo(*it); 5311 const LLRelationship* pBuddyInfo = LLAvatarTracker::instance().getBuddyInfo(*it);
5311 if ( (!gRlvHandler.isException(RLV_BHVR_TPLURE, *it)) && 5312 if ( (!gRlvHandler.isException(RLV_BHVR_TPLURE, *it, RLV_CHECK_PERMISSIVE)) &&
5312 ((!pBuddyInfo) || (!pBuddyInfo->isOnline()) || (!pBuddyInfo->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION))) ) 5313 ((!pBuddyInfo) || (!pBuddyInfo->isOnline()) || (!pBuddyInfo->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION))) )
5313 { 5314 {
5314 delete userdata; 5315 delete userdata;
diff --git a/linden/indra/newview/llviewertexteditor.cpp b/linden/indra/newview/llviewertexteditor.cpp
index 76b752c..8f4a944 100644
--- a/linden/indra/newview/llviewertexteditor.cpp
+++ b/linden/indra/newview/llviewertexteditor.cpp
@@ -96,7 +96,7 @@ public:
96 else 96 else
97 { 97 {
98// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) 98// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c)
99 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour("viewnote")) ) 99 if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) )
100 { 100 {
101 return; 101 return;
102 } 102 }
diff --git a/linden/indra/newview/rlvdefines.h b/linden/indra/newview/rlvdefines.h
index 4e6a4d4..d1e0b75 100644
--- a/linden/indra/newview/rlvdefines.h
+++ b/linden/indra/newview/rlvdefines.h
@@ -41,13 +41,14 @@
41 41
42// Version of the specifcation we support 42// Version of the specifcation we support
43const S32 RLV_VERSION_MAJOR = 1; 43const S32 RLV_VERSION_MAJOR = 1;
44const S32 RLV_VERSION_MINOR = 20; 44const S32 RLV_VERSION_MINOR = 21;
45const S32 RLV_VERSION_PATCH = 2; 45const S32 RLV_VERSION_PATCH = 0;
46const S32 RLV_VERSION_BUILD = 0;
46 47
47// Implementation version 48// Implementation version
48const S32 RLVa_VERSION_MAJOR = 1; 49const S32 RLVa_VERSION_MAJOR = 1;
49const S32 RLVa_VERSION_MINOR = 0; 50const S32 RLVa_VERSION_MINOR = 0;
50const S32 RLVa_VERSION_PATCH = 3; 51const S32 RLVa_VERSION_PATCH = 4;
51const S32 RLVa_VERSION_BUILD = 4; 52const S32 RLVa_VERSION_BUILD = 4;
52 53
53// The official viewer version we're patching against 54// The official viewer version we're patching against
@@ -136,6 +137,7 @@ enum ERlvBehaviour {
136 RLV_BHVR_SHOWLOC, // "showloc" 137 RLV_BHVR_SHOWLOC, // "showloc"
137 RLV_BHVR_TPTO, // "tpto" 138 RLV_BHVR_TPTO, // "tpto"
138 RLV_BHVR_ACCEPTTP, // "accepttp" 139 RLV_BHVR_ACCEPTTP, // "accepttp"
140 RLV_BHVR_ACCEPTPERMISSION, // "acceptpermission"
139 RLV_BHVR_SHOWNAMES, // "shownames" 141 RLV_BHVR_SHOWNAMES, // "shownames"
140 RLV_BHVR_FLY, // "fly" 142 RLV_BHVR_FLY, // "fly"
141 RLV_BHVR_GETSITID, // "getsitid" 143 RLV_BHVR_GETSITID, // "getsitid"
@@ -147,6 +149,9 @@ enum ERlvBehaviour {
147 RLV_BHVR_SHOWHOVERTEXTHUD, // "showhovertexthud" 149 RLV_BHVR_SHOWHOVERTEXTHUD, // "showhovertexthud"
148 RLV_BHVR_SHOWHOVERTEXT, // "showhovertext" 150 RLV_BHVR_SHOWHOVERTEXT, // "showhovertext"
149 RLV_BHVR_NOTIFY, // "notify" 151 RLV_BHVR_NOTIFY, // "notify"
152 RLV_BHVR_DEFAULTWEAR, // "defaultwear"
153 RLV_BHVR_VERSIONNUM, // "versionnum"
154 RLV_BHVR_PERMISSIVE, // "permissive"
150 155
151 RLV_BHVR_COUNT, 156 RLV_BHVR_COUNT,
152 RLV_BHVR_UNKNOWN 157 RLV_BHVR_UNKNOWN
@@ -174,6 +179,12 @@ enum ERlvCmdRet {
174 RLV_RET_UNKNOWN // Command unkown 179 RLV_RET_UNKNOWN // Command unkown
175}; 180};
176 181
182enum ERlvExceptionCheck {
183 RLV_CHECK_PERMISSIVE, // Exception can be set by any object
184 RLV_CHECK_STRICT, // Exception must be set by all objects holding the restriction
185 RLV_CHECK_DEFAULT // Permissive or strict will be determined by currently enforced restrictions
186};
187
177// ============================================================================ 188// ============================================================================
178// Settings 189// Settings
179 190
diff --git a/linden/indra/newview/rlvextensions.cpp b/linden/indra/newview/rlvextensions.cpp
index 10d1c46..f31c62e 100644
--- a/linden/indra/newview/rlvextensions.cpp
+++ b/linden/indra/newview/rlvextensions.cpp
@@ -12,13 +12,14 @@
12// ============================================================================ 12// ============================================================================
13 13
14std::map<std::string, S16> RlvExtGetSet::m_DbgAllowed; 14std::map<std::string, S16> RlvExtGetSet::m_DbgAllowed;
15std::map<std::string, std::string> RlvExtGetSet::m_PseudoDebug;
15 16
16// Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h 17// Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h
17RlvExtGetSet::RlvExtGetSet() 18RlvExtGetSet::RlvExtGetSet()
18{ 19{
19 if (!m_DbgAllowed.size()) // m_DbgAllowed is static and should only be initialized once 20 if (!m_DbgAllowed.size()) // m_DbgAllowed is static and should only be initialized once
20 { 21 {
21 m_DbgAllowed.insert(std::pair<std::string, S16>("AvatarSex", DBG_READ | DBG_PSEUDO)); 22 m_DbgAllowed.insert(std::pair<std::string, S16>("AvatarSex", DBG_READ | DBG_WRITE | DBG_PSEUDO));
22 m_DbgAllowed.insert(std::pair<std::string, S16>("RenderResolutionDivisor", DBG_READ | DBG_WRITE)); 23 m_DbgAllowed.insert(std::pair<std::string, S16>("RenderResolutionDivisor", DBG_READ | DBG_WRITE));
23 #ifdef RLV_EXTENSION_CMD_GETSETDEBUG_EX 24 #ifdef RLV_EXTENSION_CMD_GETSETDEBUG_EX
24 m_DbgAllowed.insert(std::pair<std::string, S16>(RLV_SETTING_FORBIDGIVETORLV, DBG_READ)); 25 m_DbgAllowed.insert(std::pair<std::string, S16>(RLV_SETTING_FORBIDGIVETORLV, DBG_READ));
@@ -172,19 +173,27 @@ std::string RlvExtGetSet::onGetDebug(std::string strSetting)
172 return std::string(); 173 return std::string();
173} 174}
174 175
175// Checked: 2009-06-03 (RLVa-0.2.0h) | Added: RLVa-0.2.0h 176// Checked: 2009-10-03 (RLVa-1.0.4e) | Added: RLVa-1.0.4e
176std::string RlvExtGetSet::onGetPseudoDebug(const std::string& strSetting) 177std::string RlvExtGetSet::onGetPseudoDebug(const std::string& strSetting)
177{ 178{
178 // Skip sanity checking because it's all done in RlvExtGetSet::onGetDebug() already 179 // Skip sanity checking because it's all done in RlvExtGetSet::onGetDebug() already
179 if ("AvatarSex" == strSetting) 180 if ("AvatarSex" == strSetting)
180 { 181 {
181 if (gAgent.getAvatarObject()) 182 std::map<std::string, std::string>::const_iterator itPseudo = m_PseudoDebug.find(strSetting);
182 return llformat("%d", (gAgent.getAvatarObject()->getSex() == SEX_MALE)); // [See LLFloaterCustomize::LLFloaterCustomize()] 183 if (itPseudo != m_PseudoDebug.end())
184 {
185 return itPseudo->second;
186 }
187 else
188 {
189 if (gAgent.getAvatarObject())
190 return llformat("%d", (gAgent.getAvatarObject()->getSex() == SEX_MALE)); // [See LLFloaterCustomize::LLFloaterCustomize()]
191 }
183 } 192 }
184 return std::string(); 193 return std::string();
185} 194}
186 195
187// Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h 196// Checked: 2009-10-10 (RLVa-1.0.4e) | Modified: RLVa-1.0.4e
188void RlvExtGetSet::onSetDebug(std::string strSetting, const std::string& strValue) 197void RlvExtGetSet::onSetDebug(std::string strSetting, const std::string& strValue)
189{ 198{
190 S16 dbgFlags; 199 S16 dbgFlags;
@@ -219,6 +228,21 @@ void RlvExtGetSet::onSetDebug(std::string strSetting, const std::string& strValu
219 pSetting->setPersist( (pSetting->isDefault()) ? ((dbgFlags & DBG_PERSIST) == DBG_PERSIST) : false ); 228 pSetting->setPersist( (pSetting->isDefault()) ? ((dbgFlags & DBG_PERSIST) == DBG_PERSIST) : false );
220 } 229 }
221 } 230 }
231 else
232 {
233 onSetPseudoDebug(strSetting, strValue);
234 }
235 }
236}
237
238// Checked: 2009-10-10 (RLVa-1.0.4e) | Modified: RLVa-1.0.4e
239void RlvExtGetSet::onSetPseudoDebug(const std::string& strSetting, const std::string& strValue)
240{
241 if ("AvatarSex" == strSetting)
242 {
243 BOOL fValue;
244 if (LLStringUtil::convertToBOOL(strValue, fValue))
245 m_PseudoDebug[strSetting] = strValue;
222 } 246 }
223} 247}
224 248
diff --git a/linden/indra/newview/rlvextensions.h b/linden/indra/newview/rlvextensions.h
index 5c10c58..5720ba0 100644
--- a/linden/indra/newview/rlvextensions.h
+++ b/linden/indra/newview/rlvextensions.h
@@ -24,6 +24,7 @@ protected:
24 std::string onGetDebug(std::string strSetting); 24 std::string onGetDebug(std::string strSetting);
25 std::string onGetPseudoDebug(const std::string& strSetting); 25 std::string onGetPseudoDebug(const std::string& strSetting);
26 void onSetDebug(std::string strSetting, const std::string& strValue); 26 void onSetDebug(std::string strSetting, const std::string& strValue);
27 void onSetPseudoDebug(const std::string& strSetting, const std::string& strValue);
27 28
28 std::string onGetEnv(std::string strSetting); 29 std::string onGetEnv(std::string strSetting);
29 void onSetEnv(std::string strSetting, const std::string& strValue); 30 void onSetEnv(std::string strSetting, const std::string& strValue);
@@ -33,6 +34,7 @@ protected:
33public: 34public:
34 enum { DBG_READ = 0x01, DBG_WRITE = 0x02, DBG_PERSIST = 0x04, DBG_PSEUDO = 0x08 }; 35 enum { DBG_READ = 0x01, DBG_WRITE = 0x02, DBG_PERSIST = 0x04, DBG_PSEUDO = 0x08 };
35 static std::map<std::string, S16> m_DbgAllowed; 36 static std::map<std::string, S16> m_DbgAllowed;
37 static std::map<std::string, std::string> m_PseudoDebug;
36 38
37 static bool findDebugSetting(/*[in,out]*/ std::string& strSetting, /*[out]*/ S16& flags); 39 static bool findDebugSetting(/*[in,out]*/ std::string& strSetting, /*[out]*/ S16& flags);
38 static S16 getDebugSettingFlags(const std::string& strSetting); 40 static S16 getDebugSettingFlags(const std::string& strSetting);
diff --git a/linden/indra/newview/rlvhandler.cpp b/linden/indra/newview/rlvhandler.cpp
index 6044aa9..69e2e2f 100644
--- a/linden/indra/newview/rlvhandler.cpp
+++ b/linden/indra/newview/rlvhandler.cpp
@@ -286,7 +286,7 @@ bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDe
286 if (!fDetachable) 286 if (!fDetachable)
287 { 287 {
288 #ifdef RLV_EXPERIMENTAL_FIRSTUSE 288 #ifdef RLV_EXPERIMENTAL_FIRSTUSE
289 LLFirstUse::useRlvDetach(); 289 //LLFirstUse::useRlvDetach();
290 #endif // RLV_EXPERIMENTAL_FIRSTUSE 290 #endif // RLV_EXPERIMENTAL_FIRSTUSE
291 291
292 // NOTE: m_Attachments can contain duplicate <idxAttachPt, idRlvObj> pairs (ie @detach:spine=n,detach=n from an attachment on spine) 292 // NOTE: m_Attachments can contain duplicate <idxAttachPt, idRlvObj> pairs (ie @detach:spine=n,detach=n from an attachment on spine)
@@ -338,27 +338,47 @@ bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDe
338// Behaviour related functions 338// Behaviour related functions
339// 339//
340 340
341bool RlvHandler::hasBehaviourExcept(const std::string& strBehaviour, const LLUUID& idObj) const
342{
343 for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj)
344 if ( (idObj != itObj->second.m_UUID) && (itObj->second.hasBehaviour(strBehaviour)) )
345 return true;
346 return false;
347}
348
349bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const 341bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const
350{ 342{
351 for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) 343 for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj)
352 if ( (idObj != itObj->second.m_UUID) && (itObj->second.hasBehaviour(eBehaviour, strOption)) ) 344 if ( (idObj != itObj->second.m_UUID) && (itObj->second.hasBehaviour(eBehaviour, strOption, false)) )
353 return true; 345 return true;
354 return false; 346 return false;
355} 347}
356 348
357bool RlvHandler::hasBehaviourExcept(const std::string& strBehaviour, const std::string& strOption, const LLUUID& idObj) const 349// Checked: 2009-10-04 (RLVa-1.0.4c) | Modified: RLVa-1.0.4c
350bool RlvHandler::isException(ERlvBehaviour eBhvr, const RlvExceptionOption& varOption, ERlvExceptionCheck typeCheck) const
358{ 351{
359 for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) 352 // We need to "strict check" exceptions only if: the restriction is actually in place *and* (isPermissive(eBhvr) == FALSE)
360 if ( (idObj != itObj->second.m_UUID) && (itObj->second.hasBehaviour(strBehaviour, strOption)) ) 353 if (RLV_CHECK_DEFAULT == typeCheck)
361 return true; 354 typeCheck = ( (hasBehaviour(eBhvr)) && (!isPermissive(eBhvr)) ) ? RLV_CHECK_STRICT : RLV_CHECK_PERMISSIVE;
355
356 std::list<LLUUID> objList;
357 if (RLV_CHECK_STRICT == typeCheck)
358 {
359 // If we're "strict checking" then we need the UUID of every object that currently has 'eBhvr' restricted
360 for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj)
361 if (itObj->second.hasBehaviour(eBhvr, !hasBehaviour(RLV_BHVR_PERMISSIVE)))
362 objList.push_back(itObj->first);
363 }
364
365 for (rlv_exception_map_t::const_iterator itException = m_Exceptions.lower_bound(eBhvr),
366 endException = m_Exceptions.upper_bound(eBhvr); itException != endException; ++itException)
367 {
368 if (itException->second.varOption == varOption)
369 {
370 // For permissive checks we just return on the very first match
371 if (RLV_CHECK_PERMISSIVE == typeCheck)
372 return true;
373
374 // For strict checks we don't return until the list is empty (every object with 'eBhvr' restricted also contains the exception)
375 std::list<LLUUID>::iterator itList = std::find(objList.begin(), objList.end(), itException->second.idObject);
376 if (itList != objList.end())
377 objList.erase(itList);
378 if (objList.empty())
379 return true;
380 }
381 }
362 return false; 382 return false;
363} 383}
364 384
@@ -509,7 +529,11 @@ BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd)
509 const std::string& strOption = rlvCmd.getOption(); 529 const std::string& strOption = rlvCmd.getOption();
510 530
511 if ( (RLV_BHVR_UNKNOWN != eBehaviour) && (strOption.empty()) ) 531 if ( (RLV_BHVR_UNKNOWN != eBehaviour) && (strOption.empty()) )
532 {
533 if (rlvCmd.isStrict())
534 addException(uuid, RLV_BHVR_PERMISSIVE, eBehaviour);
512 m_Behaviours[eBehaviour]++; 535 m_Behaviours[eBehaviour]++;
536 }
513 537
514 switch (eBehaviour) 538 switch (eBehaviour)
515 { 539 {
@@ -649,7 +673,7 @@ BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd)
649 case RLV_BHVR_FARTOUCH: 673 case RLV_BHVR_FARTOUCH:
650 { 674 {
651 #ifdef RLV_EXPERIMENTAL_FIRSTUSE 675 #ifdef RLV_EXPERIMENTAL_FIRSTUSE
652 LLFirstUse::useRlvFartouch(); 676 //LLFirstUse::useRlvFartouch();
653 #endif // RLV_EXPERIMENTAL_FIRSTUSE 677 #endif // RLV_EXPERIMENTAL_FIRSTUSE
654 } 678 }
655 break; 679 break;
@@ -695,9 +719,9 @@ BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd)
695 case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:<uuid>=n - Checked: 2009-07-09 (RLVa-0.2.2a) | Modified: RLVa-1.0.0f 719 case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:<uuid>=n - Checked: 2009-07-09 (RLVa-0.2.2a) | Modified: RLVa-1.0.0f
696 { 720 {
697 LLUUID idException(strOption); 721 LLUUID idException(strOption);
698 if (!idException.isNull()) // If there's an option it should be a valid UUID 722 if (idException.notNull()) // If there's an option it should be a valid UUID
699 { 723 {
700 addException(eBehaviour, LLUUID(strOption)); 724 addException(uuid, eBehaviour, idException);
701 725
702 // Clear the object's hover text 726 // Clear the object's hover text
703 LLViewerObject* pObj = gObjectList.findObject(idException); 727 LLViewerObject* pObj = gObjectList.findObject(idException);
@@ -717,6 +741,13 @@ BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd)
717 } 741 }
718 } 742 }
719 break; 743 break;
744 case RLV_BHVR_SENDCHANNEL: // @sendchannel:<uuid>=add - Checked: 2009-10-05 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a
745 {
746 S32 nChannel; // If there's an option it should be a valid (=positive and non-zero) chat channel
747 if ( (!strOption.empty()) && (LLStringUtil::convertToS32(strOption, nChannel)) && (nChannel > 0) )
748 addException(uuid, eBehaviour, nChannel);
749 }
750 break;
720 case RLV_BHVR_RECVCHAT: // @recvchat:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f 751 case RLV_BHVR_RECVCHAT: // @recvchat:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
721 case RLV_BHVR_RECVEMOTE: // @recvemote:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f 752 case RLV_BHVR_RECVEMOTE: // @recvemote:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
722 case RLV_BHVR_RECVIM: // @recvim:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f 753 case RLV_BHVR_RECVIM: // @recvim:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
@@ -724,16 +755,20 @@ BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd)
724 case RLV_BHVR_TPLURE: // @tplure:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f 755 case RLV_BHVR_TPLURE: // @tplure:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
725 case RLV_BHVR_ACCEPTTP: // @accepttp:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f 756 case RLV_BHVR_ACCEPTTP: // @accepttp:<uuid>=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
726 { 757 {
727 addException(eBehaviour, LLUUID(strOption)); 758 LLUUID idException(strOption);
759 if (idException.notNull()) // If there's an option it should be a valid UUID
760 addException(uuid, eBehaviour, LLUUID(strOption));
728 } 761 }
729 break; 762 break;
730 default: 763 case RLV_BHVR_UNKNOWN:
731 { 764 {
732 // Give our observers a chance to handle any command we don't 765 // Give our observers a chance to handle any command we don't
733 RlvEvent rlvEvent(uuid, rlvCmd); 766 RlvEvent rlvEvent(uuid, rlvCmd);
734 m_Emitter.update(&RlvObserver::onAddCommand, rlvEvent); 767 m_Emitter.update(&RlvObserver::onAddCommand, rlvEvent);
735 } 768 }
736 break; 769 break;
770 default:
771 break;
737 } 772 }
738 return TRUE; // Add command success/failure is decided by RlvObject::addCommand() 773 return TRUE; // Add command success/failure is decided by RlvObject::addCommand()
739} 774}
@@ -756,7 +791,11 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC
756 const std::string& strOption = rlvCmd.getOption(); 791 const std::string& strOption = rlvCmd.getOption();
757 792
758 if ( (RLV_BHVR_UNKNOWN != eBehaviour) && (strOption.empty()) ) 793 if ( (RLV_BHVR_UNKNOWN != eBehaviour) && (strOption.empty()) )
794 {
795 if (rlvCmd.isStrict())
796 removeException(uuid, RLV_BHVR_PERMISSIVE, eBehaviour);
759 m_Behaviours[eBehaviour]--; 797 m_Behaviours[eBehaviour]--;
798 }
760 799
761 switch (eBehaviour) 800 switch (eBehaviour)
762 { 801 {
@@ -842,9 +881,9 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC
842 case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:<uuid>=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f 881 case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:<uuid>=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
843 { 882 {
844 LLUUID idException(strOption); 883 LLUUID idException(strOption);
845 if (!idException.isNull()) // If there's an option it should be a valid UUID 884 if (idException.notNull()) // If there's an option it should be a valid UUID
846 { 885 {
847 removeException(eBehaviour, LLUUID(strOption)); 886 removeException(uuid, eBehaviour, idException);
848 887
849 // Restore the object's hover text 888 // Restore the object's hover text
850 LLViewerObject* pObj = gObjectList.findObject(idException); 889 LLViewerObject* pObj = gObjectList.findObject(idException);
@@ -869,6 +908,13 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC
869 } 908 }
870 } 909 }
871 break; 910 break;
911 case RLV_BHVR_SENDCHANNEL: // @sendchannel:<uuid>=rem - Checked: 2009-10-05 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a
912 {
913 S32 nChannel; // If there's an option it should be a valid (=positive and non-zero) chat channel
914 if ( (!strOption.empty()) && (LLStringUtil::convertToS32(strOption, nChannel)) && (nChannel > 0) )
915 removeException(uuid, eBehaviour, nChannel);
916 }
917 break;
872 case RLV_BHVR_RECVCHAT: // @recvchat:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f 918 case RLV_BHVR_RECVCHAT: // @recvchat:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
873 case RLV_BHVR_RECVEMOTE: // @recvemote:<uui>=red - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f 919 case RLV_BHVR_RECVEMOTE: // @recvemote:<uui>=red - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
874 case RLV_BHVR_RECVIM: // @recvim:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f 920 case RLV_BHVR_RECVIM: // @recvim:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
@@ -876,16 +922,20 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC
876 case RLV_BHVR_TPLURE: // @recvim:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f 922 case RLV_BHVR_TPLURE: // @recvim:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
877 case RLV_BHVR_ACCEPTTP: // @accepttp:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f 923 case RLV_BHVR_ACCEPTTP: // @accepttp:<uuid>=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
878 { 924 {
879 removeException(eBehaviour, LLUUID(strOption)); 925 LLUUID idException(strOption);
926 if (idException.notNull()) // If there's an option it should be a valid UUID
927 removeException(uuid, eBehaviour, LLUUID(strOption));
880 } 928 }
881 break; 929 break;
882 default: 930 case RLV_BHVR_UNKNOWN:
883 { 931 {
884 // Give our observers a chance to handle any command we don't 932 // Give our observers a chance to handle any command we don't
885 RlvEvent rlvEvent(uuid, rlvCmd); 933 RlvEvent rlvEvent(uuid, rlvCmd);
886 m_Emitter.update(&RlvObserver::onRemoveCommand, rlvEvent); 934 m_Emitter.update(&RlvObserver::onRemoveCommand, rlvEvent);
887 } 935 }
888 break; 936 break;
937 default:
938 break;
889 } 939 }
890 return TRUE; // Remove commands don't fail, doesn't matter what we return here 940 return TRUE; // Remove commands don't fail, doesn't matter what we return here
891} 941}
@@ -1006,13 +1056,15 @@ BOOL RlvHandler::processForceCommand(const LLUUID& idObj, const RlvCommand& rlvC
1006 } 1056 }
1007 } 1057 }
1008 break; 1058 break;
1009 default: 1059 case RLV_BHVR_UNKNOWN:
1010 { 1060 {
1011 // Give our observers a chance to handle any command we don't 1061 // Give our observers a chance to handle any command we don't
1012 RlvEvent rlvEvent(idObj, rlvCmd); 1062 RlvEvent rlvEvent(idObj, rlvCmd);
1013 fHandled = m_Emitter.update(&RlvObserver::onForceCommand, rlvEvent); 1063 fHandled = m_Emitter.update(&RlvObserver::onForceCommand, rlvEvent);
1014 } 1064 }
1015 break; 1065 break;
1066 default:
1067 break;
1016 } 1068 }
1017 return fHandled; // If we handled it then it'll still be TRUE; if an observer doesn't handle it'll be FALSE 1069 return fHandled; // If we handled it then it'll still be TRUE; if an observer doesn't handle it'll be FALSE
1018} 1070}
@@ -1030,6 +1082,9 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm
1030 case RLV_BHVR_VERSION: // @version=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) 1082 case RLV_BHVR_VERSION: // @version=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h)
1031 strReply = getVersionString(); 1083 strReply = getVersionString();
1032 break; 1084 break;
1085 case RLV_BHVR_VERSIONNUM: // @versionnum=<channel> - Checked: 2009-10-04 (RLVa-1.0.4b) | Added: RLVa-1.0.4b
1086 strReply = getVersionNumString();
1087 break;
1033 case RLV_BHVR_GETOUTFIT: // @getoufit[:<layer>]=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d 1088 case RLV_BHVR_GETOUTFIT: // @getoufit[:<layer>]=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d
1034 { 1089 {
1035 // (Quirk: RLV 1.16.1 will execute @getoutfit=<channel> if <layer> is invalid, so we need to as well) 1090 // (Quirk: RLV 1.16.1 will execute @getoutfit=<channel> if <layer> is invalid, so we need to as well)
@@ -1225,13 +1280,15 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm
1225 strReply = uuid.asString(); 1280 strReply = uuid.asString();
1226 } 1281 }
1227 break; 1282 break;
1228 default: 1283 case RLV_BHVR_UNKNOWN:
1229 { 1284 {
1230 // Give our observers a chance to handle any command we don't 1285 // Give our observers a chance to handle any command we don't
1231 RlvEvent rlvEvent(uuid, rlvCmd); 1286 RlvEvent rlvEvent(uuid, rlvCmd);
1232 return m_Emitter.update(&RlvObserver::onReplyCommand, rlvEvent); 1287 return m_Emitter.update(&RlvObserver::onReplyCommand, rlvEvent);
1233 } 1288 }
1234 break; 1289 break;
1290 default:
1291 break;
1235 } 1292 }
1236 1293
1237 if (fHandled) 1294 if (fHandled)
@@ -1318,7 +1375,7 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded)
1318 itObj->second.m_fLookup = true; 1375 itObj->second.m_fLookup = true;
1319 1376
1320 // In both cases we should check for "@detach=n" and actually lock down the attachment point it got attached to 1377 // In both cases we should check for "@detach=n" and actually lock down the attachment point it got attached to
1321 if (itObj->second.hasBehaviour(RLV_BHVR_DETACH)) 1378 if (itObj->second.hasBehaviour(RLV_BHVR_DETACH, false))
1322 { 1379 {
1323 // (Copy/paste from processAddCommand) 1380 // (Copy/paste from processAddCommand)
1324 setDetachable(idxAttachPt, pObj->getID(), false); 1381 setDetachable(idxAttachPt, pObj->getID(), false);
@@ -1569,7 +1626,7 @@ void RlvHandler::filterChat(std::string& strUTF8Text, bool fFilterEmote) const
1569 { 1626 {
1570 strUTF8Text = "..."; // Emote contains illegal character (or character sequence) 1627 strUTF8Text = "..."; // Emote contains illegal character (or character sequence)
1571 } 1628 }
1572 else if (!hasBehaviour("emote")) 1629 else if (!hasBehaviour(RLV_BHVR_EMOTE))
1573 { 1630 {
1574 int idx = strUTF8Text.find('.'); // Truncate at 20 characters or at the dot (whichever is shorter) 1631 int idx = strUTF8Text.find('.'); // Truncate at 20 characters or at the dot (whichever is shorter)
1575 strUTF8Text = utf8str_chtruncate(strUTF8Text, ( (idx > 0) && (idx < 20) ) ? idx + 1 : 20); 1632 strUTF8Text = utf8str_chtruncate(strUTF8Text, ( (idx > 0) && (idx < 20) ) ? idx + 1 : 20);
@@ -1674,17 +1731,18 @@ bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const
1674 return false; // @sendchat wouldn't filter it so @redirchat won't redirect it either 1731 return false; // @sendchat wouldn't filter it so @redirchat won't redirect it either
1675 } 1732 }
1676 1733
1677 bool fSendChannel = hasBehaviour("sendchannel"); 1734 bool fSendChannel = hasBehaviour(RLV_BHVR_SENDCHANNEL); S32 nChannel = 0;
1678 for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) 1735 for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj)
1679 { 1736 {
1680 for (rlv_command_list_t::const_iterator itCmd = itObj->second.m_Commands.begin(), 1737 for (rlv_command_list_t::const_iterator itCmd = itObj->second.m_Commands.begin(),
1681 endCmd = itObj->second.m_Commands.end(); itCmd != endCmd; ++itCmd) 1738 endCmd = itObj->second.m_Commands.end(); itCmd != endCmd; ++itCmd)
1682 { 1739 {
1683 if ( ( ((!fIsEmote) && (RLV_BHVR_REDIRCHAT == itCmd->getBehaviourType())) || 1740 if ( ( ((!fIsEmote) && (RLV_BHVR_REDIRCHAT == itCmd->getBehaviourType())) || // Redirect if: (not an emote and @redirchat
1684 ((fIsEmote) && (RLV_BHVR_REDIREMOTE == itCmd->getBehaviourType())) ) && 1741 ((fIsEmote) && (RLV_BHVR_REDIREMOTE == itCmd->getBehaviourType())) ) && // OR an emote and @rediremote)
1685 ( (!fSendChannel) || (hasBehaviour("sendchannel", itCmd->getOption())) ) ) 1742 (LLStringUtil::convertToS32(itCmd->getOption(), nChannel)) && // AND the channel is a number
1743 ( (!fSendChannel) || (isException(RLV_BHVR_SENDCHANNEL, nChannel)) ) ) // AND we're allowed to send to that channel
1686 { 1744 {
1687 rlvSendChatReply(itCmd->getOption(), strUTF8Text); 1745 rlvSendChatReply(nChannel, strUTF8Text);
1688 } 1746 }
1689 } 1747 }
1690 } 1748 }
diff --git a/linden/indra/newview/rlvhandler.h b/linden/indra/newview/rlvhandler.h
index 4470632..5295a72 100644
--- a/linden/indra/newview/rlvhandler.h
+++ b/linden/indra/newview/rlvhandler.h
@@ -18,7 +18,7 @@
18typedef std::map<LLUUID, RlvObject> rlv_object_map_t; 18typedef std::map<LLUUID, RlvObject> rlv_object_map_t;
19typedef std::multimap<S32, LLUUID> rlv_detach_map_t; 19typedef std::multimap<S32, LLUUID> rlv_detach_map_t;
20typedef std::map<S32, LLUUID> rlv_reattach_map_t; 20typedef std::map<S32, LLUUID> rlv_reattach_map_t;
21typedef std::multimap<LLUUID, ERlvBehaviour> rlv_exception_map_t; 21typedef std::multimap<ERlvBehaviour, RlvException> rlv_exception_map_t;
22 22
23class RlvHandler 23class RlvHandler
24{ 24{
@@ -29,7 +29,7 @@ public:
29 // -------------------------------- 29 // --------------------------------
30 30
31 /* 31 /*
32 * Rule checking functions 32 * Attachment point helper functions
33 */ 33 */
34public: 34public:
35 // Returns a pointer to the attachment point for a supplied parameter 35 // Returns a pointer to the attachment point for a supplied parameter
@@ -42,45 +42,45 @@ public:
42 S32 getAttachPointIndex(const LLViewerJointAttachment* pObj) const; 42 S32 getAttachPointIndex(const LLViewerJointAttachment* pObj) const;
43 bool hasAttachPointName(const LLInventoryItem* pItem, bool fStrict) const; 43 bool hasAttachPointName(const LLInventoryItem* pItem, bool fStrict) const;
44 44
45 // Returns TRUE is at least one object contains the specified behaviour (and optional parameter) 45 // --------------------------------
46
47 /*
48 * Rule checking functions
49 */
46 // NOTE: - to check @detach=n -> hasLockedAttachment() / hasLockedHUD() / isDetachable() 50 // NOTE: - to check @detach=n -> hasLockedAttachment() / hasLockedHUD() / isDetachable()
51 // - to check exceptions -> isException()
47 // - to check @addoutfit=n -> isWearable() 52 // - to check @addoutfit=n -> isWearable()
48 // - to check @remoutfit=n -> isRemovable() 53 // - to check @remoutfit=n -> isRemovable()
49 // - to check exceptions -> isException() 54public:
50 // (You *can* use hasBehaviour(); the specialized ones just don't have to iterate over all the objects) 55 // Returns TRUE is at least one object contains the specified behaviour (and optional option)
51 bool hasBehaviour(ERlvBehaviour eBehaviour) const { return (eBehaviour < RLV_BHVR_COUNT) ? (0 != m_Behaviours[eBehaviour]) : false; } 56 bool hasBehaviour(ERlvBehaviour eBehaviour) const { return (eBehaviour < RLV_BHVR_COUNT) ? (0 != m_Behaviours[eBehaviour]) : false; }
52 bool hasBehaviour(const std::string& strBehaviour) const;
53 bool hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const; 57 bool hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const;
54 bool hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const; 58 // Returns TRUE if at least one object (except the specified one) contains the specified behaviour (and optional option)
55
56 // Returns TRUE if at least one object (except the specified one) contains the specified behaviour
57 bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const; 59 bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const;
58 bool hasBehaviourExcept(const std::string& strBehaviour, const LLUUID& uuid) const;
59 bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const; 60 bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const;
60 bool hasBehaviourExcept(const std::string& strBehaviour, const std::string& strOption, const LLUUID& idObj) const;
61 61
62 // Returns TRUE if there is at least 1 undetachable attachment 62 // Returns TRUE if there is at least 1 non-detachable attachment
63 bool hasLockedAttachment() const { return (0 != m_Attachments.size()); } 63 bool hasLockedAttachment() const { return (0 != m_Attachments.size()); }
64 // Returns TRUE if there is at least 1 undetachable HUD attachment 64 // Returns TRUE if there is at least 1 non-detachable HUD attachment
65 bool hasLockedHUD() const; 65 bool hasLockedHUD() const;
66
67 // Returns TRUE if the specified attachment point is detachable 66 // Returns TRUE if the specified attachment point is detachable
68 bool isDetachable(S32 idxAttachPt) const { return (idxAttachPt) && (m_Attachments.find(idxAttachPt) == m_Attachments.end()); } 67 bool isDetachable(S32 idxAttachPt) const { return (idxAttachPt) && (m_Attachments.find(idxAttachPt) == m_Attachments.end()); }
69 bool isDetachable(const LLInventoryItem* pItem) const; 68 bool isDetachable(const LLInventoryItem* pItem) const;
70 bool isDetachable(LLViewerJointAttachment* pAttachPt) const; 69 bool isDetachable(LLViewerJointAttachment* pAttachPt) const;
71 bool isDetachable(LLViewerObject* pObj) const; 70 bool isDetachable(LLViewerObject* pObj) const;
72 // Returns TRUE if the specified attachment point is set undetachable by anything other than pObj (or one of its children) 71 // Returns TRUE if the specified attachment point is set non-detachable by anything other than pObj (or one of its children)
73 bool isDetachableExcept(S32 idxAttachPt, LLViewerObject* pObj) const; 72 bool isDetachableExcept(S32 idxAttachPt, LLViewerObject* pObj) const;
74 // Marks the specified attachment point as (un)detachable (return value indicates success ; used by unit tests) 73 // Marks the specified attachment point as (non-)detachable (return value indicates success ; used by unit tests)
75 bool setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable); 74 bool setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable);
76 bool setDetachable(LLViewerObject* pObj, const LLUUID& idRlvObj, bool fDetachable); 75 bool setDetachable(LLViewerObject* pObj, const LLUUID& idRlvObj, bool fDetachable);
77 76
78 // Adds or removes an exception for the specified restriction 77 // Adds or removes an exception for the specified behaviour
79 void addException(ERlvBehaviour eBehaviour, const LLUUID& uuid); 78 void addException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption);
80 void removeException(ERlvBehaviour eBehaviour, const LLUUID& uuid); 79 void removeException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption);
81 // Returns TRUE is the specified UUID is exempt from a restriction (tplure/sendim/recvim/etc) 80 // Returns TRUE if the specified option was added as an exception for the specified behaviour
82 bool isException(ERlvBehaviour eBehaviour, const LLUUID& uuid) const; 81 bool isException(ERlvBehaviour eBhvr, const RlvExceptionOption& varOption, ERlvExceptionCheck typeCheck = RLV_CHECK_DEFAULT) const;
83 bool isException(const std::string& strBehaviour, const LLUUID& uuid) const; 82 // Returns TRUE if the specified behaviour should behave "permissive" (rather than "strict"/"secure")
83 bool isPermissive(ERlvBehaviour eBhvr) const;
84 84
85 // Returns TRUE if the specified layer is removable (use hasBehaviour(RLV_BHVR_REMOUTFIT) for the general case) 85 // Returns TRUE if the specified layer is removable (use hasBehaviour(RLV_BHVR_REMOUTFIT) for the general case)
86 bool isRemovable(EWearableType type) const { return (type < WT_COUNT) ? (0 == m_LayersRem[type]) : true; } 86 bool isRemovable(EWearableType type) const { return (type < WT_COUNT) ? (0 == m_LayersRem[type]) : true; }
@@ -121,6 +121,7 @@ public:
121 void filterNames(std::string& strUTF8Text) const; // @shownames 121 void filterNames(std::string& strUTF8Text) const; // @shownames
122 const std::string& getAnonym(const std::string& strName) const; // @shownames 122 const std::string& getAnonym(const std::string& strName) const; // @shownames
123 std::string getVersionString() const; // @version 123 std::string getVersionString() const; // @version
124 std::string getVersionNumString() const; // @versionnum
124 BOOL isAgentNearby(const LLUUID& uuid) const; // @shownames 125 BOOL isAgentNearby(const LLUUID& uuid) const; // @shownames
125 bool redirectChatOrEmote(const std::string& strUTF8Test) const; // @redirchat and @rediremote 126 bool redirectChatOrEmote(const std::string& strUTF8Test) const; // @redirchat and @rediremote
126 127
@@ -274,11 +275,10 @@ extern rlv_handler_t gRlvHandler;
274// Inlined member functions 275// Inlined member functions
275// 276//
276 277
277// Checked: 2009-07-09 (RLVa-1.0.0f) 278// Checked: 2009-10-04 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a
278inline void RlvHandler::addException(ERlvBehaviour eBehaviour, const LLUUID& uuid) 279inline void RlvHandler::addException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption)
279{ 280{
280 if (!uuid.isNull()) 281 m_Exceptions.insert(std::pair<ERlvBehaviour, RlvException>(eBhvr, RlvException(idObj, eBhvr, varOption)));
281 m_Exceptions.insert(std::pair<LLUUID, ERlvBehaviour>(uuid, eBehaviour));
282} 282}
283 283
284// Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f 284// Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f
@@ -288,7 +288,7 @@ inline bool RlvHandler::canShowHoverText(LLViewerObject *pObj) const
288 !( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTALL)) || 288 !( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTALL)) ||
289 ( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTWORLD)) && (!pObj->isHUDAttachment()) ) || 289 ( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTWORLD)) && (!pObj->isHUDAttachment()) ) ||
290 ( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTHUD)) && (pObj->isHUDAttachment()) ) || 290 ( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTHUD)) && (pObj->isHUDAttachment()) ) ||
291 (isException(RLV_BHVR_SHOWHOVERTEXT, pObj->getID())) ) ); 291 (isException(RLV_BHVR_SHOWHOVERTEXT, pObj->getID(), RLV_CHECK_PERMISSIVE)) ) );
292} 292}
293 293
294// Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d 294// Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d
@@ -321,6 +321,12 @@ inline std::string RlvHandler::getVersionString() const
321 RLVa_VERSION_MAJOR, RLVa_VERSION_MINOR, RLVa_VERSION_PATCH); 321 RLVa_VERSION_MAJOR, RLVa_VERSION_MINOR, RLVa_VERSION_PATCH);
322} 322}
323 323
324// Checked: 2009-10-04 (RLVa-1.0.4b) | Added: RLVa-1.0.4b
325inline std::string RlvHandler::getVersionNumString() const
326{
327 return llformat("%d%02d%02d%02d", RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, RLV_VERSION_BUILD);
328}
329
324// Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d 330// Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d
325inline bool RlvHandler::hasAttachPointName(const LLInventoryItem *pItem, bool fStrict) const 331inline bool RlvHandler::hasAttachPointName(const LLInventoryItem *pItem, bool fStrict) const
326{ 332{
@@ -334,18 +340,6 @@ inline bool RlvHandler::hasBehaviour(ERlvBehaviour eBehaviour, const std::string
334} 340}
335 341
336// Checked: 342// Checked:
337inline bool RlvHandler::hasBehaviour(const std::string& strBehaviour) const
338{
339 return hasBehaviourExcept(strBehaviour, LLUUID::null);
340}
341
342// Checked:
343inline bool RlvHandler::hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const
344{
345 return hasBehaviourExcept(strBehaviour, strOption, LLUUID::null);
346}
347
348// Checked:
349inline bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const 343inline bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const
350{ 344{
351 return hasBehaviourExcept(eBehaviour, std::string(), idObj); 345 return hasBehaviourExcept(eBehaviour, std::string(), idObj);
@@ -379,22 +373,11 @@ inline bool RlvHandler::isDetachable(LLViewerObject* pObj) const
379 return (pObj == NULL) || (!pObj->isAttachment()) || (isDetachable(getAttachPointIndex(pObj))); 373 return (pObj == NULL) || (!pObj->isAttachment()) || (isDetachable(getAttachPointIndex(pObj)));
380} 374}
381 375
382// Checked: 376inline bool RlvHandler::isPermissive(ERlvBehaviour eBhvr) const
383inline bool RlvHandler::isException(ERlvBehaviour eBehaviour, const LLUUID& uuid) const
384{
385 for (rlv_exception_map_t::const_iterator itException = m_Exceptions.lower_bound(uuid),
386 endException = m_Exceptions.upper_bound(uuid); itException != endException; ++itException)
387 {
388 if (itException->second == eBehaviour)
389 return true;
390 }
391 return false;
392}
393
394// Checked:
395inline bool RlvHandler::isException(const std::string& strBehaviour, const LLUUID& uuid) const
396{ 377{
397 return hasBehaviour(strBehaviour, uuid.asString()); 378 return (RlvCommand::hasStrictVariant(eBhvr))
379 ? !((hasBehaviour(RLV_BHVR_PERMISSIVE)) || (isException(RLV_BHVR_PERMISSIVE, eBhvr, RLV_CHECK_PERMISSIVE)))
380 : true;
398} 381}
399 382
400// Checked: 2009-07-29 (RLVa-1.0.1b) | Added: RLVa-1.0.1b 383// Checked: 2009-07-29 (RLVa-1.0.1b) | Added: RLVa-1.0.1b
@@ -428,19 +411,16 @@ inline bool RlvHandler::isRemovableExcept(EWearableType type, const LLUUID& idOb
428 } 411 }
429#endif // RLV_EXTENSION_FLAG_NOSTRIP 412#endif // RLV_EXTENSION_FLAG_NOSTRIP
430 413
431// Checked: 2009-07-09 (RLVa-1.0.0f) 414// Checked: 2009-10-04 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a
432inline void RlvHandler::removeException(ERlvBehaviour eBehaviour, const LLUUID &uuid) 415inline void RlvHandler::removeException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption)
433{ 416{
434 if (!uuid.isNull()) 417 for (rlv_exception_map_t::iterator itException = m_Exceptions.lower_bound(eBhvr),
418 endException = m_Exceptions.upper_bound(eBhvr); itException != endException; ++itException)
435 { 419 {
436 for (rlv_exception_map_t::iterator itException = m_Exceptions.lower_bound(uuid), 420 if ( (itException->second.idObject == idObj) && (itException->second.varOption == varOption) )
437 endException = m_Exceptions.upper_bound(uuid); itException != endException; ++itException)
438 { 421 {
439 if (itException->second == eBehaviour) 422 m_Exceptions.erase(itException);
440 { 423 break;
441 m_Exceptions.erase(itException);
442 break;
443 }
444 } 424 }
445 } 425 }
446} 426}
diff --git a/linden/indra/newview/rlvhelper.cpp b/linden/indra/newview/rlvhelper.cpp
index f495384..c8d430d 100644
--- a/linden/indra/newview/rlvhelper.cpp
+++ b/linden/indra/newview/rlvhelper.cpp
@@ -23,7 +23,7 @@ RlvCommand::RlvBhvrTable RlvCommand::m_BhvrMap;
23 23
24// Checked: 2009-09-10 (RLVa-1.0.3a) | Modified: RLVa-1.0.3a 24// Checked: 2009-09-10 (RLVa-1.0.3a) | Modified: RLVa-1.0.3a
25RlvCommand::RlvCommand(const std::string& strCommand) 25RlvCommand::RlvCommand(const std::string& strCommand)
26 : m_eBehaviour(RLV_BHVR_UNKNOWN), m_eParamType(RLV_TYPE_UNKNOWN) 26 : m_eBehaviour(RLV_BHVR_UNKNOWN), m_fStrict(false), m_eParamType(RLV_TYPE_UNKNOWN)
27{ 27{
28 if ((m_fValid = parseCommand(strCommand, m_strBehaviour, m_strOption, m_strParam))) 28 if ((m_fValid = parseCommand(strCommand, m_strBehaviour, m_strOption, m_strParam)))
29 { 29 {
@@ -51,8 +51,12 @@ RlvCommand::RlvCommand(const std::string& strCommand)
51 return; 51 return;
52 } 52 }
53 53
54 RlvBhvrTable::const_iterator itBhvr = m_BhvrMap.find(m_strBehaviour); 54 // Check if this is the "strict" (aka "secure") variation of a behaviour
55 if (itBhvr != m_BhvrMap.end()) 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))) )
56 m_eBehaviour = itBhvr->second; 60 m_eBehaviour = itBhvr->second;
57} 61}
58 62
@@ -104,8 +108,8 @@ void RlvCommand::initLookupTable()
104 "remoutfit", "getoutfit", "getattach", "showinv", "viewnote", "unsit", "sit", "sendchannel", "getstatus", "getstatusall", 108 "remoutfit", "getoutfit", "getattach", "showinv", "viewnote", "unsit", "sit", "sendchannel", "getstatus", "getstatusall",
105 "getinv", "getinvworn", "findfolder", "findfolders", "attach", "attachall", "detachall", "getpath", "attachthis", 109 "getinv", "getinvworn", "findfolder", "findfolders", "attach", "attachall", "detachall", "getpath", "attachthis",
106 "attachallthis", "detachthis", "detachallthis", "fartouch", "showworldmap", "showminimap", "showloc", "tpto", "accepttp", 110 "attachallthis", "detachthis", "detachallthis", "fartouch", "showworldmap", "showminimap", "showloc", "tpto", "accepttp",
107 "shownames", "fly", "getsitid", "setdebug", "setenv", "detachme", "showhovertextall", "showhovertextworld", 111 "acceptpermission", "shownames", "fly", "getsitid", "setdebug", "setenv", "detachme", "showhovertextall",
108 "showhovertexthud", "showhovertext", "notify" 112 "showhovertextworld", "showhovertexthud", "showhovertext", "notify", "defaultwear", "versionnum", "permissive"
109 }; 113 };
110 114
111 for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++) 115 for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++)
@@ -133,12 +137,14 @@ bool RlvObject::addCommand(const RlvCommand& rlvCmd)
133 return false; 137 return false;
134 138
135 // Don't add duplicate commands for this object (ie @detach=n followed by another @detach=n later on) 139 // Don't add duplicate commands for this object (ie @detach=n followed by another @detach=n later on)
136 bool fDuplicate = 140 for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
137 (RLV_BHVR_UNKNOWN != rlvCmd.getBehaviourType()) 141 {
138 ? hasBehaviour(rlvCmd.getBehaviourType(), rlvCmd.getOption()) 142 if ( (itCmd->getBehaviour() == rlvCmd.getBehaviour()) && (itCmd->getOption() == rlvCmd.getOption()) &&
139 : hasBehaviour(rlvCmd.getBehaviour(), rlvCmd.getOption()); 143 (itCmd->isStrict() == rlvCmd.isStrict() ) )
140 if (fDuplicate) 144 {
141 return false; 145 return false;
146 }
147 }
142 148
143 // Now that we know it's not a duplicate, add it to the end of the list 149 // Now that we know it's not a duplicate, add it to the end of the list
144 m_Commands.push_back(rlvCmd); 150 m_Commands.push_back(rlvCmd);
@@ -155,7 +161,8 @@ bool RlvObject::removeCommand(const RlvCommand& rlvCmd)
155 for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) 161 for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
156 { 162 {
157 //if (*itCmd == rlvCmd) <- commands will never be equal since one is an add and the other is a remove *rolls eyes* 163 //if (*itCmd == rlvCmd) <- commands will never be equal since one is an add and the other is a remove *rolls eyes*
158 if ( (itCmd->getBehaviour() == rlvCmd.getBehaviour()) && (itCmd->getOption() == rlvCmd.getOption()) ) 164 if ( (itCmd->getBehaviour() == rlvCmd.getBehaviour()) && (itCmd->getOption() == rlvCmd.getOption()) &&
165 (itCmd->isStrict() == rlvCmd.isStrict() ) )
159 { 166 {
160 m_Commands.erase(itCmd); 167 m_Commands.erase(itCmd);
161 return true; 168 return true;
@@ -164,34 +171,18 @@ bool RlvObject::removeCommand(const RlvCommand& rlvCmd)
164 return false; // Command was never added so nothing to remove now 171 return false; // Command was never added so nothing to remove now
165} 172}
166 173
167bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour) const 174bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, bool fStrictOnly) const
168{
169 for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
170 if ( (itCmd->getBehaviourType() == eBehaviour) && (itCmd->getOption().empty()) )
171 return true;
172 return false;
173}
174
175bool RlvObject::hasBehaviour(const std::string& strBehaviour) const
176{
177 for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
178 if ( (itCmd->getBehaviour() == strBehaviour) && (itCmd->getOption().empty()) )
179 return true;
180 return false;
181}
182
183bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const
184{ 175{
185 for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) 176 for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
186 if ( (itCmd->getBehaviourType() == eBehaviour) && (itCmd->getOption() == strOption) ) 177 if ( (itCmd->getBehaviourType() == eBehaviour) && (itCmd->getOption().empty()) && ((!fStrictOnly) || (itCmd->isStrict())) )
187 return true; 178 return true;
188 return false; 179 return false;
189} 180}
190 181
191bool RlvObject::hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const 182bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption, bool fStrictOnly) const
192{ 183{
193 for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) 184 for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
194 if ( (itCmd->getBehaviour() == strBehaviour) && (itCmd->getOption() == strOption) ) 185 if ( (itCmd->getBehaviourType() == eBehaviour) && (itCmd->getOption() == strOption) && ((!fStrictOnly) || (itCmd->isStrict())) )
195 return true; 186 return true;
196 return false; 187 return false;
197} 188}
@@ -361,6 +352,11 @@ RlvWLSnapshot* RlvWLSnapshot::takeSnapshot()
361 352
362BOOL RlvSettings::fShowNameTags = FALSE; 353BOOL RlvSettings::fShowNameTags = FALSE;
363 354
355BOOL RlvSettings::getEnableWear()
356{
357 return rlvGetSettingBOOL(RLV_SETTING_ENABLEWEAR, TRUE) && (!gRlvHandler.hasBehaviour(RLV_BHVR_DEFAULTWEAR));
358}
359
364#ifdef RLV_EXTENSION_STARTLOCATION 360#ifdef RLV_EXTENSION_STARTLOCATION
365 // Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1d 361 // Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1d
366 void RlvSettings::updateLoginLastLocation() 362 void RlvSettings::updateLoginLastLocation()
@@ -475,6 +471,13 @@ bool rlvCanDeleteOrReturn()
475 return fIsAllowed; 471 return fIsAllowed;
476} 472}
477 473
474// Checked: 2009-10-04 (RLVa-1.0.4b) | Modified: RLVa-1.0.4b
475BOOL rlvEnableWearEnabler(void* pParam)
476{
477 // Visually disables the "Enable Wear" option when restricted from toggling it
478 return (!gRlvHandler.hasBehaviour(RLV_BHVR_DEFAULTWEAR));
479}
480
478// Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d 481// Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d
479S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type) 482S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type)
480{ 483{
diff --git a/linden/indra/newview/rlvhelper.h b/linden/indra/newview/rlvhelper.h
index f36989b..42d10b8 100644
--- a/linden/indra/newview/rlvhelper.h
+++ b/linden/indra/newview/rlvhelper.h
@@ -9,6 +9,15 @@
9#include "llwlparamset.h" 9#include "llwlparamset.h"
10#include "rlvdefines.h" 10#include "rlvdefines.h"
11 11
12#ifdef LL_WINDOWS
13 #pragma warning (push)
14 #pragma warning (disable : 4702) // warning C4702: unreachable code
15#endif
16#include <boost/variant.hpp>
17#ifdef LL_WINDOWS
18 #pragma warning (pop)
19#endif
20
12// ============================================================================ 21// ============================================================================
13// RlvCommand 22// RlvCommand
14// 23//
@@ -28,10 +37,12 @@ public:
28 const std::string& getOption() const { return m_strOption; } 37 const std::string& getOption() const { return m_strOption; }
29 const std::string& getParam() const { return m_strParam; } 38 const std::string& getParam() const { return m_strParam; }
30 ERlvParamType getParamType() const { return m_eParamType; } 39 ERlvParamType getParamType() const { return m_eParamType; }
40 bool isStrict() const { return m_fStrict; }
31 bool isValid() const { return m_fValid; } 41 bool isValid() const { return m_fValid; }
32 42
33 static ERlvBehaviour getBehaviourFromString(const std::string& strBhvr); 43 static ERlvBehaviour getBehaviourFromString(const std::string& strBhvr);
34 static const std::string& getStringFromBehaviour(ERlvBehaviour eBhvr); 44 static const std::string& getStringFromBehaviour(ERlvBehaviour eBhvr);
45 static bool hasStrictVariant(ERlvBehaviour eBhvr);
35 46
36 static void initLookupTable(); 47 static void initLookupTable();
37protected: 48protected:
@@ -50,6 +61,7 @@ protected:
50 bool m_fValid; 61 bool m_fValid;
51 std::string m_strBehaviour; 62 std::string m_strBehaviour;
52 ERlvBehaviour m_eBehaviour; 63 ERlvBehaviour m_eBehaviour;
64 bool m_fStrict;
53 std::string m_strOption; 65 std::string m_strOption;
54 std::string m_strParam; 66 std::string m_strParam;
55 ERlvParamType m_eParamType; 67 ERlvParamType m_eParamType;
@@ -78,10 +90,8 @@ public:
78 bool removeCommand(const RlvCommand& rlvCmd); 90 bool removeCommand(const RlvCommand& rlvCmd);
79 91
80 std::string getStatusString(const std::string& strMatch) const; 92 std::string getStatusString(const std::string& strMatch) const;
81 bool hasBehaviour(ERlvBehaviour eBehaviour) const; 93 bool hasBehaviour(ERlvBehaviour eBehaviour, bool fStrictOnly) const;
82 bool hasBehaviour(const std::string& strBehaviour) const; 94 bool hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption, bool fStrictOnly) const;
83 bool hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const;
84 bool hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const;
85 95
86 const rlv_command_list_t* getCommandList() const { return &m_Commands; } 96 const rlv_command_list_t* getCommandList() const { return &m_Commands; }
87 97
@@ -190,6 +200,24 @@ private:
190typedef std::list<RlvRetainedCommand> rlv_retained_list_t; 200typedef std::list<RlvRetainedCommand> rlv_retained_list_t;
191 201
192// ============================================================================ 202// ============================================================================
203// RlvException
204//
205
206typedef boost::variant<std::string, LLUUID, S32, ERlvBehaviour> RlvExceptionOption;
207
208struct RlvException
209{
210public:
211 LLUUID idObject; // UUID of the object that added the exception
212 ERlvBehaviour eBehaviour; // Behaviour the exception applies to
213 RlvExceptionOption varOption; // Exception data (type is dependent on eBehaviour)
214
215 RlvException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& option) : idObject(idObj), eBehaviour(eBhvr), varOption(option) {}
216private:
217 RlvException();
218};
219
220// ============================================================================
193// RlvWLSnapshot 221// RlvWLSnapshot
194// 222//
195 223
@@ -225,7 +253,7 @@ public:
225 static BOOL getDebug() { return rlvGetSettingBOOL(RLV_SETTING_DEBUG, FALSE); } 253 static BOOL getDebug() { return rlvGetSettingBOOL(RLV_SETTING_DEBUG, FALSE); }
226 static BOOL getForbidGiveToRLV() { return rlvGetSettingBOOL(RLV_SETTING_FORBIDGIVETORLV, TRUE); } 254 static BOOL getForbidGiveToRLV() { return rlvGetSettingBOOL(RLV_SETTING_FORBIDGIVETORLV, TRUE); }
227 255
228 static BOOL getEnableWear() { return rlvGetSettingBOOL(RLV_SETTING_ENABLEWEAR, FALSE); } 256 static BOOL getEnableWear();
229 static BOOL getHideLockedLayers() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDLAYER, FALSE); } 257 static BOOL getHideLockedLayers() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDLAYER, FALSE); }
230 static BOOL getHideLockedAttach() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDATTACH, FALSE); } 258 static BOOL getHideLockedAttach() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDATTACH, FALSE); }
231 static BOOL getHideLockedInventory() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDINVENTORY, FALSE); } 259 static BOOL getHideLockedInventory() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDINVENTORY, FALSE); }
@@ -290,6 +318,7 @@ struct RlvSelectIsSittingOn : public LLSelectedNodeFunctor
290 318
291BOOL rlvAttachToEnabler(void* pParam); 319BOOL rlvAttachToEnabler(void* pParam);
292bool rlvCanDeleteOrReturn(); 320bool rlvCanDeleteOrReturn();
321BOOL rlvEnableWearEnabler(void* pParam);
293S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type); 322S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type);
294bool rlvIsEmote(const std::string& strUTF8Text); 323bool rlvIsEmote(const std::string& strUTF8Text);
295bool rlvIsValidReplyChannel(S32 nChannel); 324bool rlvIsValidReplyChannel(S32 nChannel);
@@ -344,6 +373,22 @@ inline void RlvCurrentlyWorn::fetchItem(const LLUUID& idItem)
344 } 373 }
345} 374}
346 375
376inline bool RlvCommand::hasStrictVariant(ERlvBehaviour eBhvr)
377{
378 switch (eBhvr)
379 {
380 case RLV_BHVR_RECVCHAT:
381 case RLV_BHVR_RECVEMOTE:
382 case RLV_BHVR_RECVIM:
383 case RLV_BHVR_SENDIM:
384 case RLV_BHVR_TPLURE:
385 case RLV_BHVR_SENDCHANNEL:
386 return true;
387 default:
388 return false;
389 }
390}
391
347// ============================================================================ 392// ============================================================================
348// Inlined helper functions 393// Inlined helper functions
349// 394//